goat3d

diff converters/ass2goat/src/main.c @ 29:3d669155709d

- switched the unix build to use the internal vmath/anim as well - fixed a memory corruption issue which was caused by including the system-wide installed version of the anim.h header file - started the ass2goat assimp->goat3d converter
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 29 Sep 2013 21:53:03 +0300
parents
children af1310ed212b
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/converters/ass2goat/src/main.c	Sun Sep 29 21:53:03 2013 +0300
     1.3 @@ -0,0 +1,147 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include "goat3d.h"
     1.7 +#include "assimp/cimport.h"
     1.8 +#include "assimp/postprocess.h"
     1.9 +#include "assimp/scene.h"
    1.10 +
    1.11 +int convert(const char *infname, const char *outfname);
    1.12 +void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl);
    1.13 +void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode);
    1.14 +
    1.15 +int main(int argc, char **argv)
    1.16 +{
    1.17 +	int i, num_done = 0;
    1.18 +
    1.19 +	for(i=1; i<argc; i++) {
    1.20 +		if(argv[i][0] == '-') {
    1.21 +		} else {
    1.22 +			char *lastdot;
    1.23 +			char *outfname = malloc(strlen(argv[i]) + 4);
    1.24 +			strcpy(outfname, argv[i]);
    1.25 +
    1.26 +			if((lastdot = strrchr(outfname, '.'))) {
    1.27 +				*lastdot = 0;
    1.28 +			}
    1.29 +			strcat(outfname, ".xml");
    1.30 +
    1.31 +			printf("converting %s -> %s\n", argv[i], outfname);
    1.32 +			convert(argv[i], outfname);
    1.33 +			num_done++;
    1.34 +		}
    1.35 +	}
    1.36 +
    1.37 +	if(!num_done) {
    1.38 +		fprintf(stderr, "you must specify a 3D scene file to convert\n");
    1.39 +		return 1;
    1.40 +	}
    1.41 +
    1.42 +	return 0;
    1.43 +}
    1.44 +
    1.45 +#define PPFLAGS	\
    1.46 +	(aiProcess_Triangulate | \
    1.47 +	 aiProcess_GenNormals | \
    1.48 +	 aiProcess_JoinIdenticalVertices | \
    1.49 +	 aiProcess_CalcTangentSpace | \
    1.50 +	 aiProcess_LimitBoneWeights | \
    1.51 +	 aiProcess_GenUVCoords)
    1.52 +
    1.53 +int convert(const char *infname, const char *outfname)
    1.54 +{
    1.55 +	int i;
    1.56 +	const struct aiScene *aiscn;
    1.57 +	struct goat3d *goat;
    1.58 +
    1.59 +	if(!(aiscn = aiImportFile(infname, PPFLAGS))) {
    1.60 +		fprintf(stderr, "failed to import %s\n", infname);
    1.61 +		return -1;
    1.62 +	}
    1.63 +
    1.64 +	goat = goat3d_create();
    1.65 +
    1.66 +	for(i=0; i<(int)aiscn->mNumMaterials; i++) {
    1.67 +		struct aiMaterial *aimat = aiscn->mMaterials[i];
    1.68 +		struct goat3d_material *mat = goat3d_create_mtl();
    1.69 +
    1.70 +		process_material(mat, aimat);
    1.71 +		goat3d_add_mtl(goat, mat);
    1.72 +	}
    1.73 +
    1.74 +	for(i=0; i<(int)aiscn->mRootNode->mNumChildren; i++) {
    1.75 +		process_node(goat, 0, aiscn->mRootNode->mChildren[i]);
    1.76 +	}
    1.77 +
    1.78 +	goat3d_save(goat, outfname);
    1.79 +	goat3d_free(goat);
    1.80 +	aiReleaseImport(aiscn);
    1.81 +	return 0;
    1.82 +}
    1.83 +
    1.84 +void process_material(struct goat3d_material *mtl, struct aiMaterial *aimtl)
    1.85 +{
    1.86 +	struct aiString aistr;
    1.87 +	struct aiColor4D color;
    1.88 +	float val;
    1.89 +
    1.90 +	if(aiGetMaterialString(aimtl, AI_MATKEY_NAME, &aistr) == aiReturn_SUCCESS) {
    1.91 +		goat3d_set_mtl_name(mtl, aistr.data);
    1.92 +	}
    1.93 +
    1.94 +	if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_DIFFUSE, &color) == aiReturn_SUCCESS) {
    1.95 +		goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, color.r, color.g, color.b);
    1.96 +	}
    1.97 +
    1.98 +	if(aiGetMaterialColor(aimtl, AI_MATKEY_COLOR_SPECULAR, &color) == aiReturn_SUCCESS) {
    1.99 +		float sstr = 1.0;
   1.100 +		aiGetMaterialFloatArray(aimtl, AI_MATKEY_SHININESS_STRENGTH, &sstr, 0);
   1.101 +		goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_SPECULAR, color.r * sstr, color.g * sstr, color.b * sstr);
   1.102 +	}
   1.103 +
   1.104 +	if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_BUMPSCALING, &val, 0) == aiReturn_SUCCESS) {
   1.105 +		goat3d_set_mtl_attrib3f(mtl, GOAT3D_MAT_ATTR_BUMP, val, val, val);
   1.106 +	}
   1.107 +
   1.108 +	if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_REFLECTIVITY, &val, 0) == aiReturn_SUCCESS) {
   1.109 +		goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_REFLECTION, val);
   1.110 +	}
   1.111 +
   1.112 +	if(aiGetMaterialFloatArray(aimtl, AI_MATKEY_OPACITY, &val, 0) == aiReturn_SUCCESS) {
   1.113 +		goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, 1.0 - val);
   1.114 +	}
   1.115 +
   1.116 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_DIFFUSE(0), &aistr) == aiReturn_SUCCESS) {
   1.117 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_DIFFUSE, aistr.data);
   1.118 +	}
   1.119 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SPECULAR(0), &aistr) == aiReturn_SUCCESS) {
   1.120 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SPECULAR, aistr.data);
   1.121 +	}
   1.122 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_SHININESS(0), &aistr) == aiReturn_SUCCESS) {
   1.123 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_SHININESS, aistr.data);
   1.124 +	}
   1.125 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_NORMALS(0), &aistr) == aiReturn_SUCCESS) {
   1.126 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_NORMAL, aistr.data);
   1.127 +	}
   1.128 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_REFLECTION(0), &aistr) == aiReturn_SUCCESS) {
   1.129 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_REFLECTION, aistr.data);
   1.130 +	}
   1.131 +	if(aiGetMaterialString(aimtl, AI_MATKEY_TEXTURE_OPACITY(0), &aistr) == aiReturn_SUCCESS) {
   1.132 +		// TODO this is semantically inverted... maybe add an alpha attribute?
   1.133 +		goat3d_set_mtl_attrib_map(mtl, GOAT3D_MAT_ATTR_TRANSMISSION, aistr.data);
   1.134 +	}
   1.135 +}
   1.136 +
   1.137 +void process_node(struct goat3d *goat, struct goat3d_node *parent, struct aiNode *ainode)
   1.138 +{
   1.139 +	int i;
   1.140 +	struct goat3d_node *node;
   1.141 +
   1.142 +	node = goat3d_create_node();
   1.143 +	goat3d_set_node_name(node, ainode->mName.data);
   1.144 +
   1.145 +	for(i=0; i<ainode->mNumChildren; i++) {
   1.146 +		process_node(goat, node, ainode->mChildren[i]);
   1.147 +	}
   1.148 +
   1.149 +	goat3d_add_node(goat, node);
   1.150 +}