Tools/mmaps_generator: Allow specifying custom offmesh area/flags

This commit is contained in:
Shauren
2023-10-16 10:55:34 +02:00
parent 3e71d793b4
commit 348e29c79f
4 changed files with 70 additions and 43 deletions

View File

@@ -19,6 +19,7 @@
#include "Containers.h"
#include "IntermediateValues.h"
#include "MapTree.h"
#include "Memory.h"
#include "MMapDefines.h"
#include "ModelInstance.h"
#include "PathCommon.h"
@@ -60,7 +61,6 @@ namespace MMAP
bool debugOutput, bool bigBaseUnit, int mapid, char const* offMeshFilePath, unsigned int threads) :
m_terrainBuilder (nullptr),
m_debugOutput (debugOutput),
m_offMeshFilePath (offMeshFilePath),
m_threads (threads),
m_skipContinents (skipContinents),
m_skipJunkMaps (skipJunkMaps),
@@ -83,6 +83,8 @@ namespace MMAP
m_threads = std::max(1u, m_threads);
discoverTiles();
ParseOffMeshConnectionsFile(offMeshFilePath);
}
/**************************************************************************/
@@ -193,6 +195,41 @@ namespace MMAP
}
}
/**************************************************************************/
void MapBuilder::ParseOffMeshConnectionsFile(char const* offMeshFilePath)
{
// no meshfile input given?
if (offMeshFilePath == nullptr)
return;
auto fp = Trinity::make_unique_ptr_with_deleter(fopen(offMeshFilePath, "rb"), &::fclose);
if (!fp)
{
printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath);
return;
}
char buf[512] = { };
while (fgets(buf, 512, fp.get()))
{
OffMeshData offMesh;
int32 scanned = sscanf(buf, "%u %u,%u (%f %f %f) (%f %f %f) %f %hhu %hu", &offMesh.MapId, &offMesh.TileX, &offMesh.TileY,
&offMesh.From[0], &offMesh.From[1], &offMesh.From[2], &offMesh.To[0], &offMesh.To[1], &offMesh.To[2],
&offMesh.Radius, &offMesh.AreaId, &offMesh.Flags);
if (scanned < 10)
continue;
offMesh.Bidirectional = true;
if (scanned < 12)
offMesh.Flags = NAV_GROUND;
if (scanned < 11)
offMesh.AreaId = NAV_AREA_GROUND;
m_offMeshConnections.push_back(offMesh);
}
}
/**************************************************************************/
std::set<uint32>* MapBuilder::getTileList(uint32 mapID)
{
@@ -504,7 +541,7 @@ namespace MMAP
float bmin[3], bmax[3];
m_mapBuilder->getTileBounds(tileX, tileY, allVerts.getCArray(), allVerts.size() / 3, bmin, bmax);
m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_mapBuilder->m_offMeshFilePath);
m_terrainBuilder->loadOffMeshConnections(mapID, tileX, tileY, meshData, m_mapBuilder->m_offMeshConnections);
// build navmesh tile
buildMoveMapTile(mapID, tileX, tileY, meshData, bmin, bmax, navMesh);

View File

@@ -193,12 +193,14 @@ namespace MMAP
uint32 percentageDone(uint32 totalTiles, uint32 totalTilesDone) const;
uint32 currentPercentageDone() const;
void ParseOffMeshConnectionsFile(char const* offMeshFilePath);
TerrainBuilder* m_terrainBuilder;
TileList m_tiles;
bool m_debugOutput;
char const* m_offMeshFilePath;
std::vector<OffMeshData> m_offMeshConnections;
unsigned int m_threads;
bool m_skipContinents;
bool m_skipJunkMaps;

View File

@@ -834,51 +834,26 @@ namespace MMAP
}
/**************************************************************************/
void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, char const* offMeshFilePath)
void TerrainBuilder::loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData, std::vector<OffMeshData> const& offMeshConnections)
{
// no meshfile input given?
if (offMeshFilePath == nullptr)
return;
FILE* fp = fopen(offMeshFilePath, "rb");
if (!fp)
for (OffMeshData const& offMeshConnection : offMeshConnections)
{
printf(" loadOffMeshConnections:: input file %s not found!\n", offMeshFilePath);
return;
}
// pretty silly thing, as we parse entire file and load only the tile we need
// but we don't expect this file to be too large
char* buf = new char[512];
while(fgets(buf, 512, fp))
{
float p0[3], p1[3];
uint32 mid, tx, ty;
float size;
if (sscanf(buf, "%u %u,%u (%f %f %f) (%f %f %f) %f", &mid, &tx, &ty,
&p0[0], &p0[1], &p0[2], &p1[0], &p1[1], &p1[2], &size) != 10)
if (mapID != offMeshConnection.MapId || tileX != offMeshConnection.TileX || tileY != offMeshConnection.TileY)
continue;
if (mapID == mid && tileX == tx && tileY == ty)
{
meshData.offMeshConnections.append(p0[1]);
meshData.offMeshConnections.append(p0[2]);
meshData.offMeshConnections.append(p0[0]);
meshData.offMeshConnections.append(offMeshConnection.From[1]);
meshData.offMeshConnections.append(offMeshConnection.From[2]);
meshData.offMeshConnections.append(offMeshConnection.From[0]);
meshData.offMeshConnections.append(p1[1]);
meshData.offMeshConnections.append(p1[2]);
meshData.offMeshConnections.append(p1[0]);
meshData.offMeshConnectionDirs.append(1); // 1 - both direction, 0 - one sided
meshData.offMeshConnectionRads.append(size); // agent size equivalent
// can be used same way as polygon flags
meshData.offMeshConnectionsAreas.append((unsigned char)0xFF);
meshData.offMeshConnectionsFlags.append((unsigned short)0xFF); // all movement masks can make this path
}
meshData.offMeshConnections.append(offMeshConnection.To[1]);
meshData.offMeshConnections.append(offMeshConnection.To[2]);
meshData.offMeshConnections.append(offMeshConnection.To[0]);
meshData.offMeshConnectionDirs.append(offMeshConnection.Bidirectional ? 1 : 0);
meshData.offMeshConnectionRads.append(offMeshConnection.Radius); // agent size equivalent
// can be used same way as polygon flags
meshData.offMeshConnectionsAreas.append(offMeshConnection.AreaId);
meshData.offMeshConnectionsFlags.append(offMeshConnection.Flags);
}
delete [] buf;
fclose(fp);
}
}

View File

@@ -58,6 +58,19 @@ 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
{
G3D::Array<float> solidVerts;
@@ -83,7 +96,7 @@ namespace MMAP
void loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
bool loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData);
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, char const* offMeshFilePath);
void loadOffMeshConnections(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, std::vector<OffMeshData> const& offMeshConnections);
bool usesLiquids() const { return !m_skipLiquid; }