aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/tools/mesh_extractor/ContinentBuilder.cpp99
-rw-r--r--src/tools/mesh_extractor/TileBuilder.cpp251
-rw-r--r--src/tools/mesh_extractor/TileBuilder.h7
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(&params, 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(&params, &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(&params, 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(&params, &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