// @ Project : MayaMELExportedObjectDump // @ File Name : oglexpdump.cpp // @ Date : 2007-2-21 // @ Author : kongfu.yang // @ Company : http://www.play3d.net // @ Copyright : 2007-2, Example source license. By keep this header comment, you may use this source file in your project for non-commicial or commicial purpose. #include #include #include #define u8 unsigned char #define u16 unsigned short #define u32 unsigned int struct OGLHeader { char id[4]; // = "OGL" magic u32 ver; // 0x04 u32 objCount; u32 objRadius; // 0x0000 }; struct OGLBlockHeader { u32 blockType; // 0x21, obj indexed u32 blockContent; // 0x30, coord; 0x31, normal; 0x3A, uv; 0x60 material; 0x3B texture file u32 elementCount; u32 shape; // 0x0004, TRIANGLE and MATERIAL_ID; 0xff00 material }; struct vertex { float x; float y; float z; }; struct face { int a,b,c; }; struct normal { float x,y,z; }; struct uv { float u,v; }; struct color { float r,g,b; }; struct texture { u32 blockType; // 0x21, obj indexed u32 nameLength; char *fileName; u32 u; // 1 u32 v; // 1 }; struct material { int nameLength; char *name; color ambient; color diffuse; color specular; float transparency; float cosinePower; }; struct OGLExpObj { OGLBlockHeader faceHeader; face * faces; OGLBlockHeader vertexHeader; vertex *vertexs; OGLBlockHeader normalHeader; normal *normals; OGLBlockHeader uvHeader; uv *uvs; }; struct OGLExp { OGLHeader header; OGLExpObj *objs; OGLBlockHeader materialHeader; material * materials; }; int verbose=0; u8 floatBuf[8]; #define READ_MEL_FLOAT(var) \ fread( floatBuf, 8, 1, fp ); \ if ( verbose ) { \ for ( int j = 0; j < 8; ++j ) \ printf("%02X", floatBuf[j]); \ printf("; "); \ } \ (var) = *((double*)floatBuf); void loadExp(char * fname, OGLExp * exp) { FILE * fp = fopen(fname, "rb"); // read export header fread( & (exp->header), sizeof(OGLHeader), 1, fp ); printf("\nExported Maya Object:\n %d objects\nradius %d\n", exp->header.objCount, exp->header.objRadius); exp->objs = (OGLExpObj*) malloc( sizeof(OGLExpObj) * exp->header.objCount ); // todo : error check OGLExpObj *obj = exp->objs; long size; for ( int i = 0; i < exp->header.objCount; ++ i ) { printf("reading object, index=%d\n", i); // read one object // read face // read vertex // read normal // read uv // face printf("offset %d, to face block header\n", ftell(fp)); fread( &(obj->faceHeader), sizeof(OGLBlockHeader), 1, fp ); printf("block readed: type=%x, content=%x\n", obj->faceHeader.blockType, obj->faceHeader.blockContent ); printf("it has %d face.\n", obj->faceHeader.elementCount / 3); // the mel script write faces * 3 in elementCount size = sizeof(face) * obj->faceHeader.elementCount / 3; // the mel script write faces * 3 in elementCount obj->faces = (face *)malloc( size ); printf("offset %d, to face block header\n", ftell(fp)); fread( &(obj->faces), size, 1, fp ); // vertex printf("offset %d, to vertex block header\n", ftell(fp)); fread( &(obj->vertexHeader), sizeof(OGLBlockHeader), 1, fp ); printf("block readed: type=%x, content=%x\n", obj->vertexHeader.blockType, obj->vertexHeader.blockContent ); printf("it has %d vertex.\n", obj->vertexHeader.elementCount); size = sizeof(vertex) * obj->vertexHeader.elementCount; // vertex has 3 element obj->vertexs = (vertex *)malloc( size ); printf("offset %d, to read vertex\n", ftell(fp)); // read and convert for ( int i = 0; i < obj->vertexHeader.elementCount ; ++ i ) { if ( verbose ) printf("read %04dth vertex, ", i); READ_MEL_FLOAT( obj->vertexs[i].x ); READ_MEL_FLOAT( obj->vertexs[i].y ); READ_MEL_FLOAT( obj->vertexs[i].z ); if ( verbose ) { printf(" => "); printf("(%f, %f, %f)\n", obj->vertexs[i].x,obj->vertexs[i].y,obj->vertexs[i].z); } } //fread( &(obj->vertexs), size, 1, fp ); // normal printf("offset %d, to read normal\n", ftell(fp)); fread( &(obj->normalHeader), sizeof(OGLBlockHeader), 1, fp ); printf("block readed: type=%x, content=%x\n", obj->normalHeader.blockType, obj->normalHeader.blockContent ); printf("it has %d normal.\n", obj->normalHeader.elementCount); size = sizeof(vertex) * obj->normalHeader.elementCount; obj->normals = (normal *)malloc( size ); // read and convert for ( int i = 0; i < obj->normalHeader.elementCount ; ++ i ) { if ( verbose ) printf("read %04dth normal, ", i); READ_MEL_FLOAT( obj->normals[i].x ); READ_MEL_FLOAT( obj->normals[i].y ); READ_MEL_FLOAT( obj->normals[i].z ); if ( verbose ) { printf(" => "); printf("(%f, %f, %f)\n", obj->normals[i].x,obj->normals[i].y,obj->normals[i].z); } } //fread( &(obj->normals), size, 1, fp ); // uv printf("offset %d, to read uv\n", ftell(fp)); fread( &(obj->uvHeader), sizeof(OGLBlockHeader), 1, fp ); printf("block readed: type=%x, content=%x\n", obj->uvHeader.blockType, obj->uvHeader.blockContent ); printf("it has %d uv.\n", obj->uvHeader.elementCount); size = sizeof(uv) * obj->uvHeader.elementCount; obj->uvs = (uv *)malloc( size ); // read and convert for ( int i = 0; i < obj->uvHeader.elementCount ; ++ i ) { if ( verbose ) printf("read %04dth uv, ", i); READ_MEL_FLOAT( obj->uvs[i].u ); READ_MEL_FLOAT( obj->uvs[i].v ); if ( verbose ) { printf(" => "); printf("(%f, %f)\n", obj->uvs[i].u,obj->uvs[i].v); } } //fread( &(obj->uvs), size, 1, fp ); } // read materials if ( ! feof(fp) ) { printf("offset %d, to read material\n", ftell(fp)); fread( & (exp->materialHeader), sizeof(OGLBlockHeader), 1, fp ); printf("block readed: type=%x, content=%x\n", exp->materialHeader.blockType, exp->materialHeader.blockContent ); printf("exported %d materials.\n", exp->materialHeader.elementCount); size = sizeof(material) * exp->materialHeader.elementCount; exp->materials = (material *) malloc(size); material * pmat; for ( int i = 0; i < exp->materialHeader.elementCount; ++i ) { pmat = &(exp->materials[i]); fread( & (pmat->nameLength), sizeof(int), 1, fp ); pmat->name = (char*) malloc( pmat->nameLength + 1 ); fread( pmat->name, pmat->nameLength+1, 1, fp ); // tail 0 as string end flag is written. //pmat->name[pmat->nameLength] = 0; printf("name: %s, length %d\n", pmat->name, pmat->nameLength); /* 1 - 0100000100 (260 - 1023= -763) 11001100110011101100100111111000000000000000000000000 (1.7206032761683968) */ // ambient READ_MEL_FLOAT( pmat->ambient.r ); READ_MEL_FLOAT( pmat->ambient.g ); READ_MEL_FLOAT( pmat->ambient.b ); printf("ambient color (%f,%f,%f)\n", pmat->ambient.r, pmat->ambient.g, pmat->ambient.b ); // diffuse READ_MEL_FLOAT( pmat->diffuse.r ); READ_MEL_FLOAT( pmat->diffuse.g ); READ_MEL_FLOAT( pmat->diffuse.b ); printf("diffuse color (%f,%f,%f)\n", pmat->diffuse.r, pmat->diffuse.g, pmat->diffuse.b ); // specular READ_MEL_FLOAT( pmat->specular.r ); READ_MEL_FLOAT( pmat->specular.g ); READ_MEL_FLOAT( pmat->specular.b ); printf("specular color (%f,%f,%f)\n", pmat->specular.r, pmat->specular.g, pmat->specular.b ); // transparency READ_MEL_FLOAT( pmat->transparency); printf("transparency: %f\n", pmat->transparency); // cosinePower READ_MEL_FLOAT( pmat->cosinePower ); printf("shininess (cosine power): %f\n", pmat->cosinePower); } } fclose(fp); } void dumpExp(OGLExp * exp) { if ( exp == NULL ) { printf("invalid exp: null\n"); return; } // todo: dump all data in ascii standard out } int main(int argc, char ** argv) { if ( argc < 2 ) { printf("usage: OGLExpDump [-v] exportedFileName"); return 1; } char * arg = argv[1]; if ( strcmp(arg, "-v") == 0 ) { printf("run in verbose mode.\n"); verbose = 1; arg = argv[2]; } char * fname = arg; OGLExp exp; loadExp(fname, &exp); }