diff options
-rw-r--r-- | src/tools/mesh_extractor/MeshExtractor.cpp | 53 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.cpp | 20 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.h | 19 | ||||
-rw-r--r-- | src/tools/mesh_extractor/WorldModelGroup.cpp | 27 | ||||
-rw-r--r-- | src/tools/mesh_extractor/WorldModelGroup.h | 11 |
5 files changed, 117 insertions, 13 deletions
diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 8eb6ba5cb6e..117a398d5cf 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -170,13 +170,62 @@ void ExtractGameobjectModels() fclose(output); delete[] indices; delete[] vertices; + + uint32 displayId = (*itr)->Values[0]; + uint32 pathLength = fileName.size(); + fwrite(&displayId, sizeof(uint32), 1, modelList); + fwrite(&pathLength, sizeof(uint32), 1, modelList); + fwrite(fileName.c_str(), sizeof(char), pathLength, modelList); } else if (extension == "wmo") { - //WorldModelRoot model(path); + WorldModelRoot model(path); + + 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; + } + + fwrite(Constants::VMAPMagic, 1, 8, output); + uint32 numVertices = 0; + fwrite(&numVertices, sizeof(uint32), 1, output); // will be filled later + fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); + fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); + + uint32 i = 0; + for (std::vector<WorldModelGroup>::iterator itr2 = model.Groups.begin(); itr2 != model.Groups.end(); ++itr2) + { + fwrite(&itr2->Header.Flags, sizeof(uint32), 1, output); + fwrite(&itr2->Header.WmoId, sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[0], sizeof(uint32), 1, output); + fwrite(&itr2->Header.BoundingBox[1], sizeof(uint32), 1, output); + uint32 LiquidFlags = itr2->HasLiquidData ? 1 : 0; + fwrite(&LiquidFlags, sizeof(uint32), 1, output); + + fwrite("GRP ", sizeof(char), 4, output); + uint32 k = 0; + uint32 mobaBatch = itr2->MOBALength / 12; + uint32* MobaEx = new uint32[mobaBatch*4]; + + for(uint32 i = 8; i < itr2->MOBALength; i += 12) + MobaEx[k++] = itr2->MOBA[i]; + + int mobaSizeGrp = mobaBatch * 4 + 4; + fwrite(&mobaSizeGrp, 4, 1, output); + fwrite(&mobaBatch, 4, 1, output); + fwrite(MobaEx, 4, k, output); + delete[] MobaEx; + + // Note: still not finished + } + + fclose(output); } } + fclose(modelList); printf("GameObject models extraction finished!"); Constants::ToWoWCoords = false; } @@ -252,7 +301,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 finished)\n", Constants::EXTRACT_FLAG_GOB_MODELS); + printf("- %u to extract GameObject models (Not yet finished, you need to run VMapAssembler on the extracted files)\n", Constants::EXTRACT_FLAG_GOB_MODELS); printf("- %u to extract MMaps (Not yet finished)\n", Constants::EXTRACT_FLAG_MMAPS); } } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 4414a02d681..b1b054e942e 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -483,4 +483,22 @@ char* Utils::GetPlainName(const char* FileName) if((temp = (char*)strrchr(FileName, '\\')) != NULL) FileName = temp + 1; return (char*)FileName; -}
\ No newline at end of file +} + +WMOGroupHeader WMOGroupHeader::Read( FILE* stream ) +{ + WMOGroupHeader ret; + fread(&ret.OffsetGroupName, sizeof(uint32), 1, stream); + fread(&ret.OffsetDescriptiveName, sizeof(uint32), 1, stream); + fread(&ret.Flags, sizeof(uint32), 1, stream); + ret.BoundingBox[0] = Vector3::Read(stream); + ret.BoundingBox[1] = Vector3::Read(stream); + fread(&ret.OffsetPortals, sizeof(uint32), 1, stream); + fread(&ret.CountPortals, sizeof(uint32), 1, stream); + fread(&ret.CountBatches, sizeof(uint16), 4, stream); + fread(&ret.Fogs, sizeof(uint8), 4, stream); + fread(&ret.LiquidTypeRelated, sizeof(uint32), 1, stream); + fread(&ret.WmoId, sizeof(uint32), 1, stream); + + return ret; +} diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 47a6354d3b2..c5dd04fde06 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -289,6 +289,25 @@ public: static H2OInformation Read(FILE* stream); }; +class WMOGroupHeader +{ +public: + WMOGroupHeader() {} + + uint32 OffsetGroupName; + uint32 OffsetDescriptiveName; + uint32 Flags; + Vector3 BoundingBox[2]; + uint32 OffsetPortals; + uint32 CountPortals; + uint16 CountBatches[4]; + uint8 Fogs[4]; + uint32 LiquidTypeRelated; + uint32 WmoId; + + static WMOGroupHeader Read(FILE* stream); +}; + // Dummy class to act as an interface. class IDefinition { diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index c7e6f0c525e..35a5ba69782 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -1,8 +1,9 @@ #include "WorldModelGroup.h" #include "ChunkedData.h" #include "Chunk.h" +#include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), IsBad(false), MOBA(NULL) { Data = new ChunkedData(path); if (!Data->Stream) @@ -14,16 +15,20 @@ WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupInde int32 firstSub = mainChunk->FindSubChunkOffset("MOPY"); if (firstSub == -1) return; + + Name = Utils::GetPlainName(path.c_str()); + FILE* stream = mainChunk->GetStream(); fseek(stream, firstSub, SEEK_SET); SubData = new ChunkedData(stream, mainChunk->Length - firstSub); - ReadBoundingBox(); + ReadHeader(); ReadMaterials(); ReadTriangles(); ReadVertices(); ReadNormals(); ReadLiquid(); + ReadBatches(); } void WorldModelGroup::ReadNormals() @@ -108,15 +113,23 @@ void WorldModelGroup::ReadMaterials() } } -void WorldModelGroup::ReadBoundingBox() +void WorldModelGroup::ReadHeader() { Chunk* chunk = Data->GetChunkByName("MOGP"); if (!chunk) return; FILE* stream = chunk->GetStream(); - fseek(stream, 8, SEEK_CUR); - fread(&Flags, sizeof(uint32), 1, stream); - BoundingBox[0] = Vector3::Read(stream); - BoundingBox[1] = Vector3::Read(stream); + Header = WMOGroupHeader::Read(stream); +} + +void WorldModelGroup::ReadBatches() +{ + Chunk* chunk = Data->GetChunkByName("MOBA"); + if (!chunk) + return; + + MOBALength = chunk->Length / 2; + MOBA = new uint16[MOBALength]; + fread(MOBA, sizeof(uint16), MOBALength, chunk->GetStream()); } diff --git a/src/tools/mesh_extractor/WorldModelGroup.h b/src/tools/mesh_extractor/WorldModelGroup.h index 1dc754d0221..e4fe34cbc75 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.h +++ b/src/tools/mesh_extractor/WorldModelGroup.h @@ -10,13 +10,17 @@ public: ChunkedData* Data; ChunkedData* SubData; int GroupIndex; - Vector3 BoundingBox[2]; - uint32 Flags; + std::string Name; + WMOGroupHeader Header; + std::vector<uint8> TriangleFlags; std::vector<uint8> TriangleMaterials; std::vector<Triangle<uint16> > Triangles; std::vector<Vector3> Vertices; std::vector<Vector3> Normals; + // @ToDo: Research. + uint16* MOBA; + uint32 MOBALength; bool HasLiquidData; bool IsBad; @@ -28,6 +32,7 @@ private: void ReadVertices(); void ReadTriangles(); void ReadMaterials(); - void ReadBoundingBox(); + void ReadHeader(); + void ReadBatches(); }; #endif
\ No newline at end of file |