// ============================================================== // This file is part of Glest Shared Library (www.glest.org) // // Copyright (C) 2001-2008 Martiņo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #include "model.h" #include #include #include #include "interpolation.h" #include "conversion.h" #include "util.h" #include "leak_dumper.h" using namespace Shared::Platform; using namespace std; namespace Shared{ namespace Graphics{ using namespace Util; // ===================================================== // class Mesh // ===================================================== // ==================== constructor & destructor ==================== Mesh::Mesh(){ frameCount= 0; vertexCount= 0; indexCount= 0; vertices= NULL; normals= NULL; texCoords= NULL; tangents= NULL; indices= NULL; interpolationData= NULL; for(int i=0; iupdate(t, cycle); } void Mesh::updateInterpolationVertices(float t, bool cycle) const{ interpolationData->updateVertices(t, cycle); } // ==================== load ==================== void Mesh::loadV2(const string &dir, FILE *f, TextureManager *textureManager){ //read header MeshHeaderV2 meshHeader; size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV2), 1, f); if(meshHeader.normalFrameCount!=meshHeader.vertexFrameCount){ throw runtime_error("Old model: vertex frame count different from normal frame count"); } if(meshHeader.texCoordFrameCount!=1){ throw runtime_error("Old model: texture coord frame count is not 1"); } //init frameCount= meshHeader.vertexFrameCount; vertexCount= meshHeader.pointCount; indexCount= meshHeader.indexCount; init(); //misc twoSided= false; customColor= false; //texture if(meshHeader.hasTexture && textureManager!=NULL){ texturePaths[mtDiffuse]= toLower(reinterpret_cast(meshHeader.texName)); string texPath= dir+"/"+texturePaths[mtDiffuse]; textures[mtDiffuse]= static_cast(textureManager->getTexture(texPath)); if(textures[mtDiffuse]==NULL){ textures[mtDiffuse]= textureManager->newTexture2D(); textures[mtDiffuse]->load(texPath); } } //read data readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); if(textures[mtDiffuse]!=NULL){ readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); } readBytes = fread(&diffuseColor, sizeof(Vec3f), 1, f); readBytes = fread(&opacity, sizeof(float32), 1, f); fseek(f, sizeof(Vec4f)*(meshHeader.colorFrameCount-1), SEEK_CUR); readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); } void Mesh::loadV3(const string &dir, FILE *f, TextureManager *textureManager){ //read header MeshHeaderV3 meshHeader; size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV3), 1, f); if(meshHeader.normalFrameCount!=meshHeader.vertexFrameCount){ throw runtime_error("Old model: vertex frame count different from normal frame count"); } //init frameCount= meshHeader.vertexFrameCount; vertexCount= meshHeader.pointCount; indexCount= meshHeader.indexCount; init(); //misc twoSided= (meshHeader.properties & mp3TwoSided) != 0; customColor= (meshHeader.properties & mp3CustomColor) != 0; //texture if(!(meshHeader.properties & mp3NoTexture) && textureManager!=NULL){ texturePaths[mtDiffuse]= toLower(reinterpret_cast(meshHeader.texName)); string texPath= dir+"/"+texturePaths[mtDiffuse]; textures[mtDiffuse]= static_cast(textureManager->getTexture(texPath)); if(textures[mtDiffuse]==NULL){ textures[mtDiffuse]= textureManager->newTexture2D(); textures[mtDiffuse]->load(texPath); } } //read data readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); if(textures[mtDiffuse]!=NULL){ for(int i=0; i(cMapPath)); string mapFullPath= dir + "/" + mapPath; textures[i]= static_cast(textureManager->getTexture(mapFullPath)); if(textures[i]==NULL){ textures[i]= textureManager->newTexture2D(); if(meshTextureChannelCount[i]!=-1){ textures[i]->getPixmap()->init(meshTextureChannelCount[i]); } textures[i]->load(mapFullPath); } } flag*= 2; } //read data readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); if(meshHeader.textures!=0){ readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); } readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); //tangents if(textures[mtNormal]!=NULL){ computeTangents(); } } void Mesh::save(const string &dir, FILE *f){ /*MeshHeader meshHeader; meshHeader.vertexFrameCount= vertexFrameCount; meshHeader.normalFrameCount= normalFrameCount; meshHeader.texCoordFrameCount= texCoordFrameCount; meshHeader.colorFrameCount= colorFrameCount; meshHeader.pointCount= pointCount; meshHeader.indexCount= indexCount; meshHeader.properties= 0; if(twoSided) meshHeader.properties|= mpTwoSided; if(customTexture) meshHeader.properties|= mpCustomTexture; if(texture==NULL){ meshHeader.properties|= mpNoTexture; meshHeader.texName[0]= '\0'; } else{ strcpy(reinterpret_cast(meshHeader.texName), texName.c_str()); texture->getPixmap()->saveTga(dir+"/"+texName); } fwrite(&meshHeader, sizeof(MeshHeader), 1, f); fwrite(vertices, sizeof(Vec3f)*vertexFrameCount*pointCount, 1, f); fwrite(normals, sizeof(Vec3f)*normalFrameCount*pointCount, 1, f); fwrite(texCoords, sizeof(Vec2f)*texCoordFrameCount*pointCount, 1, f); fwrite(colors, sizeof(Vec4f)*colorFrameCount, 1, f); fwrite(indices, sizeof(uint32)*indexCount, 1, f);*/ } void Mesh::computeTangents(){ delete [] tangents; tangents= new Vec3f[vertexCount]; for(int i=0; i(fileHeader.id), "G3D", 3)!=0){ printf("In [%s::%s] file = [%s] fileheader.id = [%s][%c]\n",__FILE__,__FUNCTION__,path.c_str(),reinterpret_cast(fileHeader.id),fileHeader.id[0]); throw runtime_error("Not a valid S3D model"); } fileVersion= fileHeader.version; //version 4 if(fileHeader.version==4){ //model header ModelHeader modelHeader; readBytes = fread(&modelHeader, sizeof(ModelHeader), 1, f); meshCount= modelHeader.meshCount; if(modelHeader.type!=mtMorphMesh){ throw runtime_error("Invalid model type"); } //load meshes meshes= new Mesh[meshCount]; for(uint32 i=0; i