TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MMAP::MapBuilder Class Reference

#include <MapBuilder.h>

Public Member Functions

 MapBuilder (float maxWalkableAngle=70.f, bool skipLiquid=false, bool skipContinents=false, bool skipJunkMaps=true, bool skipBattlegrounds=false, bool debugOutput=false, bool bigBaseUnit=false, const char *offMeshFilePath=NULL)
 
 ~MapBuilder ()
 
void buildMap (uint32 mapID)
 
void buildMeshFromFile (char *name)
 
void buildSingleTile (uint32 mapID, uint32 tileX, uint32 tileY)
 
void buildAllMaps (int threads)
 
void WorkerThread ()
 

Private Member Functions

void discoverTiles ()
 
std::set< uint32 > * getTileList (uint32 mapID)
 
void buildNavMesh (uint32 mapID, dtNavMesh *&navMesh)
 
void buildTile (uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh *navMesh)
 
void buildMoveMapTile (uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, float bmin[3], float bmax[3], dtNavMesh *navMesh)
 
void getTileBounds (uint32 tileX, uint32 tileY, float *verts, int vertCount, float *bmin, float *bmax)
 
void getGridBounds (uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY)
 
bool shouldSkipMap (uint32 mapID)
 
bool isTransportMap (uint32 mapID)
 
bool shouldSkipTile (uint32 mapID, uint32 tileX, uint32 tileY)
 

Private Attributes

TerrainBuilderm_terrainBuilder
 
TileList m_tiles
 
bool m_debugOutput
 
const char * m_offMeshFilePath
 
bool m_skipContinents
 
bool m_skipJunkMaps
 
bool m_skipBattlegrounds
 
float m_maxWalkableAngle
 
bool m_bigBaseUnit
 
rcContextm_rcContext
 
std::vector< std::thread > _workerThreads
 
ProducerConsumerQueue< uint32_queue
 
std::atomic< bool_cancelationToken
 

Constructor & Destructor Documentation

MMAP::MapBuilder::MapBuilder ( float  maxWalkableAngle = 70.f,
bool  skipLiquid = false,
bool  skipContinents = false,
bool  skipJunkMaps = true,
bool  skipBattlegrounds = false,
bool  debugOutput = false,
bool  bigBaseUnit = false,
const char *  offMeshFilePath = NULL 
)
50  :
52  m_debugOutput (debugOutput),
53  m_offMeshFilePath (offMeshFilePath),
54  m_skipContinents (skipContinents),
55  m_skipJunkMaps (skipJunkMaps),
56  m_skipBattlegrounds (skipBattlegrounds),
57  m_maxWalkableAngle (maxWalkableAngle),
58  m_bigBaseUnit (bigBaseUnit),
59  m_rcContext (NULL),
60  _cancelationToken (false)
61  {
62  m_terrainBuilder = new TerrainBuilder(skipLiquid);
63 
64  m_rcContext = new rcContext(false);
65 
66  discoverTiles();
67  }
Definition: Recast.h:101
bool m_skipBattlegrounds
Definition: MapBuilder.h:137
arena_t NULL
Definition: jemalloc_internal.h:624
bool m_skipContinents
Definition: MapBuilder.h:135
bool m_skipJunkMaps
Definition: MapBuilder.h:136
std::atomic< bool > _cancelationToken
Definition: MapBuilder.h:147
bool m_bigBaseUnit
Definition: MapBuilder.h:140
bool m_debugOutput
Definition: MapBuilder.h:132
float m_maxWalkableAngle
Definition: MapBuilder.h:139
TerrainBuilder * m_terrainBuilder
Definition: MapBuilder.h:129
void discoverTiles()
Definition: MapBuilder.cpp:83
rcContext * m_rcContext
Definition: MapBuilder.h:143
const char * m_offMeshFilePath
Definition: MapBuilder.h:134

+ Here is the call graph for this function:

MMAP::MapBuilder::~MapBuilder ( )
71  {
72  for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
73  {
74  (*it).m_tiles->clear();
75  delete (*it).m_tiles;
76  }
77 
78  delete m_terrainBuilder;
79  delete m_rcContext;
80  }
TileList m_tiles
Definition: MapBuilder.h:130
TerrainBuilder * m_terrainBuilder
Definition: MapBuilder.h:129
rcContext * m_rcContext
Definition: MapBuilder.h:143

Member Function Documentation

void MMAP::MapBuilder::buildAllMaps ( int  threads)
177  {
178  for (int i = 0; i < threads; ++i)
179  {
180  _workerThreads.push_back(std::thread(&MapBuilder::WorkerThread, this));
181  }
182 
183  m_tiles.sort([](MapTiles a, MapTiles b)
184  {
185  return a.m_tiles->size() > b.m_tiles->size();
186  });
187 
188  for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
189  {
190  uint32 mapId = it->m_mapId;
191  if (!shouldSkipMap(mapId))
192  {
193  if (threads > 0)
194  _queue.Push(mapId);
195  else
196  buildMap(mapId);
197  }
198  }
199 
200  while (!_queue.Empty())
201  {
202  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
203  }
204 
205  _cancelationToken = true;
206 
207  _queue.Cancel();
208 
209  for (auto& thread : _workerThreads)
210  {
211  thread.join();
212  }
213  }
TileList m_tiles
Definition: MapBuilder.h:130
void buildMap(uint32 mapID)
Definition: MapBuilder.cpp:359
bool shouldSkipMap(uint32 mapID)
Definition: MapBuilder.cpp:889
std::atomic< bool > _cancelationToken
Definition: MapBuilder.h:147
uint32_t uint32
Definition: Define.h:150
float milliseconds()
Definition: units.h:92
void Push(const T &value)
Definition: ProducerConsumerQueue.h:40
void WorkerThread()
Definition: MapBuilder.cpp:161
std::vector< std::thread > _workerThreads
Definition: MapBuilder.h:145
void Cancel()
Definition: ProducerConsumerQueue.h:86
ProducerConsumerQueue< uint32 > _queue
Definition: MapBuilder.h:146
bool Empty()
Definition: ProducerConsumerQueue.h:48

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildMap ( uint32  mapID)
360  {
361 #ifndef __APPLE__
362  //printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID);
363 #endif
364 
365  std::set<uint32>* tiles = getTileList(mapID);
366 
367  // make sure we process maps which don't have tiles
368  if (!tiles->size())
369  {
370  // convert coord bounds to grid bounds
371  uint32 minX, minY, maxX, maxY;
372  getGridBounds(mapID, minX, minY, maxX, maxY);
373 
374  // add all tiles within bounds to tile list.
375  for (uint32 i = minX; i <= maxX; ++i)
376  for (uint32 j = minY; j <= maxY; ++j)
377  tiles->insert(StaticMapTree::packTileID(i, j));
378  }
379 
380  if (!tiles->empty())
381  {
382  // build navMesh
383  dtNavMesh* navMesh = NULL;
384  buildNavMesh(mapID, navMesh);
385  if (!navMesh)
386  {
387  printf("[Map %04i] Failed creating navmesh!\n", mapID);
388  return;
389  }
390 
391  // now start building mmtiles for each tile
392  printf("[Map %04i] We have %u tiles. \n", mapID, (unsigned int)tiles->size());
393  for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it)
394  {
395  uint32 tileX, tileY;
396 
397  // unpack tile coords
398  StaticMapTree::unpackTileID((*it), tileX, tileY);
399 
400  if (shouldSkipTile(mapID, tileX, tileY))
401  continue;
402 
403  buildTile(mapID, tileX, tileY, navMesh);
404  }
405 
406  dtFreeNavMesh(navMesh);
407  }
408 
409  printf("[Map %04u] Complete!\n", mapID);
410  }
arena_t NULL
Definition: jemalloc_internal.h:624
void dtFreeNavMesh(dtNavMesh *navmesh)
Definition: DetourNavMesh.cpp:149
Definition: DetourNavMesh.h:323
void buildNavMesh(uint32 mapID, dtNavMesh *&navMesh)
Definition: MapBuilder.cpp:452
uint32_t uint32
Definition: Define.h:150
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY)
Definition: MapBuilder.cpp:1022
std::set< uint32 > * getTileList(uint32 mapID)
Definition: MapBuilder.cpp:148
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh *navMesh)
Definition: MapBuilder.cpp:413
void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY)
Definition: MapBuilder.cpp:216
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildMeshFromFile ( char *  name)
259  {
260  FILE* file = fopen(name, "rb");
261  if (!file)
262  return;
263 
264  printf("Building mesh from file\n");
265  int tileX, tileY, mapId;
266  if (fread(&mapId, sizeof(int), 1, file) != 1)
267  {
268  fclose(file);
269  return;
270  }
271  if (fread(&tileX, sizeof(int), 1, file) != 1)
272  {
273  fclose(file);
274  return;
275  }
276  if (fread(&tileY, sizeof(int), 1, file) != 1)
277  {
278  fclose(file);
279  return;
280  }
281 
282  dtNavMesh* navMesh = NULL;
283  buildNavMesh(mapId, navMesh);
284  if (!navMesh)
285  {
286  printf("Failed creating navmesh! \n");
287  fclose(file);
288  return;
289  }
290 
291  uint32 verticesCount, indicesCount;
292  if (fread(&verticesCount, sizeof(uint32), 1, file) != 1)
293  {
294  fclose(file);
295  return;
296  }
297 
298  if (fread(&indicesCount, sizeof(uint32), 1, file) != 1)
299  {
300  fclose(file);
301  return;
302  }
303 
304  float* verts = new float[verticesCount];
305  int* inds = new int[indicesCount];
306 
307  if (fread(verts, sizeof(float), verticesCount, file) != verticesCount)
308  {
309  fclose(file);
310  delete[] verts;
311  delete[] inds;
312  return;
313  }
314 
315  if (fread(inds, sizeof(int), indicesCount, file) != indicesCount)
316  {
317  fclose(file);
318  delete[] verts;
319  delete[] inds;
320  return;
321  }
322 
323  MeshData data;
324 
325  for (uint32 i = 0; i < verticesCount; ++i)
326  data.solidVerts.append(verts[i]);
327  delete[] verts;
328 
329  for (uint32 i = 0; i < indicesCount; ++i)
330  data.solidTris.append(inds[i]);
331  delete[] inds;
332 
333  TerrainBuilder::cleanVertices(data.solidVerts, data.solidTris);
334  // get bounds of current tile
335  float bmin[3], bmax[3];
336  getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax);
337 
338  // build navmesh tile
339  buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh);
340  fclose(file);
341  }
void buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, float bmin[3], float bmax[3], dtNavMesh *navMesh)
Definition: MapBuilder.cpp:527
static void cleanVertices(G3D::Array< float > &verts, G3D::Array< int > &tris)
Definition: TerrainBuilder.cpp:838
arena_t NULL
Definition: jemalloc_internal.h:624
Definition: DetourNavMesh.h:323
void buildNavMesh(uint32 mapID, dtNavMesh *&navMesh)
Definition: MapBuilder.cpp:452
uint32_t uint32
Definition: Define.h:150
void getTileBounds(uint32 tileX, uint32 tileY, float *verts, int vertCount, float *bmin, float *bmax)
Definition: MapBuilder.cpp:870
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildMoveMapTile ( uint32  mapID,
uint32  tileX,
uint32  tileY,
MeshData meshData,
float  bmin[3],
float  bmax[3],
dtNavMesh navMesh 
)
private
530  {
531  // console output
532  std::string tileString = Trinity::StringFormat("[Map %04u] [%02i,%02i]: ", mapID, tileX, tileY);
533  printf("%s Building movemap tiles...\n", tileString.c_str());
534 
535  IntermediateValues iv;
536 
537  float* tVerts = meshData.solidVerts.getCArray();
538  int tVertCount = meshData.solidVerts.size() / 3;
539  int* tTris = meshData.solidTris.getCArray();
540  int tTriCount = meshData.solidTris.size() / 3;
541 
542  float* lVerts = meshData.liquidVerts.getCArray();
543  int lVertCount = meshData.liquidVerts.size() / 3;
544  int* lTris = meshData.liquidTris.getCArray();
545  int lTriCount = meshData.liquidTris.size() / 3;
546  uint8* lTriFlags = meshData.liquidType.getCArray();
547 
548  // these are WORLD UNIT based metrics
549  // this are basic unit dimentions
550  // value have to divide GRID_SIZE(533.3333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc )
551  const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.5333333f : 0.2666666f;
552 
553  // All are in UNIT metrics!
554  const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f);
555  const static int VERTEX_PER_TILE = m_bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP
556  const static int TILES_PER_MAP = VERTEX_PER_MAP/VERTEX_PER_TILE;
557 
558  rcConfig config;
559  memset(&config, 0, sizeof(rcConfig));
560 
561  rcVcopy(config.bmin, bmin);
562  rcVcopy(config.bmax, bmax);
563 
565  config.cs = BASE_UNIT_DIM;
566  config.ch = BASE_UNIT_DIM;
568  config.tileSize = VERTEX_PER_TILE;
569  config.walkableRadius = m_bigBaseUnit ? 1 : 2;
570  config.borderSize = config.walkableRadius + 3;
571  config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize
572  config.walkableHeight = m_bigBaseUnit ? 3 : 6;
573  // a value >= 3|6 allows npcs to walk over some fences
574  // a value >= 4|8 allows npcs to walk over all fences
575  config.walkableClimb = m_bigBaseUnit ? 4 : 8;
576  config.minRegionArea = rcSqr(60);
577  config.mergeRegionArea = rcSqr(50);
578  config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons)
579  config.detailSampleDist = config.cs * 64;
580  config.detailSampleMaxError = config.ch * 2;
581 
582  // this sets the dimensions of the heightfield - should maybe happen before border padding
583  rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
584 
585  // allocate subregions : tiles
586  Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP];
587 
588  // Initialize per tile config.
589  rcConfig tileCfg = config;
590  tileCfg.width = config.tileSize + config.borderSize*2;
591  tileCfg.height = config.tileSize + config.borderSize*2;
592 
593  // merge per tile poly and detail meshes
594  rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP];
595  rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP];
596  int nmerge = 0;
597  // build all tiles
598  for (int y = 0; y < TILES_PER_MAP; ++y)
599  {
600  for (int x = 0; x < TILES_PER_MAP; ++x)
601  {
602  Tile& tile = tiles[x + y * TILES_PER_MAP];
603 
604  // Calculate the per tile bounding box.
605  tileCfg.bmin[0] = config.bmin[0] + float(x*config.tileSize - config.borderSize)*config.cs;
606  tileCfg.bmin[2] = config.bmin[2] + float(y*config.tileSize - config.borderSize)*config.cs;
607  tileCfg.bmax[0] = config.bmin[0] + float((x+1)*config.tileSize + config.borderSize)*config.cs;
608  tileCfg.bmax[2] = config.bmin[2] + float((y+1)*config.tileSize + config.borderSize)*config.cs;
609 
610  // build heightfield
611  tile.solid = rcAllocHeightfield();
612  if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
613  {
614  printf("%s Failed building heightfield! \n", tileString.c_str());
615  continue;
616  }
617 
618  // mark all walkable tiles, both liquids and solids
619  unsigned char* triFlags = new unsigned char[tTriCount];
620  memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char));
621  rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags);
622  rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb);
623  delete[] triFlags;
624 
626  rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
628 
629  rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb);
630 
631  // compact heightfield spans
632  tile.chf = rcAllocCompactHeightfield();
633  if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf))
634  {
635  printf("%s Failed compacting heightfield! \n", tileString.c_str());
636  continue;
637  }
638 
639  // build polymesh intermediates
640  if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf))
641  {
642  printf("%s Failed eroding area! \n", tileString.c_str());
643  continue;
644  }
645 
646  if (!rcBuildDistanceField(m_rcContext, *tile.chf))
647  {
648  printf("%s Failed building distance field! \n", tileString.c_str());
649  continue;
650  }
651 
652  if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea))
653  {
654  printf("%s Failed building regions! \n", tileString.c_str());
655  continue;
656  }
657 
658  tile.cset = rcAllocContourSet();
659  if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset))
660  {
661  printf("%s Failed building contours! \n", tileString.c_str());
662  continue;
663  }
664 
665  // build polymesh
666  tile.pmesh = rcAllocPolyMesh();
667  if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh))
668  {
669  printf("%s Failed building polymesh! \n", tileString.c_str());
670  continue;
671  }
672 
673  tile.dmesh = rcAllocPolyMeshDetail();
674  if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh))
675  {
676  printf("%s Failed building polymesh detail! \n", tileString.c_str());
677  continue;
678  }
679 
680  // free those up
681  // we may want to keep them in the future for debug
682  // but right now, we don't have the code to merge them
683  rcFreeHeightField(tile.solid);
684  tile.solid = NULL;
685  rcFreeCompactHeightfield(tile.chf);
686  tile.chf = NULL;
687  rcFreeContourSet(tile.cset);
688  tile.cset = NULL;
689 
690  pmmerge[nmerge] = tile.pmesh;
691  dmmerge[nmerge] = tile.dmesh;
692  nmerge++;
693  }
694  }
695 
696  iv.polyMesh = rcAllocPolyMesh();
697  if (!iv.polyMesh)
698  {
699  printf("%s alloc iv.polyMesh FAILED!\n", tileString.c_str());
700  delete[] pmmerge;
701  delete[] dmmerge;
702  delete[] tiles;
703  return;
704  }
705  rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh);
706 
707  iv.polyMeshDetail = rcAllocPolyMeshDetail();
708  if (!iv.polyMeshDetail)
709  {
710  printf("%s alloc m_dmesh FAILED!\n", tileString.c_str());
711  delete[] pmmerge;
712  delete[] dmmerge;
713  delete[] tiles;
714  return;
715  }
716  rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail);
717 
718  // free things up
719  delete[] pmmerge;
720  delete[] dmmerge;
721  delete[] tiles;
722 
723  // set polygons as walkable
724  // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off
725  for (int i = 0; i < iv.polyMesh->npolys; ++i)
726  if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
727  iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
728 
729  // setup mesh parameters
731  memset(&params, 0, sizeof(params));
732  params.verts = iv.polyMesh->verts;
733  params.vertCount = iv.polyMesh->nverts;
734  params.polys = iv.polyMesh->polys;
735  params.polyAreas = iv.polyMesh->areas;
736  params.polyFlags = iv.polyMesh->flags;
737  params.polyCount = iv.polyMesh->npolys;
738  params.nvp = iv.polyMesh->nvp;
739  params.detailMeshes = iv.polyMeshDetail->meshes;
740  params.detailVerts = iv.polyMeshDetail->verts;
741  params.detailVertsCount = iv.polyMeshDetail->nverts;
742  params.detailTris = iv.polyMeshDetail->tris;
743  params.detailTriCount = iv.polyMeshDetail->ntris;
744 
745  params.offMeshConVerts = meshData.offMeshConnections.getCArray();
746  params.offMeshConCount = meshData.offMeshConnections.size()/6;
747  params.offMeshConRad = meshData.offMeshConnectionRads.getCArray();
748  params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray();
749  params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray();
750  params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray();
751 
752  params.walkableHeight = BASE_UNIT_DIM*config.walkableHeight; // agent height
753  params.walkableRadius = BASE_UNIT_DIM*config.walkableRadius; // agent radius
754  params.walkableClimb = BASE_UNIT_DIM*config.walkableClimb; // keep less that walkableHeight (aka agent height)!
755  params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE;
756  params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE;
757  rcVcopy(params.bmin, bmin);
758  rcVcopy(params.bmax, bmax);
759  params.cs = config.cs;
760  params.ch = config.ch;
761  params.tileLayer = 0;
762  params.buildBvTree = true;
763 
764  // will hold final navmesh
765  unsigned char* navData = NULL;
766  int navDataSize = 0;
767 
768  do
769  {
770  // these values are checked within dtCreateNavMeshData - handle them here
771  // so we have a clear error message
772  if (params.nvp > DT_VERTS_PER_POLYGON)
773  {
774  printf("%s Invalid verts-per-polygon value! \n", tileString.c_str());
775  break;
776  }
777  if (params.vertCount >= 0xffff)
778  {
779  printf("%s Too many vertices! \n", tileString.c_str());
780  break;
781  }
782  if (!params.vertCount || !params.verts)
783  {
784  // occurs mostly when adjacent tiles have models
785  // loaded but those models don't span into this tile
786 
787  // message is an annoyance
788  //printf("%sNo vertices to build tile! \n", tileString.c_str());
789  break;
790  }
791  if (!params.polyCount || !params.polys ||
792  TILES_PER_MAP*TILES_PER_MAP == params.polyCount)
793  {
794  // we have flat tiles with no actual geometry - don't build those, its useless
795  // keep in mind that we do output those into debug info
796  // drop tiles with only exact count - some tiles may have geometry while having less tiles
797  printf("%s No polygons to build on tile! \n", tileString.c_str());
798  break;
799  }
800  if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
801  {
802  printf("%s No detail mesh to build tile! \n", tileString.c_str());
803  break;
804  }
805 
806  printf("%s Building navmesh tile...\n", tileString.c_str());
807  if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
808  {
809  printf("%s Failed building navmesh tile! \n", tileString.c_str());
810  break;
811  }
812 
813  dtTileRef tileRef = 0;
814  printf("%s Adding tile to navmesh...\n", tileString.c_str());
815  // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
816  // is removed via removeTile()
817  dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
818  if (!tileRef || dtResult != DT_SUCCESS)
819  {
820  printf("%s Failed adding tile to navmesh! \n", tileString.c_str());
821  break;
822  }
823 
824  // file output
825  char fileName[255];
826  sprintf(fileName, "mmaps/%04u%02i%02i.mmtile", mapID, tileY, tileX);
827  FILE* file = fopen(fileName, "wb");
828  if (!file)
829  {
830  char message[1024];
831  sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
832  perror(message);
833  navMesh->removeTile(tileRef, NULL, NULL);
834  break;
835  }
836 
837  printf("%s Writing to file...\n", tileString.c_str());
838 
839  // write header
840  MmapTileHeader header;
842  header.size = uint32(navDataSize);
843  fwrite(&header, sizeof(MmapTileHeader), 1, file);
844 
845  // write data
846  fwrite(navData, sizeof(unsigned char), navDataSize, file);
847  fclose(file);
848 
849  // now that tile is written to disk, we can unload it
850  navMesh->removeTile(tileRef, NULL, NULL);
851  }
852  while (0);
853 
854  if (m_debugOutput)
855  {
856  // restore padding so that the debug visualization is correct
857  for (int i = 0; i < iv.polyMesh->nverts; ++i)
858  {
859  unsigned short* v = &iv.polyMesh->verts[i*3];
860  v[0] += (unsigned short)config.borderSize;
861  v[2] += (unsigned short)config.borderSize;
862  }
863 
864  iv.generateObjFile(mapID, tileX, tileY, meshData);
865  iv.writeIV(mapID, tileX, tileY);
866  }
867  }
bool rcBuildPolyMeshDetail(rcContext *ctx, const rcPolyMesh &mesh, const rcCompactHeightfield &chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail &dmesh)
Definition: RecastMeshDetail.cpp:1117
int tileLayer
The tile's layer within the layered destination mesh. Limit: >= 0
Definition: DetourNavMeshBuilder.h:86
The navigation mesh owns the tile memory and is responsible for freeing it.
Definition: DetourNavMesh.h:104
bool usesLiquids()
Definition: TerrainBuilder.h:88
rcCompactHeightfield * rcAllocCompactHeightfield()
Definition: Recast.cpp:95
float detailSampleMaxError
Definition: Recast.h:242
void rcFreeCompactHeightfield(rcCompactHeightfield *chf)
Definition: Recast.cpp:102
float cs
The xz-plane cell size of the polygon mesh. [Limit: > 0] [Unit: wu].
Definition: DetourNavMeshBuilder.h:97
uint64_d dtTileRef
Definition: DetourNavMesh.h:53
Definition: MapDefines.h:25
const unsigned char * offMeshConDir
Definition: DetourNavMeshBuilder.h:72
int walkableRadius
Definition: Recast.h:216
const unsigned char * polyAreas
The user defined area ids assigned to each polygon. [Size: polyCount].
Definition: DetourNavMeshBuilder.h:38
const float * offMeshConVerts
Off-mesh connection vertices. [(ax, ay, az, bx, by, bz) * offMeshConCount] [Unit: wu]...
Definition: DetourNavMeshBuilder.h:61
const unsigned short * polys
The polygon data. [Size: polyCount * 2 * nvp].
Definition: DetourNavMeshBuilder.h:36
float bmin[3]
The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu].
Definition: Recast.h:199
int nvp
Number maximum number of vertices per polygon. [Limit: >= 3].
Definition: DetourNavMeshBuilder.h:40
bool rcCreateHeightfield(rcContext *ctx, rcHeightfield &hf, int width, int height, const float *bmin, const float *bmax, float cs, float ch)
Definition: Recast.cpp:211
int tileSize
The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx].
Definition: Recast.h:187
float orig[3]
The world space origin of the navigation mesh's tile space. [(x, y, z)].
Definition: DetourNavMesh.h:314
float walkableHeight
The agent height. [Unit: wu].
Definition: DetourNavMeshBuilder.h:94
Definition: DetourNavMeshBuilder.h:26
const unsigned char * detailTris
The detail mesh triangles. [Size: 4 * detailTriCount].
Definition: DetourNavMeshBuilder.h:50
float ch
The y-axis cell height of the polygon mesh. [Limit: > 0] [Unit: wu].
Definition: DetourNavMeshBuilder.h:98
int walkableClimb
Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx]...
Definition: Recast.h:212
const dtNavMeshParams * getParams() const
The navigation mesh initialization params.
Definition: DetourNavMesh.cpp:286
Definition: Recast.h:178
static const unsigned int DT_SUCCESS
Definition: DetourStatus.h:26
float bmax[3]
The maximum bounds of the tile. [(x, y, z)] [Unit: wu].
Definition: DetourNavMeshBuilder.h:88
arena_t NULL
Definition: jemalloc_internal.h:624
dtStatus addTile(unsigned char *data, int dataSize, int flags, dtTileRef lastRef, dtTileRef *result)
Definition: DetourNavMesh.cpp:834
int mergeRegionArea
Definition: Recast.h:230
bool rcMergePolyMeshes(rcContext *ctx, rcPolyMesh **meshes, const int nmeshes, rcPolyMesh &mesh)
Definition: RecastMesh.cpp:1302
void rcFreeHeightField(rcHeightfield *hf)
Definition: Recast.cpp:80
float walkableClimb
The agent maximum traversable ledge. (Up/Down) [Unit: wu].
Definition: DetourNavMeshBuilder.h:96
int borderSize
The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]...
Definition: Recast.h:190
void rcFilterLedgeSpans(rcContext *ctx, const int walkableHeight, const int walkableClimb, rcHeightfield &solid)
Definition: RecastFilter.cpp:84
float detailSampleDist
Definition: Recast.h:238
void rcCalcGridSize(const float *bmin, const float *bmax, float cs, int *w, int *h)
Definition: Recast.cpp:200
unsigned int dtStatus
Definition: DetourStatus.h:22
int maxEdgeLen
The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx]...
Definition: Recast.h:219
void rcFilterLowHangingWalkableObstacles(rcContext *ctx, const int walkableClimb, rcHeightfield &solid)
Definition: RecastFilter.cpp:36
void rcFilterWalkableLowHeightSpans(rcContext *ctx, int walkableHeight, rcHeightfield &solid)
Definition: RecastFilter.cpp:180
int walkableHeight
Definition: Recast.h:209
const unsigned short * offMeshConFlags
User defined flags assigned to the off-mesh connections. [Size: offMeshConCount]. ...
Definition: DetourNavMeshBuilder.h:65
rcContourSet * rcAllocContourSet()
Definition: Recast.cpp:134
bool buildBvTree
Definition: DetourNavMeshBuilder.h:102
int detailTriCount
The number of triangles in the detail mesh.
Definition: DetourNavMeshBuilder.h:51
float maxSimplificationError
Definition: Recast.h:223
int offMeshConCount
The number of off-mesh connections. [Limit: >= 0].
Definition: DetourNavMeshBuilder.h:76
float ch
The y-axis cell size to use for fields. [Limit: > 0] [Units: wu].
Definition: Recast.h:196
std::string sprintf(CStringRef format, ArgList args)
Definition: format.h:3096
Definition: Recast.h:383
rcPolyMeshDetail * rcAllocPolyMeshDetail()
Definition: Recast.cpp:171
rcHeightfield * rcAllocHeightfield()
Definition: Recast.cpp:73
bool dtCreateNavMeshData(dtNavMeshCreateParams *params, unsigned char **outData, int *outDataSize)
Definition: DetourNavMeshBuilder.cpp:254
const unsigned short * verts
The polygon mesh vertices. [(x, y, z) * vertCount] [Unit: vx].
Definition: DetourNavMeshBuilder.h:34
float bmin[3]
The minimum bounds of the tile. [(x, y, z)] [Unit: wu].
Definition: DetourNavMeshBuilder.h:87
static const unsigned char RC_WALKABLE_AREA
Definition: Recast.h:543
bool m_bigBaseUnit
Definition: MapBuilder.h:140
G3D::int16 y
Definition: Vector2int16.h:38
int maxVertsPerPoly
Definition: Recast.h:234
void rcClearUnwalkableTriangles(rcContext *ctx, const float walkableSlopeAngle, const float *verts, int nv, const int *tris, int nt, unsigned char *areas)
Definition: Recast.cpp:276
bool m_debugOutput
Definition: MapBuilder.h:132
void rcVcopy(float *dest, const float *v)
Definition: Recast.h:677
float bmax[3]
The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu].
Definition: Recast.h:202
float walkableRadius
The agent radius. [Unit: wu].
Definition: DetourNavMeshBuilder.h:95
float m_maxWalkableAngle
Definition: MapBuilder.h:139
float walkableSlopeAngle
The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees].
Definition: Recast.h:205
rcPolyMesh * rcAllocPolyMesh()
Definition: Recast.cpp:153
const float * detailVerts
The detail mesh vertices. [Size: 3 * detailVertsCount] [Unit: wu].
Definition: DetourNavMeshBuilder.h:48
bool rcErodeWalkableArea(rcContext *ctx, int radius, rcCompactHeightfield &chf)
Definition: RecastArea.cpp:37
Definition: MapDefines.h:10
T rcSqr(T a)
Definition: Recast.h:582
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
TerrainBuilder * m_terrainBuilder
Definition: MapBuilder.h:129
int tileY
The tile's y-grid location within the multi-tile desitation mesh. (Along the z-axis.)
Definition: DetourNavMeshBuilder.h:85
int polyCount
Number of polygons in the mesh. [Limit: >= 1].
Definition: DetourNavMeshBuilder.h:39
int height
The height of the field along the z-axis. [Limit: >= 0] [Units: vx].
Definition: Recast.h:184
float cs
The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu].
Definition: Recast.h:193
const unsigned int * detailMeshes
The height detail sub-mesh data. [Size: 4 * polyCount].
Definition: DetourNavMeshBuilder.h:47
bool rcBuildDistanceField(rcContext *ctx, rcCompactHeightfield &chf)
Definition: RecastRegion.cpp:1256
bool rcBuildRegions(rcContext *ctx, rcCompactHeightfield &chf, const int borderSize, const int minRegionArea, const int mergeRegionArea)
Definition: RecastRegion.cpp:1532
void rcRasterizeTriangles(rcContext *ctx, const float *verts, const int nv, const int *tris, const unsigned char *areas, const int nt, rcHeightfield &solid, const int flagMergeThr=1)
Definition: RecastRasterization.cpp:348
int tileX
The tile's x-grid location within the multi-tile destination mesh. (Along the x-axis.)
Definition: DetourNavMeshBuilder.h:84
rcContext * m_rcContext
Definition: MapBuilder.h:143
uint8_t uint8
Definition: Define.h:152
const unsigned short * polyFlags
The user defined flags assigned to each polygon. [Size: polyCount].
Definition: DetourNavMeshBuilder.h:37
bool usesLiquids
Definition: MapDefines.h:16
int vertCount
The number vertices in the polygon mesh. [Limit: >= 3].
Definition: DetourNavMeshBuilder.h:35
uint32_t uint32
Definition: g3dmath.h:168
G3D::int16 x
Definition: Vector2int16.h:37
const float * offMeshConRad
Off-mesh connection radii. [Size: offMeshConCount] [Unit: wu].
Definition: DetourNavMeshBuilder.h:63
bool rcBuildContours(rcContext *ctx, rcCompactHeightfield &chf, const float maxError, const int maxEdgeLen, rcContourSet &cset, const int buildFlags=RC_CONTOUR_TESS_WALL_EDGES)
Definition: RecastContour.cpp:824
int minRegionArea
The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx]...
Definition: Recast.h:226
std::set< uint32 > params[2]
Definition: DisableMgr.cpp:45
dtStatus removeTile(dtTileRef ref, unsigned char **data, int *dataSize)
Definition: DetourNavMesh.cpp:1156
static const float GRID_SIZE
Definition: TerrainBuilder.h:50
int detailVertsCount
The number of vertices in the detail mesh.
Definition: DetourNavMeshBuilder.h:49
bool rcBuildPolyMesh(rcContext *ctx, rcContourSet &cset, const int nvp, rcPolyMesh &mesh)
Definition: RecastMesh.cpp:982
int width
The width of the field along the x-axis. [Limit: >= 0] [Units: vx].
Definition: Recast.h:181
Definition: Recast.h:404
bool rcMergePolyMeshDetails(rcContext *ctx, rcPolyMeshDetail **meshes, const int nmeshes, rcPolyMeshDetail &mesh)
Definition: RecastMeshDetail.cpp:1336
const unsigned char * offMeshConAreas
User defined area ids assigned to the off-mesh connections. [Size: offMeshConCount].
Definition: DetourNavMeshBuilder.h:67
static const int DT_VERTS_PER_POLYGON
Definition: DetourNavMesh.h:57
void rcFreeContourSet(rcContourSet *cset)
Definition: Recast.cpp:141
bool rcBuildCompactHeightfield(rcContext *ctx, const int walkableHeight, const int walkableClimb, rcHeightfield &hf, rcCompactHeightfield &chf)
Definition: Recast.cpp:327
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildNavMesh ( uint32  mapID,
dtNavMesh *&  navMesh 
)
private

*** calculate number of bits needed to store tiles & polys ***/

453  {
454  std::set<uint32>* tiles = getTileList(mapID);
455 
456  // old code for non-statically assigned bitmask sizes:
458  //int tileBits = dtIlog2(dtNextPow2(tiles->size()));
459  //if (tileBits < 1) tileBits = 1; // need at least one bit!
460  //int polyBits = sizeof(dtPolyRef)*8 - SALT_MIN_BITS - tileBits;
461 
462  int polyBits = STATIC_POLY_BITS;
463 
464  int maxTiles = tiles->size();
465  int maxPolysPerTile = 1 << polyBits;
466 
467  /*** calculate bounds of map ***/
468 
469  uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY;
470  for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it)
471  {
472  StaticMapTree::unpackTileID(*it, tileX, tileY);
473 
474  if (tileX > tileXMax)
475  tileXMax = tileX;
476  else if (tileX < tileXMin)
477  tileXMin = tileX;
478 
479  if (tileY > tileYMax)
480  tileYMax = tileY;
481  else if (tileY < tileYMin)
482  tileYMin = tileY;
483  }
484 
485  // use Max because '32 - tileX' is negative for values over 32
486  float bmin[3], bmax[3];
487  getTileBounds(tileXMax, tileYMax, NULL, 0, bmin, bmax);
488 
489  /*** now create the navmesh ***/
490 
491  // navmesh creation params
492  dtNavMeshParams navMeshParams;
493  memset(&navMeshParams, 0, sizeof(dtNavMeshParams));
494  navMeshParams.tileWidth = GRID_SIZE;
495  navMeshParams.tileHeight = GRID_SIZE;
496  rcVcopy(navMeshParams.orig, bmin);
497  navMeshParams.maxTiles = maxTiles;
498  navMeshParams.maxPolys = maxPolysPerTile;
499 
500  navMesh = dtAllocNavMesh();
501  printf("[Map %04u] Creating navMesh...\n", mapID);
502  if (!navMesh->init(&navMeshParams))
503  {
504  printf("[Map %04u] Failed creating navmesh! \n", mapID);
505  return;
506  }
507 
508  char fileName[25];
509  sprintf(fileName, "mmaps/%04u.mmap", mapID);
510 
511  FILE* file = fopen(fileName, "wb");
512  if (!file)
513  {
514  dtFreeNavMesh(navMesh);
515  char message[1024];
516  sprintf(message, "[Map %04u] Failed to open %s for writing!\n", mapID, fileName);
517  perror(message);
518  return;
519  }
520 
521  // now that we know navMesh params are valid, we can write them to file
522  fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file);
523  fclose(file);
524  }
dtStatus init(const dtNavMeshParams *params)
Definition: DetourNavMesh.cpp:222
float orig[3]
The world space origin of the navigation mesh's tile space. [(x, y, z)].
Definition: DetourNavMesh.h:314
static const int STATIC_POLY_BITS
Definition: DetourNavMesh.h:95
arena_t NULL
Definition: jemalloc_internal.h:624
void dtFreeNavMesh(dtNavMesh *navmesh)
Definition: DetourNavMesh.cpp:149
std::string sprintf(CStringRef format, ArgList args)
Definition: format.h:3096
uint32_t uint32
Definition: Define.h:150
void getTileBounds(uint32 tileX, uint32 tileY, float *verts, int vertCount, float *bmin, float *bmax)
Definition: MapBuilder.cpp:870
void rcVcopy(float *dest, const float *v)
Definition: Recast.h:677
int maxPolys
The maximum number of polygons each tile can contain.
Definition: DetourNavMesh.h:318
float tileWidth
The width of each tile. (Along the x-axis.)
Definition: DetourNavMesh.h:315
std::set< uint32 > * getTileList(uint32 mapID)
Definition: MapBuilder.cpp:148
Definition: DetourNavMesh.h:312
dtNavMesh * dtAllocNavMesh()
Definition: DetourNavMesh.cpp:138
float tileHeight
The height of each tile. (Along the z-axis.)
Definition: DetourNavMesh.h:316
int maxTiles
The maximum number of tiles the navigation mesh can contain.
Definition: DetourNavMesh.h:317
static const float GRID_SIZE
Definition: TerrainBuilder.h:50
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildSingleTile ( uint32  mapID,
uint32  tileX,
uint32  tileY 
)
345  {
346  dtNavMesh* navMesh = NULL;
347  buildNavMesh(mapID, navMesh);
348  if (!navMesh)
349  {
350  printf("Failed creating navmesh! \n");
351  return;
352  }
353 
354  buildTile(mapID, tileX, tileY, navMesh);
355  dtFreeNavMesh(navMesh);
356  }
arena_t NULL
Definition: jemalloc_internal.h:624
void dtFreeNavMesh(dtNavMesh *navmesh)
Definition: DetourNavMesh.cpp:149
Definition: DetourNavMesh.h:323
void buildNavMesh(uint32 mapID, dtNavMesh *&navMesh)
Definition: MapBuilder.cpp:452
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh *navMesh)
Definition: MapBuilder.cpp:413
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::buildTile ( uint32  mapID,
uint32  tileX,
uint32  tileY,
dtNavMesh navMesh 
)
private
414  {
415  printf("[Map %04i] Building tile [%02u,%02u]\n", mapID, tileX, tileY);
416 
417  MeshData meshData;
418 
419  // get heightmap data
420  m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData);
421 
422  // get model data
423  m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData);
424 
425  // if there is no data, give up now
426  if (!meshData.solidVerts.size() && !meshData.liquidVerts.size())
427  return;
428 
429  // remove unused vertices
430  TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris);
431  TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris);
432 
433  // gather all mesh data for final data check, and bounds calculation
434  G3D::Array<float> allVerts;
435  allVerts.append(meshData.liquidVerts);
436  allVerts.append(meshData.solidVerts);
437 
438  if (!allVerts.size())
439  return;
440 
441  // get bounds of current tile
442  float bmin[3], bmax[3];
443  getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax);
444 
445  m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_offMeshFilePath);
446 
447  // build navmesh tile
448  buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh);
449  }
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
Definition: TerrainBuilder.cpp:122
void buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, float bmin[3], float bmax[3], dtNavMesh *navMesh)
Definition: MapBuilder.cpp:527
static void cleanVertices(G3D::Array< float > &verts, G3D::Array< int > &tris)
Definition: TerrainBuilder.cpp:838
T * getCArray()
Definition: Array.h:256
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
Definition: TerrainBuilder.cpp:627
void getTileBounds(uint32 tileX, uint32 tileY, float *verts, int vertCount, float *bmin, float *bmax)
Definition: MapBuilder.cpp:870
int size() const
Definition: Array.h:430
TerrainBuilder * m_terrainBuilder
Definition: MapBuilder.h:129
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, const char *offMeshFilePath)
Definition: TerrainBuilder.cpp:881
void append(const T &value)
Definition: Array.h:583
const char * m_offMeshFilePath
Definition: MapBuilder.h:134
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::discoverTiles ( )
private
84  {
85  std::vector<std::string> files;
86  uint32 mapID, tileX, tileY, tileID, count = 0;
87 
88  printf("Discovering maps... ");
89  getDirContents(files, "maps");
90  for (uint32 i = 0; i < files.size(); ++i)
91  {
92  mapID = uint32(atoi(files[i].substr(0, 4).c_str()));
93  if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end())
94  {
95  m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>));
96  count++;
97  }
98  }
99 
100  files.clear();
101  getDirContents(files, "vmaps", "*.vmtree");
102  for (uint32 i = 0; i < files.size(); ++i)
103  {
104  mapID = uint32(atoi(files[i].substr(0, 4).c_str()));
105  if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end())
106  {
107  m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>));
108  count++;
109  }
110  }
111  printf("found %u.\n", count);
112 
113  count = 0;
114  printf("Discovering tiles... ");
115  for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr)
116  {
117  std::set<uint32>* tiles = (*itr).m_tiles;
118  mapID = (*itr).m_mapId;
119 
120  files.clear();
121  getDirContents(files, "vmaps", Trinity::StringFormat("%04u*.vmtile", mapID));
122  for (uint32 i = 0; i < files.size(); ++i)
123  {
124  tileX = uint32(atoi(files[i].substr(8, 2).c_str()));
125  tileY = uint32(atoi(files[i].substr(5, 2).c_str()));
126  tileID = StaticMapTree::packTileID(tileY, tileX);
127 
128  tiles->insert(tileID);
129  count++;
130  }
131 
132  files.clear();
133  getDirContents(files, "maps", Trinity::StringFormat("%04u*", mapID));
134  for (uint32 i = 0; i < files.size(); ++i)
135  {
136  tileY = uint32(atoi(files[i].substr(5, 2).c_str()));
137  tileX = uint32(atoi(files[i].substr(8, 2).c_str()));
138  tileID = StaticMapTree::packTileID(tileX, tileY);
139 
140  if (tiles->insert(tileID).second)
141  count++;
142  }
143  }
144  printf("found %u.\n\n", count);
145  }
TileList m_tiles
Definition: MapBuilder.h:130
uint32_t uint32
Definition: Define.h:150
ListFilesResult getDirContents(std::vector< std::string > &fileList, std::string dirpath=".", std::string filter="*")
Definition: PathCommon.h:90
std::string StringFormat(Format &&fmt, Args &&...args)
Default TC string format function.
Definition: StringFormat.h:28
uint32_t uint32
Definition: g3dmath.h:168
void printf(BasicWriter< Char > &w, BasicCStringRef< Char > format, ArgList args)
Definition: format.h:3083

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::getGridBounds ( uint32  mapID,
uint32 minX,
uint32 minY,
uint32 maxX,
uint32 maxY 
)
private
217  {
218  maxX = INT_MAX;
219  maxY = INT_MAX;
220  minX = INT_MIN;
221  minY = INT_MIN;
222 
223  float bmin[3] = { 0, 0, 0 };
224  float bmax[3] = { 0, 0, 0 };
225  float lmin[3] = { 0, 0, 0 };
226  float lmax[3] = { 0, 0, 0 };
227  MeshData meshData;
228 
229  // make sure we process maps which don't have tiles
230  // initialize the static tree, which loads WDT models
231  if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData))
232  return;
233 
234  // get the coord bounds of the model data
235  if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0)
236  return;
237 
238  // get the coord bounds of the model data
239  if (meshData.solidVerts.size() && meshData.liquidVerts.size())
240  {
241  rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax);
242  rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax);
243  rcVmin(bmin, lmin);
244  rcVmax(bmax, lmax);
245  }
246  else if (meshData.solidVerts.size())
247  rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax);
248  else
249  rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax);
250 
251  // convert coord bounds to grid bounds
252  maxX = 32 - bmin[0] / GRID_SIZE;
253  maxY = 32 - bmin[2] / GRID_SIZE;
254  minX = 32 - bmax[0] / GRID_SIZE;
255  minY = 32 - bmax[2] / GRID_SIZE;
256  }
void rcVmin(float *mn, const float *v)
Definition: Recast.h:657
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
Definition: TerrainBuilder.cpp:627
void rcCalcBounds(const float *verts, int nv, float *bmin, float *bmax)
Definition: Recast.cpp:187
TerrainBuilder * m_terrainBuilder
Definition: MapBuilder.h:129
static const float GRID_SIZE
Definition: TerrainBuilder.h:50
void rcVmax(float *mx, const float *v)
Definition: Recast.h:667

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::getTileBounds ( uint32  tileX,
uint32  tileY,
float *  verts,
int  vertCount,
float *  bmin,
float *  bmax 
)
private
871  {
872  // this is for elevation
873  if (verts && vertCount)
874  rcCalcBounds(verts, vertCount, bmin, bmax);
875  else
876  {
877  bmin[1] = FLT_MIN;
878  bmax[1] = FLT_MAX;
879  }
880 
881  // this is for width and depth
882  bmax[0] = (32 - int(tileX)) * GRID_SIZE;
883  bmax[2] = (32 - int(tileY)) * GRID_SIZE;
884  bmin[0] = bmax[0] - GRID_SIZE;
885  bmin[2] = bmax[2] - GRID_SIZE;
886  }
void rcCalcBounds(const float *verts, int nv, float *bmin, float *bmax)
Definition: Recast.cpp:187
static const float GRID_SIZE
Definition: TerrainBuilder.h:50

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::set< uint32 > * MMAP::MapBuilder::getTileList ( uint32  mapID)
private
149  {
150  TileList::iterator itr = std::find(m_tiles.begin(), m_tiles.end(), mapID);
151  if (itr != m_tiles.end())
152  return (*itr).m_tiles;
153 
154  std::set<uint32>* tiles = new std::set<uint32>();
155  m_tiles.emplace_back(MapTiles(mapID, tiles));
156  return tiles;
157  }
TileList m_tiles
Definition: MapBuilder.h:130

+ Here is the caller graph for this function:

bool MMAP::MapBuilder::isTransportMap ( uint32  mapID)
private
959  {
960  switch (mapID)
961  {
962  // transport maps
963  case 582:
964  case 584:
965  case 586:
966  case 587:
967  case 588:
968  case 589:
969  case 590:
970  case 591:
971  case 592:
972  case 593:
973  case 594:
974  case 596:
975  case 610:
976  case 612:
977  case 613:
978  case 614:
979  case 620:
980  case 621:
981  case 622:
982  case 623:
983  case 641:
984  case 642:
985  case 647:
986  case 662:
987  case 672:
988  case 673:
989  case 674:
990  case 712:
991  case 713:
992  case 718:
993  case 738:
994  case 739:
995  case 740:
996  case 741:
997  case 742:
998  case 743:
999  case 747:
1000  case 748:
1001  case 749:
1002  case 750:
1003  case 762:
1004  case 763:
1005  case 765:
1006  case 766:
1007  case 767:
1008  case 1113:
1009  case 1132:
1010  case 1133:
1011  case 1172:
1012  case 1173:
1013  case 1192:
1014  case 1231:
1015  return true;
1016  default:
1017  return false;
1018  }
1019  }

+ Here is the caller graph for this function:

bool MMAP::MapBuilder::shouldSkipMap ( uint32  mapID)
private
890  {
891  if (m_skipContinents)
892  switch (mapID)
893  {
894  case 0:
895  case 1:
896  case 530:
897  case 571:
898  case 870:
899  case 1116:
900  return true;
901  default:
902  break;
903  }
904 
905  if (m_skipJunkMaps)
906  switch (mapID)
907  {
908  case 13: // test.wdt
909  case 25: // ScottTest.wdt
910  case 29: // Test.wdt
911  case 42: // Colin.wdt
912  case 169: // EmeraldDream.wdt (unused, and very large)
913  case 451: // development.wdt
914  case 573: // ExteriorTest.wdt
915  case 597: // CraigTest.wdt
916  case 605: // development_nonweighted.wdt
917  case 606: // QA_DVD.wdt
918  case 651: // ElevatorSpawnTest.wdt
919  case 1060: // LevelDesignLand-DevOnly.wdt
920  case 1181: // PattyMackTestGarrisonBldgMap.wdt
921  case 1264: // Propland-DevOnly.wdt
922  case 1270: // devland3.wdt
923  case 1427: // PattyMackTestGarrisonBldgMap2.wdt
924  return true;
925  default:
926  if (isTransportMap(mapID))
927  return true;
928  break;
929  }
930 
932  switch (mapID)
933  {
934  case 30: // Alterac Valley
935  case 37: // ?
936  case 489: // Warsong Gulch
937  case 529: // Arathi Basin
938  case 566: // Eye of the Storm
939  case 607: // Strand of the Ancients
940  case 628: // Isle of Conquest
941  case 726: // Twin Peaks
942  case 727: // Silvershard Mines
943  case 761: // The Battle for Gilneas
944  case 968: // Rated Eye of the Storm
945  case 998: // Temple of Kotmogu
946  case 1010: // CTF3
947  case 1105: // Deepwind Gorge
948  case 1280: // Southshore vs. Tarren Mill
949  return true;
950  default:
951  break;
952  }
953 
954  return false;
955  }
bool isTransportMap(uint32 mapID)
Definition: MapBuilder.cpp:958
bool m_skipBattlegrounds
Definition: MapBuilder.h:137
bool m_skipContinents
Definition: MapBuilder.h:135
bool m_skipJunkMaps
Definition: MapBuilder.h:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool MMAP::MapBuilder::shouldSkipTile ( uint32  mapID,
uint32  tileX,
uint32  tileY 
)
private
1023  {
1024  char fileName[255];
1025  sprintf(fileName, "mmaps/%04u%02i%02i.mmtile", mapID, tileY, tileX);
1026  FILE* file = fopen(fileName, "rb");
1027  if (!file)
1028  return false;
1029 
1030  MmapTileHeader header;
1031  int count = fread(&header, sizeof(MmapTileHeader), 1, file);
1032  fclose(file);
1033  if (count != 1)
1034  return false;
1035 
1036  if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != uint32(DT_NAVMESH_VERSION))
1037  return false;
1038 
1039  if (header.mmapVersion != MMAP_VERSION)
1040  return false;
1041 
1042  return true;
1043  }
uint32 mmapVersion
Definition: MapDefines.h:14
uint32 mmapMagic
Definition: MapDefines.h:12
std::string sprintf(CStringRef format, ArgList args)
Definition: format.h:3096
uint32_t uint32
Definition: Define.h:150
Definition: MapDefines.h:10
uint32 dtVersion
Definition: MapDefines.h:13
#define MMAP_MAGIC
Definition: MapBuilder.cpp:31
#define MMAP_VERSION
Definition: MapBuilder.cpp:32
static const int DT_NAVMESH_VERSION
A version number used to detect compatibility of navigation tile data.
Definition: DetourNavMesh.h:69

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MMAP::MapBuilder::WorkerThread ( )
162  {
163  while (1)
164  {
165  uint32 mapId = 0;
166 
167  _queue.WaitAndPop(mapId);
168 
169  if (_cancelationToken)
170  return;
171 
172  buildMap(mapId);
173  }
174  }
void buildMap(uint32 mapID)
Definition: MapBuilder.cpp:359
void WaitAndPop(T &value)
Definition: ProducerConsumerQueue.h:69
std::atomic< bool > _cancelationToken
Definition: MapBuilder.h:147
uint32_t uint32
Definition: Define.h:150
ProducerConsumerQueue< uint32 > _queue
Definition: MapBuilder.h:146

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

std::atomic<bool> MMAP::MapBuilder::_cancelationToken
private
ProducerConsumerQueue<uint32> MMAP::MapBuilder::_queue
private
std::vector<std::thread> MMAP::MapBuilder::_workerThreads
private
bool MMAP::MapBuilder::m_bigBaseUnit
private
bool MMAP::MapBuilder::m_debugOutput
private
float MMAP::MapBuilder::m_maxWalkableAngle
private
const char* MMAP::MapBuilder::m_offMeshFilePath
private
rcContext* MMAP::MapBuilder::m_rcContext
private
bool MMAP::MapBuilder::m_skipBattlegrounds
private
bool MMAP::MapBuilder::m_skipContinents
private
bool MMAP::MapBuilder::m_skipJunkMaps
private
TerrainBuilder* MMAP::MapBuilder::m_terrainBuilder
private
TileList MMAP::MapBuilder::m_tiles
private

The documentation for this class was generated from the following files: