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;