diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-07-23 21:45:24 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-07-23 21:45:24 +0200 |
commit | 8a00ab156149f34718c198085830978cd8e91cea (patch) | |
tree | 9dc6ee4c5127d152f4c693bbb525a9a8f64bd50f /src | |
parent | 00eed485156963cab5caa75b8e36dd7a332a423e (diff) |
Tools/mmaps_generator: Fixed tile detection for vmap-only maps after a0f13391a0404d859cf4f8b8dee0c801f2640473
Diffstat (limited to 'src')
-rw-r--r-- | src/tools/mmaps_generator/MapBuilder.cpp | 220 | ||||
-rw-r--r-- | src/tools/mmaps_generator/MapBuilder.h | 41 |
2 files changed, 95 insertions, 166 deletions
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index d57d284cb2a..03e8e88c763 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -17,17 +17,26 @@ #include "MapBuilder.h" #include "IntermediateValues.h" +#include "MapDefines.h" #include "MapTree.h" #include "MapUtils.h" #include "Memory.h" #include "MMapDefines.h" #include "ModelInstance.h" #include "PathCommon.h" +#include "StringConvert.h" #include "StringFormat.h" #include <DetourNavMesh.h> #include <DetourNavMeshBuilder.h> +#include <boost/filesystem/directory.hpp> #include <climits> +namespace FileExtensions +{ +static boost::filesystem::path tilelist = ".tilelist"; +static boost::filesystem::path vmtile = ".vmtile"; +} + namespace MMAP { TileBuilder::TileBuilder(MapBuilder* mapBuilder, bool skipLiquid, bool bigBaseUnit, bool debugOutput) : @@ -98,12 +107,7 @@ namespace MMAP delete builder; m_tileBuilders.clear(); - - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - (*it).m_tiles->clear(); - delete (*it).m_tiles; - } + m_tiles.clear(); delete m_terrainBuilder; delete m_rcContext; @@ -112,87 +116,79 @@ namespace MMAP /**************************************************************************/ void MapBuilder::discoverTiles() { - std::vector<std::string> files; - uint32 mapID, tileX, tileY, tileID, count = 0; - - printf("Discovering maps... "); - getDirContents(files, "maps"); - for (uint32 i = 0; i < files.size(); ++i) + boost::filesystem::directory_iterator end; + for (auto itr = boost::filesystem::directory_iterator("maps"); itr != end; ++itr) { - mapID = uint32(atoi(files[i].substr(0, 4).c_str())); - if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end()) - { - m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>)); - count++; - } - } + if (!boost::filesystem::is_regular_file(*itr)) + continue; - files.clear(); - getDirContents(files, "vmaps", "*.vmtree"); - for (uint32 i = 0; i < files.size(); ++i) - { - mapID = uint32(atoi(files[i].substr(0, 4).c_str())); - if (std::find(m_tiles.begin(), m_tiles.end(), mapID) == m_tiles.end()) + if (itr->path().extension() != FileExtensions::tilelist) + continue; + + Optional<uint32> mapId = Trinity::StringTo<uint32>(std::string_view(itr->path().filename().string()).substr(0, 4)); + if (!mapId) + continue; + + if (shouldSkipMap(*mapId)) + continue; + + if (auto tileList = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(itr->path().string().c_str(), "rb"))) { - m_tiles.emplace_back(MapTiles(mapID, new std::set<uint32>)); - count++; + u_map_magic mapMagic = { }; + uint32 versionMagic = { }; + uint32 build; + char tilesData[64 * 64] = { }; + if (fread(mapMagic.data(), mapMagic.size(), 1, tileList.get()) == 1 + && mapMagic == MapMagic + && fread(&versionMagic, sizeof(versionMagic), 1, tileList.get()) == 1 + && versionMagic == MapVersionMagic + && fread(&build, sizeof(build), 1, tileList.get()) == 1 + && fread(std::data(tilesData), 64 * 64, 1, tileList.get()) == 1) + { + Trinity::Containers::FlatSet<uint32>& tiles = m_tiles[*mapId]; + for (uint32 tileX = 0; tileX < 64; ++tileX) + for (uint32 tileY = 0; tileY < 64; ++tileY) + if (tilesData[tileX * 64 + tileY] == '1') + if (tiles.insert(StaticMapTree::packTileID(tileX, tileY)).second) + ++m_totalTiles; + } } } - printf("found %u.\n", count); - count = 0; - printf("Discovering tiles... "); - for (TileList::iterator itr = m_tiles.begin(); itr != m_tiles.end(); ++itr) + for (auto itr = boost::filesystem::directory_iterator("vmaps"); itr != end; ++itr) { - std::set<uint32>* tiles = (*itr).m_tiles; - mapID = (*itr).m_mapId; + if (!boost::filesystem::is_directory(*itr)) + continue; - files.clear(); - getDirContents(files, "vmaps", Trinity::StringFormat("{:04}_*.vmtile", mapID)); - for (uint32 i = 0; i < files.size(); ++i) - { - tileX = uint32(atoi(files[i].substr(8, 2).c_str())); - tileY = uint32(atoi(files[i].substr(5, 2).c_str())); - tileID = StaticMapTree::packTileID(tileY, tileX); + Optional<uint32> mapId = Trinity::StringTo<uint32>(itr->path().filename().string()); + if (!mapId) + continue; - tiles->insert(tileID); - count++; - } + if (shouldSkipMap(*mapId)) + continue; - files.clear(); - getDirContents(files, "maps", Trinity::StringFormat("{:04}*", mapID)); - for (uint32 i = 0; i < files.size(); ++i) + Trinity::Containers::FlatSet<uint32>& tiles = m_tiles[*mapId]; + for (auto fileItr = boost::filesystem::directory_iterator(*itr); fileItr != end; ++fileItr) { - tileY = uint32(atoi(files[i].substr(5, 2).c_str())); - tileX = uint32(atoi(files[i].substr(8, 2).c_str())); - tileID = StaticMapTree::packTileID(tileX, tileY); + if (!boost::filesystem::is_regular_file(*fileItr)) + continue; - if (tiles->insert(tileID).second) - count++; - } + if (fileItr->path().extension() != FileExtensions::vmtile) + continue; - // make sure we process maps which don't have tiles - if (tiles->empty()) - { - // convert coord bounds to grid bounds - uint32 minX, minY, maxX, maxY; - getGridBounds(mapID, minX, minY, maxX, maxY); - - // add all tiles within bounds to tile list. - for (uint32 i = minX; i <= maxX; ++i) - for (uint32 j = minY; j <= maxY; ++j) - if (tiles->insert(StaticMapTree::packTileID(i, j)).second) - count++; + std::string fileName = fileItr->path().filename().string(); + + uint32 tileX = Trinity::StringTo<uint32>(std::string_view(fileName).substr(8, 2)).value_or(0); + uint32 tileY = Trinity::StringTo<uint32>(std::string_view(fileName).substr(5, 2)).value_or(0); + uint32 tileID = StaticMapTree::packTileID(tileY, tileX); + + if (tiles.insert(tileID).second) + ++m_totalTiles; } } - printf("found %u.\n\n", count); - // Calculate tiles to process in total - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - if (!shouldSkipMap(it->m_mapId)) - m_totalTiles += it->m_tiles->size(); - } + printf("Discovering maps... found %u.\n", uint32(m_tiles.size())); + printf("Discovering tiles... found %u.\n\n", m_totalTiles); } /**************************************************************************/ @@ -231,15 +227,12 @@ namespace MMAP } /**************************************************************************/ - std::set<uint32>* MapBuilder::getTileList(uint32 mapID) + std::span<uint32 const> MapBuilder::getTileList(uint32 mapID) const { - TileList::iterator itr = std::find(m_tiles.begin(), m_tiles.end(), mapID); - if (itr != m_tiles.end()) - return (*itr).m_tiles; + if (Trinity::Containers::FlatSet<uint32> const* tiles = Trinity::Containers::MapGetValuePtr(m_tiles, mapID)) + return *tiles; - std::set<uint32>* tiles = new std::set<uint32>(); - m_tiles.emplace_back(MapTiles(mapID, tiles)); - return tiles; + return { }; } /**************************************************************************/ @@ -285,11 +278,8 @@ namespace MMAP else { // Build all maps if no map id has been specified - for (TileList::iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - if (!shouldSkipMap(it->m_mapId)) - buildMap(it->m_mapId); - } + for (auto& [mapId, _] : m_tiles) + buildMap(mapId); } while (!_queue.Empty()) @@ -308,48 +298,6 @@ namespace MMAP } /**************************************************************************/ - void MapBuilder::getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY) - { - maxX = INT_MAX; - maxY = INT_MAX; - minX = INT_MIN; - minY = INT_MIN; - - float bmin[3] = { 0, 0, 0 }; - float bmax[3] = { 0, 0, 0 }; - float lmin[3] = { 0, 0, 0 }; - float lmax[3] = { 0, 0, 0 }; - MeshData meshData; - - // make sure we process maps which don't have tiles - // initialize the static tree, which loads WDT models - if (!m_terrainBuilder->loadVMap(mapID, 64, 64, meshData)) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() + meshData.liquidVerts.size() == 0) - return; - - // get the coord bounds of the model data - if (meshData.solidVerts.size() && meshData.liquidVerts.size()) - { - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - rcVmin(bmin, lmin); - rcVmax(bmax, lmax); - } - else if (meshData.solidVerts.size()) - rcCalcBounds(meshData.solidVerts.getCArray(), meshData.solidVerts.size() / 3, bmin, bmax); - else - rcCalcBounds(meshData.liquidVerts.getCArray(), meshData.liquidVerts.size() / 3, lmin, lmax); - - // convert coord bounds to grid bounds - maxX = 32 - bmin[0] / GRID_SIZE; - maxY = 32 - bmin[2] / GRID_SIZE; - minX = 32 - bmax[0] / GRID_SIZE; - minY = 32 - bmax[2] / GRID_SIZE; - } - void MapBuilder::buildMeshFromFile(char* name) { FILE* file = fopen(name, "rb"); @@ -460,28 +408,28 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildMap(uint32 mapID) { - std::set<uint32>* tiles = getTileList(mapID); + std::span<uint32 const> tiles = getTileList(mapID); - if (!tiles->empty()) + if (!tiles.empty()) { // build navMesh dtNavMesh* navMesh = nullptr; buildNavMesh(mapID, navMesh); if (!navMesh) { - printf("[Map %04i] Failed creating navmesh!\n", mapID); - m_totalTilesProcessed += tiles->size(); + printf("[Map %04u] Failed creating navmesh!\n", mapID); + m_totalTilesProcessed += tiles.size(); return; } // now start building mmtiles for each tile - printf("[Map %04i] We have %u tiles. \n", mapID, (unsigned int)tiles->size()); - for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) + printf("[Map %04u] We have %u tiles. \n", mapID, uint32(tiles.size())); + for (uint32 packedTile : tiles) { uint32 tileX, tileY; // unpack tile coords - StaticMapTree::unpackTileID((*it), tileX, tileY); + StaticMapTree::unpackTileID(packedTile, tileX, tileY); TileInfo tileInfo; tileInfo.m_mapId = mapID; @@ -560,7 +508,7 @@ namespace MMAP parentMapId = sMapStore[parentMapId].ParentMapID; } - std::set<uint32>* tiles = getTileList(navMeshParamsMapId); + std::span<uint32 const> tiles = getTileList(navMeshParamsMapId); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -570,15 +518,15 @@ namespace MMAP int polyBits = DT_POLY_BITS; - int maxTiles = tiles->size(); + int maxTiles = tiles.size(); int maxPolysPerTile = 1 << polyBits; /*** calculate bounds of map ***/ uint32 tileXMin = 64, tileYMin = 64, tileXMax = 0, tileYMax = 0, tileX, tileY; - for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it) + for (uint32 packedTile : tiles) { - StaticMapTree::unpackTileID(*it, tileX, tileY); + StaticMapTree::unpackTileID(packedTile, tileX, tileY); if (tileX > tileXMax) tileXMax = tileX; diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index ecad8221adc..748458c9220 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -18,40 +18,22 @@ #ifndef _MAP_BUILDER_H #define _MAP_BUILDER_H -#include <vector> -#include <set> -#include <list> -#include <atomic> -#include <thread> - -#include "TerrainBuilder.h" - -#include "Recast.h" -#include "DetourNavMesh.h" +#include "FlatSet.h" #include "Optional.h" #include "ProducerConsumerQueue.h" +#include "TerrainBuilder.h" +#include <DetourNavMesh.h> +#include <Recast.h> +#include <atomic> +#include <span> +#include <thread> +#include <vector> using namespace VMAP; namespace MMAP { - struct MapTiles - { - MapTiles() : m_mapId(uint32(-1)), m_tiles(nullptr) {} - - MapTiles(uint32 id, std::set<uint32>* tiles) : m_mapId(id), m_tiles(tiles) {} - ~MapTiles() {} - - uint32 m_mapId; - std::set<uint32>* m_tiles; - - bool operator==(uint32 id) - { - return m_mapId == id; - } - }; - - typedef std::list<MapTiles> TileList; + typedef std::unordered_map<uint32, Trinity::Containers::FlatSet<uint32>> TileList; struct Tile { @@ -173,14 +155,13 @@ namespace MMAP void buildMap(uint32 mapID); // detect maps and tiles void discoverTiles(); - std::set<uint32>* getTileList(uint32 mapID); + std::span<uint32 const> getTileList(uint32 mapID) const; void buildNavMesh(uint32 mapID, dtNavMesh* &navMesh); void getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax) const; - void getGridBounds(uint32 mapID, uint32 &minX, uint32 &minY, uint32 &maxX, uint32 &maxY); bool shouldSkipMap(uint32 mapID) const; bool isTransportMap(uint32 mapID) const; @@ -213,7 +194,7 @@ namespace MMAP int32 m_mapid; - std::atomic<uint32> m_totalTiles; + uint32 m_totalTiles; std::atomic<uint32> m_totalTilesProcessed; // build performance - not really used for now |