goat3d
view converters/ass2goat/src/main.c @ 38:60f2037680ee
split the exporter into two files to make it more readable (and maybe make an importer too at some point?)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 07 Oct 2013 20:02:57 +0300 |
parents | |
children | af1310ed212b |
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "goat3d.h"
4 #include "assimp/cimport.h"
5 #include "assimp/postprocess.h"
6 #include "assimp/scene.h"
8 int convert(const char *infname, const char *outfname);
9 void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl);
10 void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode);
12 int main(int argc, char **argv)
13 {
14 int i, num_done = 0;
16 for(i=1; i<argc; i++) {
17 if(argv[i][0] == '-') {
18 } else {
19 char *lastdot;
20 char *outfname = malloc(strlen(argv[i]) + 4);
21 strcpy(outfname, argv[i]);
23 if((lastdot = strrchr(outfname, '.'))) {
24 *lastdot = 0;
25 }
26 strcat(outfname, ".xml");
28 printf("converting %s -> %s\n", argv[i], outfname);
29 convert(argv[i], outfname);
30 num_done++;
31 }
32 }
34 if(!num_done) {
35 fprintf(stderr, "you must specify a 3D scene file to convert\n");
36 return 1;
37 }
39 return 0;
40 }
42 #define PPFLAGS \
43 (aiProcess_Triangulate | \
44 aiProcess_GenNormals | \
45 aiProcess_JoinIdenticalVertices | \
46 aiProcess_CalcTangentSpace | \
47 aiProcess_LimitBoneWeights | \
48 aiProcess_GenUVCoords)
50 int convert(const char *infname, const char *outfname)
51 {
52 int i;
53 const struct aiScene *aiscn;
54 struct goat3d *goat;
56 if(!(aiscn = aiImportFile(infname, PPFLAGS))) {
57 fprintf(stderr, "failed to import %s\n", infname);
58 return -1;
59 }
61 goat = goat3d_create();
63 for(i=0; i<(int)aiscn->mNumMaterials; i++) {
64 struct aiMaterial *aimat = aiscn->mMaterials[i];
65 struct goat3d_material *mat = goat3d_create_mtl();
67 process_material(mat, aimat);
68 goat3d_add_mtl(goat, mat);
69 }
71 for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) {
72 process_node(goat, 0, aiscn->mRootNode->mChildren[i]);
73 }
75 goat3d_save(goat, outfname);
76 goat3d_free(goat);
77 aiReleaseImport(aiscn);
78 return 0;
79 }
81 void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl)
82 {
83 struct aiString aistr;
84 struct aiColor4D color;
85 float val;
87 if(aiGetMaterialString(aimtl, AI_MATKEY_NAME, &aistr) == aiReturn_SUCCESS) {
88 goat3d_set_mtl_name(mtl, aistr.data);
89 }
91 if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_DIFFUSE, &color) == aiReturn_SUCCESS) {
92 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, color.r, color.g, color.b);
93 }
95 if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_SPECULAR, &color) == aiReturn_SUCCESS) {
96 float sstr = 1.0;
97 aiGetMaterialFloatArray(aimtl, AI_MATKEY_SHININESS_STRENGTH, &sstr, 0);
98 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, color.r * sstr, color.g * sstr, color.b * sstr);
99 }
101 if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_BUMPSCALING, &val, 0) == aiReturn_SUCCESS) {
102 goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_BUMP, val, val, val);
103 }
105 if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_REFLECTIVITY, &val, 0) == aiReturn_SUCCESS) {
106 goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_REFLECTION, val);
107 }
109 if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_OPACITY, &val, 0) == aiReturn_SUCCESS) {
110 goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, 1.0 - val);
111 }
113 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_DIFFUSE(0), &aistr) == aiReturn_SUCCESS) {
114 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, aistr.data);
115 }
116 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SPECULAR(0), &aistr) == aiReturn_SUCCESS) {
117 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, aistr.data);
118 }
119 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SHININESS(0), &aistr) == aiReturn_SUCCESS) {
120 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, aistr.data);
121 }
122 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_NORMALS(0), &aistr) == aiReturn_SUCCESS) {
123 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, aistr.data);
124 }
125 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_REFLECTION(0), &aistr) == aiReturn_SUCCESS) {
126 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, aistr.data);
127 }
128 if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_OPACITY(0), &aistr) == aiReturn_SUCCESS) {
129 // TODO this is semantically inverted... maybe add an alpha attribute?
130 goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, aistr.data);
131 }
132 }
134 void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode)
135 {
136 int i;
137 struct goat3d_node *node;
139 node = goat3d_create_node();
140 goat3d_set_node_name(node, ainode->mName.data);
142 for(i=0; i<ainode->mNumChildren; i++) {
143 process_node(goat, node, ainode->mChildren[i]);
144 }
146 goat3d_add_node(goat, node);
147 }