diff options
-rw-r--r-- | src/tools/mesh_extractor/ContinentBuilder.cpp | 99 | ||||
-rw-r--r-- | src/tools/mesh_extractor/TileBuilder.cpp | 251 | ||||
-rw-r--r-- | src/tools/mesh_extractor/TileBuilder.h | 7 |
3 files changed, 64 insertions, 293 deletions
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<uint32>& 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 |