Last active
August 29, 2015 14:03
-
-
Save Subv/0956c2d726c7cfe8aa01 to your computer and use it in GitHub Desktop.
Some tile division stuff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp | |
index 131041e..113fd8d 100644 | |
--- a/src/tools/mmaps_generator/MapBuilder.cpp | |
+++ b/src/tools/mmaps_generator/MapBuilder.cpp | |
@@ -513,18 +513,8 @@ namespace MMAP | |
fclose(file); | |
} | |
- /**************************************************************************/ | |
- void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, | |
- MeshData &meshData, float bmin[3], float bmax[3], | |
- dtNavMesh* navMesh) | |
+ void buildSubTile(bool useLiquids, float* bmin, float* bmax, bool m_bigBaseUnit, dtNavMesh* navMesh, char* tileString, MeshData& meshData, uint32 mapID, uint32 x, uint32 y, uint32 tileX, uint32 tileY, Tile& tile, rcConfig tileCfg, rcConfig config, rcContext* m_rcContext) | |
{ | |
- // console output | |
- char tileString[20]; | |
- sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY); | |
- printf("%s Building movemap tiles...\n", tileString); | |
- | |
- IntermediateValues iv; | |
- | |
float* tVerts = meshData.solidVerts.getCArray(); | |
int tVertCount = meshData.solidVerts.size() / 3; | |
int* tTris = meshData.solidTris.getCArray(); | |
@@ -542,199 +532,110 @@ namespace MMAP | |
const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.5333333f : 0.2666666f; | |
// All are in UNIT metrics! | |
- const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); | |
+ const static int VERTEX_PER_MAP = int(GRID_SIZE / BASE_UNIT_DIM + 0.5f); | |
const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP | |
- const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; | |
- | |
- rcConfig config; | |
- memset(&config, 0, sizeof(rcConfig)); | |
- | |
- rcVcopy(config.bmin, bmin); | |
- rcVcopy(config.bmax, bmax); | |
- | |
- config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; | |
- config.cs = BASE_UNIT_DIM; | |
- config.ch = BASE_UNIT_DIM; | |
- config.walkableSlopeAngle = m_maxWalkableAngle; | |
- config.tileSize = VERTEX_PER_TILE; | |
- config.walkableRadius = m_bigBaseUnit ? 1 : 2; | |
- config.borderSize = config.walkableRadius + 3; | |
- config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize | |
- config.walkableHeight = m_bigBaseUnit ? 3 : 6; | |
- // a value >= 3|6 allows npcs to walk over some fences | |
- // a value >= 4|8 allows npcs to walk over all fences | |
- config.walkableClimb = m_bigBaseUnit ? 4 : 8; | |
- config.minRegionArea = rcSqr(60); | |
- config.mergeRegionArea = rcSqr(50); | |
- config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons) | |
- config.detailSampleDist = config.cs * 64; | |
- config.detailSampleMaxError = config.ch * 2; | |
- | |
- // this sets the dimensions of the heightfield - should maybe happen before border padding | |
- rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); | |
- | |
- // allocate subregions : tiles | |
- Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; | |
+ const static int TILES_PER_MAP = VERTEX_PER_MAP / VERTEX_PER_TILE; | |
- // Initialize per tile config. | |
- rcConfig tileCfg = config; | |
- tileCfg.width = config.tileSize + config.borderSize*2; | |
- tileCfg.height = config.tileSize + config.borderSize*2; | |
+ // Enlarge the borders a bit | |
+ tileCfg.bmin[0] -= config.borderSize * config.cs; | |
+ tileCfg.bmin[2] -= config.borderSize * config.cs; | |
+ tileCfg.bmax[0] += config.borderSize * config.cs; | |
+ tileCfg.bmax[2] += config.borderSize * config.cs; | |
- // merge per tile poly and detail meshes | |
- rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; | |
- rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; | |
- int nmerge = 0; | |
- // build all tiles | |
- for (int y = 0; y < TILES_PER_MAP; ++y) | |
+ // build heightfield | |
+ tile.solid = rcAllocHeightfield(); | |
+ if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) | |
{ | |
- for (int x = 0; x < TILES_PER_MAP; ++x) | |
- { | |
- Tile& tile = tiles[x + y * TILES_PER_MAP]; | |
- | |
- // 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; | |
- | |
- // build heightfield | |
- tile.solid = rcAllocHeightfield(); | |
- if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch)) | |
- { | |
- printf("%s Failed building heightfield! \n", tileString); | |
- continue; | |
- } | |
- | |
- // mark all walkable tiles, both liquids and solids | |
- unsigned char* triFlags = new unsigned char[tTriCount]; | |
- memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); | |
- rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); | |
- rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); | |
- delete[] triFlags; | |
- | |
- rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); | |
- rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); | |
- rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); | |
- | |
- rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); | |
- | |
- // compact heightfield spans | |
- tile.chf = rcAllocCompactHeightfield(); | |
- if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) | |
- { | |
- printf("%s Failed compacting heightfield! \n", tileString); | |
- continue; | |
- } | |
+ printf("%s Failed building heightfield! \n", tileString); | |
+ return; | |
+ } | |
- // build polymesh intermediates | |
- if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) | |
- { | |
- printf("%s Failed eroding area! \n", tileString); | |
- continue; | |
- } | |
+ // mark all walkable tiles, both liquids and solids | |
+ unsigned char* triFlags = new unsigned char[tTriCount]; | |
+ memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char)); | |
+ rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); | |
+ rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); | |
+ delete[] triFlags; | |
- if (!rcBuildDistanceField(m_rcContext, *tile.chf)) | |
- { | |
- printf("%s Failed building distance field! \n", tileString); | |
- continue; | |
- } | |
+ rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid); | |
+ rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid); | |
+ rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid); | |
- if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) | |
- { | |
- printf("%s Failed building regions! \n", tileString); | |
- continue; | |
- } | |
+ rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb); | |
- tile.cset = rcAllocContourSet(); | |
- if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) | |
- { | |
- printf("%s Failed building contours! \n", tileString); | |
- continue; | |
- } | |
+ // compact heightfield spans | |
+ tile.chf = rcAllocCompactHeightfield(); | |
+ if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf)) | |
+ { | |
+ printf("%s Failed compacting heightfield! \n", tileString); | |
+ return; | |
+ } | |
- // build polymesh | |
- tile.pmesh = rcAllocPolyMesh(); | |
- if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) | |
- { | |
- printf("%s Failed building polymesh! \n", tileString); | |
- continue; | |
- } | |
+ // build polymesh intermediates | |
+ if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf)) | |
+ { | |
+ printf("%s Failed eroding area! \n", tileString); | |
+ return; | |
+ } | |
- tile.dmesh = rcAllocPolyMeshDetail(); | |
- if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh)) | |
- { | |
- printf("%s Failed building polymesh detail! \n", tileString); | |
- continue; | |
- } | |
- | |
- // free those up | |
- // we may want to keep them in the future for debug | |
- // but right now, we don't have the code to merge them | |
- rcFreeHeightField(tile.solid); | |
- tile.solid = NULL; | |
- rcFreeCompactHeightfield(tile.chf); | |
- tile.chf = NULL; | |
- rcFreeContourSet(tile.cset); | |
- tile.cset = NULL; | |
+ if (!rcBuildDistanceField(m_rcContext, *tile.chf)) | |
+ { | |
+ printf("%s Failed building distance field! \n", tileString); | |
+ return; | |
+ } | |
- pmmerge[nmerge] = tile.pmesh; | |
- dmmerge[nmerge] = tile.dmesh; | |
- nmerge++; | |
- } | |
+ if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea)) | |
+ { | |
+ printf("%s Failed building regions! \n", tileString); | |
+ return; | |
} | |
- iv.polyMesh = rcAllocPolyMesh(); | |
- if (!iv.polyMesh) | |
+ tile.cset = rcAllocContourSet(); | |
+ if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset)) | |
{ | |
- printf("%s alloc iv.polyMesh FIALED!\n", tileString); | |
- delete[] pmmerge; | |
- delete[] dmmerge; | |
- delete[] tiles; | |
+ printf("%s Failed building contours! \n", tileString); | |
return; | |
} | |
- rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); | |
- iv.polyMeshDetail = rcAllocPolyMeshDetail(); | |
- if (!iv.polyMeshDetail) | |
+ // build polymesh | |
+ tile.pmesh = rcAllocPolyMesh(); | |
+ if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) | |
{ | |
- printf("%s alloc m_dmesh FIALED!\n", tileString); | |
- delete[] pmmerge; | |
- delete[] dmmerge; | |
- delete[] tiles; | |
+ printf("%s Failed building polymesh! \n", tileString); | |
return; | |
} | |
- rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); | |
- // free things up | |
- delete[] pmmerge; | |
- delete[] dmmerge; | |
- delete[] tiles; | |
+ tile.dmesh = rcAllocPolyMeshDetail(); | |
+ if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh)) | |
+ { | |
+ printf("%s Failed building polymesh detail! \n", tileString); | |
+ return; | |
+ } | |
// set polygons as walkable | |
// TODO: special flags 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]; | |
+ for (int i = 0; i < tile.pmesh->npolys; ++i) | |
+ if (tile.pmesh->areas[i] & RC_WALKABLE_AREA) | |
+ tile.pmesh->flags[i] = tile.pmesh->areas[i]; | |
// setup mesh parameters | |
dtNavMeshCreateParams params; | |
memset(¶ms, 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.verts = tile.pmesh->verts; | |
+ params.vertCount = tile.pmesh->nverts; | |
+ params.polys = tile.pmesh->polys; | |
+ params.polyAreas = tile.pmesh->areas; | |
+ params.polyFlags = tile.pmesh->flags; | |
+ params.polyCount = tile.pmesh->npolys; | |
+ params.nvp = tile.pmesh->nvp; | |
+ params.detailMeshes = tile.dmesh->meshes; | |
+ params.detailVerts = tile.dmesh->verts; | |
+ params.detailVertsCount = tile.dmesh->nverts; | |
+ params.detailTris = tile.dmesh->tris; | |
+ params.detailTriCount = tile.dmesh->ntris; | |
params.offMeshConVerts = meshData.offMeshConnections.getCArray(); | |
- params.offMeshConCount = meshData.offMeshConnections.size()/6; | |
+ params.offMeshConCount = meshData.offMeshConnections.size() / 6; | |
params.offMeshConRad = meshData.offMeshConnectionRads.getCArray(); | |
params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray(); | |
params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); | |
@@ -743,10 +644,10 @@ namespace MMAP | |
params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height | |
params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius | |
params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)! | |
- 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.tileX = (((tileCfg.bmin[0] + tileCfg.bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; | |
+ params.tileY = (((tileCfg.bmin[2] + tileCfg.bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; | |
+ rcVcopy(params.bmin, tileCfg.bmin); | |
+ rcVcopy(params.bmax, tileCfg.bmax); | |
params.cs = config.cs; | |
params.ch = config.ch; | |
params.tileLayer = 0; | |
@@ -794,42 +695,41 @@ namespace MMAP | |
continue; | |
} | |
- printf("%s Building navmesh tile...\n", tileString); | |
+ printf("%s [%i, %i] Building navmesh tile...\n", tileString, y, x); | |
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize)) | |
{ | |
printf("%s Failed building navmesh tile! \n", tileString); | |
continue; | |
} | |
- dtTileRef tileRef = 0; | |
- printf("%s Adding tile to navmesh...\n", tileString); | |
+ /*dtTileRef tileRef = 0; | |
+ printf("%s [%i, %i] Adding tile to navmesh...\n", tileString, y, x); | |
// 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("%s Failed adding tile to navmesh! \n", tileString); | |
+ continue; | |
+ }*/ | |
// file output | |
char fileName[255]; | |
- sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); | |
+ sprintf(fileName, "mmaps/%03u%02i%02i_____%02i%02i.mmtile", mapID, tileY, tileX, y, x); | |
FILE* file = fopen(fileName, "wb"); | |
if (!file) | |
{ | |
char message[1024]; | |
sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName); | |
perror(message); | |
- navMesh->removeTile(tileRef, NULL, NULL); | |
continue; | |
} | |
- printf("%s Writing to file...\n", tileString); | |
+ printf("%s [%i, %i] Writing to file...\n", tileString, y, x); | |
// write header | |
MmapTileHeader header; | |
- header.usesLiquids = m_terrainBuilder->usesLiquids(); | |
+ header.usesLiquids = useLiquids; | |
header.size = uint32(navDataSize); | |
fwrite(&header, sizeof(MmapTileHeader), 1, file); | |
@@ -837,24 +737,143 @@ namespace MMAP | |
fwrite(navData, sizeof(unsigned char), navDataSize, file); | |
fclose(file); | |
- // now that tile is written to disk, we can unload it | |
- navMesh->removeTile(tileRef, NULL, NULL); | |
- } | |
- while (0); | |
+ } while (0); | |
- if (m_debugOutput) | |
+ if (true) | |
{ | |
// restore padding so that the debug visualization is correct | |
- for (int i = 0; i < iv.polyMesh->nverts; ++i) | |
+ /*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; | |
+ unsigned short* v = &iv.polyMesh->verts[i * 3]; | |
+ v[0] += (unsigned short)config.borderSize; | |
+ v[2] += (unsigned short)config.borderSize; | |
} | |
iv.generateObjFile(mapID, tileX, tileY, meshData); | |
- iv.writeIV(mapID, tileX, tileY); | |
+ iv.writeIV(mapID, tileX, tileY);*/ | |
} | |
+ | |
+ // free those up | |
+ // we may want to keep them in the future for debug | |
+ // but right now, we don't have the code to merge them | |
+ rcFreeHeightField(tile.solid); | |
+ tile.solid = NULL; | |
+ rcFreeCompactHeightfield(tile.chf); | |
+ tile.chf = NULL; | |
+ rcFreeContourSet(tile.cset); | |
+ tile.cset = NULL; | |
+ } | |
+ | |
+ /**************************************************************************/ | |
+ void MapBuilder::buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, | |
+ MeshData &meshData, float bmin[3], float bmax[3], | |
+ dtNavMesh* navMesh) | |
+ { | |
+ // console output | |
+ char tileString[20]; | |
+ sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY); | |
+ printf("%s Building movemap tiles...\n", tileString); | |
+ | |
+ IntermediateValues iv; | |
+ | |
+ // these are WORLD UNIT based metrics | |
+ // this are basic unit dimentions | |
+ // value have to divide GRID_SIZE(533.3333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) | |
+ const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.5333333f : 0.2666666f; | |
+ | |
+ // All are in UNIT metrics! | |
+ const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f); | |
+ const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP | |
+ const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE; | |
+ | |
+ rcConfig config; | |
+ memset(&config, 0, sizeof(rcConfig)); | |
+ | |
+ rcVcopy(config.bmin, bmin); | |
+ rcVcopy(config.bmax, bmax); | |
+ | |
+ config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; | |
+ config.cs = BASE_UNIT_DIM; | |
+ config.ch = BASE_UNIT_DIM; | |
+ config.walkableSlopeAngle = m_maxWalkableAngle; | |
+ config.tileSize = VERTEX_PER_TILE; | |
+ config.walkableRadius = m_bigBaseUnit ? 1 : 2; | |
+ config.borderSize = config.walkableRadius + 3; | |
+ config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize | |
+ config.walkableHeight = m_bigBaseUnit ? 3 : 6; | |
+ // a value >= 3|6 allows npcs to walk over some fences | |
+ // a value >= 4|8 allows npcs to walk over all fences | |
+ config.walkableClimb = m_bigBaseUnit ? 4 : 8; | |
+ config.minRegionArea = rcSqr(60); | |
+ config.mergeRegionArea = rcSqr(50); | |
+ config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons) | |
+ config.detailSampleDist = config.cs * 64; | |
+ config.detailSampleMaxError = config.ch * 2; | |
+ | |
+ // this sets the dimensions of the heightfield - should maybe happen before border padding | |
+ rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); | |
+ | |
+ // allocate subregions : tiles | |
+ Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; | |
+ | |
+ // 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*[TILES_PER_MAP * TILES_PER_MAP]; | |
+ rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; | |
+ int nmerge = 0; | |
+ // build all tiles | |
+ for (int y = 0; y < TILES_PER_MAP; ++y) | |
+ { | |
+ for (int x = 0; x < TILES_PER_MAP; ++x) | |
+ { | |
+ Tile& tile = tiles[x + y * TILES_PER_MAP]; | |
+ | |
+ // 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; | |
+ | |
+ buildSubTile(m_terrainBuilder->usesLiquids(), bmin, bmax, m_bigBaseUnit, navMesh, tileString, meshData, mapID, x, y, tileX, tileY, tile, tileCfg, config, m_rcContext); | |
+ | |
+ pmmerge[nmerge] = tile.pmesh; | |
+ dmmerge[nmerge] = tile.dmesh; | |
+ nmerge++; | |
+ } | |
+ } | |
+ | |
+ return; | |
+ | |
+ iv.polyMesh = rcAllocPolyMesh(); | |
+ if (!iv.polyMesh) | |
+ { | |
+ printf("%s alloc iv.polyMesh FIALED!\n", tileString); | |
+ delete[] pmmerge; | |
+ delete[] dmmerge; | |
+ delete[] tiles; | |
+ return; | |
+ } | |
+ rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh); | |
+ | |
+ iv.polyMeshDetail = rcAllocPolyMeshDetail(); | |
+ if (!iv.polyMeshDetail) | |
+ { | |
+ printf("%s alloc m_dmesh FIALED!\n", tileString); | |
+ delete[] pmmerge; | |
+ delete[] dmmerge; | |
+ delete[] tiles; | |
+ return; | |
+ } | |
+ rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail); | |
+ | |
+ // free things up | |
+ delete[] pmmerge; | |
+ delete[] dmmerge; | |
+ delete[] tiles; | |
} | |
/**************************************************************************/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment