diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-11-05 18:55:45 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-11-05 18:55:45 +0100 |
| commit | 145bbde2317f139c5be796801a7b254265c250d1 (patch) | |
| tree | eb7004bdac6ef5444f7e3ca70c343dc5ff6912f1 /src | |
| parent | 1e56367b3004be6e8a6144e0885ccc1ca3674e40 (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.cpp | 57 | ||||
| -rw-r--r-- | src/common/Collision/Management/MMapManager.h | 3 | ||||
| -rw-r--r-- | src/common/Collision/Maps/MMapDefines.h | 51 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/MapBuilder.cpp | 25 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.cpp | 2 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.h | 14 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TileBuilder.cpp | 9 | ||||
| -rw-r--r-- | src/tools/mmaps_generator/TileBuilder.h | 2 |
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, ¶ms); paramsResult != LoadResult::Success) + return paramsResult; + + NavMeshPtr mesh(dtAllocNavMesh()); + ASSERT(mesh); + if (dtStatusFailed(mesh->init(¶ms))) + { + 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(¶ms, 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(¶ms))) + 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; |
