Tools/MMapsGenerator: Add some more input parameters to improve mmaps load performances (#25520)

* Some research about mmaps load performances

* Tools/MMapsGenerator: Add some more input parameters

Add some more input parameters which affect the resulting mmaps:
- --smallOutputSize: sets both walkableSlopeAngle and walkableSlopeAngleNotSteep to 55°, reducing by a lot the .mmtile size and the number of polys. A rcFilterLedgeSpans() call is included too to filter out some polys. Default to false.
- --maxAngle: Restore this parameter removed some commits ago. Specifies the max walkable angle of a Creature when in combat. Default to 85
- --maxAngleNotSteep: Max walkable angle of a Player and of a Creature out of combat. Must be less or equal than --maxAngle. Default to 55.

A performance profiling comparison highlighted that .mmtile load grows exponential with the number of polys. A small server with GridUnload enabled and without preloading all grids on startup will be more affected than a big server with GridUnload disabled and preloading grids on startup.
This commit is contained in:
Giacomo Pozzoni
2020-10-04 21:08:54 +02:00
committed by GitHub
parent 5be7c2ad4f
commit b6e205f7ef
3 changed files with 64 additions and 13 deletions

View File

@@ -31,16 +31,19 @@
namespace MMAP
{
MapBuilder::MapBuilder(bool skipLiquid,
MapBuilder::MapBuilder(Optional<float> maxWalkableAngle, Optional<float> maxWalkableAngleNotSteep, bool skipLiquid,
bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds,
bool debugOutput, bool bigBaseUnit, int mapid, char const* offMeshFilePath) :
bool debugOutput, bool bigBaseUnit, bool smallOutputSize, int mapid, char const* offMeshFilePath) :
m_terrainBuilder (nullptr),
m_debugOutput (debugOutput),
m_offMeshFilePath (offMeshFilePath),
m_skipContinents (skipContinents),
m_skipJunkMaps (skipJunkMaps),
m_skipBattlegrounds (skipBattlegrounds),
m_maxWalkableAngle (maxWalkableAngle),
m_maxWalkableAngleNotSteep (maxWalkableAngleNotSteep),
m_bigBaseUnit (bigBaseUnit),
m_smallOutputSize (smallOutputSize),
m_mapid (mapid),
m_totalTiles (0u),
m_totalTilesProcessed(0u),
@@ -602,8 +605,9 @@ namespace MMAP
delete[] triFlags;
rcFilterLowHangingWalkableObstacles(m_rcContext, config.walkableClimb, *tile.solid);
// disabled as it ignores walkableSlopeAngle settings
//rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
// disabled by default as it ignores walkableSlopeAngle settings
if (m_smallOutputSize)
rcFilterLedgeSpans(m_rcContext, tileCfg.walkableHeight, tileCfg.walkableClimb, *tile.solid);
rcFilterWalkableLowHeightSpans(m_rcContext, tileCfg.walkableHeight, *tile.solid);
// add liquid triangles
@@ -836,6 +840,11 @@ namespace MMAP
header.size = uint32(navDataSize);
fwrite(&header, sizeof(MmapTileHeader), 1, file);
/*
dtMeshHeader* navDataHeader = (dtMeshHeader*)navData;
printf("Poly count: %d\n", navDataHeader->polyCount);
*/
// write data
fwrite(navData, sizeof(unsigned char), navDataSize, file);
fclose(file);
@@ -1016,8 +1025,10 @@ namespace MMAP
config.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
config.cs = tileConfig.BASE_UNIT_DIM;
config.ch = tileConfig.BASE_UNIT_DIM;
config.walkableSlopeAngle = 85;
config.walkableSlopeAngleNotSteep = 55;
// Keeping these 2 slope angles the same reduces a lot the number of polys.
// 55 should be the minimum, maybe 70 is ok (keep in mind blink uses mmaps), 85 is too much for players
config.walkableSlopeAngle = m_maxWalkableAngle ? *m_maxWalkableAngle : m_smallOutputSize ? 55 : 85;
config.walkableSlopeAngleNotSteep = m_maxWalkableAngleNotSteep ? *m_maxWalkableAngleNotSteep : 55;
config.tileSize = tileConfig.VERTEX_PER_TILE;
config.walkableRadius = m_bigBaseUnit ? 1 : 2;
config.borderSize = config.walkableRadius + 3;

View File

@@ -22,6 +22,7 @@
#include "Recast.h"
#include "DetourNavMesh.h"
#include "Optional.h"
#include "ProducerConsumerQueue.h"
#include <vector>
@@ -94,12 +95,15 @@ namespace MMAP
class MapBuilder
{
public:
MapBuilder(bool skipLiquid = false,
MapBuilder(Optional<float> maxWalkableAngle,
Optional<float> maxWalkableAngleNotSteep,
bool skipLiquid = false,
bool skipContinents = false,
bool skipJunkMaps = true,
bool skipBattlegrounds = false,
bool debugOutput = false,
bool bigBaseUnit = false,
bool smallOutputSize = false,
int mapid = -1,
char const* offMeshFilePath = nullptr);
@@ -159,7 +163,10 @@ namespace MMAP
bool m_skipJunkMaps;
bool m_skipBattlegrounds;
Optional<float> m_maxWalkableAngle;
Optional<float> m_maxWalkableAngleNotSteep;
bool m_bigBaseUnit;
bool m_smallOutputSize;
int32 m_mapid;

View File

@@ -75,6 +75,8 @@ bool handleArgs(int argc, char** argv,
int &mapnum,
int &tileX,
int &tileY,
Optional<float>& maxAngle,
Optional<float>& maxAngleNotSteep,
bool &skipLiquid,
bool &skipContinents,
bool &skipJunkMaps,
@@ -82,6 +84,7 @@ bool handleArgs(int argc, char** argv,
bool &debugOutput,
bool &silent,
bool &bigBaseUnit,
bool &smallOutputSize,
char* &offMeshInputPath,
char* &file,
unsigned int& threads)
@@ -89,7 +92,31 @@ bool handleArgs(int argc, char** argv,
char* param = nullptr;
for (int i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "--threads") == 0)
if (strcmp(argv[i], "--maxAngle") == 0)
{
param = argv[++i];
if (!param)
return false;
float maxangle = atof(param);
if (maxangle <= 90.f && maxangle >= 0.f)
maxAngle = maxangle;
else
printf("invalid option for '--maxAngle', using default\n");
}
else if (strcmp(argv[i], "--maxAngleNotSteep") == 0)
{
param = argv[++i];
if (!param)
return false;
float maxangle = atof(param);
if (maxangle <= 90.f && maxangle >= 0.f)
maxAngleNotSteep = maxangle;
else
printf("invalid option for '--maxAngleNotSteep', using default\n");
}
else if (strcmp(argv[i], "--threads") == 0)
{
param = argv[++i];
if (!param)
@@ -215,6 +242,10 @@ bool handleArgs(int argc, char** argv,
offMeshInputPath = param;
}
else if (strcmp(argv[i], "--smallOutputSize") == 0)
{
smallOutputSize = true;
}
else
{
int map = atoi(argv[i]);
@@ -262,20 +293,22 @@ int main(int argc, char** argv)
unsigned int threads = std::thread::hardware_concurrency();
int mapnum = -1;
int tileX = -1, tileY = -1;
Optional<float> maxAngle, maxAngleNotSteep;
bool skipLiquid = false,
skipContinents = false,
skipJunkMaps = true,
skipBattlegrounds = false,
debugOutput = false,
silent = false,
bigBaseUnit = false;
bigBaseUnit = false,
smallOutputSize = false;
char* offMeshInputPath = nullptr;
char* file = nullptr;
bool validParam = handleArgs(argc, argv, mapnum,
tileX, tileY,
tileX, tileY, maxAngle, maxAngleNotSteep,
skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds,
debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads);
debugOutput, silent, bigBaseUnit, smallOutputSize, offMeshInputPath, file, threads);
if (!validParam)
return silent ? -1 : finish("You have specified invalid parameters", -1);
@@ -299,8 +332,8 @@ int main(int argc, char** argv)
if (_liquidTypes.empty())
return silent ? -5 : finish("Failed to load LiquidType.dbc", -5);
MapBuilder builder(skipLiquid, skipContinents, skipJunkMaps,
skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath);
MapBuilder builder(maxAngle, maxAngleNotSteep, skipLiquid, skipContinents, skipJunkMaps,
skipBattlegrounds, debugOutput, bigBaseUnit, smallOutputSize, mapnum, offMeshInputPath);
uint32 start = getMSTime();
if (file)