Skip to content

Instantly share code, notes, and snippets.

@vermie
Created November 23, 2010 20:01
Show Gist options
  • Save vermie/712419 to your computer and use it in GitHub Desktop.
Save vermie/712419 to your computer and use it in GitHub Desktop.
generator for multiple dtTiles per mmtile
diff --git a/contrib/mmap/src/MapBuilder.cpp b/contrib/mmap/src/MapBuilder.cpp
index dde03c7..546085c 100644
--- a/contrib/mmap/src/MapBuilder.cpp
+++ b/contrib/mmap/src/MapBuilder.cpp
@@ -39,12 +39,15 @@ namespace MMAP
m_skipJunkMaps (skipJunkMaps),
m_skipBattlegrounds (skipBattlegrounds),
m_maxWalkableAngle (maxWalkableAngle),
- m_newTilesOnly (newTilesOnly)
+ m_newTilesOnly (newTilesOnly),
+ m_rcContext (NULL)
{
m_vmapManager = new VMapManager2();
m_terrainBuilder = new TerrainBuilder(skipLiquid, hiResHeightmaps);
+ m_rcContext = new rcContext;
+
discoverTiles();
}
@@ -59,6 +62,7 @@ namespace MMAP
delete m_terrainBuilder;
delete m_vmapManager;
+ delete m_rcContext;
}
void MapBuilder::discoverTiles()
@@ -641,8 +645,10 @@ namespace MMAP
{
set<uint32>* tiles = getTileList(mapID);
+ uint32 tileCount = tiles->size() * rcSqr(TILES_PER_MMTILE);
+
/*** calculate number of bits needed to store tiles & polys ***/
- int tileBits = rcMin((int)dtIlog2(dtNextPow2(tiles->size())), 12);
+ int tileBits = rcMin((int)dtIlog2(dtNextPow2(tileCount)), 12);
if (tileBits < 1) tileBits = 1; // need at least one bit!
int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits;
int maxTiles = 1 << tileBits;
@@ -676,8 +682,8 @@ namespace MMAP
// navmesh creation params
dtNavMeshParams navMeshParams;
memset(&navMeshParams, 0, sizeof(dtNavMeshParams));
- navMeshParams.tileWidth = GRID_SIZE;
- navMeshParams.tileHeight = GRID_SIZE;
+ navMeshParams.tileWidth = GRID_SIZE / TILES_PER_MMTILE;
+ navMeshParams.tileHeight = GRID_SIZE / TILES_PER_MMTILE;
rcVcopy(navMeshParams.orig, bmin);
navMeshParams.maxTiles = maxTiles;
navMeshParams.maxPolys = maxPolysPerTile;
@@ -709,7 +715,7 @@ namespace MMAP
}
void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY,
- MeshData meshData, float* bmin, float* bmax,
+ MeshData meshData, float bmin[3], float bmax[3],
dtNavMesh* navMesh)
{
// console output
@@ -728,6 +734,7 @@ namespace MMAP
return;
}
+ // write header - implicit ctor initializes values for us
mmapTileHeader header;
fwrite(&header, sizeof(header), 1, file);
@@ -750,262 +757,317 @@ namespace MMAP
int* lTris = meshData.liquidTris.getCArray();
int lTriCount = meshData.liquidTris.size() / 3;
uint8* lTriFlags = meshData.liquidType.getCArray();
- do
+
+ // init detour tile bounds
+ float tileMin[3], tileMax[3];
+ float tileSize = GRID_SIZE / TILES_PER_MMTILE;
+ rcVcopy(tileMin, bmin);
+ rcVcopy(tileMax, bmax);
+
+ /* init mmtile config */
+ rcConfig config;
+ memset(&config, 0, sizeof(rcConfig));
+ config.maxVertsPerPoly = 6;
+
+ // these are WORLD UNIT based metrics
+ config.cs = cellSize;
+ config.ch = .3f;
+ config.walkableSlopeAngle = m_maxWalkableAngle;
+
+ // these are VOXEL-based metrics
+ config.tileSize = (int)ceilf(tileSize / config.cs);
+ config.walkableRadius = (int)ceilf(agentRadius / config.cs);
+ config.borderSize = config.walkableRadius + 3;
+ config.maxEdgeLen = 1500;
+ config.walkableHeight = (int)ceilf(agentHeight / config.ch);
+ config.walkableClimb = (int)ceilf(agentHeight / config.ch);
+ config.minRegionArea = (int)rcSqr(50);
+ config.mergeRegionArea = (int)rcSqr(20);
+ config.maxSimplificationError = 1.3f;
+ config.detailSampleDist = config.cs * 16.f;
+ config.detailSampleMaxError = config.ch * 1.f;
+
+ vector<dtTileRef> finishedTiles;
+
+ for (uint32 x = 0; x < TILES_PER_MMTILE; ++x)
{
- /*** init config ***/
- rcConfig config;
- memset(&config, 0, sizeof(rcConfig));
- config.maxVertsPerPoly = 6;
-
- // these are WORLD UNIT based metrics
- config.cs = cellSize;
- config.ch = .3f;
- config.walkableSlopeAngle = m_maxWalkableAngle;
- rcVcopy(config.bmin, bmin);
- rcVcopy(config.bmax, bmax);
-
- // these are VOXEL-based metrics
- rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
- config.tileSize = (int)ceilf(GRID_SIZE / config.cs);
- config.walkableRadius = (int)ceilf(agentRadius / config.cs);
- config.borderSize = config.walkableRadius + 3;
- config.maxEdgeLen = 1500;
- config.walkableHeight = (int)ceilf(agentHeight / config.ch);
- config.walkableClimb = (int)ceilf(agentHeight / config.ch);
- config.minRegionArea = (int)rcSqr(50);
- config.mergeRegionArea = (int)rcSqr(20);
- config.maxSimplificationError = 1.3f;
- config.detailSampleDist = config.cs * 16.f;
- config.detailSampleMaxError = config.ch * 1.f;
-
- // pad bounds with a border
- config.bmin[0] -= config.borderSize*config.cs;
- config.bmin[2] -= config.borderSize*config.cs;
- config.bmax[0] += config.borderSize*config.cs;
- config.bmax[2] += config.borderSize*config.cs;
-
- // this sets the dimensions of the heightfield - should maybe happen before border padding
- rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
-
- // build performance
- rcContext context;
-
- /*********** start build ***********/
-
- // build heightfield
- printf("%sBuilding Recast Heightfield... \r", tileString);
- iv.heightfield = rcAllocHeightfield();
- if (!iv.heightfield || !rcCreateHeightfield(&context, *iv.heightfield, config.width, config.height, config.bmin, config.bmax, config.cs, config.ch))
+ tileMin[0] = bmin[0] + tileSize * x;
+ tileMax[0] = tileMin[0] + tileSize;
+
+ //if (abs(tileMax[0] - bmax[0]) < tileSize * .5)
+ // tileMax[0] = bmax[0];
+
+ for (uint32 y = 0; y < TILES_PER_MMTILE; ++y)
{
- printf("%sFailed building heightfield! \n", tileString);
- continue;
- }
+ tileMin[2] = bmin[2] + tileSize * y;
+ tileMax[2] = tileMin[2] + tileSize;
- printf("%sRasterizing triangles... \r", tileString);
+ //if (abs(tileMax[2] - bmax[2]) < tileSize * .5)
+ // tileMax[2] = bmax[2];
- // flag walkable terrain triangles
- iv.triFlags = (unsigned char*)dtAlloc(sizeof(unsigned char)*tTriCount, DT_ALLOC_PERM);
- memset(iv.triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char));
- rcClearUnwalkableTriangles(&context, config.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, iv.triFlags);
- rcRasterizeTriangles(&context, tVerts, tVertCount, tTris, iv.triFlags, tTriCount, *iv.heightfield, config.walkableClimb);
- dtFree(iv.triFlags);
- iv.triFlags = NULL;
+ clearIntermediateValues(iv);
- // filter out unwalkable spans (order of calls matters, see rcFilterLowHangingWalkableObstacles)
- rcFilterLowHangingWalkableObstacles(&context, config.walkableClimb, *iv.heightfield);
- rcFilterLedgeSpans(&context, config.walkableHeight, config.walkableClimb, *iv.heightfield);
- rcFilterWalkableLowHeightSpans(&context, config.walkableHeight, *iv.heightfield);
+ /* tile-specific config settings */
+ rcVcopy(config.bmin, tileMin);
+ rcVcopy(config.bmax, tileMax);
- // do after filtering because same rules don't apply to swimming
- rcRasterizeTriangles(&context, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *iv.heightfield, config.walkableClimb);
+ // pad bounds with a border
+ float pad = config.borderSize*config.cs;
+ config.bmin[0] -= pad;
+ config.bmin[2] -= pad;
+ config.bmax[0] += pad;
+ config.bmax[2] += pad;
- // compact heightfield spans
- printf("%sCompacting heightfield... \r", tileString);
- iv.compactHeightfield = rcAllocCompactHeightfield();
- if (!iv.compactHeightfield || !rcBuildCompactHeightfield(&context, config.walkableHeight, config.walkableClimb, *iv.heightfield, *iv.compactHeightfield))
- {
- printf("%sFailed compacting heightfield! \n", tileString);
- continue;
- }
+ // this sets the dimensions of the heightfield - should maybe happen before border padding
+ rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
+ //printf("tile width = %d \ntile height = %d\n", config.width, config.height);
- if (!m_debugOutput)
- {
- rcFreeHeightField(iv.heightfield);
- iv.heightfield = NULL;
- }
+ /* start build */
- // build polymesh intermediates
- printf("%sEroding walkable area width... \r", tileString);
- if (!rcErodeWalkableArea(&context, config.walkableRadius, *iv.compactHeightfield))
- {
- printf("%sFailed eroding area! \n", tileString);
- continue;
- }
+ // build heightfield
+ printf("%sBuilding Recast Heightfield... \r", tileString);
+ iv.heightfield = rcAllocHeightfield();
+ if (!iv.heightfield || !rcCreateHeightfield(m_rcContext, *iv.heightfield, config.width, config.height, config.bmin, config.bmax, config.cs, config.ch))
+ {
+ printf("%sFailed building heightfield! \n", tileString);
+ continue;
+ }
- printf("%sSmoothing area boundaries... \r", tileString);
- if (!rcMedianFilterWalkableArea(&context, *iv.compactHeightfield))
- {
- printf("%sFailed median filter! \n", tileString);
- continue;
- }
+ printf("%sRasterizing triangles... \r", tileString);
- printf("%sBuilding distance field... \r", tileString);
- if (!rcBuildDistanceField(&context, *iv.compactHeightfield))
- {
- printf("%sFailed building distance field! \n", tileString);
- continue;
- }
+ // flag walkable terrain triangles
+ iv.triFlags = (unsigned char*)dtAlloc(sizeof(unsigned char)*tTriCount, DT_ALLOC_PERM);
+ memset(iv.triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char));
+ rcClearUnwalkableTriangles(m_rcContext, config.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, iv.triFlags);
+ rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, iv.triFlags, tTriCount, *iv.heightfield, config.walkableClimb);
+ dtFree(iv.triFlags);
+ iv.triFlags = NULL;
- // bottleneck is here
- printf("%sBuilding regions... \r", tileString);
- if (!rcBuildRegions(&context, *iv.compactHeightfield, config.borderSize, config.minRegionArea, config.mergeRegionArea))
- {
- printf("%sFailed building regions! \n", tileString);
- continue;
- }
+ // filter out unwalkable spans (order of calls matters, see rcFilterLowHangingWalkableObstacles)
+ rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *iv.heightfield);
+ rcFilterLedgeSpans(m_rcContext, config.walkableHeight, config.walkableClimb, *iv.heightfield);
+ rcFilterWalkableLowHeightSpans(m_rcContext, config.walkableHeight, *iv.heightfield);
- printf("%sBuilding contours... \r", tileString);
- iv.contours = rcAllocContourSet();
- if (!iv.contours || !rcBuildContours(&context, *iv.compactHeightfield, config.maxSimplificationError, config.maxEdgeLen, *iv.contours))
- {
- printf("%sFailed building contours! \n", tileString);
- continue;
- }
+ // do after filtering because same rules don't apply to swimming
+ rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *iv.heightfield, config.walkableClimb);
- // build polymesh
- printf("%sBuilding polymesh... \r", tileString);
- iv.polyMesh = rcAllocPolyMesh();
- if (!iv.polyMesh || !rcBuildPolyMesh(&context, *iv.contours, config.maxVertsPerPoly, *iv.polyMesh))
- {
- printf("%sFailed building polymesh! \n", tileString);
- continue;
- }
+ // compact heightfield spans
+ printf("%sCompacting heightfield... \r", tileString);
+ iv.compactHeightfield = rcAllocCompactHeightfield();
+ if (!iv.compactHeightfield || !rcBuildCompactHeightfield(m_rcContext, config.walkableHeight, config.walkableClimb, *iv.heightfield, *iv.compactHeightfield))
+ {
+ printf("%sFailed compacting heightfield! \n", tileString);
+ continue;
+ }
- printf("%sBuilding polymesh detail... \r", tileString);
- iv.polyMeshDetail = rcAllocPolyMeshDetail();
- if (!iv.polyMeshDetail || !rcBuildPolyMeshDetail(&context, *iv.polyMesh, *iv.compactHeightfield, config.detailSampleDist, config.detailSampleMaxError, *iv.polyMeshDetail))
- {
- printf("%sFailed building polymesh detail! \n", tileString);
- continue;
- }
+ if (!m_debugOutput)
+ {
+ rcFreeHeightField(iv.heightfield);
+ iv.heightfield = NULL;
+ }
- if (!m_debugOutput)
- {
- rcFreeCompactHeightfield(iv.compactHeightfield);
- iv.compactHeightfield = NULL;
- rcFreeContourSet(iv.contours);
- iv.contours = NULL;
- }
+ // build polymesh intermediates
+ printf("%sEroding walkable area width... \r", tileString);
+ if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *iv.compactHeightfield))
+ {
+ printf("%sFailed eroding area! \n", tileString);
+ continue;
+ }
- // this might be handled within Recast at some point
- printf("%sCleaning vertex padding... \r", tileString);
- for (int i = 0; i < iv.polyMesh->nverts; ++i)
- {
- unsigned short* v = &iv.polyMesh->verts[i*3];
- v[0] -= (unsigned short)config.borderSize;
- v[2] -= (unsigned short)config.borderSize;
- }
+ printf("%sSmoothing area boundaries... \r", tileString);
+ if (!rcMedianFilterWalkableArea(m_rcContext, *iv.compactHeightfield))
+ {
+ printf("%sFailed median filter! \n", tileString);
+ continue;
+ }
- // polymesh vertex indices are stored with ushorts in detour, can't have more than 65535
- if (iv.polyMesh->nverts >= 0xffff)
- {
- printf("%sToo many vertices! \n", tileString);
- continue;
- }
+ printf("%sBuilding distance field... \r", tileString);
+ if (!rcBuildDistanceField(m_rcContext, *iv.compactHeightfield))
+ {
+ printf("%sFailed building distance field! \n", tileString);
+ continue;
+ }
- printf("%sSetting polys as walkable... \r", tileString);
- for (int i = 0; i < iv.polyMesh->npolys; ++i)
- if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
- iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
-
- dtNavMeshCreateParams params;
- memset(&params, 0, sizeof(params));
- params.verts = iv.polyMesh->verts;
- params.vertCount = iv.polyMesh->nverts;
- params.polys = iv.polyMesh->polys;
- params.polyAreas = iv.polyMesh->areas;
- params.polyFlags = iv.polyMesh->flags;
- params.polyCount = iv.polyMesh->npolys;
- params.nvp = iv.polyMesh->nvp;
- params.detailMeshes = iv.polyMeshDetail->meshes;
- params.detailVerts = iv.polyMeshDetail->verts;
- params.detailVertsCount = iv.polyMeshDetail->nverts;
- params.detailTris = iv.polyMeshDetail->tris;
- params.detailTriCount = iv.polyMeshDetail->ntris;
- params.walkableHeight = agentHeight;
- params.walkableRadius = agentRadius;
- params.walkableClimb = agentMaxClimb;
- params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE;
- params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE;
- rcVcopy(params.bmin, bmin);
- rcVcopy(params.bmax, bmax);
- params.cs = config.cs;
- params.ch = config.ch;
- params.tileSize = config.tileSize;
-
- // will hold final navmesh
- unsigned char* navData = NULL;
- int navDataSize = 0;
-
- // these values are checked within dtCreateNavMeshData - handle them here
- // so we have a clear error message
- if (params.nvp > DT_VERTS_PER_POLYGON)
- {
- printf("%s Invalid verts-per-polygon value! \n", tileString);
- continue;
- }
- if (params.vertCount >= 0xffff)
- {
- printf("%s Too many vertices! \n", tileString);
- continue;
- }
- if (!params.vertCount || !params.verts)
- {
- // occurs mostly when adjacent tiles have models
- // loaded but those models don't span into this tile
+ // bottleneck is here
+ printf("%sBuilding regions... \r", tileString);
+ if (!rcBuildRegions(m_rcContext, *iv.compactHeightfield, config.borderSize, config.minRegionArea, config.mergeRegionArea))
+ {
+ printf("%sFailed building regions! \n", tileString);
+ continue;
+ }
- // message is an annoyance
- //printf("%sNo vertices to build tile! \n", tileString);
- continue;
- }
- if (!params.polyCount || !params.polys)
- {
- printf("%s No polygons to build tile! \n", tileString);
- continue;
- }
- if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
- {
- printf("%s No detail mesh to build tile! \n", tileString);
- continue;
- }
+ printf("%sBuilding contours... \r", tileString);
+ iv.contours = rcAllocContourSet();
+ if (!iv.contours || !rcBuildContours(m_rcContext, *iv.compactHeightfield, config.maxSimplificationError, config.maxEdgeLen, *iv.contours))
+ {
+ printf("%sFailed building contours! \n", tileString);
+ continue;
+ }
- printf("%s Building navmesh tile... \r", tileString);
- if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
- {
- printf("%s Failed building navmesh tile! \n", tileString);
- continue;
- }
+ // build polymesh
+ printf("%sBuilding polymesh... \r", tileString);
+ iv.polyMesh = rcAllocPolyMesh();
+ if (!iv.polyMesh || !rcBuildPolyMesh(m_rcContext, *iv.contours, config.maxVertsPerPoly, *iv.polyMesh))
+ {
+ printf("%sFailed building polymesh! \n", tileString);
+ continue;
+ }
- dtTileRef tileRef = 0;
- printf("%s Adding tile to navmesh... \r", tileString);
- // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
- // is removed via removeTile()
- dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
- if (!tileRef || dtResult != DT_SUCCESS)
- {
- printf("%s Failed adding tile to navmesh! \n", tileString);
- continue;
+ printf("%sBuilding polymesh detail... \r", tileString);
+ iv.polyMeshDetail = rcAllocPolyMeshDetail();
+ if (!iv.polyMeshDetail || !rcBuildPolyMeshDetail(m_rcContext, *iv.polyMesh, *iv.compactHeightfield, config.detailSampleDist, config.detailSampleMaxError, *iv.polyMeshDetail))
+ {
+ printf("%sFailed building polymesh detail! \n", tileString);
+ continue;
+ }
+
+ if (!m_debugOutput)
+ {
+ rcFreeCompactHeightfield(iv.compactHeightfield);
+ iv.compactHeightfield = NULL;
+ rcFreeContourSet(iv.contours);
+ iv.contours = NULL;
+ }
+
+ // this might be handled within Recast at some point
+ // very important, without this tiles do not get attached neighbors!!
+ printf("%sCleaning vertex padding... \r", tileString);
+ for (int i = 0; i < iv.polyMesh->nverts; ++i)
+ {
+ unsigned short* v = &iv.polyMesh->verts[i*3];
+ v[0] -= (unsigned short)config.borderSize;
+ v[2] -= (unsigned short)config.borderSize;
+ }
+
+ // polymesh vertex indices are stored with ushorts in detour, can't have more than 65535
+ if (iv.polyMesh->nverts >= 0xffff)
+ {
+ printf("%sToo many vertices! \n", tileString);
+ continue;
+ }
+
+ printf("%sSetting polys as walkable... \r", tileString);
+ // handle area type here
+ // TODO: special flag for DYNAMIC polygons, ie surfaces that can be turned on and off
+ for (int i = 0; i < iv.polyMesh->npolys; ++i)
+ if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
+ iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
+
+ dtNavMeshCreateParams params;
+ memset(&params, 0, sizeof(params));
+ params.verts = iv.polyMesh->verts;
+ params.vertCount = iv.polyMesh->nverts;
+ params.polys = iv.polyMesh->polys;
+ params.polyAreas = iv.polyMesh->areas;
+ params.polyFlags = iv.polyMesh->flags;
+ params.polyCount = iv.polyMesh->npolys;
+ params.nvp = iv.polyMesh->nvp;
+ params.detailMeshes = iv.polyMeshDetail->meshes;
+ params.detailVerts = iv.polyMeshDetail->verts;
+ params.detailVertsCount = iv.polyMeshDetail->nverts;
+ params.detailTris = iv.polyMeshDetail->tris;
+ params.detailTriCount = iv.polyMeshDetail->ntris;
+ params.walkableHeight = agentHeight;
+ params.walkableRadius = agentRadius;
+ params.walkableClimb = agentMaxClimb;
+ float pos[3] = {(tileMin[0] + tileMax[0]) / 2, 0.f, (tileMin[2] + tileMax[2]) / 2};
+ navMesh->calcTileLoc(pos, &params.tileX, &params.tileY);
+ rcVcopy(params.bmin, tileMin);
+ rcVcopy(params.bmax, tileMax);
+ params.cs = config.cs;
+ params.ch = config.ch;
+ params.tileSize = config.tileSize;
+
+ // will hold final navmesh
+ unsigned char* navData = NULL;
+ int navDataSize = 0;
+
+ //printf("x = %d, y = %d \n", params.tileX, params.tileY);
+
+ // these values are checked within dtCreateNavMeshData - handle them here
+ // so we have a clear error message
+ if (params.nvp > DT_VERTS_PER_POLYGON)
+ {
+ printf("%sInvalid verts-per-polygon value! \n", tileString);
+ continue;
+ }
+ if (params.vertCount >= 0xffff)
+ {
+ printf("%sToo many vertices! \n", tileString);
+ continue;
+ }
+ if (!params.vertCount || !params.verts)
+ {
+ // occurs mostly when adjacent tiles have models
+ // loaded but those models don't span into this tile
+
+ // message is an annoyance
+ //printf("%sNo vertices to build tile! \n", tileString);
+ continue;
+ }
+ if (!params.polyCount || !params.polys)
+ {
+ printf("%sNo polygons to build tile! \n", tileString);
+ continue;
+ }
+ if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
+ {
+ printf("%sNo detail mesh to build tile! \n", tileString);
+ continue;
+ }
+
+ printf("%sBuilding navmesh tile... \r", tileString);
+ if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
+ {
+ printf("%s Failed building navmesh tile! \n", tileString);
+ continue;
+ }
+
+ dtTileRef tileRef = 0;
+ printf("%sAdding tile to navmesh... \r", tileString);
+ // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
+ // is removed via removeTile()
+ dtStatus dtResult = navMesh->addTile(navData, navDataSize, 0, 0, &tileRef);
+ if (!tileRef || dtResult != DT_SUCCESS)
+ {
+ printf("%sFailed adding tile to navmesh! \n", tileString);
+ continue;
+ }
+
+ // store tile ref so that tile can be written to disk later
+ finishedTiles.push_back(tileRef);
+ ++header.tileCount;
+
+ // TODO: writing this to file does no good, debug data is just overwritten by next tile
+ //if (m_debugOutput)
+ //{
+ // for (int i = 0; i < iv.polyMesh->nverts; ++i)
+ // {
+ // unsigned short* v = &iv.polyMesh->verts[i*3];
+ // v[0] += (unsigned short)config.borderSize;
+ // v[2] += (unsigned short)config.borderSize;
+ // }
+ // writeIV(mapID, tileX, tileY, iv);
+ //}
}
+ }
- printf("%s Writing to file... \r", tileString);
- fwrite(&navDataSize, sizeof(navDataSize), 1, file);
- fwrite(navData, sizeof(unsigned char), navDataSize, file);
+ printf("%sWriting to file... \r", tileString);
+ for (vector<dtTileRef>::iterator it = finishedTiles.begin(); it != finishedTiles.end(); ++it)
+ {
+ int dataSize;
+ unsigned char* data;
- ++header.tileCount;
+ // remove the tile from the mesh, and retrieve the tile's data so that
+ // we can write it to disk
+ navMesh->removeTile(*it, &data, &dataSize);
- // now that tile is written to disk, we can unload it
- navMesh->removeTile(tileRef, 0, 0);
- } while (0);
+ fwrite(&dataSize, sizeof(dataSize), 1, file);
+ fwrite(data, sizeof(unsigned char), dataSize, file);
+
+ // free memory used by tile
+ dtFree(data);
+ }
// re-write header, so that tilecount is up to date
fseek(file, 0, SEEK_SET);
@@ -1013,12 +1075,9 @@ namespace MMAP
fclose(file);
if (m_debugOutput)
- {
generateObjFile(mapID, tileX, tileY, meshData);
- writeIV(mapID, tileX, tileY, iv);
- }
- clearIntermediateValues(iv);
+ m_rcContext->resetLog();
}
void MapBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax)
@@ -1083,7 +1142,7 @@ namespace MMAP
fwrite(&b, sizeof(char), 1, objFile);
fclose(objFile);
- sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileX, tileY);
+ sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX);
objFile = fopen(objFileName, "wb");
if (!objFile)
{
@@ -1164,7 +1223,7 @@ namespace MMAP
string name("meshes/%03u%02i%02i.");
#define DEBUG_WRITE(fileExtension,data) \
- sprintf(fileName, (name + fileExtension).c_str(), mapID, tileX, tileY); \
+ sprintf(fileName, (name + fileExtension).c_str(), mapID, tileY, tileX); \
file = fopen(fileName, "wb"); \
if (!file) \
{ \
diff --git a/contrib/mmap/src/MapBuilder.h b/contrib/mmap/src/MapBuilder.h
index c77975d..1fc9077 100644
--- a/contrib/mmap/src/MapBuilder.h
+++ b/contrib/mmap/src/MapBuilder.h
@@ -38,6 +38,8 @@ using namespace VMAP;
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 1
+#define TILES_PER_MMTILE 64
+
namespace MMAP
{
typedef map<uint32,set<uint32>*> TileList;
@@ -112,8 +114,8 @@ namespace MMAP
uint32 tileX,
uint32 tileY,
MeshData meshData,
- float* bmin,
- float* bmax,
+ float bmin[3],
+ float bmax[3],
dtNavMesh* navMesh);
void getTileBounds(uint32 tileX, uint32 tileY,
@@ -151,6 +153,8 @@ namespace MMAP
bool m_newTilesOnly;
float m_maxWalkableAngle;
+
+ rcContext* m_rcContext;
};
}
diff --git a/contrib/mmap/win/VC100/MoveMapGen_VC100.vcxproj b/contrib/mmap/win/VC100/MoveMapGen_VC100.vcxproj
diff --git a/contrib/mmap/win/VC100/MoveMapGen_VC100.vcxproj.filters b/contrib/mmap/win/VC100/MoveMapGen_VC100.vcxproj.filters
diff --git a/dep/recastnavigation/RecastDemo/Include/Debug.h b/dep/recastnavigation/RecastDemo/Include/Debug.h
index 14c3ad3..8845a91 100644
--- a/dep/recastnavigation/RecastDemo/Include/Debug.h
+++ b/dep/recastnavigation/RecastDemo/Include/Debug.h
@@ -51,4 +51,20 @@ public:
inline const char* getFileName() const { return m_filename; }
};
+#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
+#define MMAP_VERSION 1
+
+struct mmapTileHeader
+{
+ unsigned int mmapMagic;
+ unsigned int dtVersion;
+ unsigned int mmapVersion;
+ unsigned int tileCount;
+
+ mmapTileHeader() :
+ mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION),
+ mmapVersion(MMAP_VERSION), tileCount(0)
+ {}
+};
+
#endif
diff --git a/dep/recastnavigation/RecastDemo/Source/Debug.cpp b/dep/recastnavigation/RecastDemo/Source/Debug.cpp
index 9eb8dd7..ebbc3ac 100644
--- a/dep/recastnavigation/RecastDemo/Source/Debug.cpp
+++ b/dep/recastnavigation/RecastDemo/Source/Debug.cpp
@@ -24,24 +24,54 @@ void duReadNavMesh(char* tile, dtNavMesh* &navMesh)
fread(&params, sizeof(dtNavMeshParams), 1, file);
fclose(file);
- dtFreeNavMesh(navMesh);
- navMesh = dtAllocNavMesh();
- navMesh->init(&params);
-
- file = fopen(("mmaps/" + tileName.substr(0, 3) + tileName.substr(5, 2) + tileName.substr(3, 2) + ".mmtile").c_str(), "rb");
- if(file)
+ if (!navMesh)
{
- fseek(file, 0, SEEK_END);
- int length = ftell(file);
- fseek(file, 0, SEEK_SET);
+ dtFreeNavMesh(navMesh);
+ navMesh = dtAllocNavMesh();
+ navMesh->init(&params);
+ }
- unsigned char* data = new unsigned char[length];
- fread(data, length, 1, file);
- fclose(file);
+ int map = atoi(tileName.substr(0, 3).c_str());
+ int x = atoi(tileName.substr(5, 2).c_str());
+ int y = atoi(tileName.substr(3, 2).c_str());
+ bool loaded = false;
- navMesh->addTile(data, length, DT_TILE_FREE_DATA, 0 , NULL);
- }
- else
+ char fname[50];
+
+ int count = 0;
+ for (int i = x-1; i <= x+1; ++i)
+ for (int j = y-1; j <= y+1; ++j)
+ //int i = x;
+ //int j = y;
+ {
+ sprintf(fname, "mmaps/%03i%02i%02i.mmtile", map, j, i);
+ file = fopen(fname, "rb");
+ if(file)
+ {
+ mmapTileHeader header;
+ fread(&header, sizeof(header), 1, file);
+
+ unsigned int length;
+
+ for (unsigned int i2 = 0; i2 < header.tileCount; ++i2)
+ {
+ fread(&length, sizeof(length), 1, file);
+
+ unsigned char* data = (unsigned char*)dtAlloc(length, DT_ALLOC_PERM);
+ fread(data, length, 1, file);
+
+ dtStatus status = navMesh->addTile(data, length, DT_TILE_FREE_DATA, 0 , NULL);
+
+ if (status != DT_SUCCESS)
+ dtFree(data);
+ else
+ count++;
+ }
+ fclose(file);
+ }
+ }
+
+ if (!count)
{
dtFreeNavMesh(navMesh);
navMesh = NULL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment