feat(Core/Common): delete lib game-interface inherited (#5333)

Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
This commit is contained in:
Kargatum
2021-05-07 02:16:44 +07:00
committed by GitHub
parent 6947789622
commit db7d754f3f
45 changed files with 428 additions and 475 deletions

View File

@@ -5,16 +5,12 @@
*/
#include "DynamicTree.h"
//#include "QuadTree.h"
//#include "RegularGrid.h"
#include "BoundingIntervalHierarchyWrapper.h"
#include "Log.h"
#include "RegularGrid.h"
#include "Timer.h"
#include "GameObjectModel.h"
#include "ModelInstance.h"
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include <G3D/Vector3.h>
@@ -23,10 +19,8 @@ using VMAP::ModelInstance;
namespace
{
int CHECK_TREE_PERIOD = 200;
} // namespace
}
template<> struct HashTrait< GameObjectModel>
{
@@ -44,15 +38,9 @@ template<> struct BoundsTrait< GameObjectModel>
static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();}
};
/*
static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2){
return &mdl == &mdl2;
}
*/
typedef RegularGrid2D<GameObjectModel, BIHWrap<GameObjectModel>> ParentTree;
struct DynTreeImpl : public ParentTree/*, public Intersectable*/
struct DynTreeImpl : public ParentTree
{
typedef GameObjectModel Model;
typedef ParentTree base;

View File

@@ -35,4 +35,4 @@ namespace MMAP
};
}
#endif
#endif

View File

@@ -18,7 +18,6 @@ This is the minimum interface to the VMapMamager.
namespace VMAP
{
enum VMAP_LOAD_RESULT
{
VMAP_LOAD_RESULT_ERROR,
@@ -83,6 +82,6 @@ namespace VMAP
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type) const = 0;
};
}
#endif

View File

@@ -5,7 +5,6 @@
*/
#include "MMapFactory.h"
#include "World.h"
#include <set>
namespace MMAP
@@ -23,12 +22,6 @@ namespace MMAP
return g_MMapManager;
}
bool MMapFactory::IsPathfindingEnabled(const Map* map)
{
if (!map) return false;
return !forbiddenMaps[map->GetId()] && (sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) ? true : map->IsBattlegroundOrArena());
}
void MMapFactory::InitializeDisabledMaps()
{
memset(&forbiddenMaps, 0, sizeof(forbiddenMaps));
@@ -46,4 +39,4 @@ namespace MMAP
g_MMapManager = nullptr;
}
}
}
}

View File

@@ -10,8 +10,7 @@
#include "MMapManager.h"
#include "DetourAlloc.h"
#include "DetourNavMesh.h"
#include "Navigation/DetourExtended.h"
#include "Map.h"
#include "DetourExtended.h"
#include <unordered_map>
namespace MMAP
@@ -31,7 +30,6 @@ namespace MMAP
public:
static MMapManager* createOrGetMMapManager();
static void clear();
static bool IsPathfindingEnabled(const Map* map);
static void InitializeDisabledMaps();
static bool forbiddenMaps[1000];
};

View File

@@ -4,9 +4,10 @@
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*/
#include "Config.h"
#include "MapManager.h"
#include "MMapManager.h"
#include "Config.h"
#include "Errors.h"
#include "MapDefines.h"
#include "Log.h"
#include "StringFormat.h"
@@ -25,11 +26,41 @@ namespace MMAP
// if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
}
void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
{
// the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
for (const uint32& mapId : mapIds)
loadedMMaps.emplace(mapId, nullptr);
thread_safe_environment = false;
}
MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const
{
// return the iterator if found or end() if not found/NULL
MMapDataSet::const_iterator itr = loadedMMaps.find(mapId);
if (itr != loadedMMaps.cend() && !itr->second)
itr = loadedMMaps.cend();
return itr;
}
bool MMapManager::loadMapData(uint32 mapId)
{
// we already have this map loaded?
if (loadedMMaps.find(mapId) != loadedMMaps.end())
return true;
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
if (itr != loadedMMaps.end())
{
if (itr->second)
return true;
}
else
{
if (thread_safe_environment)
itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first;
else
ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId);
}
// load and init dtNavMesh - read parameters from file
std::string fileName = acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption<std::string>("DataDir", ".").c_str(), mapId);
@@ -37,18 +68,16 @@ namespace MMAP
FILE* file = fopen(fileName.c_str(), "rb");
if (!file)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName.c_str());
#endif
return false;
}
dtNavMeshParams params;
int count = fread(&params, sizeof(dtNavMeshParams), 1, file);
uint32 count = uint32(fread(&params, sizeof(dtNavMeshParams), 1, file));
fclose(file);
if (count != 1)
{
;//TC_LOG_DEBUG(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName.c_str());
return false;
}
@@ -61,15 +90,11 @@ namespace MMAP
return false;
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
#endif
LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId);
// store inside our map list
MMapData* mmap_data = new MMapData(mesh);
mmap_data->mmapLoadedTiles.clear();
loadedMMaps.insert(std::pair<uint32, MMapData*>(mapId, mmap_data));
itr->second = mmap_data;
return true;
}
@@ -78,22 +103,8 @@ namespace MMAP
return uint32(x << 16 | y);
}
std::shared_mutex& MMapManager::GetMMapLock(uint32 mapId)
{
Map* map = sMapMgr->FindBaseMap(mapId);
if (!map)
{
LOG_INFO("misc", "ZOMG! MoveMaps: BaseMap not found!");
return this->MMapLock;
}
return map->GetMMapLock();
}
bool MMapManager::loadMap(uint32 mapId, int32 x, int32 y)
{
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
// make sure the mmap is loaded and ready to load tiles
if (!loadMapData(mapId))
return false;
@@ -104,7 +115,7 @@ namespace MMAP
// check if we already have this tile loaded
uint32 packedGridPos = packTileID(x, y);
if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end())
if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
{
LOG_ERROR("server", "MMAP:loadMap: Asked to load already loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y);
return false;
@@ -151,26 +162,18 @@ namespace MMAP
dtTileRef tileRef = 0;
dtStatus stat;
{
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
stat = mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef);
}
// memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
if (stat == DT_SUCCESS)
if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)))
{
mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
++loadedTiles;
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
dtMeshHeader* header = (dtMeshHeader*)data;
LOG_DEBUG("server", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
#endif
LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
return true;
}
else
{
LOG_ERROR("server", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
dtFree(data);
return false;
}
@@ -180,10 +183,9 @@ namespace MMAP
bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
{
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
// check if we have this map loaded
if (loadedMMaps.find(mapId) == loadedMMaps.end())
MMapDataSet::const_iterator itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
{
// file may not exist, therefore not loaded
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -192,11 +194,11 @@ namespace MMAP
return false;
}
MMapData* mmap = loadedMMaps[mapId];
MMapData* mmap = itr->second;
// check if we have this tile loaded
uint32 packedGridPos = packTileID(x, y);
if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end())
if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
{
// file may not exist, therefore not loaded
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -205,16 +207,10 @@ namespace MMAP
return false;
}
dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
dtStatus status;
{
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
status = mmap->navMesh->removeTile(tileRef, nullptr, nullptr);
}
dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos];
// unload, and mark as non loaded
if (status != DT_SUCCESS)
if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr)))
{
// this is technically a memory leak
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
@@ -224,11 +220,9 @@ namespace MMAP
}
else
{
mmap->mmapLoadedTiles.erase(packedGridPos);
mmap->loadedTileRefs.erase(packedGridPos);
--loadedTiles;
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
#endif
LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
return true;
}
@@ -237,70 +231,52 @@ namespace MMAP
bool MMapManager::unloadMap(uint32 mapId)
{
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
if (loadedMMaps.find(mapId) == loadedMMaps.end())
MMapDataSet::iterator itr = loadedMMaps.find(mapId);
if (itr == loadedMMaps.end() || !itr->second)
{
// file may not exist, therefore not loaded
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId);
#endif
return false;
}
// unload all tiles from given map
MMapData* mmap = loadedMMaps[mapId];
for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i)
MMapData* mmap = itr->second;
for (auto i : mmap->loadedTileRefs)
{
uint32 x = (i->first >> 16);
uint32 y = (i->first & 0x0000FFFF);
uint32 x = (i.first >> 16);
uint32 y = (i.first & 0x0000FFFF);
dtStatus status;
{
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
status = mmap->navMesh->removeTile(i->second, nullptr, nullptr);
}
if (status != DT_SUCCESS)
if (dtStatusFailed(mmap->navMesh->removeTile(i.second, nullptr, nullptr)))
LOG_ERROR("server", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
else
{
--loadedTiles;
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
#endif
}
}
delete mmap;
loadedMMaps.erase(mapId);
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
#endif
itr->second = nullptr;
LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
return true;
}
bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId)
{
std::unique_lock<std::shared_mutex> guard(MMapManagerLock);
// check if we have this map loaded
if (loadedMMaps.find(mapId) == loadedMMaps.end())
MMapDataSet::const_iterator itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
{
// file may not exist, therefore not loaded
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId);
#endif
return false;
}
MMapData* mmap = loadedMMaps[mapId];
MMapData* mmap = itr->second;
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId);
#endif
return false;
}
@@ -308,47 +284,44 @@ namespace MMAP
dtFreeNavMeshQuery(query);
mmap->navMeshQueries.erase(instanceId);
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
#endif
LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
return true;
}
dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId)
{
if (loadedMMaps.find(mapId) == loadedMMaps.end())
MMapDataSet::const_iterator itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
return nullptr;
return loadedMMaps[mapId]->navMesh;
return itr->second->navMesh;
}
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
{
if (loadedMMaps.find(mapId) == loadedMMaps.end())
MMapDataSet::const_iterator itr = GetMMapData(mapId);
if (itr == loadedMMaps.end())
return nullptr;
MMapData* mmap = loadedMMaps[mapId];
MMapData* mmap = itr->second;
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// pussywizard: different instances of the same map shouldn't access this simultaneously
std::unique_lock<std::shared_mutex> guard(GetMMapLock(mapId));
// check again after acquiring mutex
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
{
dtFreeNavMeshQuery(query);
LOG_ERROR("server", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
return nullptr;
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("server", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
#endif
LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
}

View File

@@ -34,7 +34,8 @@ namespace MMAP
// dummy struct to hold map's mmap data
struct MMapData
{
MMapData(dtNavMesh* mesh) : navMesh(mesh) {}
MMapData(dtNavMesh* mesh) : navMesh(mesh) { }
~MMapData()
{
for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
@@ -44,11 +45,10 @@ namespace MMAP
dtFreeNavMesh(navMesh);
}
dtNavMesh* navMesh;
// we have to use single dtNavMeshQuery for every instance, since those are not thread safe
NavMeshQuerySet navMeshQueries; // instanceId to query
MMapTileSet mmapLoadedTiles; // maps [map grid coords] to [dtTile]
NavMeshQuerySet navMeshQueries; // instanceId to query
dtNavMesh* navMesh;
MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile]
};
typedef std::unordered_map<uint32, MMapData*> MMapDataSet;
@@ -58,9 +58,10 @@ namespace MMAP
class MMapManager
{
public:
MMapManager() : loadedTiles(0) {}
MMapManager() : loadedTiles(0), thread_safe_environment(true) { }
~MMapManager();
void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
bool loadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
@@ -73,18 +74,14 @@ namespace MMAP
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
std::shared_mutex& GetMMapLock(uint32 mapId);
std::shared_mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
std::shared_mutex& GetManagerLock() { return MMapManagerLock; }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
MMapDataSet::const_iterator GetMMapData(uint32 mapId) const;
MMapDataSet loadedMMaps;
uint32 loadedTiles;
std::shared_mutex MMapManagerLock;
std::shared_mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
bool thread_safe_environment;
};
}

View File

@@ -9,14 +9,15 @@
namespace VMAP
{
IVMapManager* gVMapManager = nullptr;
VMapManager2* gVMapManager = nullptr;
//===============================================
// just return the instance
IVMapManager* VMapFactory::createOrGetVMapManager()
VMapManager2* VMapFactory::createOrGetVMapManager()
{
if (gVMapManager == 0)
gVMapManager = new VMapManager2(); // should be taken from config ... Please change if you like :-)
if (!gVMapManager)
gVMapManager = new VMapManager2();
return gVMapManager;
}

View File

@@ -9,20 +9,16 @@
#include "IVMapManager.h"
/**
This is the access point to the VMapManager.
*/
// This is the access point to the VMapManager.
namespace VMAP
{
//===========================================================
class VMapManager2;
class VMapFactory
{
public:
static IVMapManager* createOrGetVMapManager();
static VMapManager2* createOrGetVMapManager();
static void clear();
};
}
#endif

View File

@@ -15,21 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include "VMapManager2.h"
#include "MapTree.h"
#include "ModelInstance.h"
#include "WorldModel.h"
#include <G3D/Vector3.h>
#include <ace/Null_Mutex.h>
#include "DisableMgr.h"
#include "DBCStores.h"
#include "MapDefines.h"
#include "Log.h"
#include "VMapDefinitions.h"
#include "GridDefines.h"
#include "Errors.h"
#include <G3D/Vector3.h>
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
using G3D::Vector3;
@@ -38,20 +36,32 @@ namespace VMAP
VMapManager2::VMapManager2()
{
GetLiquidFlagsPtr = &GetLiquidFlagsDummy;
IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy;
thread_safe_environment = true;
}
VMapManager2::~VMapManager2(void)
VMapManager2::~VMapManager2()
{
for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i)
{
delete i->second;
}
for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i)
{
delete i->second.getModel();
}
}
void VMapManager2::InitializeThreadUnsafe(const std::vector<uint32>& mapIds)
{
// the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime
for (const uint32& mapId : mapIds)
iInstanceMapTrees.emplace(mapId, nullptr);
thread_safe_environment = false;
}
Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const
{
Vector3 pos;
@@ -63,6 +73,16 @@ namespace VMAP
return pos;
}
InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const
{
// return the iterator if found or end() if not found/NULL
InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId);
if (itr != iInstanceMapTrees.cend() && !itr->second)
itr = iInstanceMapTrees.cend();
return itr;
}
// move to MapTree too?
std::string VMapManager2::getMapFileName(unsigned int mapId)
{
@@ -92,6 +112,15 @@ namespace VMAP
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree == iInstanceMapTrees.end())
{
if (thread_safe_environment)
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first;
else
ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment",
mapId, tileX, tileY);
}
if (!instanceTree->second)
{
std::string mapFileName = getMapFileName(mapId);
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
@@ -100,7 +129,7 @@ namespace VMAP
delete newTree;
return false;
}
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
instanceTree->second = newTree;
}
return instanceTree->second->LoadMapTile(tileX, tileY, this);
@@ -109,13 +138,13 @@ namespace VMAP
void VMapManager2::unloadMap(unsigned int mapId)
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
{
instanceTree->second->UnloadMap(this);
if (instanceTree->second->numLoadedTiles() == 0)
{
delete instanceTree->second;
iInstanceMapTrees.erase(mapId);
instanceTree->second = nullptr;
}
}
}
@@ -123,25 +152,25 @@ namespace VMAP
void VMapManager2::unloadMap(unsigned int mapId, int x, int y)
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree != iInstanceMapTrees.end())
if (instanceTree != iInstanceMapTrees.end() && instanceTree->second)
{
instanceTree->second->UnloadMapTile(x, y, this);
if (instanceTree->second->numLoadedTiles() == 0)
{
delete instanceTree->second;
iInstanceMapTrees.erase(mapId);
instanceTree->second = nullptr;
}
}
}
bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS))
#if defined(ENABLE_VMAP_CHECKS)
if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
return true;
#endif
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
if (instanceTree != iInstanceMapTrees.end())
{
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
@@ -161,11 +190,11 @@ namespace VMAP
*/
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS))
#if defined(ENABLE_VMAP_CHECKS)
if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
#endif
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
if (instanceTree != iInstanceMapTrees.end())
{
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
@@ -193,11 +222,11 @@ namespace VMAP
float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_HEIGHT))
#if defined(ENABLE_VMAP_CHECKS)
if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT))
#endif
{
InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId);
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
if (instanceTree != iInstanceMapTrees.end())
{
Vector3 pos = convertPositionToInternalRep(x, y, z);
@@ -214,11 +243,11 @@ namespace VMAP
bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_AREAFLAG))
#if defined(ENABLE_VMAP_CHECKS)
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG))
#endif
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
if (instanceTree != iInstanceMapTrees.end())
{
Vector3 pos = convertPositionToInternalRep(x, y, z);
@@ -234,11 +263,11 @@ namespace VMAP
bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LIQUIDSTATUS))
#if defined(ENABLE_VMAP_CHECKS)
if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS))
#endif
{
InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId);
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
if (instanceTree != iInstanceMapTrees.end())
{
LocationInfo info;
@@ -262,7 +291,7 @@ namespace VMAP
WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
@@ -274,20 +303,19 @@ namespace VMAP
delete worldmodel;
return nullptr;
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
#endif
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
model->second.setModel(worldmodel);
}
//model->second.incRefCount();
return model->second.getModel();
}
void VMapManager2::releaseModelInstance(const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
std::lock_guard<std::mutex> guard(LoadedModelFilesLock);
std::lock_guard<std::mutex> lock(LoadedModelFilesLock);
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
{
@@ -296,9 +324,7 @@ namespace VMAP
}
if (model->second.decRefCount() == 0)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
LOG_DEBUG("maps", "VMapManager2: unloading file '%s'", filename.c_str());
#endif
delete model->second.getModel();
iLoadedModelFiles.erase(model);
}
@@ -309,4 +335,9 @@ namespace VMAP
return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y);
}
void VMapManager2::getInstanceMapTree(InstanceTreeMap& instanceMapTree)
{
instanceMapTree = iInstanceMapTrees;
}
} // namespace VMAP

View File

@@ -19,9 +19,10 @@
#define _VMAPMANAGER2_H
#include "IVMapManager.h"
#include "Define.h"
#include "Common.h"
#include <mutex>
#include <unordered_map>
#include <vector>
//===========================================================
@@ -65,12 +66,22 @@ namespace VMAP
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
typedef std::unordered_map<std::string, ManagedModel> ModelFileMap;
enum DisableTypes
{
VMAP_DISABLE_AREAFLAG = 0x1,
VMAP_DISABLE_HEIGHT = 0x2,
VMAP_DISABLE_LOS = 0x4,
VMAP_DISABLE_LIQUIDSTATUS = 0x8
};
class VMapManager2 : public IVMapManager
{
protected:
// Tree to check collision
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
bool thread_safe_environment;
// Mutex for iLoadedModelFiles
std::mutex LoadedModelFilesLock;
@@ -78,6 +89,9 @@ namespace VMAP
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; }
InstanceTreeMap::const_iterator GetMapTree(uint32 mapId) const;
public:
// public for debug
@@ -87,6 +101,8 @@ namespace VMAP
VMapManager2();
~VMapManager2() override;
void InitializeThreadUnsafe(const std::vector<uint32>& mapIds);
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override;
void unloadMap(unsigned int mapId, int x, int y) override;
@@ -113,12 +129,14 @@ namespace VMAP
return getMapFileName(mapId);
}
bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
public:
void getInstanceMapTree(InstanceTreeMap& instanceMapTree);
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
GetLiquidFlagsFn GetLiquidFlagsPtr;
typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags);
IsVMAPDisabledForFn IsVMAPDisabledForPtr;
};
}
#endif
#endif

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008+ TrinityCore <http://www.trinitycore.org/>
*/
#ifndef _MAPDEFINES_H
#define _MAPDEFINES_H
#include "Define.h"
#include "DetourNavMesh.h"
#define MAX_NUMBER_OF_GRIDS 64
#define SIZE_OF_GRIDS 533.3333f
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 11
struct MmapTileHeader
{
uint32 mmapMagic{MMAP_MAGIC};
uint32 dtVersion;
uint32 mmapVersion{MMAP_VERSION};
uint32 size{0};
char usesLiquids{true};
char padding[3]{};
MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) { }
};
// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files
static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size");
static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) +
sizeof(MmapTileHeader::dtVersion) +
sizeof(MmapTileHeader::mmapVersion) +
sizeof(MmapTileHeader::size) +
sizeof(MmapTileHeader::usesLiquids) +
sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields");
enum NavTerrain
{
NAV_EMPTY = 0x00,
NAV_GROUND = 0x01,
NAV_MAGMA = 0x02,
NAV_SLIME = 0x04,
NAV_WATER = 0x08,
NAV_UNUSED1 = 0x10,
NAV_UNUSED2 = 0x20,
NAV_UNUSED3 = 0x40,
NAV_UNUSED4 = 0x80
// we only have 8 bits
};
#endif

View File

@@ -462,4 +462,10 @@ namespace VMAP
}
iLoadedTiles.erase(tile);
}
void StaticMapTree::getModelInstances(ModelInstance*& models, uint32& count)
{
models = iTreeValues;
count = iNTreeValues;
}
}

View File

@@ -8,7 +8,7 @@
#include "MapTree.h"
#include "BoundingIntervalHierarchy.h"
#include "VMapDefinitions.h"
#include "SharedDefines.h"
#include "MapDefines.h"
#include <set>
#include <sstream>
#include <iomanip>

View File

@@ -4,19 +4,13 @@
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*/
#include "GameObjectModel.h"
#include "VMapFactory.h"
#include "VMapManager2.h"
#include "VMapDefinitions.h"
#include "WorldModel.h"
#include "GameObjectModel.h"
#include "Log.h"
#include "GameObject.h"
#include "Creature.h"
#include "TemporarySummon.h"
#include "Object.h"
#include "DBCStores.h"
#include "World.h"
#include "Timer.h"
using G3D::Vector3;
using G3D::Ray;
@@ -35,16 +29,14 @@ struct GameobjectModelData
typedef std::unordered_map<uint32, GameobjectModelData> ModelList;
ModelList model_list;
void LoadGameObjectModelList()
void LoadGameObjectModelList(std::string const& dataPath)
{
//#ifndef NO_CORE_FUNCS
uint32 oldMSTime = getMSTime();
//#endif
FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
FILE* model_list_file = fopen((dataPath + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
if (!model_list_file)
{
LOG_ERROR("server", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
LOG_ERROR("maps", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
return;
}
@@ -72,7 +64,8 @@ void LoadGameObjectModelList()
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
{
LOG_ERROR("server", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
LOG_ERROR("maps", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
fclose(model_list_file);
break;
}
@@ -95,12 +88,12 @@ void LoadGameObjectModelList()
GameObjectModel::~GameObjectModel()
{
if (iModel)
((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->releaseModelInstance(name);
VMAP::VMapFactory::createOrGetVMapManager()->releaseModelInstance(name);
}
bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info)
bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
{
ModelList::const_iterator it = model_list.find(info.Displayid);
ModelList::const_iterator it = model_list.find(modelOwner->GetDisplayId());
if (it == model_list.end())
return false;
@@ -112,24 +105,18 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
return false;
}
iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(sWorld->GetDataPath() + "vmaps/", it->second.name);
iModel = VMAP::VMapFactory::createOrGetVMapManager()->acquireModelInstance(dataPath + "vmaps/", it->second.name);
if (!iModel)
return false;
name = it->second.name;
//flags = VMAP::MOD_M2;
//adtId = 0;
//ID = 0;
iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ());
// pussywizard:
phasemask = (go.GetGoState() == GO_STATE_READY || go.IsTransport()) ? go.GetPhaseMask() : 0;
iScale = go.GetFloatValue(OBJECT_FIELD_SCALE_X);
iPos = modelOwner->GetPosition();
phasemask = modelOwner->GetPhaseMask();
iScale = modelOwner->GetScale();
iInvScale = 1.f / iScale;
G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0);
G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(modelOwner->GetOrientation(), 0, 0);
iInvRot = iRotation.inverse();
// transform bounding box:
mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
@@ -138,27 +125,24 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
rotated_bounds.merge(iRotation * mdl_box.corner(i));
iBound = rotated_bounds + iPos;
#ifdef SPAWN_CORNERS
// test:
for (int i = 0; i < 8; ++i)
{
Vector3 pos(iBound.corner(i));
const_cast<GameObject&>(go).SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN);
modelOwner->DebugVisualizeCorner(pos);
}
#endif
owner = &go;
owner = std::move(modelOwner);
return true;
}
GameObjectModel* GameObjectModel::Create(const GameObject& go)
GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
{
const GameObjectDisplayInfoEntry* info = sGameObjectDisplayInfoStore.LookupEntry(go.GetDisplayId());
if (!info)
return nullptr;
GameObjectModel* mdl = new GameObjectModel();
if (!mdl->initialize(go, *info))
if (!mdl->initialize(std::move(modelOwner), dataPath))
{
delete mdl;
return nullptr;
@@ -169,7 +153,7 @@ GameObjectModel* GameObjectModel::Create(const GameObject& go)
bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const
{
if (!(phasemask & ph_mask) || !owner->isSpawned())
if (!(phasemask & ph_mask) || !owner->IsSpawned())
return false;
float time = ray.intersectionTime(iBound);
@@ -199,6 +183,7 @@ bool GameObjectModel::UpdatePosition()
return false;
G3D::AABox mdl_box(it->second.bound);
// ignore models with no bounds
if (mdl_box == G3D::AABox::zero())
{
@@ -206,12 +191,14 @@ bool GameObjectModel::UpdatePosition()
return false;
}
iPos = Vector3(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ());
iPos = owner->GetPosition();
G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0);
iInvRot = iRotation.inverse();
// transform bounding box:
mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale);
AABox rotated_bounds;
for (int i = 0; i < 8; ++i)
rotated_bounds.merge(iRotation * mdl_box.corner(i));
@@ -221,7 +208,7 @@ bool GameObjectModel::UpdatePosition()
for (int i = 0; i < 8; ++i)
{
Vector3 pos(iBound.corner(i));
owner->SummonCreature(1, pos.x, pos.y, pos.z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000);
owner->DebugVisualizeCorner(pos);
}
#endif

View File

@@ -7,13 +7,12 @@
#ifndef _GAMEOBJECT_MODEL_H
#define _GAMEOBJECT_MODEL_H
#include "Define.h"
#include <G3D/Matrix3.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include "Define.h"
namespace VMAP
{
class WorldModel;
@@ -22,20 +21,23 @@ namespace VMAP
class GameObject;
struct GameObjectDisplayInfoEntry;
class GameObjectModel /*, public Intersectable*/
class GameObjectModelOwnerBase
{
uint32 phasemask{0};
G3D::AABox iBound;
G3D::Matrix3 iInvRot;
G3D::Vector3 iPos;
//G3D::Vector3 iRot;
float iInvScale{0};
float iScale{0};
VMAP::WorldModel* iModel;
GameObject const* owner;
public:
virtual ~GameObjectModelOwnerBase() = default;
GameObjectModel() : iModel(nullptr), owner(nullptr) { }
bool initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info);
virtual bool IsSpawned() const = 0;
virtual uint32 GetDisplayId() const = 0;
virtual uint32 GetPhaseMask() const = 0;
virtual G3D::Vector3 GetPosition() const = 0;
virtual float GetOrientation() const = 0;
virtual float GetScale() const = 0;
virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const = 0;
};
class GameObjectModel
{
GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr) { }
public:
std::string name;
@@ -44,19 +46,33 @@ public:
~GameObjectModel();
[[nodiscard]] const G3D::Vector3& getPosition() const { return iPos;}
[[nodiscard]] const G3D::Vector3& getPosition() const { return iPos; }
/** Enables\disables collision. */
void disable() { phasemask = 0;}
void enable(uint32 ph_mask) { phasemask = ph_mask;}
/** Enables\disables collision. */
void disable() { phasemask = 0; }
void enable(uint32 ph_mask) { phasemask = ph_mask; }
[[nodiscard]] bool isEnabled() const {return phasemask != 0;}
[[nodiscard]] bool isEnabled() const { return phasemask != 0; }
bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const;
static GameObjectModel* Create(const GameObject& go);
static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
bool UpdatePosition();
private:
bool initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
uint32 phasemask;
G3D::AABox iBound;
G3D::Matrix3 iInvRot;
G3D::Vector3 iPos;
float iInvScale;
float iScale;
VMAP::WorldModel* iModel;
std::unique_ptr<GameObjectModelOwnerBase> owner;
};
#endif // _GAMEOBJECT_MODEL_H
void LoadGameObjectModelList(std::string const& dataPath);
#endif // _GAMEOBJECT_MODEL_H

View File

@@ -7,13 +7,12 @@
#ifndef _MODELINSTANCE_H_
#define _MODELINSTANCE_H_
#include "Define.h"
#include <G3D/Matrix3.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include "Define.h"
namespace VMAP
{
class WorldModel;
@@ -58,12 +57,11 @@ namespace VMAP
void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
WorldModel* getWorldModel() { return iModel; }
protected:
G3D::Matrix3 iInvRot;
float iInvScale{0.0f};
WorldModel* iModel{nullptr};
public:
WorldModel* getWorldModel();
};
} // namespace VMAP

View File

@@ -241,6 +241,13 @@ namespace VMAP
return result;
}
void WmoLiquid::getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const
{
tilesX = iTilesX;
tilesY = iTilesY;
corner = iCorner;
}
// ===================== GroupModel ==================================
GroupModel::GroupModel(const GroupModel& other):
@@ -401,6 +408,13 @@ namespace VMAP
return 0;
}
void GroupModel::getMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid)
{
outVertices = vertices;
outTriangles = triangles;
liquid = iLiquid;
}
// ===================== WorldModel ==================================
void WorldModel::setGroupModels(std::vector<GroupModel>& models)
@@ -575,4 +589,9 @@ namespace VMAP
fclose(rf);
return result;
}
void WorldModel::getGroupModels(std::vector<GroupModel>& outGroupModels)
{
outGroupModels = groupModels;
}
}

View File

@@ -7,13 +7,12 @@
#ifndef _WORLDMODEL_H
#define _WORLDMODEL_H
#include "Define.h"
#include "BoundingIntervalHierarchy.h"
#include <G3D/HashTrait.h>
#include <G3D/Vector3.h>
#include <G3D/AABox.h>
#include <G3D/Ray.h>
#include "BoundingIntervalHierarchy.h"
#include "Define.h"
namespace VMAP
{
@@ -46,6 +45,7 @@ namespace VMAP
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid*& liquid);
void getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const;
private:
WmoLiquid() { }
uint32 iTilesX{0}; //!< number of tiles in x direction, each
@@ -54,8 +54,6 @@ namespace VMAP
uint32 iType{0}; //!< liquid type
float* iHeight{nullptr}; //!< (tilesX + 1)*(tilesY + 1) height values
uint8* iFlags{nullptr}; //!< info if liquid tile is used
public:
void getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const;
};
/*! holding additional info for WMO group files */
@@ -80,6 +78,7 @@ namespace VMAP
[[nodiscard]] const G3D::AABox& GetBound() const { return iBound; }
[[nodiscard]] uint32 GetMogpFlags() const { return iMogpFlags; }
[[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; }
void getMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid);
protected:
G3D::AABox iBound;
uint32 iMogpFlags{0};// 0x8 outdor; 0x2000 indoor
@@ -88,8 +87,6 @@ namespace VMAP
std::vector<MeshTriangle> triangles;
BIH meshTree;
WmoLiquid* iLiquid{nullptr};
public:
void getMeshData(std::vector<G3D::Vector3>& vertices, std::vector<MeshTriangle>& triangles, WmoLiquid*& liquid);
};
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
class WorldModel
@@ -105,12 +102,11 @@ namespace VMAP
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const;
bool writeFile(const std::string& filename);
bool readFile(const std::string& filename);
void getGroupModels(std::vector<GroupModel>& outGroupModels);
protected:
uint32 RootWMOID{0};
std::vector<GroupModel> groupModels;
BIH groupTree;
public:
void getGroupModels(std::vector<GroupModel>& groupModels);
};
} // namespace VMAP

View File

@@ -7,11 +7,10 @@
#ifndef _VMAPTOOLS_H
#define _VMAPTOOLS_H
#include "Define.h"
#include <G3D/CollisionDetection.h>
#include <G3D/AABox.h>
#include "NodeValueAccess.h"
/**
The Class is mainly taken from G3D/AABSPTree.h but modified to be able to use our internal data structure.
This is an iterator that helps us analysing the BSP-Trees.
@@ -40,7 +39,6 @@ namespace VMAP
class MyCollisionDetection
{
private:
public:
static bool collisionLocationForMovingPointFixedAABox(
const G3D::Vector3& origin,