goat3d
diff src/goat3d_writexml.cc @ 47:498ca7ac7047
- placed all the implementation stuff in the g3dimpl namespace
- added animation stuff to the public API
- started writing animation saving/loading
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 28 Dec 2013 06:47:39 +0200 |
parents | a5c5cec3cb88 |
children | 9ef9de80649c |
line diff
1.1 --- a/src/goat3d_writexml.cc Sun Dec 08 03:00:25 2013 +0200 1.2 +++ b/src/goat3d_writexml.cc Sat Dec 28 06:47:39 2013 +0200 1.3 @@ -1,12 +1,17 @@ 1.4 +#include <list> 1.5 #include <stdarg.h> 1.6 #include "goat3d_impl.h" 1.7 +#include "anim/anim.h" 1.8 #include "log.h" 1.9 1.10 +using namespace g3dimpl; 1.11 + 1.12 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level); 1.13 static bool write_mesh(const Scene *scn, goat3d_io *io, const Mesh *mesh, int idx, int level); 1.14 static bool write_light(const Scene *scn, goat3d_io *io, const Light *light, int level); 1.15 static bool write_camera(const Scene *scn, goat3d_io *io, const Camera *cam, int level); 1.16 static bool write_node(const Scene *scn, goat3d_io *io, const Node *node, int level); 1.17 +static bool write_node_anim(goat3d_io *io, const XFormNode *node, int level); 1.18 static void xmlout(goat3d_io *io, int level, const char *fmt, ...); 1.19 1.20 bool Scene::savexml(goat3d_io *io) const 1.21 @@ -38,6 +43,39 @@ 1.22 return true; 1.23 } 1.24 1.25 +static void collect_nodes(std::list<const XFormNode*> *res, const XFormNode *node) 1.26 +{ 1.27 + if(!node) return; 1.28 + 1.29 + res->push_back(node); 1.30 + 1.31 + for(int i=0; i<node->get_children_count(); i++) { 1.32 + collect_nodes(res, node->get_child(i)); 1.33 + } 1.34 +} 1.35 + 1.36 +bool Scene::save_anim_xml(const XFormNode *node, goat3d_io *io) const 1.37 +{ 1.38 + xmlout(io, 0, "<anim>\n"); 1.39 + 1.40 + const char *anim_name = node->get_animation_name(); 1.41 + if(anim_name && *anim_name) { 1.42 + xmlout(io, 1, "<name string=\"%s\"/>\n", anim_name); 1.43 + } 1.44 + 1.45 + std::list<const XFormNode*> allnodes; 1.46 + collect_nodes(&allnodes, node); 1.47 + 1.48 + std::list<const XFormNode*>::const_iterator it = allnodes.begin(); 1.49 + while(it != allnodes.end()) { 1.50 + const XFormNode *n = *it++; 1.51 + write_node_anim(io, n, 1); 1.52 + } 1.53 + 1.54 + xmlout(io, 0, "</anim>\n"); 1.55 + return true; 1.56 +} 1.57 + 1.58 static bool write_material(const Scene *scn, goat3d_io *io, const Material *mat, int level) 1.59 { 1.60 xmlout(io, level, "<mtl>\n"); 1.61 @@ -100,7 +138,7 @@ 1.62 xmlout(io, level, "<node>\n"); 1.63 xmlout(io, level + 1, "<name string=\"%s\"/>\n", node->get_name()); 1.64 1.65 - XFormNode *parent = node->get_parent(); 1.66 + const XFormNode *parent = node->get_parent(); 1.67 if(parent) { 1.68 xmlout(io, level + 1, "<parent string=\"%s\"/>\n", parent->get_name()); 1.69 } 1.70 @@ -140,6 +178,55 @@ 1.71 return true; 1.72 } 1.73 1.74 +static bool write_node_anim(goat3d_io *io, const XFormNode *node, int level) 1.75 +{ 1.76 + static const char *attr_names[] = { "position", "rotation", "scaling" }; 1.77 + struct anm_node *anode = node->get_libanim_node(); 1.78 + struct anm_animation *anim = anm_get_active_animation(anode, 0); 1.79 + 1.80 + if(!anode || !anim) { 1.81 + return false; 1.82 + } 1.83 + 1.84 + struct anm_track *trk[4]; 1.85 + 1.86 + for(int i=0; i<3; i++) { // 3 attributes 1.87 + switch(i) { 1.88 + case 0: // position 1.89 + trk[0] = anim->tracks + ANM_TRACK_POS_X; 1.90 + trk[1] = anim->tracks + ANM_TRACK_POS_Y; 1.91 + trk[2] = anim->tracks + ANM_TRACK_POS_Z; 1.92 + trk[3] = 0; 1.93 + break; 1.94 + 1.95 + case 1: // rotation 1.96 + trk[0] = anim->tracks + ANM_TRACK_ROT_X; 1.97 + trk[1] = anim->tracks + ANM_TRACK_ROT_Y; 1.98 + trk[2] = anim->tracks + ANM_TRACK_ROT_Z; 1.99 + trk[3] = anim->tracks + ANM_TRACK_ROT_W; 1.100 + break; 1.101 + 1.102 + case 2: // scaling 1.103 + trk[0] = anim->tracks + ANM_TRACK_SCL_X; 1.104 + trk[1] = anim->tracks + ANM_TRACK_SCL_Y; 1.105 + trk[2] = anim->tracks + ANM_TRACK_SCL_Z; 1.106 + trk[3] = 0; 1.107 + } 1.108 + 1.109 + if(trk[0]->count <= 0) { 1.110 + continue; // skip tracks without any keyframes 1.111 + } 1.112 + 1.113 + xmlout(io, level + 1, "<track>\n"); 1.114 + xmlout(io, level + 2, "<node string=\"%s\"/>\n", node->get_name()); 1.115 + xmlout(io, level + 2, "<attr string=\"%s\"/>\n", attr_names[i]); 1.116 + 1.117 + // TODO cont: move all the keyframe retreival to XFormNode and use that... 1.118 + 1.119 + xmlout(io, level + 1, "</track>\n"); 1.120 + } 1.121 + return true; 1.122 +} 1.123 1.124 static void xmlout(goat3d_io *io, int level, const char *fmt, ...) 1.125 {