From da60e515f058bad5cf25a9fc2502843ee7e2a367 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Fri, 27 Sep 2013 15:09:24 -0500 Subject: Tools/MeshExtractor: Fixed it's build, still in pre-alpha --- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 9bb9b11619f..c52c4a04fc4 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -266,7 +266,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Offmesh-connection settings params.offMeshConCount = 0; // none for now - params.tileSize = Constants::VertexPerMap; + //params.tileSize = Constants::VertexPerMap; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) { -- cgit v1.2.3 From b7b870be829ea19464c939f19ebc17886c8e8f2f Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Fri, 27 Sep 2013 16:01:10 -0500 Subject: Tools/MeshExtractor: Removed the fool-proof code. --- src/tools/mesh_extractor/MeshExtractor.cpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index e06f44c7125..886d07ab882 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -326,12 +326,6 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) int main(int argc, char* argv[]) { - if (!system("pause")) - { - printf("main: Error in system call to pause\n"); - return -1; - } - uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; -- cgit v1.2.3 From 85d6b7b7b347182a9fe9c07b9cb77be3ac09f036 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Fri, 27 Sep 2013 16:42:00 -0500 Subject: Tools/MeshExtractor: Added some debug messages. --- src/tools/mesh_extractor/MeshExtractor.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 886d07ab882..89bc65866b4 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -18,18 +18,26 @@ CacheClass* Cache; void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) { DBC* dbc = MPQHandler->GetDBC("Map"); + printf("Map.dbc contains %u rows.\n", dbc->Records.size()); for (std::vector::iterator itr = dbc->Records.begin(); itr != dbc->Records.end(); ++itr) { uint32 mapId = (*itr)->Values[0]; // Skip this map if a list of specific maps was provided and this one is not contained in it. if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) + { + if (debug) + printf("Map %u will not be built.\n", mapId); continue; + } std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); if (!wdt.IsValid || wdt.IsGlobalModel) + { + printf("Could not find WDT data for map %u (%s)\n", mapId, name.c_str()); continue; + } printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt, threads); builder.Build(debug); -- cgit v1.2.3 From 58348d036218d1b1a6ee85c46eff1fa5c3e3adf6 Mon Sep 17 00:00:00 2001 From: Tomatoes Date: Fri, 27 Sep 2013 18:04:14 -0700 Subject: Subv's changes to mesh extractor V2 Signed-off-by: Tomatoes --- src/tools/mesh_extractor/LiquidHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/LiquidHandler.cpp b/src/tools/mesh_extractor/LiquidHandler.cpp index 285ea1a5b74..33a661a9adf 100644 --- a/src/tools/mesh_extractor/LiquidHandler.cpp +++ b/src/tools/mesh_extractor/LiquidHandler.cpp @@ -34,7 +34,7 @@ void LiquidHandler::HandleNewLiquid() H2OInformation information = H2OInformation::Read(stream); float** heights = new float*[9]; - for (int j = 0; j < 9; ++i) + for (int j = 0; j < 9; ++j) { heights[j] = new float[9]; memset(heights[j], 0, sizeof(float) * 9); -- cgit v1.2.3 From 42ae39bf9798323d6da7275a76c65adb586940be Mon Sep 17 00:00:00 2001 From: Chaplain Date: Sat, 28 Sep 2013 15:47:23 +0300 Subject: Tools/MeshExtractor: Cleanup using static analyzing tool *printf format fixed *method arguments changed to const where needed *removed not needed strlen() from cycles *other minor changes --- src/tools/mesh_extractor/ChunkedData.cpp | 6 +++--- src/tools/mesh_extractor/ChunkedData.h | 6 +++--- src/tools/mesh_extractor/ContinentBuilder.cpp | 8 ++++---- src/tools/mesh_extractor/DoodadHandler.cpp | 3 ++- src/tools/mesh_extractor/MPQManager.cpp | 6 +++--- src/tools/mesh_extractor/MPQManager.h | 6 +++--- src/tools/mesh_extractor/MeshExtractor.cpp | 20 ++++++++++++-------- src/tools/mesh_extractor/TileBuilder.cpp | 10 ++++++++-- src/tools/mesh_extractor/Utils.cpp | 23 ++++++++++++----------- src/tools/mesh_extractor/Utils.h | 20 ++++++++++---------- src/tools/mesh_extractor/WorldModelHandler.cpp | 26 +++++++++++++++----------- 11 files changed, 75 insertions(+), 59 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ChunkedData.cpp b/src/tools/mesh_extractor/ChunkedData.cpp index e0db12a6be7..f273ef946dd 100644 --- a/src/tools/mesh_extractor/ChunkedData.cpp +++ b/src/tools/mesh_extractor/ChunkedData.cpp @@ -12,7 +12,7 @@ Stream(stream) Load(maxLength, chunksHint); } -ChunkedData::ChunkedData( std::string file, uint32 chunksHint /*= 300*/ ) +ChunkedData::ChunkedData( const std::string& file, uint32 chunksHint /*= 300*/ ) { Stream = MPQHandler->GetFile(file); if (!Stream) @@ -47,7 +47,7 @@ void ChunkedData::Load( uint32 maxLength, uint32 chunksHint ) } } -int ChunkedData::GetFirstIndex( std::string name ) +int ChunkedData::GetFirstIndex( const std::string& name ) { for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) @@ -55,7 +55,7 @@ int ChunkedData::GetFirstIndex( std::string name ) return -1; } -Chunk* ChunkedData::GetChunkByName( std::string name ) +Chunk* ChunkedData::GetChunkByName( const std::string& name ) { for (uint32 i = 0; i < Chunks.size(); ++i) if (Chunks[i]->Name == name) diff --git a/src/tools/mesh_extractor/ChunkedData.h b/src/tools/mesh_extractor/ChunkedData.h index e23648c845e..1e1cb17749e 100644 --- a/src/tools/mesh_extractor/ChunkedData.h +++ b/src/tools/mesh_extractor/ChunkedData.h @@ -8,11 +8,11 @@ class ChunkedData { public: ChunkedData(FILE* stream, uint32 maxLength, uint32 chunksHint = 300); - ChunkedData(std::string file, uint32 chunksHint = 300); + ChunkedData(const std::string &file, uint32 chunksHint = 300); ~ChunkedData(); - int GetFirstIndex(std::string name); - Chunk* GetChunkByName(std::string name); + int GetFirstIndex(const std::string& name); + Chunk* GetChunkByName(const std::string& name); void Load(uint32 maxLength, uint32 chunksHint); std::vector Chunks; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index d6125bdd8e2..a6b4e3763a0 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -17,7 +17,7 @@ private: ContinentBuilder* cBuilder; public: BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : debug(deb), Params(params), cBuilder(_cBuilder), Free(true) {} - void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } + void SetData(int x, int y, int map, const std::string& cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() { @@ -25,7 +25,7 @@ public: printf("[%02i,%02i] Building tile\n", X, Y); TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; - sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); if (f) // Check if file already exists. { @@ -50,7 +50,7 @@ public: fclose(f); } dtFree(nav); - printf("[%02u,%02u] Tile Built!\n", X, Y); + printf("[%02i,%02i] Tile Built!\n", X, Y); Free = true; return 0; } @@ -113,7 +113,7 @@ void ContinentBuilder::Build(bool debug) std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, debug, params)); - printf("Map %s ( %i ) has %u tiles. Building them with %i threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); + printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 56c2a7986f8..ed683d70520 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -30,7 +30,8 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) for (uint32 i = 0; i < refCount; i++) { int32 index; - if (int count = fread(&index, sizeof(int32), 1, stream) != 1) + int32 count; + if ((count = fread(&index, sizeof(int32), 1, stream)) != 1) printf("DoodadHandler::ProcessInternal: Failed to read some data expected 1, read %d\n", count); if (index < 0 || uint32(index) >= _definitions->size()) continue; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 91b9c121c89..c95179f2680 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -64,7 +64,7 @@ void MPQManager::InitializeDBC() printf("Using default locale: %s\n", Languages[BaseLocale]); } -FILE* MPQManager::GetFile( std::string path ) +FILE* MPQManager::GetFile(const std::string& path ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); MPQFile file(path.c_str()); @@ -73,13 +73,13 @@ FILE* MPQManager::GetFile( std::string path ) return file.GetFileStream(); } -DBC* MPQManager::GetDBC( std::string name ) +DBC* MPQManager::GetDBC(const std::string& name ) { std::string path = "DBFilesClient\\" + name + ".dbc"; return new DBC(GetFile(path)); } -FILE* MPQManager::GetFileFrom( std::string path, MPQArchive* file ) +FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) { ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL); mpq_archive* mpq_a = file->mpq_a; diff --git a/src/tools/mesh_extractor/MPQManager.h b/src/tools/mesh_extractor/MPQManager.h index 2f49ad258a5..7f9d675c4d4 100644 --- a/src/tools/mesh_extractor/MPQManager.h +++ b/src/tools/mesh_extractor/MPQManager.h @@ -14,9 +14,9 @@ public: ~MPQManager() {} void Initialize(); - FILE* GetFile(std::string path); - FILE* GetFileFrom(std::string path, MPQArchive* file); - DBC* GetDBC(std::string name); + FILE* GetFile(const std::string& path); + FILE* GetFileFrom(const std::string& path, MPQArchive* file); + DBC* GetDBC(const std::string& name); std::vector GetAllFiles(std::string extension); std::deque Archives; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 89bc65866b4..e2550eec25a 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -53,10 +53,12 @@ void ExtractDBCs() // Populate list of DBC files std::set DBCFiles; + const size_t extLen = strlen(".dbc"); for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) - if (itr->rfind(".dbc") == itr->length() - strlen(".dbc")) + if (itr->rfind(".dbc") == itr->length() - extLen) DBCFiles.insert(*itr); + const size_t folderLen = strlen("DBFilesClient\\"); // Iterate over all available locales for (std::set::iterator itr = MPQHandler->AvailableLocales.begin(); itr != MPQHandler->AvailableLocales.end(); ++itr) { @@ -73,7 +75,7 @@ void ExtractDBCs() Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); // Extract the DBC files for the given locale for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) - Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + strlen("DBFilesClient\\"))); + Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + folderLen)); } printf("DBC extraction finished!\n"); } @@ -201,16 +203,18 @@ void ExtractGameobjectModels() fwrite(&model.Header.CountGroups, sizeof(uint32), 1, output); fwrite(&model.Header.WmoId, sizeof(uint32), 1, output); + const char grp[] = { 'G' , 'R' , 'P', ' ' }; for (std::vector::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); + const WMOGroupHeader& header = itr2->Header; + fwrite(&header.Flags, sizeof(uint32), 1, output); + fwrite(&header.WmoId, sizeof(uint32), 1, output); + fwrite(&header.BoundingBox[0], sizeof(uint32), 1, output); + fwrite(&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); + fwrite(grp, sizeof(char), sizeof(grp), output); uint32 k = 0; uint32 mobaBatch = itr2->MOBALength / 12; uint32* MobaEx = new uint32[mobaBatch*4]; @@ -250,7 +254,7 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis return false; threads = atoi(param); - printf("Using %i threads\n", threads); + printf("Using %u threads\n", threads); } else if (strcmp(argv[i], "--maps") == 0) { diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index c52c4a04fc4..fa50b85caaf 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -113,9 +113,15 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); FILE* debug = fopen(buff, "wb"); 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); + { + const Vector3& vector = _Geometry->Vertices[i]; + fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z); + } 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); + { + const Triangle& triangle = _Geometry->Triangles[i]; + fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1); + } fclose(debug); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 33c30d7522c..49df7e20eba 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -72,17 +72,17 @@ uint32 Utils::Size( FILE* file ) return size; } -Vector3 Utils::ToRecast( Vector3 val ) +Vector3 Utils::ToRecast(const Vector3& val ) { return Vector3(-val.y, val.z, -val.x); } -std::string Utils::GetAdtPath( std::string world, int x, int y ) +std::string Utils::GetAdtPath(const std::string& world, int x, int y ) { return "World\\Maps\\" + world + "\\" + world + "_" + Utils::ToString(x) + "_" + Utils::ToString(y) + ".adt"; } -std::string Utils::FixModelPath( std::string path ) +std::string Utils::FixModelPath(const std::string& path ) { return Utils::GetPathBase(path) + ".M2"; } @@ -99,7 +99,7 @@ G3D::Matrix4 Utils::RotationX(float angle) return ret; } -G3D::Matrix4 Utils::GetTransformation(IDefinition def) +G3D::Matrix4 Utils::GetTransformation(const IDefinition& def) { G3D::Matrix4 translation; if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) @@ -143,7 +143,7 @@ float Utils::ToRadians( float degrees ) return Constants::PI * degrees / 180.0f; } -Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) +Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix ) { Vector3 ret; ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; @@ -152,7 +152,7 @@ Vector3 Utils::VectorTransform( Vector3 vec, G3D::Matrix4 matrix ) return ret; } -std::string Utils::GetPathBase( std::string path ) +std::string Utils::GetPathBase(const std::string& path ) { size_t lastIndex = path.find_last_of("."); if (lastIndex != std::string::npos) @@ -168,7 +168,7 @@ Vector3 Vector3::Read( FILE* file ) return ret; } -Vector3 Utils::GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int /*x*/, int /*y*/) +Vector3 Utils::GetLiquidVert(const G3D::Matrix4& transformation, Vector3 basePosition, float height, int /*x*/, int /*y*/) { if (Utils::Distance(height, 0.0f) > 0.5f) basePosition.z = 0.0f; @@ -191,7 +191,7 @@ std::string Utils::Replace( std::string str, const std::string& oldStr, const st return str; } -G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ) +G3D::Matrix4 Utils::GetWmoDoodadTransformation(const DoodadInstance& inst, const WorldModelDefinition& root ) { G3D::Matrix4 rootTransformation = Utils::GetTransformation(root); G3D::Matrix4 translation = G3D::Matrix4::translation(inst.Position.x, inst.Position.y, inst.Position.z); @@ -203,7 +203,7 @@ G3D::Matrix4 Utils::GetWmoDoodadTransformation( DoodadInstance inst, WorldModelD return scale * rotation * quatRotation ** translation * rootTransformation; } -void Utils::SaveToDisk( FILE* stream, std::string path ) +void Utils::SaveToDisk( FILE* stream, const std::string& path ) { FILE* disk = fopen(path.c_str(), "wb"); if (!disk) @@ -229,7 +229,7 @@ void Utils::SaveToDisk( FILE* stream, std::string path ) delete [] data; } -Vector3 Utils::ToWoWCoords( Vector3 vec ) +Vector3 Utils::ToWoWCoords(const Vector3& vec ) { return Vector3(vec.x, -vec.z, vec.y); } @@ -484,7 +484,8 @@ LiquidData LiquidData::Read(FILE* stream, LiquidHeader& header) H2ORenderMask H2ORenderMask::Read(FILE* stream) { H2ORenderMask ret; - if (int count = fread(&ret.Mask, sizeof(uint8), 8, stream) != 8) + int32 count; + if ((count = fread(&ret.Mask, sizeof(uint8), 8, stream)) != 8) printf("H2OHeader::Read: Failed to read some data expected 8, read %d\n", count); return ret; } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 64fb1bb35ba..e6bb6a59bda 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -342,10 +342,10 @@ public: static void Reverse(char word[]); static std::string ReadString(FILE* file); static uint32 Size(FILE* file); - static Vector3 ToRecast( Vector3 val ); - static std::string GetAdtPath(std::string world, int x, int y); - static std::string FixModelPath(std::string path); - static G3D::Matrix4 GetTransformation(IDefinition def); + static Vector3 ToRecast(const Vector3& val ); + static std::string GetAdtPath(const std::string& world, int x, int y); + static std::string FixModelPath(const std::string& path); + static G3D::Matrix4 GetTransformation(const IDefinition& def); /// They say its better to declare template functions in the header files. template static std::string ToString(T val) @@ -358,9 +358,9 @@ public: static G3D::Matrix4 RotationY(float angle); static G3D::Matrix4 RotationZ(float angle); static float ToRadians(float degrees); - static Vector3 VectorTransform(Vector3 vec, G3D::Matrix4 matrix); - static std::string GetPathBase(std::string path); - static Vector3 GetLiquidVert(G3D::Matrix4 transformation, Vector3 basePosition, float height, int x, int y); + static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix); + static std::string GetPathBase(const std::string& path); + static Vector3 GetLiquidVert(const G3D::Matrix4& transformation, Vector3 basePosition, float height, int x, int y); static float Distance(float x, float y); template static bool IsAllZero(T* arr, uint32 size) @@ -371,10 +371,10 @@ public: return true; } static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - static G3D::Matrix4 GetWmoDoodadTransformation( DoodadInstance inst, WorldModelDefinition root ); + static G3D::Matrix4 GetWmoDoodadTransformation(const DoodadInstance& inst, const WorldModelDefinition& root ); static void CreateDir( const std::string& Path ); - static void SaveToDisk(FILE* stream, std::string path); - static Vector3 ToWoWCoords( Vector3 vec ); + static void SaveToDisk(FILE* stream, const std::string& path); + static Vector3 ToWoWCoords(const Vector3& vec ); static std::string GetExtension( std::string path ); static char* GetPlainName(const char* FileName); }; diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index ecfff4e97d4..cc011b298eb 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -133,22 +133,26 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v if (!group->HasLiquidData) continue; - for (uint32 y = 0; y < group->LiquidDataHeader.Height; y++) + const LiquidHeader& liquidHeader = group->LiquidDataHeader; + LiquidData& liquidDataGeometry = group->LiquidDataGeometry; + + for (uint32 y = 0; y < liquidHeader.Height; y++) { - for (uint32 x = 0; x < group->LiquidDataHeader.Width; x++) + for (uint32 x = 0; x < liquidHeader.Width; x++) { - if (!group->LiquidDataGeometry.ShouldRender(x, y)) + + if (!liquidDataGeometry.ShouldRender(x, y)) continue; uint32 vertOffset = verts.size(); - verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, - group->LiquidDataGeometry.HeightMap[x][y], x, y)); - verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, - group->LiquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); - verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, - group->LiquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); - verts.push_back(Utils::GetLiquidVert(transformation, group->LiquidDataHeader.BaseLocation, - group->LiquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); + verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x][y], x, y)); + verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); + verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); + verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); -- cgit v1.2.3 From 7ca6f56a065a666fc605d2fa402a2eea14bc40c0 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 28 Sep 2013 23:52:55 +0200 Subject: Tools/MapExtractor: Fix string-related memory issues Fix not-NULL terminated char buffers and char[] to string conversion. Valgrind logs: Invalid read of size 1 at 0x4C2D7D4: __GI_strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x5318BAF: std::basic_string, std::allocator >::basic_string(char const*, std::allocator const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17) by 0x409471: ReadBuild(int) (System.cpp:189) by 0x40CEC6: main (System.cpp:1108) Address 0x5f851ee is 0 bytes after a block of size 94 alloc'd at 0x4C2C037: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x40F63A: MPQFile::MPQFile(char const*) (mpq_libmpq.cpp:65) by 0x409408: ReadBuild(int) (System.cpp:182) by 0x40CEC6: main (System.cpp:1108) Invalid read of size 1 at 0x57FFCAC: strtok (strtok.S:165) by 0x40D279: MPQArchive::GetFileListTo(std::vector >&) (mpq_libmpq04.h:45) by 0x40C5CF: ExtractDBCFiles(int, bool) (System.cpp:1001) by 0x40CEF5: main (System.cpp:1110) Address 0x5f91e27 is 0 bytes after a block of size 44,391 alloc'd at 0x4C2C037: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x40D1A5: MPQArchive::GetFileListTo(std::vector >&) (mpq_libmpq04.h:30) by 0x40C5CF: ExtractDBCFiles(int, bool) (System.cpp:1001) by 0x40CEF5: main (System.cpp:1110) --- src/tools/map_extractor/System.cpp | 2 +- src/tools/map_extractor/mpq_libmpq04.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 2173dab4e1c..a44c6f00acb 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -186,7 +186,7 @@ uint32 ReadBuild(int locale) exit(1); } - std::string text = m.getPointer(); + std::string text = std::string(m.getPointer(), m.getSize()); m.close(); size_t pos = text.find("version=\""); diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index 4691693d80d..a4eaf1d42db 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -27,7 +27,8 @@ public: libmpq__off_t size, transferred; libmpq__file_unpacked_size(mpq_a, filenum, &size); - char *buffer = new char[size]; + char *buffer = new char[size+1]; + buffer[size] = '\0'; libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); -- cgit v1.2.3 From a68c29e15c83bc7be1910083b26d152e2a6c80b3 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 29 Sep 2013 02:04:55 -0500 Subject: Tools/MeshExtractor: Fixed a lot of stuff, finally made the Doodads render, the WMO's have been disabled for now. ToDo: * Fix the doodads positions. * Review and re-implement some code. P.D: Help me please. --- src/tools/mesh_extractor/ADT.cpp | 6 ++-- src/tools/mesh_extractor/ADT.h | 5 ++- src/tools/mesh_extractor/ContinentBuilder.cpp | 4 +-- src/tools/mesh_extractor/DoodadHandler.cpp | 40 ++++++++++++++++++------ src/tools/mesh_extractor/DoodadHandler.h | 2 +- src/tools/mesh_extractor/Geometry.cpp | 4 +-- src/tools/mesh_extractor/MPQ.cpp | 8 ++++- src/tools/mesh_extractor/MPQManager.cpp | 7 ++++- src/tools/mesh_extractor/MapChunk.cpp | 2 ++ src/tools/mesh_extractor/MeshExtractor.cpp | 17 ++++++++-- src/tools/mesh_extractor/ObjectDataHandler.cpp | 16 ++-------- src/tools/mesh_extractor/ObjectDataHandler.h | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 6 ++-- src/tools/mesh_extractor/Utils.cpp | 29 +++++++++-------- src/tools/mesh_extractor/Utils.h | 13 +++++++- src/tools/mesh_extractor/WorldModelGroup.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.cpp | 43 +++++++++++++++++++------- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 18 files changed, 138 insertions(+), 70 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index c2ac19d5be0..7adf3625022 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -3,11 +3,11 @@ #include "LiquidHandler.h" #include "WorldModelHandler.h" -ADT::ADT( std::string file ) : ObjectData(NULL), Data(NULL), HasObjectData(false), - _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL) +ADT::ADT( std::string file, int x, int y ) : ObjectData(NULL), Data(NULL), HasObjectData(false), + _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), X(x), Y(y) { Data = new ChunkedData(file); - ObjectData = new ChunkedData(Utils::Replace(file, ".adt", "_obj0.adt")); + ObjectData = new ChunkedData(/*Utils::Replace(file, ".adt", "_obj0.adt")*/file); if (ObjectData->Stream) HasObjectData = true; else diff --git a/src/tools/mesh_extractor/ADT.h b/src/tools/mesh_extractor/ADT.h index 133596eb024..6f9973f7cde 100644 --- a/src/tools/mesh_extractor/ADT.h +++ b/src/tools/mesh_extractor/ADT.h @@ -10,7 +10,7 @@ class LiquidHandler; class ADT { public: - ADT(std::string file); + ADT(std::string file, int x, int y); ~ADT(); void Read(); @@ -25,5 +25,8 @@ public: DoodadHandler* _DoodadHandler; WorldModelHandler* _WorldModelHandler; LiquidHandler* _LiquidHandler; + + int X; + int Y; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index a6b4e3763a0..8e2c8da18e9 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -114,7 +114,7 @@ void ContinentBuilder::Build(bool debug) for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, debug, params)); printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + //for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; while (!next) @@ -123,7 +123,7 @@ void ContinentBuilder::Build(bool debug) { if ((*_th)->Free) { - (*_th)->SetData(itr->X, itr->Y, MapId, Continent); + (*_th)->SetData(40/*itr->X*/, 29/*itr->Y*/, MapId, Continent); (*_th)->activate(); next = true; break; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index ed683d70520..98515008636 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -6,8 +6,8 @@ DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { - if (!adt->HasObjectData) - return; + /*if (!adt->HasObjectData) + return;*/ Chunk* mddf = adt->ObjectData->GetChunkByName("MDDF"); if (mddf) ReadDoodadDefinitions(mddf); @@ -18,15 +18,14 @@ DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions( ReadDoodadPaths(mmid, mmdx); } -void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) +void DoodadHandler::ProcessInternal( MapChunk* mcnk ) { if (!IsSane()) return; - Chunk* doodadReferencesChunk = subChunks->GetChunkByName("MCRD"); - if (!doodadReferencesChunk) - return; - FILE* stream = doodadReferencesChunk->GetStream(); - uint32 refCount = doodadReferencesChunk->Length / 4; + + uint32 refCount = mcnk->Header.DoodadRefs; + FILE* stream = mcnk->Source->GetStream(); + fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); for (uint32 i = 0; i < refCount; i++) { int32 index; @@ -57,6 +56,8 @@ void DoodadHandler::ProcessInternal( ChunkedData* subChunks ) InsertModelGeometry(doodad, model); } + // Restore the stream position + fseek(stream, mcnk->Source->Offset, SEEK_SET); } void DoodadHandler::ReadDoodadDefinitions( Chunk* chunk ) @@ -91,13 +92,32 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } +Vector3 TransformDoodadVertex(const DoodadDefinition& def, Vector3& vec) +{ + float mapOffset = 17066.0f + (2 / 3.0f); + Vector3 MapPos = Vector3(mapOffset, 0, mapOffset); + G3D::Matrix4 rot = G3D::Matrix4::identity(); + rot = rot.pitchDegrees(def.Rotation.y - 90); + rot = rot.yawDegrees(-def.Rotation.x); + rot = rot.rollDegrees(def.Rotation.z - 90); + + Vector3 offset = def.Position - MapPos; + + // Because homoMul wants a G3D::Vector3 + G3D::Vector3 g3dvec(vec.x, vec.y, vec.z); + G3D::Vector3 g3dOffset(offset.x, offset.y, offset.z); + G3D::Vector3 ret = (rot.homoMul(g3dvec, 1) * def.Scale()) + g3dOffset; + Vector3 ret2 = (Utils::VectorTransform(vec, rot) * def.Scale()) + def.Position - MapPos; + return ret2; //Vector3(ret.x, ret.y, ret.z); +} + void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) { G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); - + for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) - Vertices.push_back(Utils::VectorTransform(*itr, transformation)); + Vertices.push_back(TransformDoodadVertex(def, *itr)/*Utils::VectorTransform(*itr, transformation)*/); for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 96aecbcce27..45b302a9c20 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -44,7 +44,7 @@ public: protected: - void ProcessInternal(ChunkedData* chunk); + void ProcessInternal(MapChunk* chunk); private: void ReadDoodadDefinitions(Chunk* chunk); diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 2fc470e8e9f..3ac52a9287d 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -117,7 +117,7 @@ void Geometry::AddAdt( ADT* adt ) if (!adt->_DoodadHandler->Triangles.empty()) AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); - if (!adt->_WorldModelHandler->Triangles.empty()) - AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); + /*if (!adt->_WorldModelHandler->Triangles.empty()) + AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles);*/ } diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index 18a9eb0f0e3..c930685c073 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -111,7 +111,13 @@ void MPQFile::close() FILE* MPQFile::GetFileStream() { - FILE* file = tmpfile(); + FILE* file = NULL; + tmpfile_s(&file); + if (!file) + { + printf("Could not create temporary file. Please run as Administrator or root\n"); + exit(1); + } fwrite(buffer, sizeof(char), size, file); fseek(file, 0, SEEK_SET); return file; diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index c95179f2680..3c63aed97d0 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -57,7 +57,7 @@ void MPQManager::InitializeDBC() Archives.push_front(_baseLocale); if (BaseLocale == -1) { - printf("No locale data detected\n"); + printf("No locale data detected. Please make sure that the executable is in the same folder as your WoW installation.\n"); ASSERT(false); } else @@ -103,6 +103,11 @@ FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) // Pack the return into a FILE stream FILE* ret = tmpfile(); + if (!ret) + { + printf("Could not create temporary file. Please run as Administrator or root\n"); + exit(1); + } fwrite(buffer, sizeof(uint8), size, ret); return ret; } diff --git a/src/tools/mesh_extractor/MapChunk.cpp b/src/tools/mesh_extractor/MapChunk.cpp index 8fe40773d43..789166d5c9b 100644 --- a/src/tools/mesh_extractor/MapChunk.cpp +++ b/src/tools/mesh_extractor/MapChunk.cpp @@ -66,6 +66,8 @@ void MapChunk::GenerateVertices( FILE* stream ) Vertices.push_back(vert); } } + // Restore stream position. + fseek(stream, Source->Offset, SEEK_SET); } bool MapChunk::HasHole( uint32 map, int x, int y ) diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index e2550eec25a..a6ab4aab98f 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -51,11 +51,13 @@ void ExtractDBCs() std::string baseDBCPath = "dbc/"; Utils::CreateDir(baseDBCPath); - // Populate list of DBC files std::set DBCFiles; const size_t extLen = strlen(".dbc"); + // Populate list of DBC files + // We get the DBC names by going over the (guaranteed to exist) default locale files + // Then we look in other locale files in case that they are available. for (std::vector::iterator itr = MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.begin(); itr != MPQHandler->LocaleFiles[MPQHandler->BaseLocale]->Files.end(); ++itr) - if (itr->rfind(".dbc") == itr->length() - extLen) + if (itr->rfind(".dbc") == itr->length() - extLen) // Check if the extension is ".dbc" DBCFiles.insert(*itr); const size_t folderLen = strlen("DBFilesClient\\"); @@ -228,7 +230,7 @@ void ExtractGameobjectModels() fwrite(MobaEx, 4, k, output); delete[] MobaEx; - // Note: still not finished + //@TODO: Finish this. } fclose(output); @@ -338,6 +340,8 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) int main(int argc, char* argv[]) { + system("pause"); + _setmaxstdio(2048); uint32 threads = 4, extractFlags = 0; std::set mapIds; bool debug = false; @@ -348,6 +352,13 @@ int main(int argc, char* argv[]) return -1; } + if (extractFlags == 0) + { + printf("You must provide a valid extractflag.\n"); + PrintUsage(); + return -1; + } + Cache = new CacheClass(); MPQHandler = new MPQManager(); MPQHandler->Initialize(); diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp index 789efc6d62c..87b24588299 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -5,17 +5,7 @@ void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) { - if (!Source->HasObjectData) - return; - // fuck it blizzard, why is this crap necessary? - int32 firstIndex = Source->ObjectData->GetFirstIndex("MCNK"); - if (firstIndex == -1) - return; - if (uint32(firstIndex + chunk->Index) > Source->ObjectData->Chunks.size()) - return; - Chunk* ourChunk = Source->ObjectData->Chunks[firstIndex + chunk->Index]; - if (ourChunk->Length == 0) - return; - ChunkedData* subChunks = new ChunkedData(ourChunk->GetStream(), ourChunk->Length, 2); - ProcessInternal(subChunks); + /*if (!Source->HasObjectData) + return;*/ + ProcessInternal(chunk); } diff --git a/src/tools/mesh_extractor/ObjectDataHandler.h b/src/tools/mesh_extractor/ObjectDataHandler.h index 75b4e45700c..9b347ef418a 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.h +++ b/src/tools/mesh_extractor/ObjectDataHandler.h @@ -9,7 +9,7 @@ public: ObjectDataHandler(ADT* _adt) : Source(_adt) {} void ProcessMapChunk(MapChunk* chunk); - virtual void ProcessInternal(ChunkedData* data) = 0; + virtual void ProcessInternal(MapChunk* data) = 0; ADT* Source; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index fa50b85caaf..04cf87e0b58 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -77,7 +77,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); _Geometry->Transform = true; - ADT* adt = new ADT(Utils::GetAdtPath(World, X, Y)); + ADT* adt = new ADT(Utils::GetAdtPath(World, X, Y), X, Y); adt->Read(); _Geometry->AddAdt(adt); delete adt; @@ -94,7 +94,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) if (tx == X && ty == Y) continue; - ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty)); + ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty), tx, ty); // If this condition is met, it means that this wdt does not contain the ADT if (!_adt->Data->Stream) { @@ -124,7 +124,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) } fclose(debug); } - + return NULL; uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 49df7e20eba..9b07aeebe96 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -49,13 +49,12 @@ void Utils::Reverse(char word[]) std::string Utils::ReadString( FILE* file ) { std::string ret; - int i = 0; while (true) { char b; if (fread(&b, sizeof(char), 1, file) != 1 || b == 0) break; - ret[i++] = b; + ret.push_back(b); } return ret; } @@ -92,10 +91,10 @@ G3D::Matrix4 Utils::RotationX(float angle) float _cos = cos(angle); float _sin = sin(angle); G3D::Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[2][1] = _sin; + ret[1][2] = -_sin; ret[2][2] = _cos; - ret[2][3] = _sin; - ret[3][2] = -_sin; - ret[3][3] = _cos; return ret; } @@ -119,10 +118,10 @@ G3D::Matrix4 Utils::RotationY( float angle ) float _cos = cos(angle); float _sin = sin(angle); G3D::Matrix4 ret = G3D::Matrix4::identity(); - ret[1][1] = _cos; - ret[1][3] = -_sin; - ret[3][1] = _sin; - ret[3][3] = _cos; + ret[0][0] = _cos; + ret[3][0] = -_sin; + ret[0][3] = _sin; + ret[2][2] = _cos; return ret; } @@ -131,10 +130,10 @@ G3D::Matrix4 Utils::RotationZ( float angle ) float _cos = cos(angle); float _sin = sin(angle); G3D::Matrix4 ret = G3D::Matrix4::identity(); + ret[0][0] = _cos; + ret[1][0] = _sin; + ret[0][1] = -_sin; ret[1][1] = _cos; - ret[1][2] = _sin; - ret[2][1] = -_sin; - ret[2][2] = _cos; return ret; } @@ -146,9 +145,9 @@ float Utils::ToRadians( float degrees ) Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix ) { Vector3 ret; - ret.x = vec.x * matrix[1][1] + vec.y * matrix[2][1] + vec.z * matrix[3][1] + matrix[4][1]; - ret.y = vec.x * matrix[1][2] + vec.y * matrix[2][2] + vec.z * matrix[3][2] + matrix[4][2]; - ret.z = vec.x * matrix[1][3] + vec.y * matrix[2][3] + vec.z * matrix[3][3] + matrix[4][3]; + ret.x = vec.x * matrix[0][0] + vec.y * matrix[1][0] + vec.z * matrix[2][0] + matrix[3][0]; + ret.y = vec.x * matrix[0][1] + vec.y * matrix[1][1] + vec.z * matrix[2][1] + matrix[3][1]; + ret.z = vec.x * matrix[0][2] + vec.y * matrix[1][2] + vec.z * matrix[2][2] + matrix[3][2]; return ret; } diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index e6bb6a59bda..b1f5bfb71be 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -25,11 +25,22 @@ struct Vector3 float y; float z; - Vector3 operator +(Vector3 const& other) + Vector3 operator +(Vector3 const& other) const { return Vector3(x + other.x, y + other.y, z + other.z); } + Vector3 operator -(Vector3 const& other) const + { + return Vector3(x - other.x, y - other.y, z - other.z); + } + + template + Vector3 operator *(T s) const + { + return Vector3(x * s, y * s, z * s); + } + static Vector3 Read(FILE* file); }; diff --git a/src/tools/mesh_extractor/WorldModelGroup.cpp b/src/tools/mesh_extractor/WorldModelGroup.cpp index 21e1c1e63e1..f76df73aaa6 100644 --- a/src/tools/mesh_extractor/WorldModelGroup.cpp +++ b/src/tools/mesh_extractor/WorldModelGroup.cpp @@ -3,7 +3,7 @@ #include "Chunk.h" #include "Utils.h" -WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false) +WorldModelGroup::WorldModelGroup( std::string path, int groupIndex ) : GroupIndex(groupIndex), MOBA(NULL), IsBad(false), HasLiquidData(false) { Data = new ChunkedData(path); if (!Data->Stream) diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index cc011b298eb..f069341e375 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -30,22 +30,22 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { - if (!adt->HasObjectData) - return; + /*if (!adt->HasObjectData) + return;*/ ReadModelPaths(); ReadDefinitions(); } -void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) +void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) { if (!IsSane()) return; - Chunk* wmoReferencesChunk = subChunks->GetChunkByName("MCRW"); - if (!wmoReferencesChunk) - return; - FILE* stream = wmoReferencesChunk->GetStream(); - uint32 refCount = wmoReferencesChunk->Length / 4; - for (uint32 i = 0; i < refCount; i++) + + uint32 refCount = mcnk->Header.MapObjectRefs; + FILE* stream = mcnk->Source->GetStream(); + fseek(stream, mcnk->Source->Offset + mcnk->Header.OffsetMCRF, SEEK_SET); + // Start looping at the last Doodad Ref index + for (uint32 i = mcnk->Header.DoodadRefs; i < refCount; i++) { int32 index; if (fread(&index, sizeof(int32), 1, stream) != 1) @@ -76,6 +76,27 @@ void WorldModelHandler::ProcessInternal( ChunkedData* subChunks ) InsertModelGeometry(Vertices, Triangles, wmo, model); } + // Restore the stream position + fseek(stream, mcnk->Source->Offset, SEEK_SET); +} + +Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec) +{ + float mapOffset = 17066.0f + (2 / 3.0f); + Vector3 MapPos = Vector3(mapOffset, 0, mapOffset); + G3D::Matrix4 rot = G3D::Matrix4::identity(); + rot = rot.pitchDegrees(def.Rotation.y - 90); + rot = rot.yawDegrees(-def.Rotation.x); + rot = rot.rollDegrees(def.Rotation.z - 90); + + Vector3 offset = def.Position - MapPos; + + // Because homoMul wants a G3D::Vector3 + G3D::Vector3 g3dvec(vec.x, vec.y, vec.z); + G3D::Vector3 g3dOffset(offset.x, offset.y, offset.z); + G3D::Vector3 ret = (rot.homoMul(g3dvec, 1) * def.Scale()) + g3dOffset; + Vector3 ret2 = (Utils::VectorTransform(vec, rot) + def.Position - MapPos) * def.Scale(); + return ret2; //Vector3(ret.x, ret.y, ret.z); } void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) @@ -85,7 +106,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v { uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) - verts.push_back(Utils::VectorTransform(*itr2, transformation)); + verts.push_back(TransformDoodadVertex(def, *itr2)/*Utils::VectorTransform(*itr2, transformation)*/); for (uint32 i = 0; i < group->Triangles.size(); ++i) { @@ -123,7 +144,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(*instance, def); int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) - verts.push_back(Utils::VectorTransform(*itr2, doodadTransformation)); + verts.push_back(TransformDoodadVertex(def, *itr2)/*Utils::VectorTransform(*itr2, doodadTransformation)*/); for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 29715ded696..d9da828da48 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -36,7 +36,7 @@ public: bool IsSane() { return _definitions && _paths; } void InsertModelGeometry(std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root); protected: - void ProcessInternal(ChunkedData* data); + void ProcessInternal(MapChunk* data); private: void ReadDefinitions(); void ReadModelPaths(); -- cgit v1.2.3 From a1fa7bf52513c388203590ab63c3c2297c971a32 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 29 Sep 2013 12:26:56 +0200 Subject: Tools/VMAP Extractor: Fix memory issues Fix not-NULL terminated char buffer and uninitialized memory written to vmaps due to WMOLiquidHeader struct padding bytes left uninitialized. The padding bytes should be ignored anyway by VMAP Assembler so no re-extraction is required. Valgrind log: Syscall param write(buf) points to uninitialised byte(s) at 0x585FB50: __write_nocancel (syscall-template.S:81) by 0x57EE2F2: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1270) by 0x57EE1D1: new_do_write (fileops.c:546) by 0x57EF904: _IO_do_write@@GLIBC_2.2.5 (fileops.c:519) by 0x57EEB70: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1341) by 0x57E3EC4: fwrite (iofwrite.c:43) by 0x41161B: WMOGroup::ConvertToVMAPGroupWmo(_IO_FILE*, WMORoot*, bool) (wmo.cpp:386) by 0x407FA9: ExtractSingleWmo(std::string&) (vmapexport.cpp:215) by 0x407B16: ExtractWmo() (vmapexport.cpp:138) by 0x409D50: main (vmapexport.cpp:497) Address 0x40398e2 is not stack'd, malloc'd or (recently) free'd Uninitialised value was created by a heap allocation at 0x4C2C7A7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x410ADA: WMOGroup::open() (wmo.cpp:224) by 0x407F54: ExtractSingleWmo(std::string&) (vmapexport.cpp:208) by 0x407B16: ExtractWmo() (vmapexport.cpp:138) by 0x409D50: main (vmapexport.cpp:497) --- src/tools/vmap4_extractor/mpq_libmpq04.h | 3 ++- src/tools/vmap4_extractor/wmo.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index 9f0163067c4..8986ca4e0c8 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -26,7 +26,8 @@ public: libmpq__off_t size, transferred; libmpq__file_unpacked_size(mpq_a, filenum, &size); - char *buffer = new char[size]; + char *buffer = new char[size + 1]; + buffer[size] = '\0'; libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index c606f06f6db..25a65f87e2c 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -221,7 +221,7 @@ bool WMOGroup::open() else if (!strcmp(fourcc,"MLIQ")) { liquflags |= 1; - hlq = new WMOLiquidHeader; + hlq = new WMOLiquidHeader(); f.read(hlq, 0x1E); LiquEx_size = sizeof(WMOLiquidVert) * hlq->xverts * hlq->yverts; LiquEx = new WMOLiquidVert[hlq->xverts * hlq->yverts]; -- cgit v1.2.3 From 279183737cef742867d6f93606ed89093642ecb7 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 29 Sep 2013 16:51:47 -0500 Subject: Tools/MeshExtractor: Fixed(??????) Doodads in the terrain. Semi-fixed WMOs in the terrain, they are wrongly rotated. P.D: HALP P.P.D: Entered "I don't know what i'm doing" mode. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/DoodadHandler.cpp | 24 ++++++---------- src/tools/mesh_extractor/DoodadHandler.h | 7 ++++- src/tools/mesh_extractor/Geometry.cpp | 4 +-- src/tools/mesh_extractor/Utils.cpp | 38 ++++++++++++++------------ src/tools/mesh_extractor/WorldModelHandler.cpp | 37 ++++++++++++++----------- 6 files changed, 59 insertions(+), 53 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 8e2c8da18e9..5065eaf74af 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -123,7 +123,7 @@ void ContinentBuilder::Build(bool debug) { if ((*_th)->Free) { - (*_th)->SetData(40/*itr->X*/, 29/*itr->Y*/, MapId, Continent); + (*_th)->SetData(29/*itr->X*/, 40/*itr->Y*/, MapId, Continent); (*_th)->activate(); next = true; break; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 98515008636..5e489681f51 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -94,21 +94,15 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) Vector3 TransformDoodadVertex(const DoodadDefinition& def, Vector3& vec) { - float mapOffset = 17066.0f + (2 / 3.0f); - Vector3 MapPos = Vector3(mapOffset, 0, mapOffset); - G3D::Matrix4 rot = G3D::Matrix4::identity(); - rot = rot.pitchDegrees(def.Rotation.y - 90); - rot = rot.yawDegrees(-def.Rotation.x); - rot = rot.rollDegrees(def.Rotation.z - 90); - - Vector3 offset = def.Position - MapPos; + // Rotate our Doodad vertex + G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXZY(Utils::ToRadians(-def.Rotation.z), Utils::ToRadians(def.Rotation.x), Utils::ToRadians(-def.Rotation.y + 180)); + Vector3 ret = Utils::VectorTransform(vec, rot); + + // Convert the rotated Doodad vector to our current coordinate system + ret = Vector3(ret.x, ret.z, -ret.y); - // Because homoMul wants a G3D::Vector3 - G3D::Vector3 g3dvec(vec.x, vec.y, vec.z); - G3D::Vector3 g3dOffset(offset.x, offset.y, offset.z); - G3D::Vector3 ret = (rot.homoMul(g3dvec, 1) * def.Scale()) + g3dOffset; - Vector3 ret2 = (Utils::VectorTransform(vec, rot) * def.Scale()) + def.Position - MapPos; - return ret2; //Vector3(ret.x, ret.y, ret.z); + // And finally translate it to our origin + return ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); } void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) @@ -117,7 +111,7 @@ void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* mode uint32 vertOffset = Vertices.size(); for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) - Vertices.push_back(TransformDoodadVertex(def, *itr)/*Utils::VectorTransform(*itr, transformation)*/); + Vertices.push_back(TransformDoodadVertex(def, *itr)); for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); diff --git a/src/tools/mesh_extractor/DoodadHandler.h b/src/tools/mesh_extractor/DoodadHandler.h index 45b302a9c20..51377f32d01 100644 --- a/src/tools/mesh_extractor/DoodadHandler.h +++ b/src/tools/mesh_extractor/DoodadHandler.h @@ -17,13 +17,18 @@ public: virtual float Scale() const { return DecimalScale / 1024.0f; } + Vector3 FixCoords(Vector3& vec) + { + return Vector3(vec.z, vec.x, vec.y); + } + void Read(FILE* stream) { int count = 0; count += fread(&MmidIndex, sizeof(uint32), 1, stream); count += fread(&UniqueId, sizeof(uint32), 1, stream); - Position = Vector3::Read(stream); + Position = (Vector3::Read(stream)); Rotation = Vector3::Read(stream); count += fread(&DecimalScale, sizeof(uint16), 1, stream); count += fread(&Flags, sizeof(uint16), 1, stream); diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 3ac52a9287d..2fc470e8e9f 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -117,7 +117,7 @@ void Geometry::AddAdt( ADT* adt ) if (!adt->_DoodadHandler->Triangles.empty()) AddData(adt->_DoodadHandler->Vertices, adt->_DoodadHandler->Triangles); - /*if (!adt->_WorldModelHandler->Triangles.empty()) - AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles);*/ + if (!adt->_WorldModelHandler->Triangles.empty()) + AddData(adt->_WorldModelHandler->Vertices, adt->_WorldModelHandler->Triangles); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 9b07aeebe96..e92da1a86b8 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -86,18 +86,6 @@ std::string Utils::FixModelPath(const std::string& path ) return Utils::GetPathBase(path) + ".M2"; } -G3D::Matrix4 Utils::RotationX(float angle) -{ - float _cos = cos(angle); - float _sin = sin(angle); - G3D::Matrix4 ret = G3D::Matrix4::identity(); - ret[1][1] = _cos; - ret[2][1] = _sin; - ret[1][2] = -_sin; - ret[2][2] = _cos; - return ret; -} - G3D::Matrix4 Utils::GetTransformation(const IDefinition& def) { G3D::Matrix4 translation; @@ -107,7 +95,8 @@ G3D::Matrix4 Utils::GetTransformation(const IDefinition& def) translation = G3D::Matrix4::translation(-(def.Position.z - Constants::MaxXY), -(def.Position.x - Constants::MaxXY), def.Position.y); - G3D::Matrix4 rotation = RotationX(ToRadians(def.Rotation.z)) * RotationY(ToRadians(def.Rotation.x)) * RotationZ(ToRadians(def.Rotation.y + 180)); + //G3D::Matrix4 rotation = RotationX(ToRadians(def.Rotation.z)) * RotationY(ToRadians(def.Rotation.x)) * RotationZ(ToRadians(def.Rotation.y + 180)); + G3D::Matrix4 rotation = G3D::Matrix4::identity().rollDegrees(def.Rotation.z).pitchDegrees(def.Rotation.x).yawDegrees(def.Rotation.y + 180); if (def.Scale() < 1.0f || def.Scale() > 1.0f) return G3D::Matrix4::scale(def.Scale()) * rotation * translation; return rotation * translation; @@ -137,6 +126,18 @@ G3D::Matrix4 Utils::RotationZ( float angle ) return ret; } +G3D::Matrix4 Utils::RotationX(float angle) +{ + float _cos = cos(angle); + float _sin = sin(angle); + G3D::Matrix4 ret = G3D::Matrix4::identity(); + ret[1][1] = _cos; + ret[2][1] = _sin; + ret[1][2] = -_sin; + ret[2][2] = _cos; + return ret; +} + float Utils::ToRadians( float degrees ) { return Constants::PI * degrees / 180.0f; @@ -144,11 +145,12 @@ float Utils::ToRadians( float degrees ) Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix ) { - Vector3 ret; - ret.x = vec.x * matrix[0][0] + vec.y * matrix[1][0] + vec.z * matrix[2][0] + matrix[3][0]; + G3D::Vector3 ret(vec.x, vec.y, vec.z); + ret = matrix.homoMul(ret, 1); + /*ret.x = vec.x * matrix[0][0] + vec.y * matrix[1][0] + vec.z * matrix[2][0] + matrix[3][0]; ret.y = vec.x * matrix[0][1] + vec.y * matrix[1][1] + vec.z * matrix[2][1] + matrix[3][1]; - ret.z = vec.x * matrix[0][2] + vec.y * matrix[1][2] + vec.z * matrix[2][2] + matrix[3][2]; - return ret; + ret.z = vec.x * matrix[0][2] + vec.y * matrix[1][2] + vec.z * matrix[2][2] + matrix[3][2];*/ + return Vector3(ret.x, ret.y, ret.z); } std::string Utils::GetPathBase(const std::string& path ) @@ -230,7 +232,7 @@ void Utils::SaveToDisk( FILE* stream, const std::string& path ) Vector3 Utils::ToWoWCoords(const Vector3& vec ) { - return Vector3(vec.x, -vec.z, vec.y); + return Vector3(-vec.z, vec.x, vec.y); } std::string Utils::GetExtension( std::string path ) diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index f069341e375..faaf87019bd 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -5,6 +5,7 @@ #include "Model.h" #include "Define.h" #include "G3D/Matrix4.h" +#include "G3D/Quat.h" #include WorldModelDefinition WorldModelDefinition::Read( FILE* file ) @@ -82,21 +83,25 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec) { - float mapOffset = 17066.0f + (2 / 3.0f); - Vector3 MapPos = Vector3(mapOffset, 0, mapOffset); - G3D::Matrix4 rot = G3D::Matrix4::identity(); - rot = rot.pitchDegrees(def.Rotation.y - 90); - rot = rot.yawDegrees(-def.Rotation.x); - rot = rot.rollDegrees(def.Rotation.z - 90); - - Vector3 offset = def.Position - MapPos; - - // Because homoMul wants a G3D::Vector3 - G3D::Vector3 g3dvec(vec.x, vec.y, vec.z); - G3D::Vector3 g3dOffset(offset.x, offset.y, offset.z); - G3D::Vector3 ret = (rot.homoMul(g3dvec, 1) * def.Scale()) + g3dOffset; - Vector3 ret2 = (Utils::VectorTransform(vec, rot) + def.Position - MapPos) * def.Scale(); - return ret2; //Vector3(ret.x, ret.y, ret.z); + // Rotate our Doodad vertex + G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXZY(Utils::ToRadians(-def.Rotation.z), Utils::ToRadians(def.Rotation.x), Utils::ToRadians(-def.Rotation.y + 180)); + Vector3 ret = Utils::VectorTransform(vec, rot); + + // Convert the rotated Doodad vector to our current coordinate system + ret = Vector3(ret.x, ret.z, -ret.y); + + // And finally translate it to our origin + return ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); +} + +Vector3 TransformDoodadToWMO(Vector3& vec, const DoodadInstance& inst, const WorldModelRoot& rootDef) +{ + Vector3 translation = Vector3(inst.Position.x, inst.Position.z, -inst.Position.y); + G3D::Quat quat = G3D::Quat(inst.QuatX, inst.QuatZ, -inst.QuatY, inst.QuatW); + G3D::Matrix3 rotM; + quat.toRotationMatrix(rotM); + + return (Utils::VectorTransform(vec, G3D::Matrix4(rotM)) + translation) * (1.0f / inst.Scale); } void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) @@ -144,7 +149,7 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(*instance, def); int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) - verts.push_back(TransformDoodadVertex(def, *itr2)/*Utils::VectorTransform(*itr2, doodadTransformation)*/); + verts.push_back(TransformDoodadToWMO(*itr2, *instance, *root)/*TransformDoodadVertex(instance, *itr2)*//*Utils::VectorTransform(*itr2, doodadTransformation)*/); for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } -- cgit v1.2.3 From 371dd07037afd6bd299822e0574fe5c85c305eab Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 29 Sep 2013 19:47:52 -0500 Subject: Tools/MeshExtractor: Fixed Doodads and WMOs in the terrain. Cleaned up a little. --- src/tools/mesh_extractor/ADT.cpp | 2 +- src/tools/mesh_extractor/Cache.h | 5 +- src/tools/mesh_extractor/ContinentBuilder.cpp | 4 +- src/tools/mesh_extractor/DoodadHandler.cpp | 21 +------ src/tools/mesh_extractor/MPQ.cpp | 3 +- src/tools/mesh_extractor/MeshExtractor.cpp | 3 +- src/tools/mesh_extractor/Model.cpp | 28 ++++----- src/tools/mesh_extractor/Model.h | 6 +- src/tools/mesh_extractor/ObjectDataHandler.cpp | 2 - src/tools/mesh_extractor/Utils.cpp | 86 +++++++------------------- src/tools/mesh_extractor/Utils.h | 12 ++-- src/tools/mesh_extractor/WorldModelHandler.cpp | 41 +++--------- src/tools/mesh_extractor/WorldModelRoot.cpp | 6 ++ src/tools/mesh_extractor/WorldModelRoot.h | 1 + 14 files changed, 69 insertions(+), 151 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ADT.cpp b/src/tools/mesh_extractor/ADT.cpp index 7adf3625022..79ece1213d4 100644 --- a/src/tools/mesh_extractor/ADT.cpp +++ b/src/tools/mesh_extractor/ADT.cpp @@ -7,7 +7,7 @@ ADT::ADT( std::string file, int x, int y ) : ObjectData(NULL), Data(NULL), HasOb _DoodadHandler(NULL), _WorldModelHandler(NULL), _LiquidHandler(NULL), X(x), Y(y) { Data = new ChunkedData(file); - ObjectData = new ChunkedData(/*Utils::Replace(file, ".adt", "_obj0.adt")*/file); + ObjectData = new ChunkedData(file); if (ObjectData->Stream) HasObjectData = true; else diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 60e3d8434cf..2be885fab9f 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -15,7 +15,7 @@ class GenericCache public: GenericCache() {} - static const uint32 FlushLimit = 1000; + static const uint32 FlushLimit = 300; // We can't get too close to filling up all the memory, and we have to be wary of the maximum number of open streams. void Insert(K key, T* val) { @@ -55,7 +55,8 @@ public: void Clear() { - + ModelCache.Clear(); + WorldModelCache.Clear(); } }; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 5065eaf74af..a6b4e3763a0 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -114,7 +114,7 @@ void ContinentBuilder::Build(bool debug) for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, debug, params)); printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); - //for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { bool next = false; while (!next) @@ -123,7 +123,7 @@ void ContinentBuilder::Build(bool debug) { if ((*_th)->Free) { - (*_th)->SetData(29/*itr->X*/, 40/*itr->Y*/, MapId, Continent); + (*_th)->SetData(itr->X, itr->Y, MapId, Continent); (*_th)->activate(); next = true; break; diff --git a/src/tools/mesh_extractor/DoodadHandler.cpp b/src/tools/mesh_extractor/DoodadHandler.cpp index 5e489681f51..72c051500e1 100644 --- a/src/tools/mesh_extractor/DoodadHandler.cpp +++ b/src/tools/mesh_extractor/DoodadHandler.cpp @@ -4,10 +4,9 @@ #include "Model.h" #include "G3D/Matrix4.h" -DoodadHandler::DoodadHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) +DoodadHandler::DoodadHandler( ADT* adt ) : + ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { - /*if (!adt->HasObjectData) - return;*/ Chunk* mddf = adt->ObjectData->GetChunkByName("MDDF"); if (mddf) ReadDoodadDefinitions(mddf); @@ -92,26 +91,12 @@ void DoodadHandler::ReadDoodadPaths( Chunk* id, Chunk* data ) } } -Vector3 TransformDoodadVertex(const DoodadDefinition& def, Vector3& vec) -{ - // Rotate our Doodad vertex - G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXZY(Utils::ToRadians(-def.Rotation.z), Utils::ToRadians(def.Rotation.x), Utils::ToRadians(-def.Rotation.y + 180)); - Vector3 ret = Utils::VectorTransform(vec, rot); - - // Convert the rotated Doodad vector to our current coordinate system - ret = Vector3(ret.x, ret.z, -ret.y); - - // And finally translate it to our origin - return ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); -} - void DoodadHandler::InsertModelGeometry(const DoodadDefinition& def, Model* model) { - G3D::Matrix4 transformation = Utils::GetTransformation(def); uint32 vertOffset = Vertices.size(); for (std::vector::iterator itr = model->Vertices.begin(); itr != model->Vertices.end(); ++itr) - Vertices.push_back(TransformDoodadVertex(def, *itr)); + Vertices.push_back(Utils::TransformDoodadVertex(def, *itr)); // Vertices have to be converted based on the information from the DoodadDefinition struct for (std::vector >::iterator itr = model->Triangles.begin(); itr != model->Triangles.end(); ++itr) Triangles.push_back(Triangle(Constants::TRIANGLE_TYPE_DOODAD, itr->V0 + vertOffset, itr->V1 + vertOffset, itr->V2 + vertOffset)); diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index c930685c073..4a106d0745c 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -111,8 +111,7 @@ void MPQFile::close() FILE* MPQFile::GetFileStream() { - FILE* file = NULL; - tmpfile_s(&file); + FILE* file = tmpfile(); if (!file) { printf("Could not create temporary file. Please run as Administrator or root\n"); diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index a6ab4aab98f..e23437e368d 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -10,6 +10,8 @@ #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" +#include + #include MPQManager* MPQHandler; @@ -340,7 +342,6 @@ void LoadTile(dtNavMesh*& navMesh, const char* tile) int main(int argc, char* argv[]) { - system("pause"); _setmaxstdio(2048); uint32 threads = 4, extractFlags = 0; std::set mapIds; diff --git a/src/tools/mesh_extractor/Model.cpp b/src/tools/mesh_extractor/Model.cpp index 77b1adbeaa0..5fb521d5a36 100644 --- a/src/tools/mesh_extractor/Model.cpp +++ b/src/tools/mesh_extractor/Model.cpp @@ -15,9 +15,9 @@ Model::Model( std::string path ) : IsCollidable(false), IsBad(false) Header.OffsetBoundingTriangles > 0 && Header.BoundingRadius > 0.0f) { IsCollidable = true; - ReadVertices(Stream); - ReadBoundingNormals(Stream); - ReadBoundingTriangles(Stream); + ReadVertices(); + ReadBoundingNormals(); + ReadBoundingTriangles(); } } @@ -27,41 +27,41 @@ Model::~Model() fclose(Stream); } -void Model::ReadVertices( FILE* stream ) +void Model::ReadVertices() { - fseek(stream, Header.OffsetBoundingVertices, SEEK_SET); + fseek(Stream, Header.OffsetBoundingVertices, SEEK_SET); Vertices.reserve(Header.CountBoundingVertices); for (uint32 i = 0; i < Header.CountBoundingVertices; ++i) { - Vertices.push_back(Vector3::Read(stream)); + Vertices.push_back(Vector3::Read(Stream)); if (Constants::ToWoWCoords) Vertices[i] = Utils::ToWoWCoords(Vertices[i]); } } -void Model::ReadBoundingTriangles( FILE* stream ) +void Model::ReadBoundingTriangles() { - fseek(stream, Header.OffsetBoundingTriangles, SEEK_SET); + fseek(Stream, Header.OffsetBoundingTriangles, SEEK_SET); Triangles.reserve(Header.CountBoundingTriangles / 3); for (uint32 i = 0; i < Header.CountBoundingTriangles / 3; i++) { Triangle tri; tri.Type = Constants::TRIANGLE_TYPE_DOODAD; int count = 0; - count += fread(&tri.V0, sizeof(uint16), 1, stream); - count += fread(&tri.V1, sizeof(uint16), 1, stream); - count += fread(&tri.V2, sizeof(uint16), 1, stream); + count += fread(&tri.V0, sizeof(uint16), 1, Stream); + count += fread(&tri.V1, sizeof(uint16), 1, Stream); + count += fread(&tri.V2, sizeof(uint16), 1, Stream); if (count != 3) printf("Model::ReadBoundingTriangles: Error reading data, expected 3, read %d\n", count); Triangles.push_back(tri); } } -void Model::ReadBoundingNormals( FILE* stream ) +void Model::ReadBoundingNormals() { - fseek(stream, Header.OffsetBoundingNormals, SEEK_SET); + fseek(Stream, Header.OffsetBoundingNormals, SEEK_SET); Normals.reserve(Header.CountBoundingNormals); for (uint32 i = 0; i < Header.CountBoundingNormals; i++) - Normals.push_back(Vector3::Read(stream)); + Normals.push_back(Vector3::Read(Stream)); } diff --git a/src/tools/mesh_extractor/Model.h b/src/tools/mesh_extractor/Model.h index ea9331e7c30..ed8627dad6f 100644 --- a/src/tools/mesh_extractor/Model.h +++ b/src/tools/mesh_extractor/Model.h @@ -9,9 +9,9 @@ public: Model(std::string path); ~Model(); - void ReadVertices(FILE* stream); - void ReadBoundingTriangles(FILE* stream); - void ReadBoundingNormals(FILE* stream); + void ReadVertices(); + void ReadBoundingTriangles(); + void ReadBoundingNormals(); ModelHeader Header; std::vector Vertices; std::vector Normals; diff --git a/src/tools/mesh_extractor/ObjectDataHandler.cpp b/src/tools/mesh_extractor/ObjectDataHandler.cpp index 87b24588299..f98d198eecd 100644 --- a/src/tools/mesh_extractor/ObjectDataHandler.cpp +++ b/src/tools/mesh_extractor/ObjectDataHandler.cpp @@ -5,7 +5,5 @@ void ObjectDataHandler::ProcessMapChunk( MapChunk* chunk ) { - /*if (!Source->HasObjectData) - return;*/ ProcessInternal(chunk); } diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index e92da1a86b8..f2881e9a770 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -86,56 +86,27 @@ std::string Utils::FixModelPath(const std::string& path ) return Utils::GetPathBase(path) + ".M2"; } -G3D::Matrix4 Utils::GetTransformation(const IDefinition& def) -{ - G3D::Matrix4 translation; - if (def.Position.x == 0.0f && def.Position.y == 0.0f && def.Position.z == 0.0f) - translation = G3D::Matrix4::identity(); - else - translation = G3D::Matrix4::translation(-(def.Position.z - Constants::MaxXY), - -(def.Position.x - Constants::MaxXY), def.Position.y); - - //G3D::Matrix4 rotation = RotationX(ToRadians(def.Rotation.z)) * RotationY(ToRadians(def.Rotation.x)) * RotationZ(ToRadians(def.Rotation.y + 180)); - G3D::Matrix4 rotation = G3D::Matrix4::identity().rollDegrees(def.Rotation.z).pitchDegrees(def.Rotation.x).yawDegrees(def.Rotation.y + 180); - if (def.Scale() < 1.0f || def.Scale() > 1.0f) - return G3D::Matrix4::scale(def.Scale()) * rotation * translation; - return rotation * translation; -} - -G3D::Matrix4 Utils::RotationY( float angle ) -{ - float _cos = cos(angle); - float _sin = sin(angle); - G3D::Matrix4 ret = G3D::Matrix4::identity(); - ret[0][0] = _cos; - ret[3][0] = -_sin; - ret[0][3] = _sin; - ret[2][2] = _cos; - return ret; -} - -G3D::Matrix4 Utils::RotationZ( float angle ) +Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec) { - float _cos = cos(angle); - float _sin = sin(angle); - G3D::Matrix4 ret = G3D::Matrix4::identity(); - ret[0][0] = _cos; - ret[1][0] = _sin; - ret[0][1] = -_sin; - ret[1][1] = _cos; - return ret; + // Sources of information: + /// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715 + + // This function applies to both external doodads and WMOs + + // Rotate our Doodad vertex + G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXYZ(Utils::ToRadians(def.Rotation.z), Utils::ToRadians(-def.Rotation.x), Utils::ToRadians(def.Rotation.y + 180)); + Vector3 ret = Utils::VectorTransform(vec, rot); + + // And finally scale and translate it to our origin + return (ret * def.Scale()) + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); } -G3D::Matrix4 Utils::RotationX(float angle) +Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec ) { - float _cos = cos(angle); - float _sin = sin(angle); - G3D::Matrix4 ret = G3D::Matrix4::identity(); - ret[1][1] = _cos; - ret[2][1] = _sin; - ret[1][2] = -_sin; - ret[2][2] = _cos; - return ret; + G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); + + Vector3 ret = Utils::VectorTransform(vec, G3D::Matrix4(quat.toRotationMatrix())); + return (ret * (inst.Scale / 1024.0f)) + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y); } float Utils::ToRadians( float degrees ) @@ -143,13 +114,10 @@ float Utils::ToRadians( float degrees ) return Constants::PI * degrees / 180.0f; } -Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix ) +Vector3 Utils::VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal ) { G3D::Vector3 ret(vec.x, vec.y, vec.z); - ret = matrix.homoMul(ret, 1); - /*ret.x = vec.x * matrix[0][0] + vec.y * matrix[1][0] + vec.z * matrix[2][0] + matrix[3][0]; - ret.y = vec.x * matrix[0][1] + vec.y * matrix[1][1] + vec.z * matrix[2][1] + matrix[3][1]; - ret.z = vec.x * matrix[0][2] + vec.y * matrix[1][2] + vec.z * matrix[2][2] + matrix[3][2];*/ + ret = matrix.homoMul(ret, normal ? 0 : 1); return Vector3(ret.x, ret.y, ret.z); } @@ -169,11 +137,11 @@ Vector3 Vector3::Read( FILE* file ) return ret; } -Vector3 Utils::GetLiquidVert(const G3D::Matrix4& transformation, Vector3 basePosition, float height, int /*x*/, int /*y*/) +Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/) { if (Utils::Distance(height, 0.0f) > 0.5f) basePosition.z = 0.0f; - return Utils::VectorTransform(basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height), transformation); + return Utils::TransformDoodadVertex(def, basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height)); } float Utils::Distance( float x, float y ) @@ -192,18 +160,6 @@ std::string Utils::Replace( std::string str, const std::string& oldStr, const st return str; } -G3D::Matrix4 Utils::GetWmoDoodadTransformation(const DoodadInstance& inst, const WorldModelDefinition& root ) -{ - G3D::Matrix4 rootTransformation = Utils::GetTransformation(root); - G3D::Matrix4 translation = G3D::Matrix4::translation(inst.Position.x, inst.Position.y, inst.Position.z); - G3D::Matrix4 scale = G3D::Matrix4::scale(inst.Scale); - G3D::Matrix4 rotation = Utils::RotationY(Constants::PI); - G3D::Quat quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); - G3D::Matrix4 quatRotation = quat.toRotationMatrix(); - - return scale * rotation * quatRotation ** translation * rootTransformation; -} - void Utils::SaveToDisk( FILE* stream, const std::string& path ) { FILE* disk = fopen(path.c_str(), "wb"); diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index b1f5bfb71be..a307dd4f695 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -13,6 +13,7 @@ #include struct WorldModelDefinition; +class DoodadDefinition; class DoodadInstance; #define ASSERT(assertion) { if (!(assertion)) { ACE_Stack_Trace st; fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__, __FUNCTION__, #assertion, st.c_str()); *((volatile int*)NULL) = 0; } } @@ -356,7 +357,6 @@ public: static Vector3 ToRecast(const Vector3& val ); static std::string GetAdtPath(const std::string& world, int x, int y); static std::string FixModelPath(const std::string& path); - static G3D::Matrix4 GetTransformation(const IDefinition& def); /// They say its better to declare template functions in the header files. template static std::string ToString(T val) @@ -365,13 +365,9 @@ public: ss << val; return ss.str(); } - static G3D::Matrix4 RotationX(float angle); - static G3D::Matrix4 RotationY(float angle); - static G3D::Matrix4 RotationZ(float angle); static float ToRadians(float degrees); - static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix); static std::string GetPathBase(const std::string& path); - static Vector3 GetLiquidVert(const G3D::Matrix4& transformation, Vector3 basePosition, float height, int x, int y); + static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/); static float Distance(float x, float y); template static bool IsAllZero(T* arr, uint32 size) @@ -382,11 +378,13 @@ public: return true; } static std::string Replace( std::string str, const std::string& oldStr, const std::string& newStr ); - static G3D::Matrix4 GetWmoDoodadTransformation(const DoodadInstance& inst, const WorldModelDefinition& root ); static void CreateDir( const std::string& Path ); static void SaveToDisk(FILE* stream, const std::string& path); static Vector3 ToWoWCoords(const Vector3& vec ); static std::string GetExtension( std::string path ); static char* GetPlainName(const char* FileName); + static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec); + static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false ); + static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec ); }; #endif diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index faaf87019bd..86ad8fc9984 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -31,8 +31,6 @@ WorldModelDefinition WorldModelDefinition::Read( FILE* file ) WorldModelHandler::WorldModelHandler( ADT* adt ) : ObjectDataHandler(adt), _definitions(NULL), _paths(NULL) { - /*if (!adt->HasObjectData) - return;*/ ReadModelPaths(); ReadDefinitions(); } @@ -81,41 +79,17 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) fseek(stream, mcnk->Source->Offset, SEEK_SET); } -Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec) -{ - // Rotate our Doodad vertex - G3D::Matrix4 rot = G3D::Matrix3::fromEulerAnglesXZY(Utils::ToRadians(-def.Rotation.z), Utils::ToRadians(def.Rotation.x), Utils::ToRadians(-def.Rotation.y + 180)); - Vector3 ret = Utils::VectorTransform(vec, rot); - - // Convert the rotated Doodad vector to our current coordinate system - ret = Vector3(ret.x, ret.z, -ret.y); - - // And finally translate it to our origin - return ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); -} - -Vector3 TransformDoodadToWMO(Vector3& vec, const DoodadInstance& inst, const WorldModelRoot& rootDef) -{ - Vector3 translation = Vector3(inst.Position.x, inst.Position.z, -inst.Position.y); - G3D::Quat quat = G3D::Quat(inst.QuatX, inst.QuatZ, -inst.QuatY, inst.QuatW); - G3D::Matrix3 rotM; - quat.toRotationMatrix(rotM); - - return (Utils::VectorTransform(vec, G3D::Matrix4(rotM)) + translation) * (1.0f / inst.Scale); -} - void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) { - G3D::Matrix4 transformation = Utils::GetTransformation(def); for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) { uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) - verts.push_back(TransformDoodadVertex(def, *itr2)/*Utils::VectorTransform(*itr2, transformation)*/); + verts.push_back(Utils::TransformDoodadVertex(def, *itr2)); // Transform the vertex to world space for (uint32 i = 0; i < group->Triangles.size(); ++i) { - // only include collidable tris + // only include colliding tris if ((group->TriangleFlags[i] & 0x04) != 0 && group->TriangleMaterials[i] != 0xFF) continue; Triangle tri = group->Triangles[i]; @@ -146,10 +120,9 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v if (!model->IsCollidable) continue; - G3D::Matrix4 doodadTransformation = Utils::GetWmoDoodadTransformation(*instance, def); int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) - verts.push_back(TransformDoodadToWMO(*itr2, *instance, *root)/*TransformDoodadVertex(instance, *itr2)*//*Utils::VectorTransform(*itr2, doodadTransformation)*/); + verts.push_back(Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2))); for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } @@ -171,13 +144,13 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v continue; uint32 vertOffset = verts.size(); - verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, liquidDataGeometry.HeightMap[x][y], x, y)); - verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, liquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); - verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, liquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); - verts.push_back(Utils::GetLiquidVert(transformation, liquidHeader.BaseLocation, + verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index c34a77e4531..20db07b9359 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -12,6 +12,12 @@ WorldModelRoot::WorldModelRoot( std::string path ) ReadDoodadSets(); } +WorldModelRoot::~WorldModelRoot() +{ + if (Data) + delete Data; +} + void WorldModelRoot::ReadGroups() { std::string pathBase = Utils::GetPathBase(Path); diff --git a/src/tools/mesh_extractor/WorldModelRoot.h b/src/tools/mesh_extractor/WorldModelRoot.h index c06ff3d5d2b..ad2e15b36d5 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.h +++ b/src/tools/mesh_extractor/WorldModelRoot.h @@ -11,6 +11,7 @@ class WorldModelRoot { public: WorldModelRoot(std::string path); + ~WorldModelRoot(); std::string Path; ChunkedData* Data; WorldModelHeader Header; -- cgit v1.2.3 From 02a543b0a073f23097bbe0dd490e7707b150c5a7 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 29 Sep 2013 20:06:44 -0500 Subject: Tools/MeshExtractor: Some more cleanup and memory management improvements. --- src/tools/mesh_extractor/Cache.h | 5 ++--- src/tools/mesh_extractor/Constants.h | 1 + src/tools/mesh_extractor/ContinentBuilder.cpp | 9 ++++----- src/tools/mesh_extractor/ContinentBuilder.h | 2 +- src/tools/mesh_extractor/MeshExtractor.cpp | 15 +++++++-------- src/tools/mesh_extractor/TileBuilder.cpp | 16 ++++------------ src/tools/mesh_extractor/TileBuilder.h | 2 +- src/tools/mesh_extractor/Utils.cpp | 1 + 8 files changed, 21 insertions(+), 30 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Cache.h b/src/tools/mesh_extractor/Cache.h index 2be885fab9f..9b3e046fe1e 100644 --- a/src/tools/mesh_extractor/Cache.h +++ b/src/tools/mesh_extractor/Cache.h @@ -5,9 +5,8 @@ #include "Define.h" #include #include - -class WorldModelRoot; -class Model; +#include "WorldModelRoot.h" +#include "Model.h" template class GenericCache diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 02e2d25559f..f2d9e8af8f5 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -47,6 +47,7 @@ public: static const float PI; static const float MaxStandableHeight; static bool ToWoWCoords; + static bool Debug; static const char* VMAPMagic; static const float BaseUnitDim; static const int VertexPerMap; diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index a6b4e3763a0..fd0202e36f9 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -12,11 +12,10 @@ class BuilderThread : public ACE_Task_Base private: int X, Y, MapId; std::string Continent; - bool debug; dtNavMeshParams Params; ContinentBuilder* cBuilder; public: - BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : debug(deb), Params(params), cBuilder(_cBuilder), Free(true) {} + BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} void SetData(int x, int y, int map, const std::string& cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() @@ -34,7 +33,7 @@ public: Free = true; return 0; } - uint8* nav = builder.Build(debug, Params); + uint8* nav = builder.Build(Params); if (nav) { f = fopen(buff, "wb"); @@ -89,7 +88,7 @@ void ContinentBuilder::CalculateTileBounds() getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); } -void ContinentBuilder::Build(bool debug) +void ContinentBuilder::Build() { char buff[50]; sprintf(buff, "mmaps/%03u.mmap", MapId); @@ -112,7 +111,7 @@ void ContinentBuilder::Build(bool debug) fclose(mmap); std::vector Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(this, debug, params)); + Threads.push_back(new BuilderThread(this, params)); printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h index b36ca125b9e..64d7be49aed 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -12,7 +12,7 @@ public: NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} - void Build(bool debug); + void Build(); void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); void CalculateTileBounds(); float bmin[3]; diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index e23437e368d..3d56bab5c23 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -17,7 +17,7 @@ MPQManager* MPQHandler; CacheClass* Cache; -void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) +void ExtractMMaps(std::set& mapIds, uint32 threads) { DBC* dbc = MPQHandler->GetDBC("Map"); printf("Map.dbc contains %u rows.\n", dbc->Records.size()); @@ -28,7 +28,7 @@ void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) // Skip this map if a list of specific maps was provided and this one is not contained in it. if (!mapIds.empty() && mapIds.find(mapId) == mapIds.end()) { - if (debug) + if (Constants::Debug) printf("Map %u will not be built.\n", mapId); continue; } @@ -42,14 +42,14 @@ void ExtractMMaps(std::set& mapIds, uint32 threads, bool debug) } printf("Building %s MapId %u\n", name.c_str(), mapId); ContinentBuilder builder(name, mapId, &wdt, threads); - builder.Build(debug); + builder.Build(); } } void ExtractDBCs() { printf("Extracting DBCs\n"); - // Create the filesystem structure + // Create the file system structure std::string baseDBCPath = "dbc/"; Utils::CreateDir(baseDBCPath); @@ -345,9 +345,8 @@ int main(int argc, char* argv[]) _setmaxstdio(2048); uint32 threads = 4, extractFlags = 0; std::set mapIds; - bool debug = false; - if (!HandleArgs(argc, argv, threads, mapIds, debug, extractFlags)) + if (!HandleArgs(argc, argv, threads, mapIds, Constants::Debug, extractFlags)) { PrintUsage(); return -1; @@ -355,7 +354,7 @@ int main(int argc, char* argv[]) if (extractFlags == 0) { - printf("You must provide a valid extractflag.\n"); + printf("You must provide valid extract flags.\n"); PrintUsage(); return -1; } @@ -368,7 +367,7 @@ int main(int argc, char* argv[]) ExtractDBCs(); if (extractFlags & Constants::EXTRACT_FLAG_MMAPS) - ExtractMMaps(mapIds, threads, debug); + ExtractMMaps(mapIds, threads); if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ExtractGameobjectModels(); diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 04cf87e0b58..5de41c9eb84 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -73,7 +73,7 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) +uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -95,7 +95,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) continue; ADT* _adt = new ADT(Utils::GetAdtPath(World, tx, ty), tx, ty); - // If this condition is met, it means that this wdt does not contain the ADT + // If this condition is met, it means that this WDT does not contain the ADT if (!_adt->Data->Stream) { delete _adt; @@ -107,7 +107,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) } } - if (dbg) + if (Constants::Debug) { char buff[100]; sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); @@ -124,7 +124,7 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) } fclose(debug); } - return NULL; + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -222,14 +222,6 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) printf("[%02i,%02i] Meshes merged!\n", X, Y); - // Remove padding from the polymesh data. (Remove this odditity) - for (int i = 0; i < pmesh->nverts; ++i) - { - unsigned short* v = &pmesh->verts[i * 3]; - v[0] -= (unsigned short)Config.borderSize; - v[2] -= (unsigned short)Config.borderSize; - } - // Set flags according to area types (e.g. Swim for Water) for (int i = 0; i < pmesh->npolys; i++) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 40c96f6ec42..e0ff02cc599 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -15,7 +15,7 @@ public: ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); - uint8* Build(bool dbg, dtNavMeshParams& navMeshParams); + uint8* Build(dtNavMeshParams& navMeshParams); std::string World; int X; diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index f2881e9a770..10e0bdc0d04 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -21,6 +21,7 @@ const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; const char* Constants::VMAPMagic = "VMAP041"; bool Constants::ToWoWCoords = false; +bool Constants::Debug = false; const float Constants::BaseUnitDim = 0.533333f; const int Constants::VertexPerMap = (Constants::TileSize / Constants::BaseUnitDim) + 0.5f; const int Constants::VertexPerTile = 40; -- cgit v1.2.3 From 9876108f3e75718ac34db9566fd12dc83f628160 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Sun, 29 Sep 2013 20:15:35 -0500 Subject: Tools/MeshExtractor: Removed some redundant code --- src/tools/mesh_extractor/MPQ.cpp | 3 +-- src/tools/mesh_extractor/WorldModelRoot.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQ.cpp b/src/tools/mesh_extractor/MPQ.cpp index 4a106d0745c..896d7bc32ac 100644 --- a/src/tools/mesh_extractor/MPQ.cpp +++ b/src/tools/mesh_extractor/MPQ.cpp @@ -103,8 +103,7 @@ void MPQFile::seekRelative(int offset) void MPQFile::close() { - if (buffer) - delete[] buffer; + delete[] buffer; buffer = 0; eof = true; } diff --git a/src/tools/mesh_extractor/WorldModelRoot.cpp b/src/tools/mesh_extractor/WorldModelRoot.cpp index 20db07b9359..a00506f3b16 100644 --- a/src/tools/mesh_extractor/WorldModelRoot.cpp +++ b/src/tools/mesh_extractor/WorldModelRoot.cpp @@ -14,8 +14,7 @@ WorldModelRoot::WorldModelRoot( std::string path ) WorldModelRoot::~WorldModelRoot() { - if (Data) - delete Data; + delete Data; } void WorldModelRoot::ReadGroups() -- cgit v1.2.3 From 15e7f7ab2141d2f4dcf313974bea06843b578591 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 01:05:07 -0500 Subject: Tools/MeshExtractor: Implemented mmap mesh generation for instances (They do not have ADT files, they're just a big WMO). Cleaned up some things and fixed some errors. ToDo: * Test this a bit more. * Cleanup the codebase for this, remove duplicated code. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 143 ++++++++++++++++------ src/tools/mesh_extractor/Geometry.cpp | 6 + src/tools/mesh_extractor/MeshExtractor.cpp | 6 +- src/tools/mesh_extractor/TileBuilder.cpp | 160 +++++++++++++++++++++++++ src/tools/mesh_extractor/TileBuilder.h | 4 +- src/tools/mesh_extractor/WDT.cpp | 3 +- src/tools/mesh_extractor/WDT.h | 2 + src/tools/mesh_extractor/WorldModelHandler.cpp | 2 +- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 9 files changed, 284 insertions(+), 44 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index fd0202e36f9..7708aa36617 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -11,46 +11,99 @@ class BuilderThread : public ACE_Task_Base { private: int X, Y, MapId; + bool Instance; std::string Continent; dtNavMeshParams Params; ContinentBuilder* cBuilder; + WorldModelRoot* Model; + const WorldModelDefinition* Definition; public: BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} - void SetData(int x, int y, int map, const std::string& cont) { X = x; Y = y; MapId = map; Continent = cont; } + void SetData(int x, int y, int map, const std::string& cont, bool instance, WorldModelRoot* model, const WorldModelDefinition* def) + { + X = x; + Y = y; + MapId = map; + Continent = cont; + Instance = instance; + if (Instance) + { + Model = model; + Definition = def; + } + else + Model = NULL; + } int svc() { - Free = false; - printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(cBuilder, Continent, X, Y, MapId); - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); - FILE* f = fopen(buff, "r"); - if (f) // Check if file already exists. + if (Instance) { - printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); - fclose(f); - Free = true; + // Build a WMO + printf("Building WMO %s ( %u )", Continent.c_str(), MapId); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); + char buff[100]; + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. + { + printf("Instance %s ( %u ) skipped, file already exists\n", Continent.c_str(), MapId); + fclose(f); + return 0; + } + + uint8* nav = builder.BuildInstance(Params, Model, *Definition); + if (nav) + { + f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return 0; + } + MmapTileHeader header; + header.size = builder.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(unsigned char), builder.DataSize, f); + fclose(f); + } + dtFree(nav); return 0; } - uint8* nav = builder.Build(Params); - if (nav) + else { - f = fopen(buff, "wb"); - if (!f) + Free = false; + printf("[%02i,%02i] Building tile\n", X, Y); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); + char buff[100]; + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); + fclose(f); + Free = true; return 0; } - MmapTileHeader header; - header.size = builder.DataSize; - fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder.DataSize, f); - fclose(f); + uint8* nav = builder.Build(Params); + if (nav) + { + f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return 0; + } + MmapTileHeader header; + header.size = builder.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(unsigned char), builder.DataSize, f); + fclose(f); + } + dtFree(nav); + printf("[%02i,%02i] Tile Built!\n", X, Y); + Free = true; } - dtFree(nav); - printf("[%02i,%02i] Tile Built!\n", X, Y); - Free = true; return 0; } @@ -110,28 +163,42 @@ void ContinentBuilder::Build() fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector Threads; - for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(this, params)); - printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); - for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) + + if (TileMap->IsGlobalModel) { - bool next = false; - while (!next) + printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId); + BuilderThread* thread = new BuilderThread(this, params); + Threads.push_back(thread); + thread->SetData(65, 65, MapId, Continent, true, TileMap->Model, &TileMap->ModelDefinition); + thread->activate(); + thread->wait(); + } + else + { + for (uint32 i = 0; i < NumberOfThreads; ++i) + Threads.push_back(new BuilderThread(this, params)); + printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); + for (std::vector::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { - for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) + bool next = false; + while (!next) { - if ((*_th)->Free) + for (std::vector::iterator _th = Threads.begin(); _th != Threads.end(); ++_th) { - (*_th)->SetData(itr->X, itr->Y, MapId, Continent); - (*_th)->activate(); - next = true; - break; + if ((*_th)->Free) + { + (*_th)->SetData(itr->X, itr->Y, MapId, Continent, false, NULL, NULL); + (*_th)->activate(); + next = true; + break; + } } + // Wait for 20 seconds + ACE_OS::sleep(ACE_Time_Value (0, 20000)); } - // Wait for 20 seconds - ACE_OS::sleep(ACE_Time_Value (0, 20000)); } } + Cache->Clear(); // Free memory diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 2fc470e8e9f..37f5c68bb6d 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -3,6 +3,7 @@ #include "ADT.h" #include "WorldModelHandler.h" #include "DoodadHandler.h" +#include Geometry::Geometry() : Transform(false) { @@ -14,6 +15,11 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) { min = new float[3]; max = new float[3]; + for (int i = 0; i < 3; ++i) + { + max[i] = std::numeric_limits::min(); + min[i] = std::numeric_limits::max(); + } for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) { diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 3d56bab5c23..4a312640395 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -35,7 +35,7 @@ void ExtractMMaps(std::set& mapIds, uint32 threads) std::string name = (*itr)->GetString(1); WDT wdt("World\\maps\\" + name + "\\" + name + ".wdt"); - if (!wdt.IsValid || wdt.IsGlobalModel) + if (!wdt.IsValid) { printf("Could not find WDT data for map %u (%s)\n", mapId, name.c_str()); continue; @@ -273,6 +273,8 @@ bool HandleArgs(int argc, char** argv, uint32& threads, std::set& mapLis mapList.insert(atoi(token)); token = strtok(NULL, ","); } + + free(copy); printf("Extracting only provided list of maps (%u).\n", uint32(mapList.size())); } @@ -391,7 +393,7 @@ int main(int argc, char* argv[]) // dtQueryFilter m_filter; - m_filter.setIncludeFlags(0xffff) ; + m_filter.setIncludeFlags(0xffff); m_filter.setExcludeFlags(0); // diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 5de41c9eb84..857cf7f16d8 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,6 +1,7 @@ #include "ContinentBuilder.h" #include "TileBuilder.h" #include "Geometry.h" +#include "WorldModelRoot.h" #include "Constants.h" #include "Utils.h" #include "Cache.h" @@ -60,6 +61,22 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, Config.detailSampleDist = Config.cs * 64; Config.detailSampleMaxError = Config.ch * 2; + memset(&InstanceConfig, 0, sizeof(rcConfig)); + InstanceConfig.cs = 0.2f; + InstanceConfig.ch = 0.3f; + InstanceConfig.minRegionArea = 25; + InstanceConfig.mergeRegionArea = 100; + InstanceConfig.walkableSlopeAngle = 50.0f; + InstanceConfig.detailSampleDist = 3.0f; + InstanceConfig.detailSampleMaxError = 1.5f; + InstanceConfig.walkableClimb = 1.0f / InstanceConfig.ch; + InstanceConfig.walkableHeight = 2.1f / InstanceConfig.ch; + InstanceConfig.walkableRadius = 0.6f / InstanceConfig.cs; + InstanceConfig.maxEdgeLen = 8 * InstanceConfig.walkableRadius; + InstanceConfig.maxVertsPerPoly = 6; + InstanceConfig.maxSimplificationError = 1.25f; + InstanceConfig.borderSize = 0; + Context = new rcContext; } @@ -73,6 +90,149 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } +uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def ) +{ + _Geometry = new Geometry(); + _Geometry->Transform = true; + + WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root); + + if (Constants::Debug) + { + char buff[100]; + sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); + FILE* debug = fopen(buff, "wb"); + for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) + { + const Vector3& vector = _Geometry->Vertices[i]; + fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z); + } + for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) + { + const Triangle& triangle = _Geometry->Triangles[i]; + fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1); + } + fclose(debug); + } + + float* bmin, *bmax; + _Geometry->CalculateBoundingBox(bmin, bmax); + rcVcopy(InstanceConfig.bmax, bmax); + rcVcopy(InstanceConfig.bmin, bmin); + + uint32 numVerts = _Geometry->Vertices.size(); + uint32 numTris = _Geometry->Triangles.size(); + float* vertices; + int* triangles; + uint8* areas; + _Geometry->GetRawData(vertices, triangles, areas); + _Geometry->Vertices.clear(); + _Geometry->Triangles.clear(); + + // this sets the dimensions of the heightfield - should maybe happen before border padding + rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height); + rcHeightfield* hf = rcAllocHeightfield(); + rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch); + + rcClearUnwalkableTriangles(Context, InstanceConfig.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, InstanceConfig.walkableClimb); + + rcFilterLowHangingWalkableObstacles(Context, InstanceConfig.walkableClimb, *hf); + rcFilterLedgeSpans(Context, InstanceConfig.walkableHeight, InstanceConfig.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, InstanceConfig.walkableHeight, *hf); + + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, InstanceConfig.walkableHeight, InstanceConfig.walkableClimb, *hf, *chf); + + rcErodeWalkableArea(Context, InstanceConfig.walkableRadius, *chf); + rcBuildDistanceField(Context, *chf); + rcBuildRegions(Context, *chf, InstanceConfig.borderSize, InstanceConfig.minRegionArea, InstanceConfig.minRegionArea); + + rcContourSet* contours = rcAllocContourSet(); + rcBuildContours(Context, *chf, InstanceConfig.maxSimplificationError, InstanceConfig.maxEdgeLen, *contours); + + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *contours, InstanceConfig.maxVertsPerPoly, *pmesh); + + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, InstanceConfig.detailSampleDist, InstanceConfig.detailSampleMaxError, *dmesh); + + // Set flags according to area types (e.g. Swim for Water) + for (int i = 0; i < pmesh->npolys; i++) + { + if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) + pmesh->flags[i] = Constants::POLY_FLAG_WALK; + else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) + pmesh->flags[i] = Constants::POLY_FLAG_SWIM; + } + + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + // PolyMesh data + params.verts = pmesh->verts; + params.vertCount = pmesh->nverts; + params.polys = pmesh->polys; + params.polyAreas = pmesh->areas; + params.polyFlags = pmesh->flags; + params.polyCount = pmesh->npolys; + params.nvp = pmesh->nvp; + // PolyMeshDetail data + params.detailMeshes = dmesh->meshes; + params.detailVerts = dmesh->verts; + params.detailVertsCount = dmesh->nverts; + params.detailTris = dmesh->tris; + params.detailTriCount = dmesh->ntris; + rcVcopy(params.bmin, pmesh->bmin); + rcVcopy(params.bmax, pmesh->bmax); + // General settings + params.ch = InstanceConfig.ch; + params.cs = InstanceConfig.cs; + params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch; + params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch; + params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs; + params.tileX = 0; + params.tileY = 0; + params.tileLayer = 0; + + rcVcopy(params.bmax, bmax); + rcVcopy(params.bmin, bmin); + + // Offmesh-connection settings + params.offMeshConCount = 0; // none for now + + //params.tileSize = Constants::VertexPerMap; + + if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) + { + // we have flat tiles with no actual geometry - don't build those, its useless + // keep in mind that we do output those into debug info + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("No polygons to build on tile, skipping.\n"); + delete areas; + delete triangles; + delete vertices; + return NULL; + } + + int navDataSize; + uint8* navData; + printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", pmesh->nverts, pmesh->npolys, dmesh->ntris); + bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); + + delete areas; + delete triangles; + delete vertices; + + if (result) + { + printf("NavMesh created, size %i!\n", navDataSize); + DataSize = navDataSize; + return navData; + } + + return NULL; +} + uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index e0ff02cc599..814f989486e 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -4,6 +4,7 @@ #include "Recast.h" #include "Geometry.h" +#include "WorldModelRoot.h" class ContinentBuilder; class WDT; @@ -16,12 +17,13 @@ public: void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); uint8* Build(dtNavMeshParams& navMeshParams); - + uint8* BuildInstance(dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def); std::string World; int X; int Y; int MapId; rcConfig Config; + rcConfig InstanceConfig; rcContext* Context; Geometry* _Geometry; uint32 DataSize; diff --git a/src/tools/mesh_extractor/WDT.cpp b/src/tools/mesh_extractor/WDT.cpp index 70d140e79ed..2a5a18c9848 100644 --- a/src/tools/mesh_extractor/WDT.cpp +++ b/src/tools/mesh_extractor/WDT.cpp @@ -4,7 +4,7 @@ #include "Utils.h" #include "WorldModelHandler.h" -WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false) +WDT::WDT(std::string file) : IsGlobalModel(false), IsValid(false), Model(NULL) { Data = new ChunkedData(file, 2); ReadTileTable(); @@ -21,6 +21,7 @@ void WDT::ReadGlobalModel() IsGlobalModel = true; ModelDefinition = WorldModelDefinition::Read(defChunk->GetStream()); ModelFile = Utils::ReadString(fileChunk->GetStream()); + Model = new WorldModelRoot(ModelFile); } void WDT::ReadTileTable() diff --git a/src/tools/mesh_extractor/WDT.h b/src/tools/mesh_extractor/WDT.h index a12aa65218b..ce8a97fff00 100644 --- a/src/tools/mesh_extractor/WDT.h +++ b/src/tools/mesh_extractor/WDT.h @@ -5,6 +5,7 @@ #include "ChunkedData.h" #include "WorldModelHandler.h" +#include "WorldModelRoot.h" #include "Utils.h" class WDT @@ -18,6 +19,7 @@ public: bool IsValid; std::string ModelFile; WorldModelDefinition ModelDefinition; + WorldModelRoot* Model; bool HasTile(int x, int y); private: void ReadGlobalModel(); diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 86ad8fc9984..24f63dc1e33 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -79,7 +79,7 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) fseek(stream, mcnk->Source->Offset, SEEK_SET); } -void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root ) +void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root ) { for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) { diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index d9da828da48..0611a02f764 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -34,7 +34,7 @@ public: std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } - void InsertModelGeometry(std::vector& verts, std::vector >& tris, WorldModelDefinition& def, WorldModelRoot* root); + static void InsertModelGeometry(std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root); protected: void ProcessInternal(MapChunk* data); private: -- cgit v1.2.3 From 271a57b80dc9dad02e7ddb68dde7745e8098b629 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 17:27:03 -0500 Subject: Tools/MeshExtractor: Fixed mmap extracting for instance maps and fixed a number of issues. ToDo: Cleanup the code a bit. WILL NOT CURRENTLY WORK WITH TrinityCore, if you want to test it, use the --extract 32 flag of MeshExtractor. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 59 ++++++++++++++++++------ src/tools/mesh_extractor/MeshExtractor.cpp | 62 +++++++++++++++++--------- src/tools/mesh_extractor/TileBuilder.cpp | 46 +++++++++++-------- src/tools/mesh_extractor/TileBuilder.h | 7 ++- src/tools/mesh_extractor/Utils.cpp | 20 ++++++--- src/tools/mesh_extractor/Utils.h | 6 +-- src/tools/mesh_extractor/WorldModelHandler.cpp | 35 ++++++++++----- src/tools/mesh_extractor/WorldModelHandler.h | 2 +- 8 files changed, 163 insertions(+), 74 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 7708aa36617..6449f8c1443 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -6,6 +6,7 @@ #include "Cache.h" #include "ace/Task.h" #include "Recast.h" +#include "DetourCommon.h" class BuilderThread : public ACE_Task_Base { @@ -52,7 +53,7 @@ public: return 0; } - uint8* nav = builder.BuildInstance(Params, Model, *Definition); + uint8* nav = builder.BuildInstance(Params); if (nav) { f = fopen(buff, "wb"); @@ -155,26 +156,58 @@ void ContinentBuilder::Build() CalculateTileBounds(); dtNavMeshParams params; - params.maxPolys = 1 << STATIC_POLY_BITS; - params.maxTiles = TileMap->TileTable.size(); - rcVcopy(params.orig, bmin); - params.tileHeight = Constants::TileSize; - params.tileWidth = Constants::TileSize; - fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); - fclose(mmap); + std::vector Threads; if (TileMap->IsGlobalModel) { printf("Map %s ( %u ) is a WMO. Building with 1 thread.\n", Continent.c_str(), MapId); - BuilderThread* thread = new BuilderThread(this, params); - Threads.push_back(thread); - thread->SetData(65, 65, MapId, Continent, true, TileMap->Model, &TileMap->ModelDefinition); - thread->activate(); - thread->wait(); + + TileBuilder* builder = new TileBuilder(this, Continent, 0, 0, MapId); + builder->AddGeometry(TileMap->Model, TileMap->ModelDefinition); + builder->SetCoords(0, 0); + uint8* nav = builder->BuildInstance(params); + if (nav) + { + // Set some params for the navmesh + dtMeshHeader* header = (dtMeshHeader*)nav; + dtVcopy(params.orig, header->bmin); + params.tileWidth = header->bmax[0] - header->bmin[0]; + params.tileHeight = header->bmax[2] - header->bmin[2]; + params.maxTiles = 1; + params.maxPolys = header->polyCount; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + + char buff[100]; + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, 0, 0); + FILE* f = fopen(buff, "wb"); + if (!f) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + + MmapTileHeader mheader; + mheader.size = builder->DataSize; + fwrite(&mheader, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(unsigned char), builder->DataSize, f); + fclose(f); + } + + dtFree(nav); + delete builder; } else { + params.maxPolys = 1 << STATIC_POLY_BITS; + params.maxTiles = TileMap->TileTable.size(); + rcVcopy(params.orig, bmin); + params.tileHeight = Constants::TileSize; + params.tileWidth = Constants::TileSize; + fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + for (uint32 i = 0; i < NumberOfThreads; ++i) Threads.push_back(new BuilderThread(this, params)); printf("Map %s ( %u ) has %u tiles. Building them with %u threads\n", Continent.c_str(), MapId, uint32(TileMap->TileTable.size()), NumberOfThreads); diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 4a312640395..7653faae2ab 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -328,6 +328,8 @@ void PrintUsage() void LoadTile(dtNavMesh*& navMesh, const char* tile) { FILE* f = fopen(tile, "rb"); + if (!f) + return; MmapTileHeader header; if (fread(&header, sizeof(MmapTileHeader), 1, f) != 1) @@ -376,37 +378,37 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_TEST) { - float start[] = { 0.0f, 0.0f, 0.0f }; - float end[] = { 0.0f, 0.0f, 0.0f }; + float start[] = { -230.133f, 191.085f, -24.9191f }; + float end[] = { -396.309f, 150.828f, 7.82184f }; // float m_spos[3]; - m_spos[0] = -1.0f * start[1]; + m_spos[0] = -start[1]; m_spos[1] = start[2]; - m_spos[2] = -1.0f * start[0]; + m_spos[2] = -start[0]; // float m_epos[3]; - m_epos[0] = -1.0f * end[1]; + m_epos[0] = -end[1]; m_epos[1] = end[2]; - m_epos[2] = -1.0f * end[0]; + m_epos[2] = -end[0]; // dtQueryFilter m_filter; - m_filter.setIncludeFlags(0xffff); - m_filter.setExcludeFlags(0); + m_filter.setIncludeFlags(Constants::POLY_AREA_ROAD | Constants::POLY_AREA_TERRAIN); + m_filter.setExcludeFlags(Constants::POLY_AREA_WATER); // float m_polyPickExt[3]; - m_polyPickExt[0] = 2; - m_polyPickExt[1] = 4; - m_polyPickExt[2] = 2; + m_polyPickExt[0] = 2.5f; + m_polyPickExt[1] = 2.5f; + m_polyPickExt[2] = 2.5f; // dtPolyRef m_startRef; dtPolyRef m_endRef; - FILE* mmap = fopen(".mmap", "rb"); + FILE* mmap = fopen("mmaps/389.mmap", "rb"); dtNavMeshParams params; int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); @@ -420,13 +422,16 @@ int main(int argc, char* argv[]) dtNavMeshQuery* navMeshQuery = new dtNavMeshQuery(); navMesh->init(¶ms); - LoadTile(navMesh, ".mmtile"); - LoadTile(navMesh, ".mmtile"); - LoadTile(navMesh, ".mmtile"); - LoadTile(navMesh, ".mmtile"); - LoadTile(navMesh, ".mmtile"); - LoadTile(navMesh, ".mmtile"); - + for (int i = 0; i <= 32; ++i) + { + for (int j = 0; j <= 32; ++j) + { + char buff[100]; + sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j); + LoadTile(navMesh, buff); + } + } + navMeshQuery->init(navMesh, 2048); float nearestPt[3]; @@ -440,7 +445,24 @@ int main(int argc, char* argv[]) return 0; } - printf("Found!"); + int hops; + dtPolyRef* hopBuffer = new dtPolyRef[8192]; + dtStatus status = navMeshQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, hopBuffer, &hops, 8192); + + int resultHopCount; + float* straightPath = new float[2048*3]; + unsigned char* pathFlags = new unsigned char[2048]; + dtPolyRef* pathRefs = new dtPolyRef[2048]; + + status = navMeshQuery->findStraightPath(m_spos, m_epos, hopBuffer, hops, straightPath, pathFlags, pathRefs, &resultHopCount, 2048); + std::vector FinalPath; + FinalPath.reserve(resultHopCount); + for (uint32 i = 0; i < resultHopCount; ++i) + { + Vector3 finalV = Utils::ToWoWCoords(Vector3(straightPath[i * 3 + 0], straightPath[i * 3 + 1], straightPath[i * 3 + 2])); + FinalPath.push_back(finalV); + printf("Point %f %f %f\n", finalV.x, finalV.y, finalV.z); + } } return 0; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 857cf7f16d8..aa09b21cd73 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -14,7 +14,7 @@ #include TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : - World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) + World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder), pmesh(NULL), dmesh(NULL) { /* Test, non-working values @@ -90,12 +90,12 @@ void TileBuilder::CalculateTileBounds( float*& bmin, float*& bmax, dtNavMeshPara bmax[2] = Constants::Origin[2] /*navMeshParams.orig[2]*/ + (Constants::TileSize * (Y + 1)); } -uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def ) +void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def) { _Geometry = new Geometry(); _Geometry->Transform = true; - WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root); + WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root, false); if (Constants::Debug) { @@ -114,26 +114,35 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo } fclose(debug); } +} + +void TileBuilder::SetCoords(int x, int y) +{ + X = x; + Y = y; +} - float* bmin, *bmax; +void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax) +{ _Geometry->CalculateBoundingBox(bmin, bmax); rcVcopy(InstanceConfig.bmax, bmax); rcVcopy(InstanceConfig.bmin, bmin); + if (pmesh && dmesh) + return; + uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; int* triangles; uint8* areas; _Geometry->GetRawData(vertices, triangles, areas); - _Geometry->Vertices.clear(); - _Geometry->Triangles.clear(); // this sets the dimensions of the heightfield - should maybe happen before border padding rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height); rcHeightfield* hf = rcAllocHeightfield(); rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch); - + rcClearUnwalkableTriangles(Context, InstanceConfig.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, InstanceConfig.walkableClimb); @@ -151,10 +160,10 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo rcContourSet* contours = rcAllocContourSet(); rcBuildContours(Context, *chf, InstanceConfig.maxSimplificationError, InstanceConfig.maxEdgeLen, *contours); - rcPolyMesh* pmesh = rcAllocPolyMesh(); + pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *contours, InstanceConfig.maxVertsPerPoly, *pmesh); - rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + dmesh = rcAllocPolyMeshDetail(); rcBuildPolyMeshDetail(Context, *pmesh, *chf, InstanceConfig.detailSampleDist, InstanceConfig.detailSampleMaxError, *dmesh); // Set flags according to area types (e.g. Swim for Water) @@ -165,6 +174,13 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } +} + +uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) +{ + float* bmin = NULL, *bmax = NULL; + + PrepareInstanceMesh(bmin, bmax); dtNavMeshCreateParams params; memset(¶ms, 0, sizeof(params)); @@ -190,9 +206,10 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch; params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch; params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs; - params.tileX = 0; - params.tileY = 0; + params.tileX = X; + params.tileY = Y; params.tileLayer = 0; + params.buildBvTree = true; rcVcopy(params.bmax, bmax); rcVcopy(params.bmin, bmin); @@ -208,9 +225,6 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo // keep in mind that we do output those into debug info // drop tiles with only exact count - some tiles may have geometry while having less tiles printf("No polygons to build on tile, skipping.\n"); - delete areas; - delete triangles; - delete vertices; return NULL; } @@ -219,10 +233,6 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams, WorldModelRoo printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", pmesh->nverts, pmesh->npolys, dmesh->ntris); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - delete areas; - delete triangles; - delete vertices; - if (result) { printf("NavMesh created, size %i!\n", navDataSize); diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 814f989486e..ca84387a6d9 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -17,7 +17,10 @@ public: void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); uint8* Build(dtNavMeshParams& navMeshParams); - uint8* BuildInstance(dtNavMeshParams& navMeshParams, WorldModelRoot* root, const WorldModelDefinition& def); + uint8* BuildInstance(dtNavMeshParams& navMeshParams); + void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def); + void SetCoords(int x, int y); + void PrepareInstanceMesh(float*& bmin, float*& bmax); std::string World; int X; int Y; @@ -28,5 +31,7 @@ public: Geometry* _Geometry; uint32 DataSize; ContinentBuilder* cBuilder; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; }; #endif \ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index 10e0bdc0d04..e7ffc0ed919 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -87,7 +87,7 @@ std::string Utils::FixModelPath(const std::string& path ) return Utils::GetPathBase(path) + ".M2"; } -Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec) +Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate) { // Sources of information: /// http://www.pxr.dk/wowdev/wiki/index.php?title=ADT/v18&oldid=3715 @@ -99,15 +99,21 @@ Vector3 Utils::TransformDoodadVertex(const IDefinition& def, Vector3& vec) Vector3 ret = Utils::VectorTransform(vec, rot); // And finally scale and translate it to our origin - return (ret * def.Scale()) + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); + ret = ret * def.Scale(); + if (translate) + ret = ret + Vector3(Constants::MaxXY - def.Position.z, Constants::MaxXY - def.Position.x, def.Position.y); + return ret; } -Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec ) +Vector3 Utils::TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate ) { G3D::Quat quat = G3D::Quat(-inst.QuatY, inst.QuatZ, -inst.QuatX, inst.QuatW); Vector3 ret = Utils::VectorTransform(vec, G3D::Matrix4(quat.toRotationMatrix())); - return (ret * (inst.Scale / 1024.0f)) + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y); + ret = ret * (inst.Scale / 1024.0f); + if (translate) + ret = ret + Vector3(Constants::MaxXY - inst.Position.z, Constants::MaxXY - inst.Position.x, inst.Position.y); + return ret; } float Utils::ToRadians( float degrees ) @@ -138,11 +144,11 @@ Vector3 Vector3::Read( FILE* file ) return ret; } -Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/) +Vector3 Utils::GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int x, int y, bool translate) { if (Utils::Distance(height, 0.0f) > 0.5f) basePosition.z = 0.0f; - return Utils::TransformDoodadVertex(def, basePosition + Vector3(basePosition.x * Constants::UnitSize, basePosition.y * Constants::UnitSize, height)); + return Utils::TransformDoodadVertex(def, basePosition + Vector3(x * Constants::UnitSize, y * Constants::UnitSize, height), translate); } float Utils::Distance( float x, float y ) @@ -189,7 +195,7 @@ void Utils::SaveToDisk( FILE* stream, const std::string& path ) Vector3 Utils::ToWoWCoords(const Vector3& vec ) { - return Vector3(-vec.z, vec.x, vec.y); + return Vector3(-vec.z, -vec.x, vec.y); } std::string Utils::GetExtension( std::string path ) diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index a307dd4f695..d6bb421a633 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -367,7 +367,7 @@ public: } static float ToRadians(float degrees); static std::string GetPathBase(const std::string& path); - static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/); + static Vector3 GetLiquidVert(const IDefinition& def, Vector3 basePosition, float height, int /*x*/, int /*y*/, bool translate = true); static float Distance(float x, float y); template static bool IsAllZero(T* arr, uint32 size) @@ -383,8 +383,8 @@ public: static Vector3 ToWoWCoords(const Vector3& vec ); static std::string GetExtension( std::string path ); static char* GetPlainName(const char* FileName); - static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec); + static Vector3 TransformDoodadVertex(const IDefinition& def, Vector3& vec, bool translate = true); static Vector3 VectorTransform(const Vector3& vec, const G3D::Matrix4& matrix, bool normal = false ); - static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec ); + static Vector3 TransformWmoDoodad(const DoodadInstance& inst, const WorldModelDefinition& root, Vector3& vec, bool translate = true ); }; #endif diff --git a/src/tools/mesh_extractor/WorldModelHandler.cpp b/src/tools/mesh_extractor/WorldModelHandler.cpp index 24f63dc1e33..3565a1d6af0 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.cpp +++ b/src/tools/mesh_extractor/WorldModelHandler.cpp @@ -79,13 +79,17 @@ void WorldModelHandler::ProcessInternal( MapChunk* mcnk ) fseek(stream, mcnk->Source->Offset, SEEK_SET); } -void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root ) +void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate ) { for (std::vector::iterator group = root->Groups.begin(); group != root->Groups.end(); ++group) { uint32 vertOffset = verts.size(); for (std::vector::iterator itr2 = group->Vertices.begin(); itr2 != group->Vertices.end(); ++itr2) - verts.push_back(Utils::TransformDoodadVertex(def, *itr2)); // Transform the vertex to world space + { + Vector3 v = Utils::TransformDoodadVertex(def, *itr2, translate); + // If translate is false, then we were called directly from the TileBuilder to add data to it's _Geometry member, hence, we have to manually convert the vertices to Recast format. + verts.push_back(translate ? v : Utils::ToRecast(v)); // Transform the vertex to world space + } for (uint32 i = 0; i < group->Triangles.size(); ++i) { @@ -122,7 +126,10 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v continue; int vertOffset = verts.size(); for (std::vector::iterator itr2 = model->Vertices.begin(); itr2 != model->Vertices.end(); ++itr2) - verts.push_back(Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2))); + { + Vector3 v = Utils::TransformDoodadVertex(def, Utils::TransformWmoDoodad(*instance, def, *itr2, false), translate); + verts.push_back(translate ? v : Utils::ToRecast(v)); + } for (std::vector >::iterator itr2 = model->Triangles.begin(); itr2 != model->Triangles.end(); ++itr2) tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WMO, itr2->V0 + vertOffset, itr2->V1 + vertOffset, itr2->V2 + vertOffset)); } @@ -144,14 +151,20 @@ void WorldModelHandler::InsertModelGeometry( std::vector& verts, std::v continue; uint32 vertOffset = verts.size(); - verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x][y], x, y)); - verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x + 1][y], x + 1, y)); - verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x][y + 1], x, y + 1)); - verts.push_back(Utils::GetLiquidVert(def, liquidHeader.BaseLocation, - liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1)); + + Vector3 v1 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x][y], x, y, translate); + Vector3 v2 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x + 1][y], x + 1, y, translate); + Vector3 v3 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x][y + 1], x, y + 1, translate); + Vector3 v4 = Utils::GetLiquidVert(def, liquidHeader.BaseLocation, + liquidDataGeometry.HeightMap[x + 1][y + 1], x + 1, y + 1, translate); + + verts.push_back(translate ? v1 : Utils::ToRecast(v1)); + verts.push_back(translate ? v2 : Utils::ToRecast(v2)); + verts.push_back(translate ? v3 : Utils::ToRecast(v3)); + verts.push_back(translate ? v4 : Utils::ToRecast(v4)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset, vertOffset + 2, vertOffset + 1)); tris.push_back(Triangle(Constants::TRIANGLE_TYPE_WATER, vertOffset + 2, vertOffset + 3, vertOffset + 1)); diff --git a/src/tools/mesh_extractor/WorldModelHandler.h b/src/tools/mesh_extractor/WorldModelHandler.h index 0611a02f764..87a5ad62938 100644 --- a/src/tools/mesh_extractor/WorldModelHandler.h +++ b/src/tools/mesh_extractor/WorldModelHandler.h @@ -34,7 +34,7 @@ public: std::vector Vertices; std::vector > Triangles; bool IsSane() { return _definitions && _paths; } - static void InsertModelGeometry(std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root); + static void InsertModelGeometry(std::vector& verts, std::vector >& tris, const WorldModelDefinition& def, WorldModelRoot* root, bool translate = true); protected: void ProcessInternal(MapChunk* data); private: -- cgit v1.2.3 From 520ff5a6e72f7c2d9d60311a114754861edc7de8 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 17:46:19 -0500 Subject: Tools/MeshExtractor: Some more cleanup. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 99 +++------- src/tools/mesh_extractor/TileBuilder.cpp | 251 ++++---------------------- src/tools/mesh_extractor/TileBuilder.h | 7 +- 3 files changed, 64 insertions(+), 293 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index 6449f8c1443..fedbac16596 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -12,99 +12,53 @@ class BuilderThread : public ACE_Task_Base { private: int X, Y, MapId; - bool Instance; std::string Continent; dtNavMeshParams Params; ContinentBuilder* cBuilder; - WorldModelRoot* Model; - const WorldModelDefinition* Definition; public: BuilderThread(ContinentBuilder* _cBuilder, dtNavMeshParams& params) : Params(params), cBuilder(_cBuilder), Free(true) {} - void SetData(int x, int y, int map, const std::string& cont, bool instance, WorldModelRoot* model, const WorldModelDefinition* def) + + void SetData(int x, int y, int map, const std::string& cont) { X = x; Y = y; MapId = map; Continent = cont; - Instance = instance; - if (Instance) - { - Model = model; - Definition = def; - } - else - Model = NULL; } int svc() { - if (Instance) + Free = false; + printf("[%02i,%02i] Building tile\n", X, Y); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); + char buff[100]; + sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); + FILE* f = fopen(buff, "r"); + if (f) // Check if file already exists. { - // Build a WMO - printf("Building WMO %s ( %u )", Continent.c_str(), MapId); - TileBuilder builder(cBuilder, Continent, X, Y, MapId); - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); - FILE* f = fopen(buff, "r"); - if (f) // Check if file already exists. - { - printf("Instance %s ( %u ) skipped, file already exists\n", Continent.c_str(), MapId); - fclose(f); - return 0; - } - - uint8* nav = builder.BuildInstance(Params); - if (nav) - { - f = fopen(buff, "wb"); - if (!f) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return 0; - } - MmapTileHeader header; - header.size = builder.DataSize; - fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder.DataSize, f); - fclose(f); - } - dtFree(nav); + printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); + fclose(f); + Free = true; return 0; } - else + uint8* nav = builder.Build(Params); + if (nav) { - Free = false; - printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(cBuilder, Continent, X, Y, MapId); - char buff[100]; - sprintf(buff, "mmaps/%03u%02i%02i.mmtile", MapId, Y, X); - FILE* f = fopen(buff, "r"); - if (f) // Check if file already exists. + f = fopen(buff, "wb"); + if (!f) { - printf("[%02i,%02i] Tile skipped, file already exists\n", X, Y); - fclose(f); - Free = true; + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); return 0; } - uint8* nav = builder.Build(Params); - if (nav) - { - f = fopen(buff, "wb"); - if (!f) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return 0; - } - MmapTileHeader header; - header.size = builder.DataSize; - fwrite(&header, sizeof(MmapTileHeader), 1, f); - fwrite(nav, sizeof(unsigned char), builder.DataSize, f); - fclose(f); - } - dtFree(nav); - printf("[%02i,%02i] Tile Built!\n", X, Y); - Free = true; + MmapTileHeader header; + header.size = builder.DataSize; + fwrite(&header, sizeof(MmapTileHeader), 1, f); + fwrite(nav, sizeof(unsigned char), builder.DataSize, f); + fclose(f); } + dtFree(nav); + printf("[%02i,%02i] Tile Built!\n", X, Y); + Free = true; return 0; } @@ -165,7 +119,6 @@ void ContinentBuilder::Build() TileBuilder* builder = new TileBuilder(this, Continent, 0, 0, MapId); builder->AddGeometry(TileMap->Model, TileMap->ModelDefinition); - builder->SetCoords(0, 0); uint8* nav = builder->BuildInstance(params); if (nav) { @@ -220,7 +173,7 @@ void ContinentBuilder::Build() { if ((*_th)->Free) { - (*_th)->SetData(itr->X, itr->Y, MapId, Continent, false, NULL, NULL); + (*_th)->SetData(itr->X, itr->Y, MapId, Continent); (*_th)->activate(); next = true; break; diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index aa09b21cd73..4251a6e5117 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -97,40 +97,18 @@ void TileBuilder::AddGeometry(WorldModelRoot* root, const WorldModelDefinition& WorldModelHandler::InsertModelGeometry(_Geometry->Vertices, _Geometry->Triangles, def, root, false); - if (Constants::Debug) - { - char buff[100]; - sprintf(buff, "mmaps/%s_%02u%02u.obj", World.c_str(), Y, X); - FILE* debug = fopen(buff, "wb"); - for (uint32 i = 0; i < _Geometry->Vertices.size(); ++i) - { - const Vector3& vector = _Geometry->Vertices[i]; - fprintf(debug, "v %f %f %f\n", vector.x, vector.y, vector.z); - } - for (uint32 i = 0; i < _Geometry->Triangles.size(); ++i) - { - const Triangle& triangle = _Geometry->Triangles[i]; - fprintf(debug, "f %u %u %u\n", triangle.V0 + 1, triangle.V1 + 1, triangle.V2 + 1); - } - fclose(debug); - } + OutputDebugVertices(); } -void TileBuilder::SetCoords(int x, int y) +uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) { - X = x; - Y = y; -} + float* bmin = NULL, *bmax = NULL; -void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax) -{ _Geometry->CalculateBoundingBox(bmin, bmax); + rcVcopy(InstanceConfig.bmax, bmax); rcVcopy(InstanceConfig.bmin, bmin); - if (pmesh && dmesh) - return; - uint32 numVerts = _Geometry->Vertices.size(); uint32 numTris = _Geometry->Triangles.size(); float* vertices; @@ -138,8 +116,9 @@ void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax) uint8* areas; _Geometry->GetRawData(vertices, triangles, areas); - // this sets the dimensions of the heightfield - should maybe happen before border padding + // this sets the dimensions of the heightfield rcCalcGridSize(InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, &InstanceConfig.width, &InstanceConfig.height); + rcHeightfield* hf = rcAllocHeightfield(); rcCreateHeightfield(Context, *hf, InstanceConfig.width, InstanceConfig.height, InstanceConfig.bmin, InstanceConfig.bmax, InstanceConfig.cs, InstanceConfig.ch); @@ -160,10 +139,10 @@ void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax) rcContourSet* contours = rcAllocContourSet(); rcBuildContours(Context, *chf, InstanceConfig.maxSimplificationError, InstanceConfig.maxEdgeLen, *contours); - pmesh = rcAllocPolyMesh(); + rcPolyMesh* pmesh = rcAllocPolyMesh(); rcBuildPolyMesh(Context, *contours, InstanceConfig.maxVertsPerPoly, *pmesh); - dmesh = rcAllocPolyMeshDetail(); + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcBuildPolyMeshDetail(Context, *pmesh, *chf, InstanceConfig.detailSampleDist, InstanceConfig.detailSampleMaxError, *dmesh); // Set flags according to area types (e.g. Swim for Water) @@ -174,13 +153,6 @@ void TileBuilder::PrepareInstanceMesh(float*& bmin, float*& bmax) else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } -} - -uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) -{ - float* bmin = NULL, *bmax = NULL; - - PrepareInstanceMesh(bmin, bmax); dtNavMeshCreateParams params; memset(¶ms, 0, sizeof(params)); @@ -217,7 +189,16 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) // Offmesh-connection settings params.offMeshConCount = 0; // none for now - //params.tileSize = Constants::VertexPerMap; + rcFreeHeightField(hf); + rcFreeCompactHeightfield(chf); + rcFreeContourSet(contours); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + delete vertices; + delete triangles; + delete areas; + delete bmin; + delete bmax; if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) { @@ -230,7 +211,7 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) int navDataSize; uint8* navData; - printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", pmesh->nverts, pmesh->npolys, dmesh->ntris); + printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", params.vertCount, params.polyCount, params.detailTriCount); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); if (result) @@ -243,7 +224,7 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) return NULL; } -uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams) +uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) { _Geometry = new Geometry(); _Geometry->Transform = true; @@ -277,6 +258,22 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams) } } + OutputDebugVertices(); + + uint32 numVerts = _Geometry->Vertices.size(); + uint32 numTris = _Geometry->Triangles.size(); + float* vertices; + int* triangles; + uint8* areas; + _Geometry->GetRawData(vertices, triangles, areas); + _Geometry->Vertices.clear(); + _Geometry->Triangles.clear(); + + return NULL; +} + +void TileBuilder::OutputDebugVertices() +{ if (Constants::Debug) { char buff[100]; @@ -294,182 +291,6 @@ uint8* TileBuilder::Build(dtNavMeshParams& navMeshParams) } fclose(debug); } - - uint32 numVerts = _Geometry->Vertices.size(); - uint32 numTris = _Geometry->Triangles.size(); - float* vertices; - int* triangles; - uint8* areas; - _Geometry->GetRawData(vertices, triangles, areas); - _Geometry->Vertices.clear(); - _Geometry->Triangles.clear(); - - - rcVcopy(Config.bmin, cBuilder->bmin); - rcVcopy(Config.bmax, cBuilder->bmax); - - // this sets the dimensions of the heightfield - should maybe happen before border padding - rcCalcGridSize(Config.bmin, Config.bmax, Config.cs, &Config.width, &Config.height); - - // Initialize per tile config. - rcConfig tileCfg = Config; - tileCfg.width = Config.tileSize + Config.borderSize * 2; - tileCfg.height = Config.tileSize + Config.borderSize * 2; - - // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[Constants::TilesPerMap * Constants::TilesPerMap]; - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[Constants::TilesPerMap * Constants::TilesPerMap]; - - int nmerge = 0; - for (int y = 0; y < Constants::TilesPerMap; ++y) - { - for (int x = 0; x < Constants::TilesPerMap; ++x) - { - // Calculate the per tile bounding box. - tileCfg.bmin[0] = Config.bmin[0] + float(x * Config.tileSize - Config.borderSize) * Config.cs; - tileCfg.bmin[2] = Config.bmin[2] + float(y * Config.tileSize - Config.borderSize) * Config.cs; - tileCfg.bmax[0] = Config.bmin[0] + float((x + 1) * Config.tileSize + Config.borderSize) * Config.cs; - tileCfg.bmax[2] = Config.bmin[2] + float((y + 1) * Config.tileSize + Config.borderSize) * Config.cs; - - - rcHeightfield* hf = rcAllocHeightfield(); - rcCreateHeightfield(Context, *hf, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch); - rcClearUnwalkableTriangles(Context, tileCfg.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - - // Once all geometry is rasterized, we do initial pass of filtering to - // remove unwanted overhangs caused by the conservative rasterization - // as well as filter spans where the character cannot possibly stand. - rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); - rcFilterLedgeSpans(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, tileCfg.walkableHeight, *hf); - - // Compact the heightfield so that it is faster to handle from now on. - // This will result in more cache coherent data as well as the neighbours - // between walkable cells will be calculated. - rcCompactHeightfield* chf = rcAllocCompactHeightfield(); - rcBuildCompactHeightfield(Context, tileCfg.walkableHeight, tileCfg.walkableClimb, *hf, *chf); - - rcFreeHeightField(hf); - - // Erode the walkable area by agent radius. - rcErodeWalkableArea(Context, Config.walkableRadius, *chf); - // Prepare for region partitioning, by calculating distance field along the walkable surface. - rcBuildDistanceField(Context, *chf); - // Partition the walkable surface into simple regions without holes. - rcBuildRegions(Context, *chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea); - - // Create contours. - rcContourSet* cset = rcAllocContourSet(); - rcBuildContours(Context, *chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *cset); - - // Build polygon navmesh from the contours. - rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *cset, tileCfg.maxVertsPerPoly, *pmesh); - - // Build detail mesh. - rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *dmesh); - - // Free memory - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - - pmmerge[nmerge] = pmesh; - dmmerge[nmerge] = dmesh; - ++nmerge; - } - } - - rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); - - rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); - - delete[] pmmerge; - delete[] dmmerge; - - printf("[%02i,%02i] Meshes merged!\n", X, Y); - - // Set flags according to area types (e.g. Swim for Water) - for (int i = 0; i < pmesh->npolys; i++) - { - if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) - pmesh->flags[i] = Constants::POLY_FLAG_WALK; - else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) - pmesh->flags[i] = Constants::POLY_FLAG_SWIM; - } - - dtNavMeshCreateParams params; - memset(¶ms, 0, sizeof(params)); - // PolyMesh data - params.verts = pmesh->verts; - params.vertCount = pmesh->nverts; - params.polys = pmesh->polys; - params.polyAreas = pmesh->areas; - params.polyFlags = pmesh->flags; - params.polyCount = pmesh->npolys; - params.nvp = pmesh->nvp; - // PolyMeshDetail data - params.detailMeshes = dmesh->meshes; - params.detailVerts = dmesh->verts; - params.detailVertsCount = dmesh->nverts; - params.detailTris = dmesh->tris; - params.detailTriCount = dmesh->ntris; - rcVcopy(params.bmin, pmesh->bmin); - rcVcopy(params.bmax, pmesh->bmax); - // General settings - params.ch = Config.ch; - params.cs = Config.cs; - params.walkableClimb = Constants::BaseUnitDim * Config.walkableClimb; - params.walkableHeight = Constants::BaseUnitDim * Config.walkableHeight; - params.walkableRadius = Constants::BaseUnitDim * Config.walkableRadius; - params.tileX = (((cBuilder->bmin[0] + cBuilder->bmax[0]) / 2) - navMeshParams.orig[0]) / Constants::TileSize; - params.tileY = (((cBuilder->bmin[2] + cBuilder->bmax[2]) / 2) - navMeshParams.orig[2]) / Constants::TileSize; - - rcVcopy(params.bmin, cBuilder->bmin); - rcVcopy(params.bmax, cBuilder->bmax); - - // Offmesh-connection settings - params.offMeshConCount = 0; // none for now - - //params.tileSize = Constants::VertexPerMap; - - if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) - { - // we have flat tiles with no actual geometry - don't build those, its useless - // keep in mind that we do output those into debug info - // drop tiles with only exact count - some tiles may have geometry while having less tiles - printf("[%02i,%02i] No polygons to build on tile, skipping.\n", X, Y); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - delete areas; - delete triangles; - delete vertices; - return NULL; - } - - int navDataSize; - uint8* navData; - printf("[%02i,%02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, pmesh->nverts, pmesh->npolys, dmesh->ntris); - bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); - - // Free some memory - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); - delete areas; - delete triangles; - delete vertices; - - if (result) - { - printf("[%02i,%02i] NavMesh created, size %i!\n", X, Y, navDataSize); - DataSize = navDataSize; - return navData; - } - - return NULL; } TileBuilder::~TileBuilder() diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index ca84387a6d9..165b3594ed6 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -16,11 +16,10 @@ public: ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); - uint8* Build(dtNavMeshParams& navMeshParams); + uint8* BuildTiled(dtNavMeshParams& navMeshParams); uint8* BuildInstance(dtNavMeshParams& navMeshParams); void AddGeometry(WorldModelRoot* root, const WorldModelDefinition& def); - void SetCoords(int x, int y); - void PrepareInstanceMesh(float*& bmin, float*& bmax); + void OutputDebugVertices(); std::string World; int X; int Y; @@ -31,7 +30,5 @@ public: Geometry* _Geometry; uint32 DataSize; ContinentBuilder* cBuilder; - rcPolyMesh* pmesh; - rcPolyMeshDetail* dmesh; }; #endif \ No newline at end of file -- cgit v1.2.3 From 1e23710b11c8c3c671279a0c5003f13f27f8802e Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 18:00:00 -0500 Subject: Tools/MeshExtractor: Forgot to push some changes. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index fedbac16596..be74357d1f0 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -41,7 +41,7 @@ public: Free = true; return 0; } - uint8* nav = builder.Build(Params); + uint8* nav = builder.BuildTiled(Params); if (nav) { f = fopen(buff, "wb"); diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 4251a6e5117..73987162cc8 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -14,7 +14,7 @@ #include TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : - World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder), pmesh(NULL), dmesh(NULL) + World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) { /* Test, non-working values -- cgit v1.2.3 From 3ed0a11679a97aba9c88fde38a431aa3878bb759 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 21:08:33 -0500 Subject: Tools/MeshExtractor: Do not delete the polygons before we are done using them. --- src/tools/mesh_extractor/MeshExtractor.cpp | 8 ++++---- src/tools/mesh_extractor/TileBuilder.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 7653faae2ab..3443b3d9e0a 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -378,8 +378,8 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_TEST) { - float start[] = { -230.133f, 191.085f, -24.9191f }; - float end[] = { -396.309f, 150.828f, 7.82184f }; + float start[] = { -44.641f, -34.606f, -1.045f }; + float end[] = { -66.18f, 20.222f, -1.128f }; // float m_spos[3]; @@ -408,7 +408,7 @@ int main(int argc, char* argv[]) dtPolyRef m_startRef; dtPolyRef m_endRef; - FILE* mmap = fopen("mmaps/389.mmap", "rb"); + FILE* mmap = fopen("mmaps/555.mmap", "rb"); dtNavMeshParams params; int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); @@ -427,7 +427,7 @@ int main(int argc, char* argv[]) for (int j = 0; j <= 32; ++j) { char buff[100]; - sprintf(buff, "mmaps/389%02i%02i.mmtile", i, j); + sprintf(buff, "mmaps/555%02i%02i.mmtile", i, j); LoadTile(navMesh, buff); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 73987162cc8..1871cb6186d 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -192,8 +192,6 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) rcFreeHeightField(hf); rcFreeCompactHeightfield(chf); rcFreeContourSet(contours); - rcFreePolyMesh(pmesh); - rcFreePolyMeshDetail(dmesh); delete vertices; delete triangles; delete areas; @@ -206,6 +204,8 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) // keep in mind that we do output those into debug info // drop tiles with only exact count - some tiles may have geometry while having less tiles printf("No polygons to build on tile, skipping.\n"); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); return NULL; } @@ -214,6 +214,9 @@ uint8* TileBuilder::BuildInstance( dtNavMeshParams& navMeshParams ) printf("Creating the navmesh with %i vertices, %i polys, %i triangles!\n", params.vertCount, params.polyCount, params.detailTriCount); bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + if (result) { printf("NavMesh created, size %i!\n", navDataSize); -- cgit v1.2.3 From c5c3b7ab2ac391a046396be5a14ee09d7c0a874c Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Mon, 30 Sep 2013 23:31:09 -0500 Subject: Tools/MeshExtractor: Implemented the code to generate mesh files for continent maps. Fixed a few more things ToDo: Test the generated navmesh. --- src/tools/mesh_extractor/Geometry.cpp | 4 +- src/tools/mesh_extractor/MPQManager.cpp | 2 +- src/tools/mesh_extractor/TileBuilder.cpp | 163 +++++++++++++++++++++++-------- 3 files changed, 125 insertions(+), 44 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 37f5c68bb6d..658c312a6e8 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -42,8 +42,8 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) void Geometry::CalculateMinMaxHeight( float& min, float& max ) { - min = 0.0f; - max = 0.0f; + min = std::numeric_limits::max(); + max = std::numeric_limits::min(); for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) { diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index 3c63aed97d0..e1ce4b92bf9 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -23,7 +23,7 @@ void MPQManager::Initialize() for (uint32 i = 0; i < size; ++i) { MPQArchive* arc = new MPQArchive(std::string("Data/" + std::string(Files[i])).c_str()); - Archives.push_front(arc); + Archives.push_front(arc); // MPQ files have to be transversed in reverse order to properly account for patched files printf("Opened %s\n", Files[i]); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 1871cb6186d..13566456329 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -16,51 +16,25 @@ TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder) { - /* - Test, non-working values - // Cell Size = TileSize / TileVoxelSize - // 1800 = TileVoxelSize - Config.cs = Constants::TileSize / 1800; - // Cell Height - Config.ch = 0.4f; - // Min Region Area = 20^2 - Config.minRegionArea = 20*20; - // Merge Region Area = 40^2 - Config.mergeRegionArea = 40*40; - Config.tileSize = Constants::TileSize / 4; + // Config for normal maps + memset(&Config, 0, sizeof(rcConfig)); + Config.cs = Constants::TileSize / 1800.0f; // TileSize / voxelSize + Config.ch = 0.3f; + Config.minRegionArea = 36; + Config.mergeRegionArea = 144; Config.walkableSlopeAngle = 50.0f; Config.detailSampleDist = 3.0f; Config.detailSampleMaxError = 1.25f; - Config.walkableClimb = floorf(1.0f / Config.ch); - Config.walkableHeight = ceilf(1.652778f / Config.ch); - Config.walkableRadius = ceilf(0.2951389f / Config.cs); + Config.walkableClimb = 1.0f / Config.ch; + Config.walkableHeight = 2.1 / Config.ch; + Config.walkableRadius = 0.6f / Config.cs; Config.maxEdgeLen = Config.walkableRadius * 8; - Config.borderSize = Config.walkableRadius + 4; - Config.width = 1800 + Config.borderSize * 2; - Config.height = 1800 + Config.borderSize * 2; - Config.maxVertsPerPoly = 6; + Config.borderSize = Config.walkableRadius + 8; + Config.tileSize = 1800; Config.maxSimplificationError = 1.3f; - */ - - // All are in UNIT metrics! - memset(&Config, 0, sizeof(rcConfig)); - - Config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; - Config.cs = Constants::BaseUnitDim; - Config.ch = Constants::BaseUnitDim; - Config.walkableSlopeAngle = 60.0f; - Config.tileSize = Constants::VertexPerTile; - Config.walkableRadius = 1; - Config.borderSize = Config.walkableRadius + 3; - Config.maxEdgeLen = Constants::VertexPerTile + 1; //anything bigger than tileSize - Config.walkableHeight = 3; - Config.walkableClimb = 2; // keep less than walkableHeight - Config.minRegionArea = rcSqr(60); - Config.mergeRegionArea = rcSqr(50); - Config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons) - Config.detailSampleDist = Config.cs * 64; - Config.detailSampleMaxError = Config.ch * 2; + Config.maxVertsPerPoly = 6; + // Config for instances memset(&InstanceConfig, 0, sizeof(rcConfig)); InstanceConfig.cs = 0.2f; InstanceConfig.ch = 0.3f; @@ -239,10 +213,14 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) if (_Geometry->Vertices.empty() && _Geometry->Triangles.empty()) return NULL; + float* bmin = NULL, *bmax = NULL; + CalculateTileBounds(bmin, bmax, navMeshParams); + _Geometry->CalculateMinMaxHeight(bmin[1], bmax[1]); + // again, we load everything - wasteful but who cares - for (int ty = Y - 2; ty <= Y + 2; ty++) + for (int ty = Y - 1; ty <= Y + 1; ty++) { - for (int tx = X - 2; tx <= X + 2; tx++) + for (int tx = X - 1; tx <= X + 1; tx++) { // don't load main tile again if (tx == X && ty == Y) @@ -272,6 +250,109 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); + // add border + bmin[0] -= Config.borderSize * Config.cs; + bmin[2] -= Config.borderSize * Config.cs; + bmax[0] += Config.borderSize * Config.cs; + bmax[2] += Config.borderSize * Config.cs; + + rcHeightfield* hf = rcAllocHeightfield(); + int width = Config.tileSize + (Config.borderSize * 2); + rcCreateHeightfield(Context, *hf, width, width, bmin, bmax, Config.cs, Config.ch); + + rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); + rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); + + rcFilterLowHangingWalkableObstacles(Context, Config.walkableClimb, *hf); + rcFilterLedgeSpans(Context, Config.walkableHeight, Config.walkableClimb, *hf); + rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); + + rcCompactHeightfield* chf = rcAllocCompactHeightfield(); + rcBuildCompactHeightfield(Context, Config.walkableHeight, Config.walkableClimb, *hf, *chf); + + rcErodeWalkableArea(Context, Config.walkableRadius, *chf); + rcBuildDistanceField(Context, *chf); + rcBuildRegions(Context, *chf, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + rcContourSet* contours = rcAllocContourSet(); + rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *contours); + + rcPolyMesh* pmesh = rcAllocPolyMesh(); + rcBuildPolyMesh(Context, *contours, Config.maxVertsPerPoly, *pmesh); + + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); + rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); + + dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); + // PolyMesh data + params.verts = pmesh->verts; + params.vertCount = pmesh->nverts; + params.polys = pmesh->polys; + params.polyAreas = pmesh->areas; + params.polyFlags = pmesh->flags; + params.polyCount = pmesh->npolys; + params.nvp = pmesh->nvp; + // PolyMeshDetail data + params.detailMeshes = dmesh->meshes; + params.detailVerts = dmesh->verts; + params.detailVertsCount = dmesh->nverts; + params.detailTris = dmesh->tris; + params.detailTriCount = dmesh->ntris; + rcVcopy(params.bmin, pmesh->bmin); + rcVcopy(params.bmax, pmesh->bmax); + // General settings + params.ch = InstanceConfig.ch; + params.cs = InstanceConfig.cs; + params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch; + params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch; + params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs; + params.tileX = X; + params.tileY = Y; + params.tileLayer = 0; + params.buildBvTree = true; + + rcVcopy(params.bmax, bmax); + rcVcopy(params.bmin, bmin); + + // Offmesh-connection settings + params.offMeshConCount = 0; // none for now + + rcFreeHeightField(hf); + rcFreeCompactHeightfield(chf); + rcFreeContourSet(contours); + delete vertices; + delete triangles; + delete areas; + delete bmin; + delete bmax; + + if (!params.polyCount || !params.polys || Constants::TilesPerMap * Constants::TilesPerMap == params.polyCount) + { + // we have flat tiles with no actual geometry - don't build those, its useless + // keep in mind that we do output those into debug info + // drop tiles with only exact count - some tiles may have geometry while having less tiles + printf("[%02i, %02i] No polygons to build on tile, skipping.\n", X, Y); + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + return NULL; + } + + int navDataSize; + uint8* navData; + printf("[%02i, %02i] Creating the navmesh with %i vertices, %i polys, %i triangles!\n", X, Y, params.vertCount, params.polyCount, params.detailTriCount); + bool result = dtCreateNavMeshData(¶ms, &navData, &navDataSize); + + rcFreePolyMesh(pmesh); + rcFreePolyMeshDetail(dmesh); + + if (result) + { + printf("[%02i, %02i] NavMesh created, size %i!\n", X, Y, navDataSize); + DataSize = navDataSize; + return navData; + } + return NULL; } -- cgit v1.2.3 From 1588e27f1e92b441bd68b67537851b8fea681fea Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Tue, 1 Oct 2013 14:13:11 -0500 Subject: Tools/MeshExtractor: Fixed the generated mesh for continents. Fixed a few more issues. --- src/tools/mesh_extractor/ContinentBuilder.cpp | 6 +++--- src/tools/mesh_extractor/Geometry.cpp | 4 ++-- src/tools/mesh_extractor/MeshExtractor.cpp | 8 +++---- src/tools/mesh_extractor/TileBuilder.cpp | 31 +++++++++++++++++++-------- 4 files changed, 31 insertions(+), 18 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index be74357d1f0..c90a6e527f7 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -153,9 +153,9 @@ void ContinentBuilder::Build() } else { - params.maxPolys = 1 << STATIC_POLY_BITS; - params.maxTiles = TileMap->TileTable.size(); - rcVcopy(params.orig, bmin); + params.maxPolys = 32768; + params.maxTiles = 4096; + rcVcopy(params.orig, Constants::Origin); params.tileHeight = Constants::TileSize; params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); diff --git a/src/tools/mesh_extractor/Geometry.cpp b/src/tools/mesh_extractor/Geometry.cpp index 658c312a6e8..df828dcd573 100644 --- a/src/tools/mesh_extractor/Geometry.cpp +++ b/src/tools/mesh_extractor/Geometry.cpp @@ -17,7 +17,7 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) max = new float[3]; for (int i = 0; i < 3; ++i) { - max[i] = std::numeric_limits::min(); + max[i] = std::numeric_limits::lowest(); min[i] = std::numeric_limits::max(); } @@ -43,7 +43,7 @@ void Geometry::CalculateBoundingBox( float*& min, float*& max ) void Geometry::CalculateMinMaxHeight( float& min, float& max ) { min = std::numeric_limits::max(); - max = std::numeric_limits::min(); + max = std::numeric_limits::lowest(); for (std::vector::iterator itr = Vertices.begin(); itr != Vertices.end(); ++itr) { diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index 3443b3d9e0a..fe4716da326 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -378,8 +378,8 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_TEST) { - float start[] = { -44.641f, -34.606f, -1.045f }; - float end[] = { -66.18f, 20.222f, -1.128f }; + float start[] = { 16226.200195f, 16257.000000f, 13.202200f }; + float end[] = { 16245.725586f, 16382.465820f, 47.384956f }; // float m_spos[3]; @@ -408,7 +408,7 @@ int main(int argc, char* argv[]) dtPolyRef m_startRef; dtPolyRef m_endRef; - FILE* mmap = fopen("mmaps/555.mmap", "rb"); + FILE* mmap = fopen("mmaps/001.mmap", "rb"); dtNavMeshParams params; int count = fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); @@ -427,7 +427,7 @@ int main(int argc, char* argv[]) for (int j = 0; j <= 32; ++j) { char buff[100]; - sprintf(buff, "mmaps/555%02i%02i.mmtile", i, j); + sprintf(buff, "mmaps/001%02i%02i.mmtile", i, j); LoadTile(navMesh, buff); } } diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 13566456329..51df91d2652 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -283,6 +283,15 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); + // Set flags according to area types (e.g. Swim for Water) + for (int i = 0; i < pmesh->npolys; i++) + { + if (pmesh->areas[i] == Constants::POLY_AREA_ROAD || pmesh->areas[i] == Constants::POLY_AREA_TERRAIN) + pmesh->flags[i] = Constants::POLY_FLAG_WALK; + else if (pmesh->areas[i] == Constants::POLY_AREA_WATER) + pmesh->flags[i] = Constants::POLY_FLAG_SWIM; + } + dtNavMeshCreateParams params; memset(¶ms, 0, sizeof(params)); // PolyMesh data @@ -299,21 +308,25 @@ uint8* TileBuilder::BuildTiled(dtNavMeshParams& navMeshParams) params.detailVertsCount = dmesh->nverts; params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; - rcVcopy(params.bmin, pmesh->bmin); - rcVcopy(params.bmax, pmesh->bmax); // General settings - params.ch = InstanceConfig.ch; - params.cs = InstanceConfig.cs; - params.walkableClimb = InstanceConfig.walkableClimb * InstanceConfig.ch; - params.walkableHeight = InstanceConfig.walkableHeight * InstanceConfig.ch; - params.walkableRadius = InstanceConfig.walkableRadius * InstanceConfig.cs; + params.ch = Config.ch; + params.cs = Config.cs; + params.walkableClimb = Config.walkableClimb * Config.ch; + params.walkableHeight = Config.walkableHeight * Config.ch; + params.walkableRadius = Config.walkableRadius * Config.cs; params.tileX = X; params.tileY = Y; params.tileLayer = 0; params.buildBvTree = true; - rcVcopy(params.bmax, bmax); - rcVcopy(params.bmin, bmin); + // Recalculate the bounds with the added geometry + float* bmin2 = NULL, *bmax2 = NULL; + CalculateTileBounds(bmin2, bmax2, navMeshParams); + bmin2[1] = bmin[1]; + bmax2[1] = bmax[1]; + + rcVcopy(params.bmax, bmax2); + rcVcopy(params.bmin, bmin2); // Offmesh-connection settings params.offMeshConCount = 0; // none for now -- cgit v1.2.3 From a8611de906816bfea66a948ac599fb0db69df7f8 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Tue, 1 Oct 2013 15:45:31 -0500 Subject: Tools/MeshExtractor: Fixed a few mistakes in MPQManager::GetFileFrom and Utils::SaveToDisk --- src/tools/mesh_extractor/MPQManager.cpp | 1 + src/tools/mesh_extractor/MeshExtractor.cpp | 2 +- src/tools/mesh_extractor/Utils.cpp | 22 ++++++++++++++++++---- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index e1ce4b92bf9..facd96a28f0 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -109,5 +109,6 @@ FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) exit(1); } fwrite(buffer, sizeof(uint8), size, ret); + fseek(ret, 0, SEEK_SET); return ret; } diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index fe4716da326..0d9160a610b 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -76,7 +76,7 @@ void ExtractDBCs() std::string component = "component.wow-" + std::string(MPQManager::Languages[*itr]) + ".txt"; // Extract the component file - Utils::SaveToDisk(MPQHandler->GetFile(component), path + component); + Utils::SaveToDisk(MPQHandler->GetFileFrom(component, MPQHandler->LocaleFiles[*itr]), path + component); // Extract the DBC files for the given locale for (std::set::iterator itr2 = DBCFiles.begin(); itr2 != DBCFiles.end(); ++itr2) Utils::SaveToDisk(MPQHandler->GetFileFrom(*itr2, MPQHandler->LocaleFiles[*itr]), path + (itr2->c_str() + folderLen)); diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index e7ffc0ed919..24cfb5cd1db 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -173,24 +173,38 @@ void Utils::SaveToDisk( FILE* stream, const std::string& path ) if (!disk) { printf("SaveToDisk: Could not save file %s to disk, please verify that you have write permissions on that directory\n", path.c_str()); + fclose(stream); return; } uint32 size = Utils::Size(stream); uint8* data = new uint8[size]; // Read the data to an array - if (fread(data, 1, size, stream) != 1) + size_t read = fread(data, size, 1, stream); + if (read != 1) { - printf("SaveToDisk: Error reading from Stream while trying to save file %s to disck.\n", path.c_str()); + printf("SaveToDisk: Error reading from Stream while trying to save file %s to disk.\n", path.c_str()); + fclose(disk); + fclose(stream); return; } + // And write it in the file - fwrite(data, 1, size, disk); + size_t wrote = fwrite(data, size, 1, disk); + if (wrote != 1) + { + printf("SaveToDisk: Error writing to the file while trying to save %s to disk.\n", path.c_str()); + fclose(stream); + fclose(disk); + return; + } // Close the filestream fclose(disk); + fclose(stream); + // Free the used memory - delete [] data; + delete[] data; } Vector3 Utils::ToWoWCoords(const Vector3& vec ) -- cgit v1.2.3 From 8fb1f7cc97bdb92999309597c5e7259099bf5ce4 Mon Sep 17 00:00:00 2001 From: Sebastian Valle Date: Tue, 1 Oct 2013 16:27:57 -0500 Subject: Tools/MeshExtractor: Implemented 7ca6f56a065a666fc605d2fa402a2eea14bc40c0 in MeshExtractor and fixed a memory leak. --- src/tools/mesh_extractor/MPQ.h | 3 ++- src/tools/mesh_extractor/MPQManager.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/tools') diff --git a/src/tools/mesh_extractor/MPQ.h b/src/tools/mesh_extractor/MPQ.h index 2f8b082f526..30e11741550 100644 --- a/src/tools/mesh_extractor/MPQ.h +++ b/src/tools/mesh_extractor/MPQ.h @@ -26,7 +26,8 @@ public: libmpq__off_t size, transferred; libmpq__file_unpacked_size(mpq_a, filenum, &size); - char *buffer = new char[size]; + char* buffer = new char[size + 1]; + buffer[size] = '\0'; libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred); diff --git a/src/tools/mesh_extractor/MPQManager.cpp b/src/tools/mesh_extractor/MPQManager.cpp index facd96a28f0..4d3ab808a2e 100644 --- a/src/tools/mesh_extractor/MPQManager.cpp +++ b/src/tools/mesh_extractor/MPQManager.cpp @@ -110,5 +110,6 @@ FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file ) } fwrite(buffer, sizeof(uint8), size, ret); fseek(ret, 0, SEEK_SET); + delete[] buffer; return ret; } -- cgit v1.2.3