aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-07-23 21:45:24 +0200
committerShauren <shauren.trinity@gmail.com>2025-07-23 21:45:24 +0200
commit8a00ab156149f34718c198085830978cd8e91cea (patch)
tree9dc6ee4c5127d152f4c693bbb525a9a8f64bd50f /src
parent00eed485156963cab5caa75b8e36dd7a332a423e (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.cpp220
-rw-r--r--src/tools/mmaps_generator/MapBuilder.h41
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