/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#ifndef _MAP_BUILDER_H
#define _MAP_BUILDER_H
#include "FlatSet.h"
#include "Optional.h"
#include "ProducerConsumerQueue.h"
#include "TerrainBuilder.h"
#include
#include
#include
#include
#include
#include
using namespace VMAP;
namespace MMAP
{
typedef std::unordered_map> TileList;
struct Tile
{
Tile() : chf(nullptr), solid(nullptr), cset(nullptr), pmesh(nullptr), dmesh(nullptr) {}
~Tile()
{
rcFreeCompactHeightfield(chf);
rcFreeContourSet(cset);
rcFreeHeightField(solid);
rcFreePolyMesh(pmesh);
rcFreePolyMeshDetail(dmesh);
}
rcCompactHeightfield* chf;
rcHeightfield* solid;
rcContourSet* cset;
rcPolyMesh* pmesh;
rcPolyMeshDetail* dmesh;
};
struct TileConfig
{
TileConfig(bool bigBaseUnit)
{
// these are WORLD UNIT based metrics
// this are basic unit dimentions
// value have to divide GRID_SIZE(533.3333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc )
BASE_UNIT_DIM = bigBaseUnit ? 0.5333333f : 0.2666666f;
// All are in UNIT metrics!
VERTEX_PER_MAP = int(GRID_SIZE / BASE_UNIT_DIM + 0.5f);
VERTEX_PER_TILE = bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP
TILES_PER_MAP = VERTEX_PER_MAP / VERTEX_PER_TILE;
}
float BASE_UNIT_DIM;
int VERTEX_PER_MAP;
int VERTEX_PER_TILE;
int TILES_PER_MAP;
};
struct TileInfo
{
TileInfo() : m_mapId(uint32(-1)), m_tileX(), m_tileY(), m_navMeshParams() {}
uint32 m_mapId;
uint32 m_tileX;
uint32 m_tileY;
dtNavMeshParams m_navMeshParams;
};
// ToDo: move this to its own file. For now it will stay here to keep the changes to a minimum, especially in the cpp file
class MapBuilder;
class TileBuilder
{
public:
TileBuilder(MapBuilder* mapBuilder,
bool skipLiquid,
bool bigBaseUnit,
bool debugOutput);
TileBuilder(TileBuilder&&) = default;
~TileBuilder();
void WorkerThread();
void WaitCompletion();
void buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh);
// move map building
void buildMoveMapTile(uint32 mapID,
uint32 tileX,
uint32 tileY,
MeshData& meshData,
float bmin[3],
float bmax[3],
dtNavMesh* navMesh);
bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const;
private:
bool m_bigBaseUnit;
bool m_debugOutput;
MapBuilder* m_mapBuilder;
TerrainBuilder* m_terrainBuilder;
std::thread m_workerThread;
// build performance - not really used for now
rcContext* m_rcContext;
};
class MapBuilder
{
friend class TileBuilder;
public:
MapBuilder(Optional maxWalkableAngle,
Optional maxWalkableAngleNotSteep,
bool skipLiquid,
bool skipContinents,
bool skipJunkMaps,
bool skipBattlegrounds,
bool debugOutput,
bool bigBaseUnit,
int mapid,
char const* offMeshFilePath,
unsigned int threads);
~MapBuilder();
void buildMeshFromFile(char* name);
// builds an mmap tile for the specified map and its mesh
void buildSingleTile(uint32 mapID, uint32 tileX, uint32 tileY);
// builds list of maps, then builds all of mmap tiles (based on the skip settings)
void buildMaps(Optional mapID);
private:
// builds all mmap tiles for the specified map id (ignores skip settings)
void buildMap(uint32 mapID);
// detect maps and tiles
void discoverTiles();
std::span 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;
bool shouldSkipMap(uint32 mapID) const;
bool isTransportMap(uint32 mapID) const;
bool isDevMap(uint32 mapID) const;
bool isBattlegroundMap(uint32 mapID) const;
bool isContinentMap(uint32 mapID) const;
rcConfig GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) const;
uint32 percentageDone(uint32 totalTiles, uint32 totalTilesDone) const;
uint32 currentPercentageDone() const;
void ParseOffMeshConnectionsFile(char const* offMeshFilePath);
TerrainBuilder* m_terrainBuilder;
TileList m_tiles;
bool m_debugOutput;
std::vector m_offMeshConnections;
unsigned int m_threads;
bool m_skipContinents;
bool m_skipJunkMaps;
bool m_skipBattlegrounds;
bool m_skipLiquid;
Optional m_maxWalkableAngle;
Optional m_maxWalkableAngleNotSteep;
bool m_bigBaseUnit;
int32 m_mapid;
uint32 m_totalTiles;
std::atomic m_totalTilesProcessed;
// build performance - not really used for now
rcContext* m_rcContext;
std::vector m_tileBuilders;
ProducerConsumerQueue _queue;
std::atomic _cancelationToken;
};
}
#endif