goat3d
changeset 55:af1310ed212b
not done yet
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 19 Jan 2014 14:56:44 +0200 |
parents | 6d514398a728 |
children | ca549434dc95 |
files | converters/ass2goat/.clang_complete converters/ass2goat/src/main.c src/goat3d.cc src/goat3d.h src/goat3d_impl.h src/goat3d_write.cc src/goat3d_writexml.cc |
diffstat | 7 files changed, 211 insertions(+), 50 deletions(-) [+] |
line diff
1.1 --- a/converters/ass2goat/.clang_complete Fri Jan 17 18:30:35 2014 +0200 1.2 +++ b/converters/ass2goat/.clang_complete Sun Jan 19 14:56:44 2014 +0200 1.3 @@ -1,2 +1,3 @@ 1.4 -I../../src 1.5 -I/usr/local/include 1.6 +-I/usr/local/include/assimp
2.1 --- a/converters/ass2goat/src/main.c Fri Jan 17 18:30:35 2014 +0200 2.2 +++ b/converters/ass2goat/src/main.c Sun Jan 19 14:56:44 2014 +0200 2.3 @@ -5,28 +5,51 @@ 2.4 #include "assimp/postprocess.h" 2.5 #include "assimp/scene.h" 2.6 2.7 -int convert(const char *infname, const char *outfname); 2.8 +enum { 2.9 + CONV_SCENE, 2.10 + CONV_ANIM 2.11 +}; 2.12 + 2.13 +int convert(const char *infname); 2.14 +int convert_anim(const char *infname); 2.15 void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl); 2.16 void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode); 2.17 +int process_anim(struct goat3d *goat, struct aiAnimation *aianim); 2.18 +static int output_filename(char *buf, int bufsz, const char *fname, const char *suffix); 2.19 +static long assimp_time(const struct aiAnimation *anim, double aitime); 2.20 2.21 int main(int argc, char **argv) 2.22 { 2.23 int i, num_done = 0; 2.24 + int conv_targ = CONV_SCENE; 2.25 2.26 for(i=1; i<argc; i++) { 2.27 if(argv[i][0] == '-') { 2.28 + if(argv[i][2] != 0) { 2.29 + fprintf(stderr, "invalid option: %s\n", argv[i]); 2.30 + return 1; 2.31 + } 2.32 + 2.33 + switch(argv[i][1]) { 2.34 + case 'a': 2.35 + conv_targ = CONV_ANIM; 2.36 + break; 2.37 + 2.38 + case 's': 2.39 + conv_targ = CONV_SCENE; 2.40 + break; 2.41 + 2.42 + default: 2.43 + fprintf(stderr, "invalid option: %s\n", argv[i]); 2.44 + return 1; 2.45 + } 2.46 + 2.47 } else { 2.48 - char *lastdot; 2.49 - char *outfname = malloc(strlen(argv[i]) + 4); 2.50 - strcpy(outfname, argv[i]); 2.51 - 2.52 - if((lastdot = strrchr(outfname, '.'))) { 2.53 - *lastdot = 0; 2.54 + if(conv_targ == CONV_SCENE) { 2.55 + convert(argv[i]); 2.56 + } else { 2.57 + convert_anim(argv[i]); 2.58 } 2.59 - strcat(outfname, ".xml"); 2.60 - 2.61 - printf("converting %s -> %s\n", argv[i], outfname); 2.62 - convert(argv[i], outfname); 2.63 num_done++; 2.64 } 2.65 } 2.66 @@ -39,7 +62,7 @@ 2.67 return 0; 2.68 } 2.69 2.70 -#define PPFLAGS \ 2.71 +#define SCE_PPFLAGS \ 2.72 (aiProcess_Triangulate | \ 2.73 aiProcess_GenNormals | \ 2.74 aiProcess_JoinIdenticalVertices | \ 2.75 @@ -47,13 +70,23 @@ 2.76 aiProcess_LimitBoneWeights | \ 2.77 aiProcess_GenUVCoords) 2.78 2.79 -int convert(const char *infname, const char *outfname) 2.80 +#define ANM_PPFLAGS \ 2.81 + (aiProcess_LimitBoneWeights) 2.82 + 2.83 +int convert(const char *infname) 2.84 { 2.85 - int i; 2.86 + int i, bufsz; 2.87 const struct aiScene *aiscn; 2.88 struct goat3d *goat; 2.89 + char *outfname; 2.90 2.91 - if(!(aiscn = aiImportFile(infname, PPFLAGS))) { 2.92 + bufsz = output_filename(0, 0, infname, "goat3d"); 2.93 + outfname = alloca(bufsz); 2.94 + output_filename(outfname, bufsz, infname, "goat3d"); 2.95 + printf("converting %s -> %s\n", infname, outfname); 2.96 + 2.97 + 2.98 + if(!(aiscn = aiImportFile(infname, SCE_PPFLAGS))) { 2.99 fprintf(stderr, "failed to import %s\n", infname); 2.100 return -1; 2.101 } 2.102 @@ -78,6 +111,42 @@ 2.103 return 0; 2.104 } 2.105 2.106 +int convert_anim(const char *infname) 2.107 +{ 2.108 + int i, bufsz; 2.109 + const struct aiScene *aiscn; 2.110 + struct goat3d *goat; 2.111 + char *outfname; 2.112 + 2.113 + bufsz = output_filename(0, 0, infname, "goatanim"); 2.114 + outfname = alloca(bufsz); 2.115 + output_filename(outfname, bufsz, infname, "goatanim"); 2.116 + printf("converting %s -> %s\n", infname, outfname); 2.117 + 2.118 + 2.119 + if(!(aiscn = aiImportFile(infname, ANM_PPFLAGS))) { 2.120 + fprintf(stderr, "failed to import %s\n", infname); 2.121 + return -1; 2.122 + } 2.123 + 2.124 + goat = goat3d_create(); 2.125 + 2.126 + for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) { 2.127 + process_node(goat, 0, aiscn->mRootNode->mChildren[i]); 2.128 + } 2.129 + 2.130 + for(i=0; i<aiscn->mNumAnimations; i++) { 2.131 + if(process_anim(goat, aiscn->mAnimations[i]) == -1) { 2.132 + return -1; 2.133 + } 2.134 + } 2.135 + 2.136 + goat3d_save_anim(goat, outfname); 2.137 + goat3d_free(goat); 2.138 + aiReleaseImport(aiscn); 2.139 + return 0; 2.140 +} 2.141 + 2.142 void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl) 2.143 { 2.144 struct aiString aistr; 2.145 @@ -145,3 +214,108 @@ 2.146 2.147 goat3d_add_node(goat, node); 2.148 } 2.149 + 2.150 +int process_anim(struct goat3d *goat, struct aiAnimation *aianim) 2.151 +{ 2.152 + int i, j, num_nodes, rnodes_count; 2.153 + const char *anim_name; 2.154 + 2.155 + if(aianim->mName.length <= 0) { 2.156 + anim_name = "unnamed"; 2.157 + } else { 2.158 + anim_name = aianim->mName.data; 2.159 + } 2.160 + 2.161 + num_nodes = goat3d_get_node_count(goat); 2.162 + 2.163 + rnodes_count = 0; 2.164 + for(i=0; i<num_nodes; i++) { 2.165 + int anim_idx; 2.166 + struct goat3d_node *n = goat3d_get_node(goat, i); 2.167 + /* skip non-root nodes */ 2.168 + if(goat3d_get_node_parent(n)) { 2.169 + break; 2.170 + } 2.171 + 2.172 + /* then add another animation to those root nodes */ 2.173 + anim_idx = goat3d_get_anim_count(n); 2.174 + goat3d_add_anim(n); 2.175 + goat3d_use_anim(n, anim_idx); 2.176 + 2.177 + goat3d_set_anim_name(n, anim_name); 2.178 + } 2.179 + 2.180 + /* for each animation "channel" ... */ 2.181 + for(i=0; i<(int)aianim->mNumChannels; i++) { 2.182 + struct goat3d_node *node; 2.183 + struct aiNodeAnim *ainodeanim = aianim->mChannels[i]; 2.184 + 2.185 + /* find the node it refers to */ 2.186 + const char *nodename = ainodeanim->mNodeName.data; 2.187 + if(!(node = goat3d_get_node_by_name(goat, nodename))) { 2.188 + fprintf(stderr, "failed to process animation for unknown node: %s\n", nodename); 2.189 + return -1; 2.190 + } 2.191 + 2.192 + /* add all the keys ... */ 2.193 + for(j=0; j<(int)ainodeanim->mNumPositionKeys; j++) { 2.194 + struct aiVectorKey *key = ainodeanim->mPositionKeys + j; 2.195 + long tm = assimp_time(aianim, key->mTime); 2.196 + goat3d_set_node_position(node, key->mValue.x, key->mValue.y, key->mValue.z, tm); 2.197 + } 2.198 + 2.199 + for(j=0; j<(int)ainodeanim->mNumRotationKeys; j++) { 2.200 + struct aiQuatKey *key = ainodeanim->mRotationKeys + j; 2.201 + long tm = assimp_time(aianim, key->mTime); 2.202 + goat3d_set_node_rotation(node, key->mValue.x, key->mValue.y, key->mValue.z, key->mValue.w, tm); 2.203 + } 2.204 + 2.205 + for(j=0; j<(int)ainodeanim->mNumScalingKeys; j++) { 2.206 + struct aiVectorKey *key = ainodeanim->mScalingKeys + j; 2.207 + long tm = assimp_time(aianim, key->mTime); 2.208 + goat3d_set_node_scaling(node, key->mValue.x, key->mValue.y, key->mValue.z, tm); 2.209 + } 2.210 + } 2.211 + 2.212 + return 0; 2.213 +} 2.214 + 2.215 +static int output_filename(char *buf, int bufsz, const char *fname, const char *suffix) 2.216 +{ 2.217 + int reqsz, namesz; 2.218 + char *tmpfname; 2.219 + const char *fname_end, *lastdot; 2.220 + 2.221 + lastdot = strrchr(fname, '.'); 2.222 + 2.223 + fname_end = lastdot ? lastdot + 1 : fname + strlen(fname); 2.224 + namesz = fname_end - fname; 2.225 + reqsz = namesz + strlen(suffix) + 2; /* plus 1 for the dot */ 2.226 + 2.227 + if(buf && bufsz) { 2.228 + tmpfname = alloca(namesz + 1); 2.229 + memcpy(tmpfname, fname, namesz); 2.230 + tmpfname[namesz] = 0; 2.231 + 2.232 + if(suffix) { 2.233 + snprintf(buf, bufsz, "%s.%s", tmpfname, suffix); 2.234 + } else { 2.235 + strncpy(buf, tmpfname, bufsz); 2.236 + } 2.237 + buf[bufsz - 1] = 0; 2.238 + } 2.239 + 2.240 + return reqsz; 2.241 +} 2.242 + 2.243 +static long assimp_time(const struct aiAnimation *anim, double aitime) 2.244 +{ 2.245 + double sec; 2.246 + if(anim->mTicksPerSecond < 1e-6) { 2.247 + /* assume time in frames? */ 2.248 + sec = aitime / 30.0; 2.249 + } else { 2.250 + sec = aitime / anim->mTicksPerSecond; 2.251 + } 2.252 + return (long)(sec * 1000.0); 2.253 +}
3.1 --- a/src/goat3d.cc Fri Jan 17 18:30:35 2014 +0200 3.2 +++ b/src/goat3d.cc Sun Jan 19 14:56:44 2014 +0200 3.3 @@ -162,14 +162,14 @@ 3.4 return res; 3.5 } 3.6 3.7 -GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const struct goat3d_node *root, const char *fname) 3.8 +GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const char *fname) 3.9 { 3.10 FILE *fp = fopen(fname, "wb"); 3.11 if(!fp) { 3.12 return -1; 3.13 } 3.14 3.15 - int res = goat3d_save_anim_file(g, root, fp); 3.16 + int res = goat3d_save_anim_file(g, fp); 3.17 fclose(fp); 3.18 return res; 3.19 } 3.20 @@ -185,7 +185,7 @@ 3.21 return goat3d_load_anim_io(g, &io); 3.22 } 3.23 3.24 -GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, const struct goat3d_node *root, FILE *fp) 3.25 +GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, FILE *fp) 3.26 { 3.27 goat3d_io io; 3.28 io.cls = fp; 3.29 @@ -193,7 +193,7 @@ 3.30 io.write = write_file; 3.31 io.seek = seek_file; 3.32 3.33 - return goat3d_save_anim_io(g, root, &io); 3.34 + return goat3d_save_anim_io(g, &io); 3.35 } 3.36 3.37 GOAT3DAPI int goat3d_load_anim_io(struct goat3d *g, struct goat3d_io *io) 3.38 @@ -206,12 +206,12 @@ 3.39 return 0; 3.40 } 3.41 3.42 -GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, const struct goat3d_node *root, struct goat3d_io *io) 3.43 +GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, struct goat3d_io *io) 3.44 { 3.45 if(goat3d_getopt(g, GOAT3D_OPT_SAVEXML)) { 3.46 - return g->scn->save_anim_xml(root, io) ? 0 : -1; 3.47 + return g->scn->save_anim_xml(io) ? 0 : -1; 3.48 } 3.49 - return g->scn->save_anim(root, io) ? 0 : -1; 3.50 + return g->scn->save_anim(io) ? 0 : -1; 3.51 } 3.52 3.53
4.1 --- a/src/goat3d.h Fri Jan 17 18:30:35 2014 +0200 4.2 +++ b/src/goat3d.h Sun Jan 19 14:56:44 2014 +0200 4.3 @@ -90,13 +90,13 @@ 4.4 4.5 /* load/save animation files (g must already be loaded to load animations) */ 4.6 GOAT3DAPI int goat3d_load_anim(struct goat3d *g, const char *fname); 4.7 -GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const struct goat3d_node *root, const char *fname); 4.8 +GOAT3DAPI int goat3d_save_anim(const struct goat3d *g, const char *fname); 4.9 4.10 GOAT3DAPI int goat3d_load_anim_file(struct goat3d *g, FILE *fp); 4.11 -GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, const struct goat3d_node *root, FILE *fp); 4.12 +GOAT3DAPI int goat3d_save_anim_file(const struct goat3d *g, FILE *fp); 4.13 4.14 GOAT3DAPI int goat3d_load_anim_io(struct goat3d *g, struct goat3d_io *io); 4.15 -GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, const struct goat3d_node *root, struct goat3d_io *io); 4.16 +GOAT3DAPI int goat3d_save_anim_io(const struct goat3d *g, struct goat3d_io *io); 4.17 4.18 /* misc scene properties */ 4.19 GOAT3DAPI int goat3d_set_name(struct goat3d *g, const char *name);
5.1 --- a/src/goat3d_impl.h Fri Jan 17 18:30:35 2014 +0200 5.2 +++ b/src/goat3d_impl.h Sun Jan 19 14:56:44 2014 +0200 5.3 @@ -81,10 +81,10 @@ 5.4 bool savexml(goat3d_io *io) const; 5.5 5.6 bool load_anim(goat3d_io *io); 5.7 - bool save_anim(const XFormNode *node, goat3d_io *io) const; 5.8 + bool save_anim(goat3d_io *io) const; 5.9 5.10 bool load_anim_xml(goat3d_io *io); 5.11 - bool save_anim_xml(const XFormNode *node, goat3d_io *io) const; 5.12 + bool save_anim_xml(goat3d_io *io) const; 5.13 }; 5.14 5.15 void io_fprintf(goat3d_io *io, const char *fmt, ...);
6.1 --- a/src/goat3d_write.cc Fri Jan 17 18:30:35 2014 +0200 6.2 +++ b/src/goat3d_write.cc Sun Jan 19 14:56:44 2014 +0200 6.3 @@ -68,7 +68,7 @@ 6.4 return false; 6.5 } 6.6 6.7 -bool Scene::save_anim(const XFormNode *node, goat3d_io *io) const 6.8 +bool Scene::save_anim(goat3d_io *io) const 6.9 { 6.10 return false; 6.11 }
7.1 --- a/src/goat3d_writexml.cc Fri Jan 17 18:30:35 2014 +0200 7.2 +++ b/src/goat3d_writexml.cc Sun Jan 19 14:56:44 2014 +0200 7.3 @@ -43,33 +43,19 @@ 7.4 return true; 7.5 } 7.6 7.7 -static void collect_nodes(std::list<const XFormNode*> *res, const XFormNode *node) 7.8 -{ 7.9 - if(!node) return; 7.10 - 7.11 - res->push_back(node); 7.12 - 7.13 - for(int i=0; i<node->get_children_count(); i++) { 7.14 - collect_nodes(res, node->get_child(i)); 7.15 - } 7.16 -} 7.17 - 7.18 -bool Scene::save_anim_xml(const XFormNode *node, goat3d_io *io) const 7.19 +bool Scene::save_anim_xml(goat3d_io *io) const 7.20 { 7.21 xmlout(io, 0, "<anim>\n"); 7.22 7.23 - const char *anim_name = node->get_animation_name(); 7.24 - if(anim_name && *anim_name) { 7.25 - xmlout(io, 1, "<name string=\"%s\"/>\n", anim_name); 7.26 + if(!nodes.empty()) { 7.27 + const char *anim_name = nodes[0]->get_animation_name(); 7.28 + if(anim_name && *anim_name) { 7.29 + xmlout(io, 1, "<name string=\"%s\"/>\n", anim_name); 7.30 + } 7.31 } 7.32 7.33 - std::list<const XFormNode*> allnodes; 7.34 - collect_nodes(&allnodes, node); 7.35 - 7.36 - std::list<const XFormNode*>::const_iterator it = allnodes.begin(); 7.37 - while(it != allnodes.end()) { 7.38 - const XFormNode *n = *it++; 7.39 - write_node_anim(io, n, 1); 7.40 + for(size_t i=0; i<nodes.size(); i++) { 7.41 + write_node_anim(io, nodes[i], 1); 7.42 } 7.43 7.44 xmlout(io, 0, "</anim>\n");