goat3d

changeset 48:9ef9de80649c

implemented animation track XML saving
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 29 Dec 2013 06:01:59 +0200
parents 498ca7ac7047
children 0ecb788a87f7 fa5c52ea9d59
files src/goat3d_writexml.cc src/xform_node.cc src/xform_node.h
diffstat 3 files changed, 123 insertions(+), 36 deletions(-) [+]
line diff
     1.1 --- a/src/goat3d_writexml.cc	Sat Dec 28 06:47:39 2013 +0200
     1.2 +++ b/src/goat3d_writexml.cc	Sun Dec 29 06:01:59 2013 +0200
     1.3 @@ -180,48 +180,35 @@
     1.4  
     1.5  static bool write_node_anim(goat3d_io *io, const XFormNode *node, int level)
     1.6  {
     1.7 +	/* NOTE: the order of names must correspond to the order of
     1.8 +	 * XFormNode::POSITION_TRACK/ROTATION_TRACK/SCALING_TRACK enum
     1.9 +	 */
    1.10  	static const char *attr_names[] = { "position", "rotation", "scaling" };
    1.11 -	struct anm_node *anode = node->get_libanim_node();
    1.12 -	struct anm_animation *anim = anm_get_active_animation(anode, 0);
    1.13  
    1.14 -	if(!anode || !anim) {
    1.15 -		return false;
    1.16 -	}
    1.17 -
    1.18 -	struct anm_track *trk[4];
    1.19 -
    1.20 -	for(int i=0; i<3; i++) {	// 3 attributes
    1.21 -		switch(i) {
    1.22 -		case 0:	// position
    1.23 -			trk[0] = anim->tracks + ANM_TRACK_POS_X;
    1.24 -			trk[1] = anim->tracks + ANM_TRACK_POS_Y;
    1.25 -			trk[2] = anim->tracks + ANM_TRACK_POS_Z;
    1.26 -			trk[3] = 0;
    1.27 -			break;
    1.28 -
    1.29 -		case 1:	// rotation
    1.30 -			trk[0] = anim->tracks + ANM_TRACK_ROT_X;
    1.31 -			trk[1] = anim->tracks + ANM_TRACK_ROT_Y;
    1.32 -			trk[2] = anim->tracks + ANM_TRACK_ROT_Z;
    1.33 -			trk[3] = anim->tracks + ANM_TRACK_ROT_W;
    1.34 -			break;
    1.35 -
    1.36 -		case 2:	// scaling
    1.37 -			trk[0] = anim->tracks + ANM_TRACK_SCL_X;
    1.38 -			trk[1] = anim->tracks + ANM_TRACK_SCL_Y;
    1.39 -			trk[2] = anim->tracks + ANM_TRACK_SCL_Z;
    1.40 -			trk[3] = 0;
    1.41 -		}
    1.42 -
    1.43 -		if(trk[0]->count <= 0) {
    1.44 -			continue;	// skip tracks without any keyframes
    1.45 -		}
    1.46 +	// for each of: position/rotation/scaling
    1.47 +	for(int i=0; i<3; i++) {
    1.48 +		int num_keys = node->get_key_count(i);
    1.49 +		if(!num_keys) continue;
    1.50  
    1.51  		xmlout(io, level + 1, "<track>\n");
    1.52  		xmlout(io, level + 2, "<node string=\"%s\"/>\n", node->get_name());
    1.53 -		xmlout(io, level + 2, "<attr string=\"%s\"/>\n", attr_names[i]);
    1.54 +		xmlout(io, level + 2, "<attr string=\"%s\"/>\n\n", attr_names[i]);
    1.55  
    1.56 -		// TODO cont: move all the keyframe retreival to XFormNode and use that...
    1.57 +		// for each key in that track
    1.58 +		for(int j=0; j<num_keys; j++) {
    1.59 +			long tm = node->get_key_time(i, j);
    1.60 +
    1.61 +			float value[4];
    1.62 +			int num_elems = node->get_key_value(i, j, value);
    1.63 +
    1.64 +			if(num_elems == 3) {
    1.65 +				xmlout(io, level + 2, "<key><time int=\"%ld\"/><value float3=\"%g %g %g\"/></key>\n",
    1.66 +						tm, value[0], value[1], value[2]);
    1.67 +			} else {
    1.68 +				xmlout(io, level + 2, "<key><time int=\"%ld\"/><value float4=\"%g %g %g %g\"/></key>\n",
    1.69 +						tm, value[0], value[1], value[2], value[3]);
    1.70 +			}
    1.71 +		}
    1.72  
    1.73  		xmlout(io, level + 1, "</track>\n");
    1.74  	}
     2.1 --- a/src/xform_node.cc	Sat Dec 28 06:47:39 2013 +0200
     2.2 +++ b/src/xform_node.cc	Sun Dec 29 06:01:59 2013 +0200
     2.3 @@ -184,7 +184,84 @@
     2.4  	return anm_get_active_animation_name(anm);
     2.5  }
     2.6  
     2.7 +static const int track_type_base[] = {ANM_TRACK_POS_X, ANM_TRACK_ROT_X, ANM_TRACK_SCL_X};
     2.8 +static const int track_type_nelem[] = {3, 4, 3};
     2.9  
    2.10 +int XFormNode::get_key_count(int trackid) const
    2.11 +{
    2.12 +	struct anm_animation *anim = anm_get_active_animation(anm, 0);
    2.13 +	return anim->tracks[track_type_base[trackid]].count;
    2.14 +}
    2.15 +
    2.16 +int XFormNode::get_position_key_count() const
    2.17 +{
    2.18 +	return get_key_count(POSITION_TRACK);
    2.19 +}
    2.20 +
    2.21 +int XFormNode::get_rotation_key_count() const
    2.22 +{
    2.23 +	return get_key_count(ROTATION_TRACK);
    2.24 +}
    2.25 +
    2.26 +int XFormNode::get_scaling_key_count() const
    2.27 +{
    2.28 +	return get_key_count(SCALING_TRACK);
    2.29 +}
    2.30 +
    2.31 +long XFormNode::get_key_time(int trackid, int idx) const
    2.32 +{
    2.33 +	struct anm_animation *anim = anm_get_active_animation(anm, 0);
    2.34 +	struct anm_keyframe *key = anm_get_keyframe(anim->tracks + track_type_base[trackid], idx);
    2.35 +	return ANM_TM2MSEC(key->time);
    2.36 +}
    2.37 +
    2.38 +long XFormNode::get_position_key_time(int idx) const
    2.39 +{
    2.40 +	return get_key_time(POSITION_TRACK, idx);
    2.41 +}
    2.42 +
    2.43 +long XFormNode::get_rotation_key_time(int idx) const
    2.44 +{
    2.45 +	return get_key_time(ROTATION_TRACK, idx);
    2.46 +}
    2.47 +
    2.48 +long XFormNode::get_scaling_key_time(int idx) const
    2.49 +{
    2.50 +	return get_key_time(SCALING_TRACK, idx);
    2.51 +}
    2.52 +
    2.53 +int XFormNode::get_key_value(int trackid, int idx, float *val) const
    2.54 +{
    2.55 +	struct anm_animation *anim = anm_get_active_animation(anm, 0);
    2.56 +
    2.57 +	int nelem = track_type_nelem[trackid];
    2.58 +	for(int i=0; i<nelem; i++) {
    2.59 +		struct anm_keyframe *key = anm_get_keyframe(anim->tracks + track_type_base[trackid] + i, idx);
    2.60 +		val[i] = key->val;
    2.61 +	}
    2.62 +	return nelem;
    2.63 +}
    2.64 +
    2.65 +Vector3 XFormNode::get_position_key_value(int idx) const
    2.66 +{
    2.67 +	float val[3];
    2.68 +	get_key_value(POSITION_TRACK, idx, val);
    2.69 +	return Vector3(val[0], val[1], val[2]);
    2.70 +}
    2.71 +
    2.72 +Quaternion XFormNode::get_rotation_key_value(int idx) const
    2.73 +{
    2.74 +	float val[4];
    2.75 +	get_key_value(ROTATION_TRACK, idx, val);
    2.76 +	return Quaternion(val[3], val[0], val[1], val[2]);
    2.77 +}
    2.78 +
    2.79 +Vector3 XFormNode::get_scaling_key_value(int idx) const
    2.80 +{
    2.81 +	float val[3];
    2.82 +	get_key_value(SCALING_TRACK, idx, val);
    2.83 +	return Vector3(val[0], val[1], val[2]);
    2.84 +}
    2.85  
    2.86  void XFormNode::set_position(const Vector3 &pos, long tmsec)
    2.87  {
     3.1 --- a/src/xform_node.h	Sat Dec 28 06:47:39 2013 +0200
     3.2 +++ b/src/xform_node.h	Sun Dec 29 06:01:59 2013 +0200
     3.3 @@ -33,6 +33,8 @@
     3.4  	XFormNode &operator =(const XFormNode &node) { return *this; }
     3.5  
     3.6  public:
     3.7 +	enum { POSITION_TRACK, ROTATION_TRACK, SCALING_TRACK };
     3.8 +
     3.9  	XFormNode();
    3.10  	virtual ~XFormNode();
    3.11  
    3.12 @@ -76,6 +78,27 @@
    3.13  	virtual void set_animation_name(const char *name);
    3.14  	virtual const char *get_animation_name() const;
    3.15  
    3.16 +	// raw keyframe retrieval without interpolation
    3.17 +	// NOTE: trackid parameters correspond to the values of the unnamed enumeration at the top
    3.18 +
    3.19 +	virtual int get_key_count(int trackid) const;
    3.20 +	virtual int get_position_key_count() const;
    3.21 +	virtual int get_rotation_key_count() const;
    3.22 +	virtual int get_scaling_key_count() const;
    3.23 +
    3.24 +	virtual long get_key_time(int trackid, int idx) const;
    3.25 +	virtual long get_position_key_time(int idx) const;
    3.26 +	virtual long get_rotation_key_time(int idx) const;
    3.27 +	virtual long get_scaling_key_time(int idx) const;
    3.28 +
    3.29 +	/* writes the key value through the val pointer, and returns the number
    3.30 +	 * of elements in that value (3 for pos/scale, 4 for rotation).
    3.31 +	 */
    3.32 +	virtual int get_key_value(int trackid, int idx, float *val) const;
    3.33 +	virtual Vector3 get_position_key_value(int idx) const;
    3.34 +	virtual Quaternion get_rotation_key_value(int idx) const;
    3.35 +	virtual Vector3 get_scaling_key_value(int idx) const;
    3.36 +
    3.37  
    3.38  	virtual void set_position(const Vector3 &pos, long tmsec = 0);
    3.39  	virtual Vector3 get_node_position(long tmsec = 0) const;