static void parseKeyFramer( MeshModel *root ){ _log( "KeyFramer" ); enterChunk(); string file_3ds; unsigned short rev,curr_time=0; while( int id=nextChunk() ){ switch( id ){ case 0xb009: //CURR_TIME in.sgetn( (char*)&curr_time,2 ); _log( "CURR_TIME: "+itoa(curr_time) ); break; case 0xb00a: //KFHDR in.sgetn( (char*)&rev,2 ); file_3ds=parseString(); in.sgetn( (char*)&anim_len,2 ); _log( "KFHDR: revision="+itoa(rev)+" 3dsfile="+file_3ds+" anim_len="+itoa(anim_len) ); break; case 0xb002: //object keyframer data... parseMeshInfo( root,curr_time ); break; } } if( !collapse ){ root->setAnimator( d_new Animator( root,anim_len ) ); } leaveChunk(); }
static MeshModel* parseFile() { unsigned short id; int len; in.sgetn((char*)&id, 2); in.sgetn((char*)&len, 4); if (id != CHUNK_MAIN) return 0; chunk_end = (int)in.pubseekoff(0, std::ios_base::cur) + len - 6; enterChunk(); MeshModel* root = new MeshModel(); while (int id = nextChunk()) { switch (id) { case CHUNK_SCENE: parseScene(root); break; case CHUNK_KEYFRAMER: parseKeyFramer(root); break; } } leaveChunk(); return root; }
static void parseFaceList() { unsigned short cnt; in.sgetn((char*)&cnt, 2); _log("FaceList cnt=" + itoa(cnt)); while (cnt--) { unsigned short v[4]; in.sgetn((char*)v, 8); Face3DS face; face.verts[0] = v[0]; face.verts[1] = v[1]; face.verts[2] = v[2]; if (flip_tris) std::swap(face.verts[1], face.verts[2]); faces.push_back(face); } enterChunk(); while (int id = nextChunk()) { switch (id) { case CHUNK_FACEMAT: parseFaceMat(); break; } } leaveChunk(); }
static void parseTriMesh( MeshModel *mesh ){ _log( "TriMesh" ); enterChunk(); Transform tform; faces.clear(); MeshLoader::beginMesh(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_VERTLIST: if( !animonly ) parseVertList(); break; case CHUNK_MAPLIST: if( !animonly ) parseMapList(); break; case CHUNK_FACELIST: if( !animonly ) parseFaceList(); break; case CHUNK_TRMATRIX: in.sgetn( (char*)&tform,48 ); if( conv ) tform=conv_tform * tform * -conv_tform; break; } } leaveChunk(); //should really do something here... // bool neg_x=tform.m.j.cross(tform.m.k).dot(tform.m.i)<0; int k; mesh->setWorldTform( tform ); if( animonly ){ MeshLoader::endMesh( 0 ); return; } Transform inv_tform=-tform; for( k=0;k<MeshLoader::numVertices();++k ){ Surface::Vertex &v=MeshLoader::refVertex( k ); v.coords=inv_tform * v.coords; } for( k=0;k<faces.size();++k ){ const Face3DS &f=faces[k]; MeshLoader::addTriangle( f.verts,f.brush ); } MeshLoader::endMesh( mesh ); mesh->updateNormals(); faces.clear(); }
static void parseMaterial() { _log("Material"); Brush mat; std::string name, tex_name; enterChunk(); while (int id = nextChunk()) { switch (id) { case CHUNK_MATNAME: name = parseString(); break; case CHUNK_DIFFUSE: mat.setColor(parseColor()); break; case CHUNK_AMBIENT: break; case CHUNK_SPECULAR: break; case CHUNK_TEXTURE: enterChunk(); while (int id = nextChunk()) { switch (id) { case CHUNK_MAPFILE: tex_name = parseString(); break; } } leaveChunk(); break; } } if (tex_name.size()) { mat.setTexture(0, Texture(tex_name, 0), 0); mat.setColor(Vector(1, 1, 1)); } if (name.size()) { materials_map[name] = mat; } leaveChunk(); }
static void parseScene( MeshModel *root ){ _log( "Scene" ); enterChunk(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_OBJECT: parseObject( root ); break; case CHUNK_MATERIAL: if( !animonly ) parseMaterial(); break; } } leaveChunk(); }
static Vector parseColor(){ Vector v; unsigned char rgb[3]; enterChunk(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_RGBF: in.sgetn( (char*)&v,12 ); break; case CHUNK_RGBB: in.sgetn( (char*)rgb,3 ); v=Vector( rgb[0]/255.0f,rgb[1]/255.0f,rgb[2]/255.0f ); } } leaveChunk(); return v; }
static void parseObject( MeshModel *root ){ //skip name string name=parseString(); _log( "Object:"+name ); MeshModel *mesh=0; enterChunk(); while( int id=nextChunk() ){ switch( id ){ case CHUNK_TRIMESH: mesh=d_new MeshModel(); mesh->setName( name ); mesh->setParent( root ); name_map[name]=mesh; parseTriMesh( mesh ); break; } } leaveChunk(); }
static void parseMeshInfo( MeshModel *root,float curr_time ){ _log( "OBJECT_NODE_TAG" ); enterChunk(); string name,inst; Vector pivot; Animation anim; unsigned short id=65535,parent=65535,flags1,flags2; Box box( (Vector()),(Vector()) ); Vector box_centre; while( int chunk_id=nextChunk() ){ switch( chunk_id ){ case 0xb030: //NODE_ID in.sgetn( (char*)&id,2 ); _log( "NODE_ID: "+itoa(id) ); break; case 0xb010: //NODE_HDR name=parseString(); in.sgetn( (char*)&flags1,2 ); in.sgetn( (char*)&flags2,2 ); in.sgetn( (char*)&parent,2 ); _log( "NODE_HDR: name="+name+" parent="+itoa(parent) ); break; case 0xb011: //INSTANCE NAME inst=parseString(); _log( "INSTANCE_NAME: "+inst ); break; case 0xb013: //PIVOT in.sgetn( (char*)&pivot,12 ); if( conv ) pivot=conv_tform * pivot; _log( "PIVOT: "+ftoa(pivot.x)+","+ftoa(pivot.y)+","+ftoa(pivot.z) ); break; case 0xb014: //BOUNDBOX in.sgetn( (char*)&box.a,12 ); in.sgetn( (char*)&box.b,12 ); box_centre=box.centre(); if( conv ) box_centre=conv_tform * box_centre; _log( "BOUNDBOX: min="+ftoa(box.a.x)+","+ftoa(box.a.y)+","+ftoa(box.a.z)+" max="+ftoa(box.b.x)+","+ftoa(box.b.y)+","+ftoa(box.b.z) ); break; case 0xb020: //POS_TRACK_TAG case 0xb021: //ROT_TRACK_TAG case 0xb022: //SCALE_TRACK_TAG if( !collapse ) parseAnimKeys( &anim,chunk_id ); break; } } leaveChunk(); MeshModel *p=root; if( parent!=65535 ){ map<int,MeshModel*>::const_iterator it=id_map.find( parent ); if( it==id_map.end() ) return; p=it->second; } MeshModel *mesh=0; if( name=="$$$DUMMY" ){ mesh=d_new MeshModel(); mesh->setName( inst ); mesh->setParent( p ); }else{ map<string,MeshModel*>::const_iterator it=name_map.find( name ); if( it==name_map.end() ) return; mesh=it->second; name_map.erase( name ); if( pivot!=Vector() ){ mesh->transform( -pivot ); } Transform t= mesh->getWorldTform(); mesh->setParent( p ); mesh->setWorldTform( t ); } mesh->setAnimation( anim ); if( id!=65535 ) id_map[id]=mesh; }