mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-26 23:26:23 +00:00
feat(Core/Common): delete lib game-interface inherited (#5333)
Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -35,4 +35,4 @@ namespace MMAP
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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(¶ms, sizeof(dtNavMeshParams), 1, file);
|
||||
uint32 count = uint32(fread(¶ms, 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
53
src/common/Collision/Maps/MapDefines.h
Normal file
53
src/common/Collision/Maps/MapDefines.h
Normal 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
|
||||
@@ -462,4 +462,10 @@ namespace VMAP
|
||||
}
|
||||
iLoadedTiles.erase(tile);
|
||||
}
|
||||
|
||||
void StaticMapTree::getModelInstances(ModelInstance*& models, uint32& count)
|
||||
{
|
||||
models = iTreeValues;
|
||||
count = iNTreeValues;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user