diff options
-rw-r--r-- | src/tools/mesh_extractor/Constants.h | 17 | ||||
-rw-r--r-- | src/tools/mesh_extractor/ContinentBuilder.cpp | 44 | ||||
-rw-r--r-- | src/tools/mesh_extractor/ContinentBuilder.h | 10 | ||||
-rw-r--r-- | src/tools/mesh_extractor/MeshExtractor.cpp | 82 | ||||
-rw-r--r-- | src/tools/mesh_extractor/TileBuilder.cpp | 231 | ||||
-rw-r--r-- | src/tools/mesh_extractor/TileBuilder.h | 4 | ||||
-rw-r--r-- | src/tools/mesh_extractor/Utils.cpp | 4 |
7 files changed, 265 insertions, 127 deletions
diff --git a/src/tools/mesh_extractor/Constants.h b/src/tools/mesh_extractor/Constants.h index 89cd6da20a2..54fa073fbef 100644 --- a/src/tools/mesh_extractor/Constants.h +++ b/src/tools/mesh_extractor/Constants.h @@ -32,12 +32,13 @@ public: enum ExtractFlags { - EXTRACT_FLAG_DBC = 1, - EXTRACT_FLAG_MAPS = 2, - EXTRACT_FLAG_VMAPS = 4, - EXTRACT_FLAG_GOB_MODELS = 8, - EXTRACT_FLAG_MMAPS = 16, - EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS + EXTRACT_FLAG_DBC = 0x01, + EXTRACT_FLAG_MAPS = 0x02, + EXTRACT_FLAG_VMAPS = 0x04, + EXTRACT_FLAG_GOB_MODELS = 0x08, + EXTRACT_FLAG_MMAPS = 0x10, + EXTRACT_FLAG_TEST = 0x20, + EXTRACT_FLAG_ALLOWED = EXTRACT_FLAG_DBC | EXTRACT_FLAG_MAPS | EXTRACT_FLAG_VMAPS | EXTRACT_FLAG_GOB_MODELS | EXTRACT_FLAG_MMAPS | EXTRACT_FLAG_TEST }; static const float TileSize; @@ -49,6 +50,10 @@ public: static const float MaxStandableHeight; static bool ToWoWCoords; static const char* VMAPMagic; + static const float BaseUnitDim; + static const int VertexPerMap; + static const int VertexPerTile; + static const int TilesPerMap; }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/ContinentBuilder.cpp b/src/tools/mesh_extractor/ContinentBuilder.cpp index e4a1d2ca9f4..013c0ff256a 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.cpp +++ b/src/tools/mesh_extractor/ContinentBuilder.cpp @@ -14,15 +14,16 @@ private: std::string Continent; bool debug; dtNavMeshParams Params; + ContinentBuilder* cBuilder; public: - BuilderThread(bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params) {} + BuilderThread(ContinentBuilder* _cBuilder, bool deb, dtNavMeshParams& params) : Free(true), debug(deb), Params(params), cBuilder(_cBuilder) {} void SetData(int x, int y, int map, std::string cont) { X = x; Y = y; MapId = map; Continent = cont; } int svc() { Free = false; printf("[%02i,%02i] Building tile\n", X, Y); - TileBuilder builder(Continent, X, Y, MapId); + TileBuilder builder(cBuilder, Continent, X, Y, MapId); char buff[100]; sprintf(buff, "mmaps/%03u%02u%02u.mmtile", MapId, Y, X); FILE* f = fopen(buff, "r"); @@ -57,7 +58,7 @@ public: bool Free; }; -void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) +void ContinentBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) { // this is for elevation if (verts && vertCount) @@ -75,18 +76,8 @@ void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, floa bmin[2] = bmax[2] - Constants::TileSize; } -void ContinentBuilder::Build(bool debug) +void ContinentBuilder::CalculateTileBounds() { - char buff[50]; - sprintf(buff, "mmaps/%03u.mmap", MapId); - FILE* mmap = fopen(buff, "wb"); - if (!mmap) - { - printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); - return; - } - - int tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0; for (std::vector<TilePos>::iterator itr = TileMap->TileTable.begin(); itr != TileMap->TileTable.end(); ++itr) { tileXMax = std::max(itr->X, tileXMax); @@ -95,24 +86,33 @@ void ContinentBuilder::Build(bool debug) tileYMax = std::max(itr->Y, tileYMax); tileYMin = std::min(itr->Y, tileYMin); } - - float bmin[3], bmax[3]; getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax); +} + +void ContinentBuilder::Build(bool debug) +{ + char buff[50]; + sprintf(buff, "mmaps/%03u.mmap", MapId); + FILE* mmap = fopen(buff, "wb"); + if (!mmap) + { + printf("Could not create file %s. Check that you have write permissions to the destination folder and try again\n", buff); + return; + } + CalculateTileBounds(); + dtNavMeshParams params; - params.maxPolys = 32768; + params.maxPolys = 1 << STATIC_POLY_BITS; params.maxTiles = TileMap->TileTable.size(); - // rcVcopy(params.orig, bmin); - params.orig[0] = Constants::Origin[0]; - params.orig[1] = 0; - params.orig[2] = Constants::Origin[2]; + rcVcopy(params.orig, bmin); params.tileHeight = Constants::TileSize; params.tileWidth = Constants::TileSize; fwrite(¶ms, sizeof(dtNavMeshParams), 1, mmap); fclose(mmap); std::vector<BuilderThread*> Threads; for (uint32 i = 0; i < NumberOfThreads; ++i) - Threads.push_back(new BuilderThread(debug, params)); + Threads.push_back(new BuilderThread(this, debug, params)); printf("Map %s ( %i ) has %i tiles. Building them with %i threads\n", Continent.c_str(), MapId, TileMap->TileTable.size(), NumberOfThreads); for (std::vector<TilePos>::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 c923498fc5e..4c16fa0727e 100644 --- a/src/tools/mesh_extractor/ContinentBuilder.h +++ b/src/tools/mesh_extractor/ContinentBuilder.h @@ -7,12 +7,20 @@ class ContinentBuilder { public: - ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn) {} + ContinentBuilder(std::string continent, uint32 mapId, WDT* wdt, uint32 tn) : MapId(mapId), Continent(continent), TileMap(wdt), NumberOfThreads(tn), tileXMin(64), tileYMin(64), tileXMax(0), tileYMax(0) {} void Build(bool debug); + void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax); + void CalculateTileBounds(); + float bmin[3]; + float bmax[3]; private: std::string Continent; WDT* TileMap; uint32 MapId; uint32 NumberOfThreads; + int tileXMin; + int tileYMin; + int tileXMax; + int tileYMax; }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/MeshExtractor.cpp b/src/tools/mesh_extractor/MeshExtractor.cpp index accccf4460f..7379ba87117 100644 --- a/src/tools/mesh_extractor/MeshExtractor.cpp +++ b/src/tools/mesh_extractor/MeshExtractor.cpp @@ -6,6 +6,10 @@ #include "Constants.h" #include "Model.h" +#include "Recast.h" +#include "DetourNavMesh.h" +#include "DetourNavMeshQuery.h" + #include <set> #include "Common.h" @@ -306,6 +310,19 @@ void PrintUsage() } } +void LoadTile(dtNavMesh*& navMesh, const char* tile) +{ + FILE* f = fopen(tile, "rb"); + MmapTileHeader header; + fread(&header, sizeof(MmapTileHeader), 1, f); + uint8* nav = new uint8[header.size]; + fread(nav, header.size, 1, f); + + dtStatus res = navMesh->addTile(nav, header.size, DT_TILE_FREE_DATA, 0, NULL); + + fclose(f); +} + int main(int argc, char* argv[]) { system("pause"); @@ -331,6 +348,71 @@ int main(int argc, char* argv[]) if (extractFlags & Constants::EXTRACT_FLAG_GOB_MODELS) ExtractGameobjectModels(); + + if (extractFlags & Constants::EXTRACT_FLAG_TEST) + { + float start[] = { 0.0f, 0.0f, 0.0f }; + float end[] = { 0.0f, 0.0f, 0.0f }; + + // + float m_spos[3]; + m_spos[0] = -1.0f * start[1]; + m_spos[1] = start[2]; + m_spos[2] = -1.0f * start[0]; + + // + float m_epos[3]; + m_epos[0] = -1.0f * end[1]; + m_epos[1] = end[2]; + m_epos[2] = -1.0f * end[0]; + + // + dtQueryFilter m_filter; + m_filter.setIncludeFlags(0xffff) ; + m_filter.setExcludeFlags(0); + + // + float m_polyPickExt[3]; + m_polyPickExt[0] = 2; + m_polyPickExt[1] = 4; + m_polyPickExt[2] = 2; + + // + dtPolyRef m_startRef; + dtPolyRef m_endRef; + + FILE* mmap = fopen(".mmap", "rb"); + dtNavMeshParams params; + fread(¶ms, sizeof(dtNavMeshParams), 1, mmap); + fclose(mmap); + + dtNavMesh* navMesh = new dtNavMesh(); + 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"); + + navMeshQuery->init(navMesh, 2048); + + float nearestPt[3]; + + dtStatus status = navMeshQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, nearestPt); + status = navMeshQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, nearestPt); + + // + if ( !m_startRef || !m_endRef ) + { + std::cerr << "Could not find any nearby poly's (" << m_startRef << "," << m_endRef << ")" << std::endl; + return 0; + } + + printf("Found!"); + } return 0; }
\ No newline at end of file diff --git a/src/tools/mesh_extractor/TileBuilder.cpp b/src/tools/mesh_extractor/TileBuilder.cpp index 12213b16373..2a02bc50cd4 100644 --- a/src/tools/mesh_extractor/TileBuilder.cpp +++ b/src/tools/mesh_extractor/TileBuilder.cpp @@ -1,3 +1,4 @@ +#include "ContinentBuilder.h" #include "TileBuilder.h" #include "Geometry.h" #include "Constants.h" @@ -11,8 +12,10 @@ #include "ace/Synch.h" -TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0) +TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) : _Geometry(NULL), World(world), X(x), Y(y), MapId(mapId), DataSize(0), cBuilder(_cBuilder) { + /* + Test, non-working values // Cell Size = TileSize / TileVoxelSize // 1800 = TileVoxelSize Config.cs = Constants::TileSize / 1800; @@ -35,6 +38,26 @@ TileBuilder::TileBuilder(std::string world, int x, int y, uint32 mapId) : _Geome Config.height = 1800 + Config.borderSize * 2; Config.maxVertsPerPoly = 6; 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; Context = new rcContext; } @@ -104,84 +127,101 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) _Geometry->Vertices.clear(); _Geometry->Triangles.clear(); - float bbMin[3]; - float bbMax[3]; - // CalculateTileBounds(bbMin, bbMax, navMeshParams); - rcCalcBounds(vertices, numVerts, bbMin, bbMax); - // _Geometry->CalculateMinMaxHeight(bbMin[1], bbMax[1]); - - /*bbMin[0] -= Config.borderSize * Config.cs; - bbMin[2] -= Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs; - bbMax[0] += Config.borderSize * Config.cs;*/ - - - rcHeightfield* hf = rcAllocHeightfield(); - int height, width; - rcCalcGridSize(bbMin, bbMax, Config.cs, &width, &height); - printf("Config values: Height: %i, Width: %i. Calculated values: Height: %i, Width: %i\n", Config.height, Config.width, height, width); - rcCreateHeightfield(Context, *hf, width, height, bbMin, bbMax, Config.cs, Config.ch); - rcClearUnwalkableTriangles(Context, Config.walkableSlopeAngle, vertices, numVerts, triangles, numTris, areas); - rcRasterizeTriangles(Context, vertices, numVerts, triangles, areas, numTris, *hf, Config.walkableClimb); - - printf("[%02i,%02i] Triangles rasterized!\n", X, Y); - - // 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, Config.walkableHeight, Config.walkableClimb, *hf); - rcFilterWalkableLowHeightSpans(Context, Config.walkableHeight, *hf); - - printf("[%02i,%02i] Filtering done!\n", X, Y); - - // 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, Config.walkableHeight, Config.walkableClimb, *hf, *chf); - - rcFreeHeightField(hf); - - printf("[%02i,%02i] Heightfield compressed!\n", X, Y); - - // 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, Config.borderSize, Config.minRegionArea, Config.mergeRegionArea); + + 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; - printf("[%02i,%02i] Regions built!\n", X, Y); + // merge per tile poly and detail meshes + rcPolyMesh** pmmerge = new rcPolyMesh*[Constants::TilesPerMap * Constants::TilesPerMap]; + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[Constants::TilesPerMap * Constants::TilesPerMap]; - // Create contours. - rcContourSet* cset = rcAllocContourSet(); - rcBuildContours(Context, *chf, Config.maxSimplificationError, Config.maxEdgeLen, *cset); + 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; + } + } - // Build polygon navmesh from the contours. rcPolyMesh* pmesh = rcAllocPolyMesh(); - rcBuildPolyMesh(Context, *cset, Config.maxVertsPerPoly, *pmesh); - - printf("[%02i,%02i] Polymesh built!\n", X, Y); - - // Build detail mesh. + rcMergePolyMeshes(Context, pmmerge, nmerge, *pmesh); + rcPolyMeshDetail* dmesh = rcAllocPolyMeshDetail(); - rcBuildPolyMeshDetail(Context, *pmesh, *chf, Config.detailSampleDist, Config.detailSampleMaxError, *dmesh); - - printf("[%02i,%02i] Polymesh detail built!\n", X, Y); - - rcFreeCompactHeightfield(chf); - rcFreeContourSet(cset); - - /* - * Removed with RecastNavigation v292 + rcMergePolyMeshDetails(Context, dmmerge, nmerge, *dmesh); + + delete[] pmmerge; + delete[] dmmerge; + + 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++) @@ -192,14 +232,8 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) pmesh->flags[i] = Constants::POLY_FLAG_SWIM; } - // get original bounds - /*float* tilebMin; - float* tilebMax; - CalculateTileBounds(tilebMin, tilebMax, navMeshParams); - tilebMin[1] = bbMin[1]; - tilebMax[1] = bbMax[1];*/ - dtNavMeshCreateParams params; + memset(¶ms, 0, sizeof(params)); // PolyMesh data params.verts = pmesh->verts; params.vertCount = pmesh->nverts; @@ -214,32 +248,39 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) params.detailVertsCount = dmesh->nverts; params.detailTris = dmesh->tris; params.detailTriCount = dmesh->ntris; - // Copy bounding box - /*params.bmin[0] = tilebMin[0]; - params.bmin[1] = tilebMin[1]; - params.bmin[2] = tilebMin[2]; - params.bmax[0] = tilebMax[0]; - params.bmax[1] = tilebMax[1]; - params.bmax[2] = tilebMax[2];*/ rcVcopy(params.bmin, pmesh->bmin); rcVcopy(params.bmax, pmesh->bmax); // General settings params.ch = Config.ch; params.cs = Config.cs; - params.walkableClimb = Config.walkableClimb; - params.walkableHeight = Config.walkableHeight; - params.walkableRadius = Config.walkableRadius; - params.tileX = X; - params.tileY = Y; - int _x = (((pmesh->bmin[0] + pmesh->bmax[0]) / 2) - Constants::Origin[0]) / Constants::TileSize; - int _y = (((pmesh->bmin[2] + pmesh->bmax[2]) / 2) - Constants::Origin[2]) / Constants::TileSize; - printf("[%02i,%02i] Generated with TileX: %i and TileY: %i\nbmin[0] %f bmin[1] %f bmin[2] %f bmax[0] %f bmax[1] %f bmax[2] %f\n", X, Y, _x, _y, params.bmin[0], params.bmin[1], params.bmin[2], params.bmax[0], params.bmax[1], params.bmax[2]); - params.buildBvTree = true; - params.tileLayer = 0; - + 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); @@ -248,13 +289,9 @@ uint8* TileBuilder::Build(bool dbg, dtNavMeshParams& navMeshParams) // Free some memory rcFreePolyMesh(pmesh); rcFreePolyMeshDetail(dmesh); - //delete tilebMax; - //delete tilebMin; delete areas; delete triangles; delete vertices; - //delete bbMax; - //delete bbMin; if (result) { diff --git a/src/tools/mesh_extractor/TileBuilder.h b/src/tools/mesh_extractor/TileBuilder.h index 17d6e48095a..40c96f6ec42 100644 --- a/src/tools/mesh_extractor/TileBuilder.h +++ b/src/tools/mesh_extractor/TileBuilder.h @@ -5,12 +5,13 @@ #include "Geometry.h" +class ContinentBuilder; class WDT; class TileBuilder { public: - TileBuilder(std::string world, int x, int y, uint32 mapId); + TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId); ~TileBuilder(); void CalculateTileBounds(float*& bmin, float*& bmax, dtNavMeshParams& navMeshParams); @@ -24,5 +25,6 @@ public: rcContext* Context; Geometry* _Geometry; uint32 DataSize; + ContinentBuilder* cBuilder; }; #endif
\ No newline at end of file diff --git a/src/tools/mesh_extractor/Utils.cpp b/src/tools/mesh_extractor/Utils.cpp index b1b054e942e..3639cb88acf 100644 --- a/src/tools/mesh_extractor/Utils.cpp +++ b/src/tools/mesh_extractor/Utils.cpp @@ -21,6 +21,10 @@ const float Constants::PI = 3.1415926f; const float Constants::MaxStandableHeight = 1.5f; const char* Constants::VMAPMagic = "VMAP041"; bool Constants::ToWoWCoords = false; +const float Constants::BaseUnitDim = 0.533333f; +const int Constants::VertexPerMap = (Constants::TileSize / Constants::BaseUnitDim) + 0.5f; +const int Constants::VertexPerTile = 40; +const int Constants::TilesPerMap = Constants::VertexPerMap / Constants::VertexPerTile; void Utils::CreateDir( const std::string& Path ) { |