AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
MMAP::TileBuilder Class Reference

#include "MapBuilder.h"

Public Member Functions

 TileBuilder (MapBuilder *mapBuilder, bool skipLiquid, bool debugOutput)
 
 TileBuilder (TileBuilder &&)=default
 
 ~TileBuilder ()
 
void WorkerThread ()
 
void WaitCompletion ()
 
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)
 
bool shouldSkipTile (uint32 mapID, uint32 tileX, uint32 tileY) const
 

Private Attributes

bool m_debugOutput
 
MapBuilderm_mapBuilder
 
TerrainBuilderm_terrainBuilder
 
std::thread m_workerThread
 
rcContext * m_rcContext
 

Detailed Description

Constructor & Destructor Documentation

◆ TileBuilder() [1/2]

MMAP::TileBuilder::TileBuilder ( MapBuilder mapBuilder,
bool  skipLiquid,
bool  debugOutput 
)
33 :
34 m_debugOutput(debugOutput),
35 m_mapBuilder(mapBuilder),
36 m_terrainBuilder(nullptr),
38 m_rcContext(nullptr)
39 {
40 m_terrainBuilder = new TerrainBuilder(m_mapBuilder->getConfig().DataDirPath(), skipLiquid);
41 m_rcContext = new rcContext(false);
42 }
std::string DataDirPath() const
Definition Config.h:77
Config const & getConfig() const
Definition MapBuilder.h:140
rcContext * m_rcContext
Definition MapBuilder.h:119
void WorkerThread()
Definition MapBuilder.cpp:392
bool m_debugOutput
Definition MapBuilder.h:113
std::thread m_workerThread
Definition MapBuilder.h:117
MapBuilder * m_mapBuilder
Definition MapBuilder.h:115
TerrainBuilder * m_terrainBuilder
Definition MapBuilder.h:116

References MMAP::Config::DataDirPath(), MMAP::MapBuilder::getConfig(), m_mapBuilder, m_rcContext, and m_terrainBuilder.

◆ TileBuilder() [2/2]

MMAP::TileBuilder::TileBuilder ( TileBuilder &&  )
default

◆ ~TileBuilder()

MMAP::TileBuilder::~TileBuilder ( )
45 {
47
48 delete m_terrainBuilder;
49 delete m_rcContext;
50 }
void WaitCompletion()
Definition MapBuilder.cpp:52

References m_rcContext, m_terrainBuilder, and WaitCompletion().

Member Function Documentation

◆ buildMoveMapTile()

void MMAP::TileBuilder::buildMoveMapTile ( uint32  mapID,
uint32  tileX,
uint32  tileY,
MeshData meshData,
float  bmin[3],
float  bmax[3],
dtNavMesh *  navMesh 
)
Todo:
: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off
589 {
590 // console output
591 char tileString[20];
592 sprintf(tileString, "[Map %03i] [%02i,%02i]: ", mapID, tileX, tileY);
593 printf("%s Building movemap tiles...\n", tileString);
594
595 IntermediateValues iv;
596
597 float* tVerts = meshData.solidVerts.getCArray();
598 int tVertCount = meshData.solidVerts.size() / 3;
599 int* tTris = meshData.solidTris.getCArray();
600 int tTriCount = meshData.solidTris.size() / 3;
601
602 float* lVerts = meshData.liquidVerts.getCArray();
603 int lVertCount = meshData.liquidVerts.size() / 3;
604 int* lTris = meshData.liquidTris.getCArray();
605 int lTriCount = meshData.liquidTris.size() / 3;
606 uint8* lTriFlags = meshData.liquidType.getCArray();
607
608 ResolvedMeshConfig cfg = m_mapBuilder->getConfig().GetConfigForTile(mapID, tileX, tileY);
609 int tilesPerMap = cfg.tilesPerMapEdge;
610 float baseUnitDim = cfg.baseUnitDim;
611
612 rcConfig config = m_mapBuilder->getRecastConfig(cfg, bmin, bmax);
613
614 // this sets the dimensions of the heightfield - should maybe happen before border padding
615 rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height);
616
617 // allocate subregions : tiles
618 Tile* tiles = new Tile[tilesPerMap * tilesPerMap];
619
620 // Initialize per tile config.
621 rcConfig tileCfg = config;
622 tileCfg.width = config.tileSize + config.borderSize * 2;
623 tileCfg.height = config.tileSize + config.borderSize * 2;
624
625 // merge per tile poly and detail meshes
626 rcPolyMesh** pmmerge = new rcPolyMesh*[tilesPerMap * tilesPerMap];
627 rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[tilesPerMap * tilesPerMap];
628 int nmerge = 0;
629
630 // build all tiles
631 for (int y = 0; y < tilesPerMap; ++y)
632 {
633 for (int x = 0; x < tilesPerMap; ++x)
634 {
635 Tile& tile = tiles[x + y * tilesPerMap];
636
637 // Calculate the per tile bounding box.
638 tileCfg.bmin[0] = config.bmin[0] + x * float(config.tileSize * config.cs);
639 tileCfg.bmin[2] = config.bmin[2] + y * float(config.tileSize * config.cs);
640 tileCfg.bmax[0] = config.bmin[0] + (x + 1) * float(config.tileSize * config.cs);
641 tileCfg.bmax[2] = config.bmin[2] + (y + 1) * float(config.tileSize * config.cs);
642
643 tileCfg.bmin[0] -= tileCfg.borderSize * tileCfg.cs;
644 tileCfg.bmin[2] -= tileCfg.borderSize * tileCfg.cs;
645 tileCfg.bmax[0] += tileCfg.borderSize * tileCfg.cs;
646 tileCfg.bmax[2] += tileCfg.borderSize * tileCfg.cs;
647
648 // build heightfield
649 tile.solid = rcAllocHeightfield();
650 if (!tile.solid || !rcCreateHeightfield(m_rcContext, *tile.solid, tileCfg.width, tileCfg.height, tileCfg.bmin, tileCfg.bmax, tileCfg.cs, tileCfg.ch))
651 {
652 printf("%s Failed building heightfield! \n", tileString);
653 continue;
654 }
655
656 // mark all walkable tiles, both liquids and solids
657
658 unsigned char* triFlags = new unsigned char[tTriCount];
659 memset(triFlags, NAV_GROUND, tTriCount * sizeof(unsigned char));
660 rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags);
661 rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb);
662 delete[] triFlags;
663
664 rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid);
665 rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
666 rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid);
667
668 // add liquid triangles
669 rcRasterizeTriangles(m_rcContext, lVerts, lVertCount, lTris, lTriFlags, lTriCount, *tile.solid, config.walkableClimb);
670
671 // compact heightfield spans
672 tile.chf = rcAllocCompactHeightfield();
673 if (!tile.chf || !rcBuildCompactHeightfield(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid, *tile.chf))
674 {
675 printf("%s Failed compacting heightfield! \n", tileString);
676 continue;
677 }
678
679 // build polymesh intermediates
680 if (!rcErodeWalkableArea(m_rcContext, config.walkableRadius, *tile.chf))
681 {
682 printf("%s Failed eroding area! \n", tileString);
683 continue;
684 }
685
686 if (!rcBuildDistanceField(m_rcContext, *tile.chf))
687 {
688 printf("%s Failed building distance field! \n", tileString);
689 continue;
690 }
691
692 if (!rcBuildRegions(m_rcContext, *tile.chf, tileCfg.borderSize, tileCfg.minRegionArea, tileCfg.mergeRegionArea))
693 {
694 printf("%s Failed building regions! \n", tileString);
695 continue;
696 }
697
698 tile.cset = rcAllocContourSet();
699 if (!tile.cset || !rcBuildContours(m_rcContext, *tile.chf, tileCfg.maxSimplificationError, tileCfg.maxEdgeLen, *tile.cset))
700 {
701 printf("%s Failed building contours! \n", tileString);
702 continue;
703 }
704
705 // build polymesh
706 tile.pmesh = rcAllocPolyMesh();
707 if (!tile.pmesh || !rcBuildPolyMesh(m_rcContext, *tile.cset, tileCfg.maxVertsPerPoly, *tile.pmesh))
708 {
709 printf("%s Failed building polymesh! \n", tileString);
710 continue;
711 }
712
713 tile.dmesh = rcAllocPolyMeshDetail();
714 if (!tile.dmesh || !rcBuildPolyMeshDetail(m_rcContext, *tile.pmesh, *tile.chf, tileCfg.detailSampleDist, tileCfg.detailSampleMaxError, *tile.dmesh))
715 {
716 printf("%s Failed building polymesh detail! \n", tileString);
717 continue;
718 }
719
720 // free those up
721 // we may want to keep them in the future for debug
722 // but right now, we don't have the code to merge them
723 rcFreeHeightField(tile.solid);
724 tile.solid = nullptr;
725 rcFreeCompactHeightfield(tile.chf);
726 tile.chf = nullptr;
727 rcFreeContourSet(tile.cset);
728 tile.cset = nullptr;
729
730 pmmerge[nmerge] = tile.pmesh;
731 dmmerge[nmerge] = tile.dmesh;
732 nmerge++;
733 }
734 }
735
736 iv.polyMesh = rcAllocPolyMesh();
737 if (!iv.polyMesh)
738 {
739 printf("%s alloc iv.polyMesh FAILED!\n", tileString);
740 delete[] pmmerge;
741 delete[] dmmerge;
742 delete[] tiles;
743 return;
744 }
745 rcMergePolyMeshes(m_rcContext, pmmerge, nmerge, *iv.polyMesh);
746
747 iv.polyMeshDetail = rcAllocPolyMeshDetail();
748 if (!iv.polyMeshDetail)
749 {
750 printf("%s alloc m_dmesh FAILED!\n", tileString);
751 delete[] pmmerge;
752 delete[] dmmerge;
753 delete[] tiles;
754 return;
755 }
756 rcMergePolyMeshDetails(m_rcContext, dmmerge, nmerge, *iv.polyMeshDetail);
757
758 // free things up
759 delete[] pmmerge;
760 delete[] dmmerge;
761 delete[] tiles;
762
763 // set polygons as walkable
765 for (int i = 0; i < iv.polyMesh->npolys; ++i)
766 if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
767 iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
768
769 // setup mesh parameters
770 dtNavMeshCreateParams params;
771 memset(&params, 0, sizeof(params));
772 params.verts = iv.polyMesh->verts;
773 params.vertCount = iv.polyMesh->nverts;
774 params.polys = iv.polyMesh->polys;
775 params.polyAreas = iv.polyMesh->areas;
776 params.polyFlags = iv.polyMesh->flags;
777 params.polyCount = iv.polyMesh->npolys;
778 params.nvp = iv.polyMesh->nvp;
779 params.detailMeshes = iv.polyMeshDetail->meshes;
780 params.detailVerts = iv.polyMeshDetail->verts;
781 params.detailVertsCount = iv.polyMeshDetail->nverts;
782 params.detailTris = iv.polyMeshDetail->tris;
783 params.detailTriCount = iv.polyMeshDetail->ntris;
784
785 params.offMeshConVerts = meshData.offMeshConnections.getCArray();
786 params.offMeshConCount = meshData.offMeshConnections.size() / 6;
787 params.offMeshConRad = meshData.offMeshConnectionRads.getCArray();
788 params.offMeshConDir = meshData.offMeshConnectionDirs.getCArray();
789 params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray();
790 params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray();
791
792 params.walkableHeight = baseUnitDim * config.walkableHeight; // agent height
793 params.walkableRadius = baseUnitDim * config.walkableRadius; // agent radius
794 params.walkableClimb = baseUnitDim * config.walkableClimb; // keep less that walkableHeight (aka agent height)!
795 params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE;
796 params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE;
797 rcVcopy(params.bmin, bmin);
798 rcVcopy(params.bmax, bmax);
799 params.cs = config.cs;
800 params.ch = config.ch;
801 params.tileLayer = 0;
802 params.buildBvTree = true;
803
804 // will hold final navmesh
805 unsigned char* navData = nullptr;
806 int navDataSize = 0;
807
808 do
809 {
810 // these values are checked within dtCreateNavMeshData - handle them here
811 // so we have a clear error message
812 if (params.nvp > DT_VERTS_PER_POLYGON)
813 {
814 printf("%s Invalid verts-per-polygon value! \n", tileString);
815 break;
816 }
817 if (params.vertCount >= 0xffff)
818 {
819 printf("%s Too many vertices! %d out of %d! \n", tileString, params.vertCount, 0xffff);
820 break;
821 }
822 if (!params.vertCount || !params.verts)
823 {
824 // occurs mostly when adjacent tiles have models
825 // loaded but those models don't span into this tile
826
827 // message is an annoyance
828 printf("%sNo vertices to build tile! \n", tileString);
829 break;
830 }
831 if (!params.polyCount || !params.polys)
832 {
833 // we have flat tiles with no actual geometry - don't build those, its useless
834 // keep in mind that we do output those into debug info
835 printf("%s No polygons to build on tile! \n", tileString);
836 break;
837 }
838 if (!params.detailMeshes || !params.detailVerts || !params.detailTris)
839 {
840 printf("%s No detail mesh to build tile! \n", tileString);
841 break;
842 }
843
844 printf("%s Building navmesh tile...\n", tileString);
845 if (!dtCreateNavMeshData(&params, &navData, &navDataSize))
846 {
847 printf("%s Failed building navmesh tile! \n", tileString);
848 break;
849 }
850
851 dtTileRef tileRef = 0;
852 printf("%s Adding tile to navmesh...\n", tileString);
853 // DT_TILE_FREE_DATA tells detour to unallocate memory when the tile
854 // is removed via removeTile()
855 dtStatus dtResult = navMesh->addTile(navData, navDataSize, DT_TILE_FREE_DATA, 0, &tileRef);
856 if (!tileRef || dtResult != DT_SUCCESS)
857 {
858 printf("%s Failed adding tile to navmesh! \n", tileString);
859 break;
860 }
861
862 // file output
863 const std::string fileName = Acore::StringFormat(
866 mapID, tileY, tileX
867 );
868
869 FILE* file = fopen(fileName.c_str(), "wb");
870 if (!file)
871 {
872 char message[1024];
873 sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName.c_str());
874 perror(message);
875 navMesh->removeTile(tileRef, nullptr, nullptr);
876 break;
877 }
878
879 printf("%s Writing to file...\n", tileString);
880
881 // write header
882 MmapTileHeader header;
884 header.size = uint32(navDataSize);
885 header.recastConfig = cfg.toMMAPTileRecastConfig();
886 fwrite(&header, sizeof(MmapTileHeader), 1, file);
887
888 // write data
889 fwrite(navData, sizeof(unsigned char), navDataSize, file);
890 fclose(file);
891
892 // now that tile is written to disk, we can unload it
893 navMesh->removeTile(tileRef, nullptr, nullptr);
894 } while (false);
895
896 if (m_debugOutput)
897 {
898 // restore padding so that the debug visualization is correct
899 for (int i = 0; i < iv.polyMesh->nverts; ++i)
900 {
901 unsigned short* v = &iv.polyMesh->verts[i * 3];
902 v[0] += (unsigned short)config.borderSize;
903 v[2] += (unsigned short)config.borderSize;
904 }
905
906 iv.generateObjFile(m_mapBuilder->getConfig().DataDirPath(), mapID, tileX, tileY, meshData);
907 iv.writeIV(m_mapBuilder->getConfig().DataDirPath(), mapID, tileX, tileY);
908 }
909 }
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ NAV_GROUND
Definition MapDefines.h:91
ResolvedMeshConfig GetConfigForTile(uint32 mapID, uint32 tileX, uint32 tileY) const
Definition Config.cpp:75
rcConfig getRecastConfig(ResolvedMeshConfig const &cfg, float bmin[3], float bmax[3]) const
Definition MapBuilder.cpp:1061
bool usesLiquids() const
Definition TerrainBuilder.h:88
std::string StringFormat(FormatStringView fmt, Args &&... args)
Default AC string format function.
Definition StringFormat.h:44
static const float GRID_SIZE
Definition TerrainBuilder.h:48
static char const *const TILE_FILE_NAME_FORMAT
Definition MMapMgr.h:49
int tilesPerMapEdge
Definition Config.h:51
Definition MapDefines.h:65
MmapTileRecastConfig recastConfig
Definition MapDefines.h:73
uint32 size
Definition MapDefines.h:69
char usesLiquids
Definition MapDefines.h:70

References MMAP::ResolvedMeshConfig::baseUnitDim, MMAP::Tile::chf, MMAP::Tile::cset, MMAP::Config::DataDirPath(), MMAP::Tile::dmesh, MMAP::IntermediateValues::generateObjFile(), MMAP::MapBuilder::getConfig(), MMAP::Config::GetConfigForTile(), MMAP::MapBuilder::getRecastConfig(), MMAP::GRID_SIZE, MMAP::MeshData::liquidTris, MMAP::MeshData::liquidType, MMAP::MeshData::liquidVerts, m_debugOutput, m_mapBuilder, m_rcContext, m_terrainBuilder, NAV_GROUND, MMAP::MeshData::offMeshConnectionDirs, MMAP::MeshData::offMeshConnectionRads, MMAP::MeshData::offMeshConnections, MMAP::MeshData::offMeshConnectionsAreas, MMAP::MeshData::offMeshConnectionsFlags, MMAP::Tile::pmesh, MMAP::IntermediateValues::polyMesh, MMAP::IntermediateValues::polyMeshDetail, MmapTileHeader::recastConfig, MmapTileHeader::size, MMAP::Tile::solid, MMAP::MeshData::solidTris, MMAP::MeshData::solidVerts, Acore::StringFormat(), MMAP::TILE_FILE_NAME_FORMAT, MMAP::ResolvedMeshConfig::tilesPerMapEdge, MMAP::ResolvedMeshConfig::toMMAPTileRecastConfig(), MmapTileHeader::usesLiquids, MMAP::TerrainBuilder::usesLiquids(), and MMAP::IntermediateValues::writeIV().

Referenced by MMAP::MapBuilder::buildMeshFromFile(), and buildTile().

◆ buildTile()

void MMAP::TileBuilder::buildTile ( uint32  mapID,
uint32  tileX,
uint32  tileY,
dtNavMesh *  navMesh 
)
457 {
458 if (shouldSkipTile(mapID, tileX, tileY))
459 {
461 return;
462 }
463
464 printf("%u%% [Map %04i] Building tile [%02u,%02u]\n", m_mapBuilder->currentPercentageDone(), mapID, tileX, tileY);
465
466 MeshData meshData;
467
468 // get heightmap data
469 m_terrainBuilder->loadMap(mapID, tileX, tileY, meshData);
470
471 // get model data
472 m_terrainBuilder->loadVMap(mapID, tileY, tileX, meshData);
473
474 // if there is no data, give up now
475 if (!meshData.solidVerts.size() && !meshData.liquidVerts.size())
476 {
478 return;
479 }
480
481 // remove unused vertices
482 TerrainBuilder::cleanVertices(meshData.solidVerts, meshData.solidTris);
483 TerrainBuilder::cleanVertices(meshData.liquidVerts, meshData.liquidTris);
484
485 // gather all mesh data for final data check, and bounds calculation
486 G3D::Array<float> allVerts;
487 allVerts.append(meshData.liquidVerts);
488 allVerts.append(meshData.solidVerts);
489
490 if (!allVerts.size())
491 {
493 return;
494 }
495
496 // get bounds of current tile
497 float bmin[3], bmax[3];
498 m_mapBuilder->getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax);
500
501 // build navmesh tile
502 buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh);
503
505 }
std::vector< std::string > const & OffMeshConnections() const
Definition Config.h:79
uint32 currentPercentageDone() const
Definition MapBuilder.cpp:1096
void getTileBounds(uint32 tileX, uint32 tileY, float *verts, int vertCount, float *bmin, float *bmax) const
Definition MapBuilder.cpp:912
std::atomic< uint32 > m_totalTilesProcessed
Definition MapBuilder.h:180
static void cleanVertices(G3D::Array< float > &verts, G3D::Array< int > &tris)
Definition TerrainBuilder.cpp:887
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
Definition TerrainBuilder.cpp:132
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, std::vector< std::string > const &offMeshLines)
Definition TerrainBuilder.cpp:930
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
Definition TerrainBuilder.cpp:677
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const
Definition MapBuilder.cpp:1033
void buildMoveMapTile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, float bmin[3], float bmax[3], dtNavMesh *navMesh)
Definition MapBuilder.cpp:586

References buildMoveMapTile(), MMAP::TerrainBuilder::cleanVertices(), MMAP::MapBuilder::currentPercentageDone(), MMAP::MapBuilder::getConfig(), MMAP::MapBuilder::getTileBounds(), MMAP::MeshData::liquidTris, MMAP::MeshData::liquidVerts, MMAP::TerrainBuilder::loadMap(), MMAP::TerrainBuilder::loadOffMeshConnections(), MMAP::TerrainBuilder::loadVMap(), m_mapBuilder, m_terrainBuilder, MMAP::MapBuilder::m_totalTilesProcessed, MMAP::Config::OffMeshConnections(), shouldSkipTile(), MMAP::MeshData::solidTris, and MMAP::MeshData::solidVerts.

Referenced by MMAP::MapBuilder::buildSingleTile(), and WorkerThread().

◆ shouldSkipTile()

bool MMAP::TileBuilder::shouldSkipTile ( uint32  mapID,
uint32  tileX,
uint32  tileY 
) const
1034 {
1035 const std::string fileName = Acore::StringFormat(
1038 mapID, tileY, tileX
1039 );
1040
1041 FILE* file = fopen(fileName.c_str(), "rb");
1042 if (!file)
1043 return false;
1044
1045 MmapTileHeader header;
1046 int count = fread(&header, sizeof(MmapTileHeader), 1, file);
1047 fclose(file);
1048 if (count != 1)
1049 return false;
1050
1051 if (header.mmapMagic != MMAP_MAGIC || header.dtVersion != uint32(DT_NAVMESH_VERSION))
1052 return false;
1053
1054 if (header.mmapVersion != MMAP_VERSION)
1055 return false;
1056
1057 const auto desiredRecastConfig = m_mapBuilder->getConfig().GetConfigForTile(mapID, tileX, tileY).toMMAPTileRecastConfig();
1058 return header.recastConfig == desiredRecastConfig;
1059 }
#define MMAP_VERSION
Definition MapDefines.h:29
#define MMAP_MAGIC
Definition MapDefines.h:28
MmapTileRecastConfig toMMAPTileRecastConfig() const
Definition Config.cpp:47
uint32 dtVersion
Definition MapDefines.h:67
uint32 mmapVersion
Definition MapDefines.h:68
uint32 mmapMagic
Definition MapDefines.h:66

References MMAP::Config::DataDirPath(), MmapTileHeader::dtVersion, MMAP::MapBuilder::getConfig(), MMAP::Config::GetConfigForTile(), m_mapBuilder, MMAP_MAGIC, MMAP_VERSION, MmapTileHeader::mmapMagic, MmapTileHeader::mmapVersion, MmapTileHeader::recastConfig, Acore::StringFormat(), MMAP::TILE_FILE_NAME_FORMAT, and MMAP::ResolvedMeshConfig::toMMAPTileRecastConfig().

Referenced by buildTile().

◆ WaitCompletion()

void MMAP::TileBuilder::WaitCompletion ( )
53 {
54 if (m_workerThread.joinable())
55 m_workerThread.join();
56 }

References m_workerThread.

Referenced by ~TileBuilder().

◆ WorkerThread()

void MMAP::TileBuilder::WorkerThread ( )
393 {
394 while (true)
395 {
396 TileInfo tileInfo;
397
398 m_mapBuilder->_queue.WaitAndPop(tileInfo);
399
401 return;
402
403 dtNavMesh* navMesh = dtAllocNavMesh();
404 if (!navMesh->init(&tileInfo.m_navMeshParams))
405 {
406 printf("[Map %04i] Failed creating navmesh for tile %i,%i !\n", tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY);
407 dtFreeNavMesh(navMesh);
408 return;
409 }
410
411 buildTile(tileInfo.m_mapId, tileInfo.m_tileX, tileInfo.m_tileY, navMesh);
412
413 dtFreeNavMesh(navMesh);
414 }
415 }
ProducerConsumerQueue< TileInfo > _queue
Definition MapBuilder.h:186
std::atomic< bool > _cancelationToken
Definition MapBuilder.h:187
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh *navMesh)
Definition MapBuilder.cpp:456

References MMAP::MapBuilder::_cancelationToken, MMAP::MapBuilder::_queue, buildTile(), m_mapBuilder, MMAP::TileInfo::m_mapId, MMAP::TileInfo::m_navMeshParams, MMAP::TileInfo::m_tileX, and MMAP::TileInfo::m_tileY.

Member Data Documentation

◆ m_debugOutput

bool MMAP::TileBuilder::m_debugOutput
private

Referenced by buildMoveMapTile().

◆ m_mapBuilder

MapBuilder* MMAP::TileBuilder::m_mapBuilder
private

◆ m_rcContext

rcContext* MMAP::TileBuilder::m_rcContext
private

◆ m_terrainBuilder

TerrainBuilder* MMAP::TileBuilder::m_terrainBuilder
private

◆ m_workerThread

std::thread MMAP::TileBuilder::m_workerThread
private

Referenced by WaitCompletion().


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