goat3d

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