aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-11-05 18:55:45 +0100
committerShauren <shauren.trinity@gmail.com>2025-11-05 18:55:45 +0100
commit145bbde2317f139c5be796801a7b254265c250d1 (patch)
treeeb7004bdac6ef5444f7e3ca70c343dc5ff6912f1 /src
parent1e56367b3004be6e8a6144e0885ccc1ca3674e40 (diff)
Tools/mmaps_generator: Save offmesh connections input together with navmesh params for each map
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/Management/MMapManager.cpp57
-rw-r--r--src/common/Collision/Management/MMapManager.h3
-rw-r--r--src/common/Collision/Maps/MMapDefines.h51
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp25
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.cpp2
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.h14
-rw-r--r--src/tools/mmaps_generator/TileBuilder.cpp9
-rw-r--r--src/tools/mmaps_generator/TileBuilder.h2
8 files changed, 108 insertions, 55 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp
index 7ca5650a0b5..d0862a49156 100644
--- a/src/common/Collision/Management/MMapManager.cpp
+++ b/src/common/Collision/Management/MMapManager.cpp
@@ -97,6 +97,28 @@ namespace MMAP
}
// load and init dtNavMesh - read parameters from file
+ dtNavMeshParams params;
+ if (LoadResult paramsResult = parseNavMeshParamsFile(basePath, mapId, &params); paramsResult != LoadResult::Success)
+ return paramsResult;
+
+ NavMeshPtr mesh(dtAllocNavMesh());
+ ASSERT(mesh);
+ if (dtStatusFailed(mesh->init(&params)))
+ {
+ TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {:04}", mapId);
+ return LoadResult::LibraryError;
+ }
+
+ TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded {:04}.mmap", mapId);
+
+ // store inside our map list
+ itr->second.reset(new MMapData(std::move(mesh)));
+ return LoadResult::Success;
+ }
+
+ LoadResult MMapManager::parseNavMeshParamsFile(std::string_view basePath, uint32 mapId, dtNavMeshParams* params,
+ std::vector<OffMeshData>* offmeshConnections /*= nullptr*/)
+ {
std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, basePath, mapId);
auto file = Trinity::make_unique_ptr_with_deleter<&::fclose>(fopen(fileName.c_str(), "rb"));
if (!file)
@@ -105,26 +127,39 @@ namespace MMAP
return LoadResult::FileNotFound;
}
- dtNavMeshParams params;
- uint32 count = uint32(fread(&params, sizeof(dtNavMeshParams), 1, file.get()));
- if (count != 1)
+ MmapNavMeshHeader fileHeader;
+ if (fread(&fileHeader, sizeof(MmapNavMeshHeader), 1, file.get()) != 1)
{
TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '{}'", fileName);
return LoadResult::ReadFromFileFailed;
}
- NavMeshPtr mesh(dtAllocNavMesh());
- ASSERT(mesh);
- if (dtStatusFailed(mesh->init(&params)))
+ if (fileHeader.mmapMagic != MMAP_MAGIC)
{
- TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {:04} from file {}", mapId, fileName);
- return LoadResult::LibraryError;
+ TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap {:04}.mmap", mapId);
+ return LoadResult::VersionMismatch;
}
- TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded {:04}.mmap", mapId);
+ if (fileHeader.mmapVersion != MMAP_VERSION)
+ {
+ TC_LOG_ERROR("maps", "MMAP:loadMap: {:04}.mmap was built with generator v{}, expected v{}",
+ mapId, fileHeader.mmapVersion, MMAP_VERSION);
+ return LoadResult::VersionMismatch;
+ }
+
+ memcpy(params, &fileHeader.params, sizeof(dtNavMeshParams));
+
+ if (offmeshConnections)
+ {
+ offmeshConnections->resize(fileHeader.offmeshConnectionCount);
+ if (fread(offmeshConnections->data(), sizeof(OffMeshData), offmeshConnections->size(), file.get()) != offmeshConnections->size())
+ {
+ offmeshConnections->clear();
+ TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read offmesh connections from file '{}'", fileName);
+ return LoadResult::ReadFromFileFailed;
+ }
+ }
- // store inside our map list
- itr->second.reset(new MMapData(std::move(mesh)));
return LoadResult::Success;
}
diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h
index 9973f37d51c..b48b773555b 100644
--- a/src/common/Collision/Management/MMapManager.h
+++ b/src/common/Collision/Management/MMapManager.h
@@ -19,7 +19,7 @@
#define _MMAP_MANAGER_H
#include "Define.h"
-#include <DetourNavMesh.h>
+#include "MMapDefines.h"
#include <DetourNavMeshQuery.h>
#include <memory>
#include <string_view>
@@ -58,6 +58,7 @@ namespace MMAP
static MMapManager* instance();
void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData);
+ static LoadResult parseNavMeshParamsFile(std::string_view basePath, uint32 mapId, dtNavMeshParams* params, std::vector<OffMeshData>* offmeshConnections = nullptr);
LoadResult loadMap(std::string_view basePath, uint32 mapId, int32 x, int32 y);
bool loadMapInstance(std::string_view basePath, uint32 meshMapId, uint32 instanceMapId, uint32 instanceId);
bool unloadMap(uint32 mapId, int32 x, int32 y);
diff --git a/src/common/Collision/Maps/MMapDefines.h b/src/common/Collision/Maps/MMapDefines.h
index 368281543a2..522112ebe62 100644
--- a/src/common/Collision/Maps/MMapDefines.h
+++ b/src/common/Collision/Maps/MMapDefines.h
@@ -19,22 +19,29 @@
#define MMapDefines_h__
#include "Define.h"
-#include "DetourNavMesh.h"
+#include <DetourNavMesh.h>
-const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
-#define MMAP_VERSION 15
+inline uint32 constexpr MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
+inline uint32 constexpr MMAP_VERSION = 16;
-struct MmapTileHeader
+struct MmapNavMeshHeader
{
- uint32 mmapMagic;
- uint32 dtVersion;
- uint32 mmapVersion;
- uint32 size;
- char usesLiquids;
- char padding[3];
+ uint32 mmapMagic = MMAP_MAGIC;
+ uint32 mmapVersion = MMAP_VERSION;
+ dtNavMeshParams params = { };
+ uint32 offmeshConnectionCount = 0;
+};
+
+static_assert(sizeof(MmapNavMeshHeader) == 40);
- MmapTileHeader() : mmapMagic(MMAP_MAGIC), dtVersion(DT_NAVMESH_VERSION),
- mmapVersion(MMAP_VERSION), size(0), usesLiquids(true), padding() { }
+struct MmapTileHeader
+{
+ uint32 mmapMagic = MMAP_MAGIC;
+ uint32 dtVersion = DT_NAVMESH_VERSION;
+ uint32 mmapVersion = MMAP_VERSION;
+ uint32 size = 0;
+ char usesLiquids = true;
+ char padding[3] = { };
};
// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files
@@ -60,7 +67,7 @@ enum NavArea
NAV_AREA_ALL_MASK = 0x3F // max allowed value
};
-enum NavTerrainFlag
+enum NavTerrainFlag : uint16
{
NAV_EMPTY = 0x00,
NAV_GROUND = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_GROUND),
@@ -69,4 +76,22 @@ enum NavTerrainFlag
NAV_MAGMA_SLIME = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_MAGMA_SLIME)
};
+enum OffMeshConnectionFlag : uint8
+{
+ OFFMESH_CONNECTION_FLAG_BIDIRECTIONAL = 0x01
+};
+
+struct OffMeshData
+{
+ uint32 MapId;
+ uint32 TileX;
+ uint32 TileY;
+ float From[3];
+ float To[3];
+ float Radius;
+ OffMeshConnectionFlag ConnectionFlags;
+ uint8 AreaId;
+ NavTerrainFlag Flags;
+};
+
#endif // MMapDefines_h__
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 3afab5ab244..7ecd2772491 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -201,7 +201,7 @@ namespace MMAP
if (scanned < 10)
continue;
- offMesh.Bidirectional = true;
+ offMesh.ConnectionFlags = OFFMESH_CONNECTION_FLAG_BIDIRECTIONAL;
if (scanned < 12)
offMesh.Flags = NAV_GROUND;
@@ -447,17 +447,16 @@ namespace MMAP
/*** now create the navmesh ***/
// navmesh creation params
- dtNavMeshParams navMeshParams;
- memset(&navMeshParams, 0, sizeof(dtNavMeshParams));
- navMeshParams.tileWidth = GRID_SIZE;
- navMeshParams.tileHeight = GRID_SIZE;
- rcVcopy(navMeshParams.orig, bmin);
- navMeshParams.maxTiles = maxTiles;
- navMeshParams.maxPolys = maxPolysPerTile;
+ MmapNavMeshHeader fileHeader;
+ fileHeader.params.tileWidth = GRID_SIZE;
+ fileHeader.params.tileHeight = GRID_SIZE;
+ rcVcopy(fileHeader.params.orig, bmin);
+ fileHeader.params.maxTiles = maxTiles;
+ fileHeader.params.maxPolys = maxPolysPerTile;
navMesh = dtAllocNavMesh();
TC_LOG_INFO("maps.mmapgen", "[Map {:04}] Creating navMesh...", mapID);
- if (!navMesh->init(&navMeshParams))
+ if (!navMesh->init(&fileHeader.params))
{
TC_LOG_ERROR("maps.mmapgen", "[Map {:04}] Failed creating navmesh!", mapID);
return;
@@ -474,8 +473,14 @@ namespace MMAP
return;
}
+ std::vector<OffMeshData> offMeshConnections;
+ std::ranges::copy_if(m_offMeshConnections, std::back_inserter(offMeshConnections), [mapID](OffMeshData const& offMeshData) { return offMeshData.MapId == mapID; });
+
+ fileHeader.offmeshConnectionCount = offMeshConnections.size();
+
// now that we know navMesh params are valid, we can write them to file
- fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, file.get());
+ fwrite(&fileHeader, sizeof(MmapNavMeshHeader), 1, file.get());
+ fwrite(offMeshConnections.data(), sizeof(OffMeshData), offMeshConnections.size(), file.get());
}
/**************************************************************************/
diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp
index d4170938819..e93f2b5a57d 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.cpp
+++ b/src/tools/mmaps_generator/TerrainBuilder.cpp
@@ -800,7 +800,7 @@ namespace MMAP
meshData.offMeshConnections.push_back(offMeshConnection.To[2]);
meshData.offMeshConnections.push_back(offMeshConnection.To[0]);
- meshData.offMeshConnectionDirs.push_back(offMeshConnection.Bidirectional ? 1 : 0);
+ meshData.offMeshConnectionDirs.push_back(offMeshConnection.ConnectionFlags & OFFMESH_CONNECTION_FLAG_BIDIRECTIONAL);
meshData.offMeshConnectionRads.push_back(offMeshConnection.Radius); // agent size equivalent
// can be used same way as polygon flags
meshData.offMeshConnectionsAreas.push_back(offMeshConnection.AreaId);
diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h
index a8a21025a98..65ebe4508a9 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.h
+++ b/src/tools/mmaps_generator/TerrainBuilder.h
@@ -18,6 +18,7 @@
#ifndef _MMAP_TERRAIN_BUILDER_H
#define _MMAP_TERRAIN_BUILDER_H
+#include "MMapDefines.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
#include <boost/filesystem/path.hpp>
@@ -61,19 +62,6 @@ namespace MMAP
// contrib/extractor/system.cpp
// src/game/Map.cpp
- struct OffMeshData
- {
- uint32 MapId;
- uint32 TileX;
- uint32 TileY;
- float From[3];
- float To[3];
- bool Bidirectional;
- float Radius;
- uint8 AreaId;
- uint16 Flags;
- };
-
struct MeshData
{
std::vector<float> solidVerts;
diff --git a/src/tools/mmaps_generator/TileBuilder.cpp b/src/tools/mmaps_generator/TileBuilder.cpp
index 6c651d6d3b4..5654a14183c 100644
--- a/src/tools/mmaps_generator/TileBuilder.cpp
+++ b/src/tools/mmaps_generator/TileBuilder.cpp
@@ -125,9 +125,8 @@ namespace MMAP
// gather all mesh data for final data check, and bounds calculation
std::vector<float> allVerts(meshData.liquidVerts.size() + meshData.solidVerts.size());
- auto allVertsOutput = allVerts.begin();
- allVertsOutput = std::ranges::copy(meshData.liquidVerts, allVertsOutput).out;
- allVertsOutput = std::ranges::copy(meshData.solidVerts, allVertsOutput).out;
+ std::ranges::copy(meshData.liquidVerts, allVerts.begin());
+ std::ranges::copy(meshData.solidVerts, allVerts.begin() + std::ssize(meshData.liquidVerts));
// get bounds of current tile
float bmin[3], bmax[3];
@@ -489,11 +488,11 @@ namespace MMAP
}
/**************************************************************************/
- void TileBuilder::getTileBounds(uint32 tileX, uint32 tileY, float* verts, int vertCount, float* bmin, float* bmax)
+ void TileBuilder::getTileBounds(uint32 tileX, uint32 tileY, float const* verts, std::size_t vertCount, float* bmin, float* bmax)
{
// this is for elevation
if (verts && vertCount)
- rcCalcBounds(verts, vertCount, bmin, bmax);
+ rcCalcBounds(verts, int(vertCount), bmin, bmax);
else
{
bmin[1] = FLT_MIN;
diff --git a/src/tools/mmaps_generator/TileBuilder.h b/src/tools/mmaps_generator/TileBuilder.h
index 203e089909d..f7c4806c515 100644
--- a/src/tools/mmaps_generator/TileBuilder.h
+++ b/src/tools/mmaps_generator/TileBuilder.h
@@ -74,7 +74,7 @@ public:
virtual bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const;
static void getTileBounds(uint32 tileX, uint32 tileY,
- float* verts, int vertCount,
+ float const* verts, std::size_t vertCount,
float* bmin, float* bmax);
rcConfig GetMapSpecificConfig(uint32 mapID, float const (&bmin)[3], float const (&bmax)[3], TileConfig const& tileConfig) const;