diff options
author | Subv <s.v.h21@hotmail.com> | 2012-10-03 21:09:05 -0500 |
---|---|---|
committer | Subv <s.v.h21@hotmail.com> | 2012-10-03 21:09:05 -0500 |
commit | d2437407f4f7ad1af3baeb351626b41bd700065c (patch) | |
tree | 3d142cde5242a178292f08dbfcbf2efe953878e3 | |
parent | e32ddea96a017c7d5ad22eca16764d74501b90f3 (diff) |
Tools/MeshExtractor:
* Fixed a bunch of errors
* Allow to extract m2 and mdx models, WMOs are still not being extracted.
-rw-r--r-- | src/tools/mesh_extractor/Chunk.cpp | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Constants.h | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/DBC.cpp | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/DBC.h | 5 | ||||
-rw-r--r-- | src/tools/mesh_extractor/MeshExtractor.cpp | 123 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Model.cpp | 29 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Model.h | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/ObjectDataHandler.cpp | 2 | ||||
-rw-r--r-- | src/tools/mesh_extractor/TileBuilder.cpp | 4 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.cpp | 36 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.h | 3 | ||||
-rw-r--r-- | src/tools/mesh_extractor/WorldModelGroup.cpp | 2 |
12 files changed, 183 insertions, 29 deletions
diff --git a/src/tools/mesh_extractor/Chunk.cpp b/src/tools/mesh_extractor/Chunk.cpp index b41fa7d07d4..2f521f1badd 100644 --- a/src/tools/mesh_extractor/Chunk.cpp +++ b/src/tools/mesh_extractor/Chunk.cpp @@ -10,7 +10,7 @@ int32 Chunk::FindSubChunkOffset(std::string name) FILE* stream = GetStream(); uint32 matched = 0; - while (ftell(stream) < Utils::Size(stream)) + while (uint32(ftell(stream)) < Utils::Size(stream)) { char b; fread(&b, sizeof(char), 1, stream); diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index f3b71812155..89cd6da20a2 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -47,6 +47,8 @@ public: static const float Origin[]; static const float PI; static const float MaxStandableHeight; + static bool ToWoWCoords; + static const char* VMAPMagic; }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp index be04ce070ee..c50e02014da 100644 --- a/src/tools/mesh_extractor/DBC.cpp +++ b/src/tools/mesh_extractor/DBC.cpp @@ -38,7 +38,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), IsFaulty(true), StringBlockSize(0) std::string DBC::GetStringByOffset( int offset ) { int len = 0; - for (int i = offset; i < StringBlockSize; i++) + for (uint32 i = offset; i < StringBlockSize; i++) { if (!StringBlock[i]) { diff --git a/src/tools/mesh_extractor/DBC.h b/src/tools/mesh_extractor/DBC.h index 6c86c1391dd..0c857bd40ed 100644 --- a/src/tools/mesh_extractor/DBC.h +++ b/src/tools/mesh_extractor/DBC.h @@ -37,9 +37,10 @@ public: return Values[index]; } - float GetFloat(int index) + template <typename T> + T GetValue(int index) { - return *(float*)(&Values[index]); + return *(T*)(&Values[index]); } std::string GetString(int index) diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index d6b701607ba..8eb6ba5cb6e 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -4,6 +4,7 @@ #include "Cache.h" #include "DBC.h" #include "Constants.h" +#include "Model.h" #include <set> @@ -70,6 +71,116 @@ void ExtractDBCs() printf("DBC extraction finished!\n"); } +void ExtractGameobjectModels() +{ + Constants::ToWoWCoords = true; + printf("Extracting GameObject models\n"); + + std::string baseBuildingsPath = "Buildings/"; + std::string baseVmapsPath = "vmaps/"; + Utils::CreateDir(baseVmapsPath); + Utils::CreateDir(baseBuildingsPath); + + FILE* modelList = fopen((baseVmapsPath + "GameObjectModels.list").c_str(), "wb"); + if (!modelList) + { + printf("Could not create file vmaps/GameObjectModels.list, please make sure that you have the write permissions in the folder\n"); + return; + } + + DBC* dbc = MPQHandler->GetDBC("GameObjectDisplayInfo"); + for (std::vector<Record*>::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) + { + std::string path = (*itr)->GetString(1); + std::string fileName = Utils::GetPlainName(path.c_str()); + std::string extension = Utils::GetExtension(fileName); + // Convert the extension to lowercase + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + if (extension == "mdx" || extension == "m2") + { + fileName = Utils::FixModelPath(fileName); + Model model(path); + + if (model.IsBad) + continue; + + FILE* output = fopen((baseBuildingsPath + fileName).c_str(), "wb"); + if (!output) + { + printf("Could not create file %s, please check that you have write permissions\n", (baseBuildingsPath + fileName).c_str()); + continue; + } + // Placeholder for 0 values + int Nop[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + fwrite(Constants::VMAPMagic, 8, 1, output); + uint32 numVerts = model.Header.CountBoundingVertices; + fwrite(&numVerts, sizeof(uint32), 1, output); + uint32 numGroups = 1; + fwrite(&numGroups, sizeof(uint32), 1, output); + fwrite(Nop, 4 * 3 , 1, output); // rootwmoid, flags, groupid + fwrite(Nop, sizeof(float), 3 * 2, output);//bbox, only needed for WMO currently + fwrite(Nop, 4, 1, output);// liquidflags + fwrite("GRP ", 4, 1, output); + + uint32 branches = 1; + uint32 wsize = sizeof(branches) + sizeof(uint32) * branches; + fwrite(&wsize, sizeof(uint32), 1, output); + fwrite(&branches, sizeof(branches), 1, output); + uint32 numTris = model.Header.CountBoundingTriangles; + fwrite(&numTris, sizeof(uint32), 1, output); + fwrite("INDX", 4, 1, output); + wsize = sizeof(uint32) + sizeof(unsigned short) * numTris; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numTris, sizeof(uint32), 1, output); + uint16* indices = new uint16[numTris]; + + if (numTris > 0) + { + uint32 i = 0; + for (std::vector<Triangle<uint16> >::iterator itr2 = model.Triangles.begin(); itr2 != model.Triangles.end(); ++itr2, ++i) + { + indices[i * 3 + 0] = itr2->V0; + indices[i * 3 + 1] = itr2->V1; + indices[i * 3 + 2] = itr2->V2; + } + fwrite(indices, sizeof(uint16), numTris, output); + } + + + fwrite("VERT", 4, 1, output); + wsize = sizeof(int) + sizeof(float) * 3 * numVerts; + fwrite(&wsize, sizeof(int), 1, output); + fwrite(&numVerts, sizeof(int), 1, output); + float* vertices = new float[numVerts*3]; + + if (numVerts > 0) + { + uint32 i = 0; + for (std::vector<Vector3>::iterator itr2 = model.Vertices.begin(); itr2 != model.Vertices.end(); ++itr2, ++i) + { + vertices[i * 3 + 0] = itr2->x; + vertices[i * 3 + 1] = itr2->y; + vertices[i * 3 + 2] = itr2->z; + } + + fwrite(vertices, sizeof(float), numVerts * 3, output); + } + + fclose(output); + delete[] indices; + delete[] vertices; + } + else if (extension == "wmo") + { + //WorldModelRoot model(path); + } + } + + printf("GameObject models extraction finished!"); + Constants::ToWoWCoords = false; +} + bool HandleArgs(int argc, char** argv, uint32& threads, std::set<uint32>& mapList, bool& debugOutput, uint32& extractFlags) { char* param = NULL; @@ -141,7 +252,7 @@ void PrintUsage() printf("- %u to extract DBCs\n", Constants::EXTRACT_FLAG_DBC); printf("- %u to extract Maps (Not yet implemented)\n", Constants::EXTRACT_FLAG_MAPS); printf("- %u to extract VMaps (Not yet implemented)\n", Constants::EXTRACT_FLAG_VMAPS); - printf("- %u to extract GameObject models (Not yet implemented)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } @@ -149,9 +260,6 @@ void PrintUsage() int main(int argc, char* argv[]) { system("pause"); - Cache = new CacheClass(); - MPQHandler = new MPQManager(); - MPQHandler->Initialize(); uint32 threads = 4, extractFlags = 0; std::set<uint32> mapIds; bool debug = false; @@ -162,11 +270,18 @@ int main(int argc, char* argv[]) return -1; } + Cache = new CacheClass(); + MPQHandler = new MPQManager(); + MPQHandler->Initialize(); + if (extractFlags & Constants::EXTRACT_FLAG_DBC) ExtractDBCs(); if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) ExtractMMaps(mapIds, threads, debug); + + if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) + ExtractGameobjectModels(); return 0; }
\ No newline at end of file diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index a1c67d23f28..10fde0ebc2d 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -2,9 +2,14 @@ #include "MPQManager.h" #include "Utils.h" -Model::Model( std::string path ) +Model::Model( std::string path ) : IsCollidable(false), IsBad(false) { Stream = MPQHandler->GetFile(Utils::FixModelPath(path)); + if (!Stream) + { + IsBad = true; + return; + } Header.Read(Stream); if (Header.OffsetBoundingNormals > 0 && Header.OffsetBoundingVertices > 0 && Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) @@ -16,26 +21,36 @@ Model::Model( std::string path ) } } +Model::~Model() +{ + if (Stream) + fclose(Stream); +} + void Model::ReadVertices( FILE* stream ) { fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); Vertices.reserve(Header.CountBoundingVertices); - for (int i = 0; i < Header.CountBoundingVertices; ++i) - Vertices[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) + { + Vertices.push_back(Vector3::Read(stream)); + if (Constants::ToWoWCoords) + Vertices[i] = Utils::ToWoWCoords(Vertices[i]); + } } void Model::ReadBoundingTriangles( FILE* stream ) { fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); Triangles.reserve(Header.CountBoundingTriangles / 3); - for (int i = 0; i < Header.CountBoundingTriangles / 3; i++) + for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) { Triangle<uint16> tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; fread(&tri.V0, sizeof(uint16), 1, stream); fread(&tri.V1, sizeof(uint16), 1, stream); fread(&tri.V2, sizeof(uint16), 1, stream); - Triangles[i] = tri; + Triangles.push_back(tri); } } @@ -43,7 +58,7 @@ void Model::ReadBoundingNormals( FILE* stream ) { fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); Normals.reserve(Header.CountBoundingNormals); - for (int i = 0; i < Header.CountBoundingNormals; i++) - Normals[i] = Vector3::Read(stream); + for (uint32 i = 0; i < Header.CountBoundingNormals; i++) + Normals.push_back(Vector3::Read(stream)); } diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h index a5b8338461d..ea9331e7c30 100644 --- a/src/tools/mesh_extractor/Model.h +++ b/src/tools/mesh_extractor/Model.h @@ -7,6 +7,7 @@ class Model { public: Model(std::string path); + ~Model(); void ReadVertices(FILE* stream); void ReadBoundingTriangles(FILE* stream); @@ -17,5 +18,6 @@ public: std::vector<Triangle<uint16> > Triangles; bool IsCollidable; FILE* Stream; + bool IsBad; }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp index 3ed2ee49604..789efc6d62c 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -11,7 +11,7 @@ void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); if (firstIndex == -1) return; - if (firstIndex + chunk->Index > Source->ObjectData->Chunks.size()) + if (uint32(firstIndex + chunk->Index) > Source->ObjectData->Chunks.size()) return; Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; if (ourChunk->Length == 0) diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5b3e181713e..12213b16373 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -88,9 +88,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) char buff[100]; sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); FILE* debug = fopen(buff, "wb"); - for (int i = 0; i < _Geometry->Vertices.size(); ++i) + for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) fprintf(debug, "v %f %f %f\n", _Geometry->Vertices[i].x, _Geometry->Vertices[i].y, _Geometry->Vertices[i].z); - for (int i = 0; i < _Geometry->Triangles.size(); ++i) + for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) fprintf(debug, "f %i %i %i\n", _Geometry->Triangles[i].V0 + 1, _Geometry->Triangles[i].V1 + 1, _Geometry->Triangles[i].V2 + 1); fclose(debug); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 5b752885d17..5fccd319554 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -19,6 +19,8 @@ const float Constants::UnitSize = Constants::ChunkSize / 8.0f; const float Constants::Origin[] = { -Constants::MaxXY, 0.0f, -Constants::MaxXY }; const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; +const char* Constants::VMAPMagic = "VMAP042"; +bool Constants::ToWoWCoords = false; void Utils::CreateDir( const std::string& Path ) { @@ -219,6 +221,21 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) delete data; } +Vector3 Utils::ToWoWCoords( Vector3 vec ) +{ + return Vector3(vec.x, -vec.z, vec.y); +} + +std::string Utils::GetExtension( std::string path ) +{ + std::string::size_type idx = path.rfind('.'); + std::string extension = ""; + + if(idx != std::string::npos) + extension = path.substr(idx+1); + return extension; +} + void MapChunkHeader::Read(FILE* stream) { fread(&Flags, sizeof(uint32), 1, stream); @@ -308,16 +325,6 @@ void ModelHeader::Read(FILE* stream) fread(&OffsetTransLookup, sizeof(uint32), 1, stream); fread(&CountUvAnimLookup, sizeof(uint32), 1, stream); fread(&OffsetUvAnimLookup, sizeof(uint32), 1, stream); - fread(&CountColors, sizeof(uint32), 1, stream); - fread(&OffsetColors, sizeof(uint32), 1, stream); - fread(&CountTextures, sizeof(uint32), 1, stream); - fread(&OffsetTextures, sizeof(uint32), 1, stream); - fread(&CountTransparency, sizeof(uint32), 1, stream); - fread(&OffsetTransparency, sizeof(uint32), 1, stream); - fread(&CountUvAnimation, sizeof(uint32), 1, stream); - fread(&OffsetUvAnimation, sizeof(uint32), 1, stream); - fread(&CountTexReplace, sizeof(uint32), 1, stream); - fread(&OffsetTexReplace, sizeof(uint32), 1, stream); VertexBox[0] = Vector3::Read(stream); VertexBox[1] = Vector3::Read(stream); fread(&VertexRadius, sizeof(float), 1, stream); @@ -468,3 +475,12 @@ H2OInformation H2OInformation::Read(FILE* stream) fread(&ret.OffsetHeightmap, sizeof(uint32), 1, stream); return ret; } + +char* Utils::GetPlainName(const char* FileName) +{ + char* temp; + + if((temp = (char*)strrchr(FileName, '\\')) != NULL) + FileName = temp + 1; + return (char*)FileName; +}
\ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index c19bc1bb29c..47a6354d3b2 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -351,5 +351,8 @@ public: static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); static void CreateDir( const std::string& Path ); static void SaveToDisk(FILE* stream, std::string path); + static Vector3 ToWoWCoords( Vector3 vec ); + static std::string GetExtension( std::string path ); + static char* GetPlainName(const char* FileName); }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index bd0d106dabb..c7e6f0c525e 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -37,7 +37,7 @@ void WorldModelGroup::ReadNormals() Normals.reserve(normalCount); FILE* stream = chunk->GetStream(); for (uint32 i = 0; i < normalCount; i++) - Normals[i] = Vector3::Read(stream); + Normals.push_back(Vector3::Read(stream)); } void WorldModelGroup::ReadLiquid() |