aboutsummaryrefslogtreecommitdiff
path: root/src/server/collision
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/collision')
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.cpp12
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h33
-rw-r--r--src/server/collision/BoundingIntervalHierarchyWrapper.h22
-rw-r--r--src/server/collision/CMakeLists.txt2
-rw-r--r--src/server/collision/DynamicTree.cpp61
-rw-r--r--src/server/collision/DynamicTree.h26
-rw-r--r--src/server/collision/Management/MMapFactory.cpp52
-rw-r--r--src/server/collision/Management/MMapFactory.h50
-rw-r--r--src/server/collision/Management/MMapManager.cpp302
-rw-r--r--src/server/collision/Management/MMapManager.h84
-rw-r--r--src/server/collision/Management/VMapManager2.cpp12
-rw-r--r--src/server/collision/Management/VMapManager2.h2
-rw-r--r--src/server/collision/Maps/MapTree.cpp24
-rw-r--r--src/server/collision/Maps/MapTree.h7
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp12
-rw-r--r--src/server/collision/Maps/TileAssembler.h4
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp18
-rw-r--r--src/server/collision/Models/ModelInstance.h2
-rw-r--r--src/server/collision/Models/WorldModel.h36
-rw-r--r--src/server/collision/RegularGrid.h18
-rw-r--r--src/server/collision/VMapDefinitions.h12
21 files changed, 650 insertions, 141 deletions
diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp
index ad3753ea3c9..340d66ddaf0 100644
--- a/src/server/collision/BoundingIntervalHierarchy.cpp
+++ b/src/server/collision/BoundingIntervalHierarchy.cpp
@@ -18,6 +18,12 @@
#include "BoundingIntervalHierarchy.h"
+#ifdef _MSC_VER
+ #define isnan _isnan
+#else
+ #define isnan std::isnan
+#endif
+
void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
{
// create space for the first node
@@ -51,7 +57,7 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
prevAxis = axis;
prevSplit = split;
// perform quick consistency checks
- Vector3 d( gridBox.hi - gridBox.lo );
+ G3D::Vector3 d( gridBox.hi - gridBox.lo );
if (d.x < 0 || d.y < 0 || d.z < 0)
throw std::logic_error("negative node extents");
for (int i = 0; i < 3; i++)
@@ -255,11 +261,11 @@ bool BIH::writeToFile(FILE* wf) const
bool BIH::readFromFile(FILE* rf)
{
uint32 treeSize;
- Vector3 lo, hi;
+ G3D::Vector3 lo, hi;
uint32 check=0, count=0;
check += fread(&lo, sizeof(float), 3, rf);
check += fread(&hi, sizeof(float), 3, rf);
- bounds = AABox(lo, hi);
+ bounds = G3D::AABox(lo, hi);
check += fread(&treeSize, sizeof(uint32), 1, rf);
tree.resize(treeSize);
check += fread(&tree[0], sizeof(uint32), treeSize, rf);
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index 7cbaedbfba6..997f9c99e5f 100644
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -31,20 +31,8 @@
#include <limits>
#include <cmath>
-#ifdef __APPLE__
- #define isnan(x) ( std::isnan(x) )
-#endif
-
#define MAX_STACK_SIZE 64
-#ifdef _MSC_VER
- #define isnan(x) _isnan(x)
-#endif
-
-using G3D::Vector3;
-using G3D::AABox;
-using G3D::Ray;
-
static inline uint32 floatToRawIntBits(float f)
{
union
@@ -69,7 +57,7 @@ static inline float intBitsToFloat(uint32 i)
struct AABound
{
- Vector3 lo, hi;
+ G3D::Vector3 lo, hi;
};
/** Bounding Interval Hierarchy Class.
@@ -105,12 +93,11 @@ class BIH
dat.maxPrims = leafSize;
dat.numPrims = primitives.size();
dat.indices = new uint32[dat.numPrims];
- dat.primBound = new AABox[dat.numPrims];
+ dat.primBound = new G3D::AABox[dat.numPrims];
getBounds(primitives[0], bounds);
for (uint32 i=0; i<dat.numPrims; ++i)
{
dat.indices[i] = i;
- AABox tb;
getBounds(primitives[i], dat.primBound[i]);
bounds.merge(dat.primBound[i]);
}
@@ -131,13 +118,13 @@ class BIH
uint32 primCount() const { return objects.size(); }
template<typename RayCallback>
- void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
+ void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
{
float intervalMin = -1.f;
float intervalMax = -1.f;
- Vector3 org = r.origin();
- Vector3 dir = r.direction();
- Vector3 invDir;
+ G3D::Vector3 org = r.origin();
+ G3D::Vector3 dir = r.direction();
+ G3D::Vector3 invDir;
for (int i=0; i<3; ++i)
{
invDir[i] = 1.f / dir[i];
@@ -270,7 +257,7 @@ class BIH
}
template<typename IsectCallback>
- void intersectPoint(const Vector3 &p, IsectCallback& intersectCallback) const
+ void intersectPoint(const G3D::Vector3 &p, IsectCallback& intersectCallback) const
{
if (!bounds.contains(p))
return;
@@ -353,12 +340,12 @@ class BIH
protected:
std::vector<uint32> tree;
std::vector<uint32> objects;
- AABox bounds;
+ G3D::AABox bounds;
struct buildData
{
uint32 *indices;
- AABox *primBound;
+ G3D::AABox *primBound;
uint32 numPrims;
int maxPrims;
};
@@ -410,4 +397,4 @@ class BIH
void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
};
-#endif // _BIH_H \ No newline at end of file
+#endif // _BIH_H
diff --git a/src/server/collision/BoundingIntervalHierarchyWrapper.h b/src/server/collision/BoundingIntervalHierarchyWrapper.h
index 8a99078caab..305d57b0075 100644
--- a/src/server/collision/BoundingIntervalHierarchyWrapper.h
+++ b/src/server/collision/BoundingIntervalHierarchyWrapper.h
@@ -33,18 +33,23 @@ class BIHWrap
{
const T* const* objects;
RayCallback& _callback;
+ uint32 objects_size;
- MDLCallback(RayCallback& callback, const T* const* objects_array ) : objects(objects_array), _callback(callback) {}
+ MDLCallback(RayCallback& callback, const T* const* objects_array, uint32 objects_size ) : objects(objects_array), _callback(callback), objects_size(objects_size) {}
- bool operator() (const Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/)
+ bool operator() (const G3D::Ray& ray, uint32 Idx, float& MaxDist, bool /*stopAtFirst*/)
{
+ if (Idx >= objects_size)
+ return false;
if (const T* obj = objects[Idx])
return _callback(ray, *obj, MaxDist/*, stopAtFirst*/);
return false;
}
- void operator() (const Vector3& p, uint32 Idx)
+ void operator() (const G3D::Vector3& p, uint32 Idx)
{
+ if (Idx >= objects_size)
+ return false;
if (const T* obj = objects[Idx])
_callback(p, *obj);
}
@@ -87,21 +92,24 @@ public:
m_objects.fastClear();
m_obj2Idx.getKeys(m_objects);
m_objects_to_push.getMembers(m_objects);
+ //assert that m_obj2Idx has all the keys
m_tree.build(m_objects, BoundsFunc::getBounds2);
}
template<typename RayCallback>
- void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& maxDist) const
+ void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& maxDist)
{
- MDLCallback<RayCallback> temp_cb(intersectCallback, m_objects.getCArray());
+ balance();
+ MDLCallback<RayCallback> temp_cb(intersectCallback, m_objects.getCArray(), m_objects.size());
m_tree.intersectRay(ray, temp_cb, maxDist, true);
}
template<typename IsectCallback>
- void intersectPoint(const Vector3& point, IsectCallback& intersectCallback) const
+ void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback)
{
- MDLCallback<IsectCallback> callback(intersectCallback, m_objects.getCArray());
+ balance();
+ MDLCallback<IsectCallback> callback(intersectCallback, m_objects.getCArray(), m_objects.size());
m_tree.intersectPoint(point, callback);
}
};
diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt
index 62af7dd081e..b4012b63812 100644
--- a/src/server/collision/CMakeLists.txt
+++ b/src/server/collision/CMakeLists.txt
@@ -33,7 +33,9 @@ set(collision_STAT_SRCS
include_directories(
${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/dep/g3dlite/include
+ ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour
${CMAKE_SOURCE_DIR}/src/server/shared
+ ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
diff --git a/src/server/collision/DynamicTree.cpp b/src/server/collision/DynamicTree.cpp
index 1a2f721a69f..c70a4b78a03 100644
--- a/src/server/collision/DynamicTree.cpp
+++ b/src/server/collision/DynamicTree.cpp
@@ -27,15 +27,24 @@
#include "GameObjectModel.h"
#include "ModelInstance.h"
+#include <G3D/AABox.h>
+#include <G3D/Ray.h>
+#include <G3D/Vector3.h>
+
using VMAP::ModelInstance;
-using G3D::Ray;
+
+namespace {
+
+int CHECK_TREE_PERIOD = 200;
+
+} // namespace
template<> struct HashTrait< GameObjectModel>{
static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; }
};
template<> struct PositionTrait< GameObjectModel> {
- static void getPosition(const GameObjectModel& g, Vector3& p) { p = g.getPosition(); }
+ static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); }
};
template<> struct BoundsTrait< GameObjectModel> {
@@ -49,11 +58,6 @@ static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2
}
*/
-int valuesPerNode = 5, numMeanSplits = 3;
-
-int UNBALANCED_TIMES_LIMIT = 5;
-int CHECK_TREE_PERIOD = 200;
-
typedef RegularGrid2D<GameObjectModel, BIHWrap<GameObjectModel> > ParentTree;
struct DynTreeImpl : public ParentTree/*, public Intersectable*/
@@ -103,43 +107,43 @@ struct DynTreeImpl : public ParentTree/*, public Intersectable*/
int unbalanced_times;
};
-DynamicMapTree::DynamicMapTree() : impl(*new DynTreeImpl())
+DynamicMapTree::DynamicMapTree() : impl(new DynTreeImpl())
{
}
DynamicMapTree::~DynamicMapTree()
{
- delete &impl;
+ delete impl;
}
void DynamicMapTree::insert(const GameObjectModel& mdl)
{
- impl.insert(mdl);
+ impl->insert(mdl);
}
void DynamicMapTree::remove(const GameObjectModel& mdl)
{
- impl.remove(mdl);
+ impl->remove(mdl);
}
bool DynamicMapTree::contains(const GameObjectModel& mdl) const
{
- return impl.contains(mdl);
+ return impl->contains(mdl);
}
void DynamicMapTree::balance()
{
- impl.balance();
+ impl->balance();
}
int DynamicMapTree::size() const
{
- return impl.size();
+ return impl->size();
}
void DynamicMapTree::update(uint32 t_diff)
{
- impl.update(t_diff);
+ impl->update(t_diff);
}
struct DynamicTreeIntersectionCallback
@@ -147,7 +151,7 @@ struct DynamicTreeIntersectionCallback
bool did_hit;
uint32 phase_mask;
DynamicTreeIntersectionCallback(uint32 phasemask) : did_hit(false), phase_mask(phasemask) {}
- bool operator()(const Ray& r, const GameObjectModel& obj, float& distance)
+ bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
{
did_hit = obj.intersectRay(r, distance, true, phase_mask);
return did_hit;
@@ -163,7 +167,7 @@ struct DynamicTreeIntersectionCallback_WithLogger
{
sLog->outDebug(LOG_FILTER_MAPS, "Dynamic Intersection log");
}
- bool operator()(const Ray& r, const GameObjectModel& obj, float& distance)
+ bool operator()(const G3D::Ray& r, const GameObjectModel& obj, float& distance)
{
sLog->outDebug(LOG_FILTER_MAPS, "testing intersection with %s", obj.name.c_str());
bool hit = obj.intersectRay(r, distance, true, phase_mask);
@@ -177,17 +181,20 @@ struct DynamicTreeIntersectionCallback_WithLogger
bool didHit() const { return did_hit;}
};
-bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const
+bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
+ const G3D::Vector3& endPos, float& maxDist) const
{
float distance = maxDist;
DynamicTreeIntersectionCallback callback(phasemask);
- impl.intersectRay(ray, callback, distance, endPos);
+ impl->intersectRay(ray, callback, distance, endPos);
if (callback.didHit())
maxDist = distance;
return callback.didHit();
}
-bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& startPos, const Vector3& endPos, Vector3& resultHit, float modifyDist) const
+bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3& startPos,
+ const G3D::Vector3& endPos, G3D::Vector3& resultHit,
+ float modifyDist) const
{
bool result = false;
float maxDist = (endPos - startPos).magnitude();
@@ -199,7 +206,7 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star
resultHit = endPos;
return false;
}
- Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
+ G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
G3D::Ray ray(startPos, dir);
float dist = maxDist;
if (getIntersectionTime(phasemask, ray, endPos, dist))
@@ -227,26 +234,26 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& star
bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
{
- Vector3 v1(x1,y1,z1), v2(x2,y2,z2);
+ G3D::Vector3 v1(x1, y1, z1), v2(x2, y2, z2);
float maxDist = (v2 - v1).magnitude();
if (!G3D::fuzzyGt(maxDist, 0) )
return true;
- Ray r(v1, (v2-v1) / maxDist);
+ G3D::Ray r(v1, (v2-v1) / maxDist);
DynamicTreeIntersectionCallback callback(phasemask);
- impl.intersectRay(r, callback, maxDist, v2);
+ impl->intersectRay(r, callback, maxDist, v2);
return !callback.did_hit;
}
float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const
{
- Vector3 v(x,y,z);
- Ray r(v, Vector3(0,0,-1));
+ G3D::Vector3 v(x, y, z);
+ G3D::Ray r(v, G3D::Vector3(0, 0, -1));
DynamicTreeIntersectionCallback callback(phasemask);
- impl.intersectZAllignedRay(r, callback, maxSearchDist);
+ impl->intersectZAllignedRay(r, callback, maxSearchDist);
if (callback.didHit())
return v.z - maxSearchDist;
diff --git a/src/server/collision/DynamicTree.h b/src/server/collision/DynamicTree.h
index ca199a9cd70..8e541fd453a 100644
--- a/src/server/collision/DynamicTree.h
+++ b/src/server/collision/DynamicTree.h
@@ -20,34 +20,36 @@
#ifndef _DYNTREE_H
#define _DYNTREE_H
-#include <G3D/Matrix3.h>
-#include <G3D/Vector3.h>
-#include <G3D/AABox.h>
-#include <G3D/Ray.h>
-
-//#include "ModelInstance.h"
#include "Define.h"
-//#include "GameObjectModel.h"
namespace G3D
{
+ class Ray;
class Vector3;
}
-using G3D::Vector3;
class GameObjectModel;
+struct DynTreeImpl;
class DynamicMapTree
{
- struct DynTreeImpl& impl;
+ DynTreeImpl *impl;
+
public:
DynamicMapTree();
~DynamicMapTree();
- bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const;
- bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const;
- bool getObjectHitPos(uint32 phasemask, const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const;
+ bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2,
+ float z2, uint32 phasemask) const;
+
+ bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray,
+ const G3D::Vector3& endPos, float& maxDist) const;
+
+ bool getObjectHitPos(uint32 phasemask, const G3D::Vector3& pPos1,
+ const G3D::Vector3& pPos2, G3D::Vector3& pResultHitPos,
+ float pModifyDist) const;
+
float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const;
void insert(const GameObjectModel&);
diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp
new file mode 100644
index 00000000000..7adf7fbfa66
--- /dev/null
+++ b/src/server/collision/Management/MMapFactory.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MMapFactory.h"
+#include "World.h"
+#include "Config.h"
+#include "DisableMgr.h"
+
+namespace MMAP
+{
+ // ######################## MMapFactory ########################
+ // our global singleton copy
+ MMapManager *g_MMapManager = NULL;
+
+ MMapManager* MMapFactory::createOrGetMMapManager()
+ {
+ if (g_MMapManager == NULL)
+ g_MMapManager = new MMapManager();
+
+ return g_MMapManager;
+ }
+
+ bool MMapFactory::IsPathfindingEnabled(uint32 mapId)
+ {
+ return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS)
+ && !DisableMgr::IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING);
+ }
+
+ void MMapFactory::clear()
+ {
+ if (g_MMapManager)
+ {
+ delete g_MMapManager;
+ g_MMapManager = NULL;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h
new file mode 100644
index 00000000000..038d44a941c
--- /dev/null
+++ b/src/server/collision/Management/MMapFactory.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MMAP_FACTORY_H
+#define _MMAP_FACTORY_H
+
+#include "MMapManager.h"
+#include "UnorderedMap.h"
+#include "DetourAlloc.h"
+#include "DetourNavMesh.h"
+#include "DetourNavMeshQuery.h"
+
+namespace MMAP
+{
+ enum MMAP_LOAD_RESULT
+ {
+ MMAP_LOAD_RESULT_ERROR,
+ MMAP_LOAD_RESULT_OK,
+ MMAP_LOAD_RESULT_IGNORED
+ };
+
+ // static class
+ // holds all mmap global data
+ // access point to MMapManager singleton
+ class MMapFactory
+ {
+ public:
+ static MMapManager* createOrGetMMapManager();
+ static void clear();
+ static bool IsPathfindingEnabled(uint32 mapId);
+ };
+}
+
+#endif
+
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp
new file mode 100644
index 00000000000..e3ed8f3310a
--- /dev/null
+++ b/src/server/collision/Management/MMapManager.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MMapManager.h"
+#include "Log.h"
+#include "World.h"
+
+namespace MMAP
+{
+ // ######################## MMapManager ########################
+ MMapManager::~MMapManager()
+ {
+ for (MMapDataSet::iterator i = loadedMMaps.begin(); i != loadedMMaps.end(); ++i)
+ delete i->second;
+
+ // by now we should not have maps loaded
+ // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
+ }
+
+ bool MMapManager::loadMapData(uint32 mapId)
+ {
+ // we already have this map loaded?
+ if (loadedMMaps.find(mapId) != loadedMMaps.end())
+ return true;
+
+ // load and init dtNavMesh - read parameters from file
+ uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap")+1;
+ char *fileName = new char[pathLen];
+ snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId);
+
+ FILE* file = fopen(fileName, "rb");
+ if (!file)
+ {
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName);
+ delete [] fileName;
+ return false;
+ }
+
+ dtNavMeshParams params;
+ int count = fread(&params, sizeof(dtNavMeshParams), 1, file);
+ fclose(file);
+ if (count != 1)
+ {
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
+ delete [] fileName;
+ return false;
+ }
+
+ dtNavMesh* mesh = dtAllocNavMesh();
+ ASSERT(mesh);
+ if (DT_SUCCESS != mesh->init(&params))
+ {
+ dtFreeNavMesh(mesh);
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName);
+ delete [] fileName;
+ return false;
+ }
+
+ delete [] fileName;
+
+ sLog->outInfo(LOG_FILTER_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));
+ return true;
+ }
+
+ uint32 MMapManager::packTileID(int32 x, int32 y)
+ {
+ return uint32(x << 16 | y);
+ }
+
+ bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y)
+ {
+ // make sure the mmap is loaded and ready to load tiles
+ if (!loadMapData(mapId))
+ return false;
+
+ // get this mmap data
+ MMapData* mmap = loadedMMaps[mapId];
+ ASSERT(mmap->navMesh);
+
+ // check if we already have this tile loaded
+ uint32 packedGridPos = packTileID(x, y);
+ if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end())
+ return false;
+
+ // load this tile :: mmaps/MMMXXYY.mmtile
+ uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile")+1;
+ char *fileName = new char[pathLen];
+
+ snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
+
+ FILE *file = fopen(fileName, "rb");
+ if (!file)
+ {
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:loadMap: Could not open mmtile file '%s'", fileName);
+ delete [] fileName;
+ return false;
+ }
+ delete [] fileName;
+
+ // read header
+ MmapTileHeader fileHeader;
+ if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
+ {
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y);
+ return false;
+ }
+
+ if (fileHeader.mmapVersion != MMAP_VERSION)
+ {
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
+ mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
+ return false;
+ }
+
+ unsigned char* data = (unsigned char*)dtAlloc(fileHeader.size, DT_ALLOC_PERM);
+ ASSERT(data);
+
+ size_t result = fread(data, fileHeader.size, 1, file);
+ if (!result)
+ {
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y);
+ fclose(file);
+ return false;
+ }
+
+ fclose(file);
+
+ dtMeshHeader* header = (dtMeshHeader*)data;
+ dtTileRef tileRef = 0;
+
+ // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
+ if (DT_SUCCESS == mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))
+ {
+ mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
+ ++loadedTiles;
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
+ return true;
+ }
+ else
+ {
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y);
+ dtFree(data);
+ return false;
+ }
+
+ return false;
+ }
+
+ bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y)
+ {
+ // check if we have this map loaded
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ {
+ // file may not exist, therefore not loaded
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y);
+ return false;
+ }
+
+ MMapData* mmap = loadedMMaps[mapId];
+
+ // check if we have this tile loaded
+ uint32 packedGridPos = packTileID(x, y);
+ if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end())
+ {
+ // file may not exist, therefore not loaded
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y);
+ return false;
+ }
+
+ dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
+
+ // unload, and mark as non loaded
+ if (DT_SUCCESS != mmap->navMesh->removeTile(tileRef, NULL, NULL))
+ {
+ // this is technically a memory leak
+ // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
+ // we cannot recover from this error - assert out
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
+ ASSERT(false);
+ }
+ else
+ {
+ mmap->mmapLoadedTiles.erase(packedGridPos);
+ --loadedTiles;
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool MMapManager::unloadMap(uint32 mapId)
+ {
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ {
+ // file may not exist, therefore not loaded
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId);
+ return false;
+ }
+
+ // unload all tiles from given map
+ MMapData* mmap = loadedMMaps[mapId];
+ for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i)
+ {
+ uint32 x = (i->first >> 16);
+ uint32 y = (i->first & 0x0000FFFF);
+ if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL))
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
+ else
+ {
+ --loadedTiles;
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
+ }
+ }
+
+ delete mmap;
+ loadedMMaps.erase(mapId);
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded %03i.mmap", mapId);
+
+ return true;
+ }
+
+ bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId)
+ {
+ // check if we have this map loaded
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ {
+ // file may not exist, therefore not loaded
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId);
+ return false;
+ }
+
+ MMapData* mmap = loadedMMaps[mapId];
+ if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
+ {
+ sLog->outDebug(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId);
+ return false;
+ }
+
+ dtNavMeshQuery* query = mmap->navMeshQueries[instanceId];
+
+ dtFreeNavMeshQuery(query);
+ mmap->navMeshQueries.erase(instanceId);
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
+
+ return true;
+ }
+
+ dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId)
+ {
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ return NULL;
+
+ return loadedMMaps[mapId]->navMesh;
+ }
+
+ dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId)
+ {
+ if (loadedMMaps.find(mapId) == loadedMMaps.end())
+ return NULL;
+
+ MMapData* mmap = loadedMMaps[mapId];
+ if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
+ {
+ // allocate mesh query
+ dtNavMeshQuery* query = dtAllocNavMeshQuery();
+ ASSERT(query);
+ if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
+ {
+ dtFreeNavMeshQuery(query);
+ sLog->outError(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
+ return NULL;
+ }
+
+ sLog->outInfo(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
+ mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
+ }
+
+ return mmap->navMeshQueries[instanceId];
+ }
+}
diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h
new file mode 100644
index 00000000000..56b1b856d65
--- /dev/null
+++ b/src/server/collision/Management/MMapManager.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MMAP_MANAGER_H
+#define _MMAP_MANAGER_H
+
+#include "UnorderedMap.h"
+#include "DetourAlloc.h"
+#include "DetourNavMesh.h"
+#include "DetourNavMeshQuery.h"
+
+// move map related classes
+namespace MMAP
+{
+ typedef UNORDERED_MAP<uint32, dtTileRef> MMapTileSet;
+ typedef UNORDERED_MAP<uint32, dtNavMeshQuery*> NavMeshQuerySet;
+
+ // dummy struct to hold map's mmap data
+ struct MMapData
+ {
+ MMapData(dtNavMesh* mesh) : navMesh(mesh) {}
+ ~MMapData()
+ {
+ for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
+ dtFreeNavMeshQuery(i->second);
+
+ if (navMesh)
+ 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]
+ };
+
+
+ typedef UNORDERED_MAP<uint32, MMapData*> MMapDataSet;
+
+ // singleton class
+ // holds all all access to mmap loading unloading and meshes
+ class MMapManager
+ {
+ public:
+ MMapManager() : loadedTiles(0) {}
+ ~MMapManager();
+
+ bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y);
+ bool unloadMap(uint32 mapId, int32 x, int32 y);
+ bool unloadMap(uint32 mapId);
+ bool unloadMapInstance(uint32 mapId, uint32 instanceId);
+
+ // the returned [dtNavMeshQuery const*] is NOT threadsafe
+ dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId);
+ dtNavMesh const* GetNavMesh(uint32 mapId);
+
+ uint32 getLoadedTilesCount() const { return loadedTiles; }
+ uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
+ private:
+ bool loadMapData(uint32 mapId);
+ uint32 packTileID(int32 x, int32 y);
+
+ MMapDataSet loadedMMaps;
+ uint32 loadedTiles;
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 5e3741ca753..8a1bd346957 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -24,13 +24,13 @@
#include "MapTree.h"
#include "ModelInstance.h"
#include "WorldModel.h"
-#include "VMapDefinitions.h"
-#include "Log.h"
#include <G3D/Vector3.h>
#include <ace/Null_Mutex.h>
#include <ace/Singleton.h>
#include "DisableMgr.h"
#include "DBCStores.h"
+#include "Log.h"
+#include "VMapDefinitions.h"
using G3D::Vector3;
@@ -257,11 +257,11 @@ namespace VMAP
WorldModel* worldmodel = new WorldModel();
if (!worldmodel->readFile(basepath + filename + ".vmo"))
{
- sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str());
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: could not load '%s%s.vmo'", basepath.c_str(), filename.c_str());
delete worldmodel;
return NULL;
}
- sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
+ VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
model->second.setModel(worldmodel);
}
@@ -277,12 +277,12 @@ namespace VMAP
ModelFileMap::iterator model = iLoadedModelFiles.find(filename);
if (model == iLoadedModelFiles.end())
{
- sLog->outError(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str());
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "VMapManager2: trying to unload non-loaded file '%s'", filename.c_str());
return;
}
if (model->second.decRefCount() == 0)
{
- sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str());
+ VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "VMapManager2: unloading file '%s'", filename.c_str());
delete model->second.getModel();
iLoadedModelFiles.erase(model);
}
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index e2e9965dbfc..51f15f0fda4 100644
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -112,6 +112,8 @@ namespace VMAP
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y);
+ public:
+ void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
};
}
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp
index 5f4e2b6aa8b..bd925d5a0c4 100644
--- a/src/server/collision/Maps/MapTree.cpp
+++ b/src/server/collision/Maps/MapTree.cpp
@@ -21,18 +21,13 @@
#include "VMapManager2.h"
#include "VMapDefinitions.h"
#include "Log.h"
+#include "Errors.h"
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
-#ifndef NO_CORE_FUNCS
- #include "Errors.h"
-#else
- #define ASSERT(x)
-#endif
-
using G3D::Vector3;
namespace VMAP
@@ -248,7 +243,7 @@ namespace VMAP
FILE* rf = fopen(fullname.c_str(), "rb");
if (!rf)
return false;
- // TODO: check magic number when implemented...
+ /// @todo check magic number when implemented...
char tiled;
char chunk[8];
if (!readChunk(rf, chunk, VMAP_MAGIC, 8) || fread(&tiled, sizeof(char), 1, rf) != 1)
@@ -277,7 +272,7 @@ namespace VMAP
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm)
{
- sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
+ VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
bool success = true;
std::string fullname = iBasePath + fname;
FILE* rf = fopen(fullname.c_str(), "rb");
@@ -310,7 +305,7 @@ namespace VMAP
if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
{
WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
- sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
+ VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
if (model)
{
// assume that global model always is the first and only tree value (could be improved...)
@@ -320,7 +315,7 @@ namespace VMAP
else
{
success = false;
- sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str());
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str());
}
}
@@ -356,7 +351,7 @@ namespace VMAP
}
if (!iTreeValues)
{
- sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
return false;
}
bool result = true;
@@ -382,7 +377,7 @@ namespace VMAP
// acquire model instance
WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
if (!model)
- sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);
// update tree
uint32 referencedVal;
@@ -432,7 +427,7 @@ namespace VMAP
loadedTileMap::iterator tile = iLoadedTiles.find(tileID);
if (tile == iLoadedTiles.end())
{
- sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-loaded tile - Map:%u X:%u Y:%u", iMapID, tileX, tileY);
return;
}
if (tile->second) // file associated with tile
@@ -466,7 +461,7 @@ namespace VMAP
else
{
if (!iLoadedSpawns.count(referencedNode))
- sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
else if (--iLoadedSpawns[referencedNode] == 0)
{
iTreeValues[referencedNode].setUnloaded();
@@ -480,5 +475,4 @@ namespace VMAP
}
iLoadedTiles.erase(tile);
}
-
}
diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h
index bd928d85c5a..e97c44d089e 100644
--- a/src/server/collision/Maps/MapTree.h
+++ b/src/server/collision/Maps/MapTree.h
@@ -31,7 +31,7 @@ namespace VMAP
struct LocationInfo
{
- LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) {};
+ LocationInfo(): hitInstance(0), hitModel(0), ground_Z(-G3D::inf()) {}
const ModelInstance* hitInstance;
const GroupModel* hitModel;
float ground_Z;
@@ -72,7 +72,7 @@ namespace VMAP
bool getObjectHitPos(const G3D::Vector3& pos1, const G3D::Vector3& pos2, G3D::Vector3& pResultHitPos, float pModifyDist) const;
float getHeight(const G3D::Vector3& pPos, float maxSearchDist) const;
bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
- bool GetLocationInfo(const Vector3 &pos, LocationInfo &info) const;
+ bool GetLocationInfo(const G3D::Vector3 &pos, LocationInfo &info) const;
bool InitMap(const std::string &fname, VMapManager2* vm);
void UnloadMap(VMapManager2* vm);
@@ -80,11 +80,12 @@ namespace VMAP
void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
bool isTiled() const { return iIsTiled; }
uint32 numLoadedTiles() const { return iLoadedTiles.size(); }
+ void getModelInstances(ModelInstance* &models, uint32 &count);
};
struct AreaInfo
{
- AreaInfo(): result(false), ground_Z(-G3D::inf()) {};
+ AreaInfo(): result(false), ground_Z(-G3D::inf()) {}
bool result;
float ground_Z;
uint32 flags;
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index 380d6b5df21..ba1ae275c9a 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -88,7 +88,7 @@ namespace VMAP
}
else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
{
- // TODO: remove extractor hack and uncomment below line:
+ /// @todo remove extractor hack and uncomment below line:
//entry->second.iPos += Vector3(533.33333f*32, 533.33333f*32, 0.f);
entry->second.iBound = entry->second.iBound + Vector3(533.33333f*32, 533.33333f*32, 0.f);
}
@@ -380,11 +380,11 @@ namespace VMAP
}
}
- fwrite(&displayId,sizeof(uint32),1,model_list_copy);
- fwrite(&name_length,sizeof(uint32),1,model_list_copy);
- fwrite(&buff,sizeof(char),name_length,model_list_copy);
- fwrite(&bounds.low(),sizeof(Vector3),1,model_list_copy);
- fwrite(&bounds.high(),sizeof(Vector3),1,model_list_copy);
+ fwrite(&displayId, sizeof(uint32), 1, model_list_copy);
+ fwrite(&name_length, sizeof(uint32), 1, model_list_copy);
+ fwrite(&buff, sizeof(char), name_length, model_list_copy);
+ fwrite(&bounds.low(), sizeof(Vector3), 1, model_list_copy);
+ fwrite(&bounds.high(), sizeof(Vector3), 1, model_list_copy);
}
fclose(model_list);
diff --git a/src/server/collision/Maps/TileAssembler.h b/src/server/collision/Maps/TileAssembler.h
index 087c2021b50..a11ce272d62 100644
--- a/src/server/collision/Maps/TileAssembler.h
+++ b/src/server/collision/Maps/TileAssembler.h
@@ -72,12 +72,12 @@ namespace VMAP
uint32 liquidflags;
std::vector<MeshTriangle> triangles;
std::vector<G3D::Vector3> vertexArray;
- class WmoLiquid *liquid;
+ class WmoLiquid* liquid;
GroupModel_Raw() : liquid(0) {}
~GroupModel_Raw();
- bool Read(FILE * f);
+ bool Read(FILE* f);
};
struct WorldModel_Raw
diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp
index 237a5b33621..e166a860cd2 100644
--- a/src/server/collision/Models/GameObjectModel.cpp
+++ b/src/server/collision/Models/GameObjectModel.cpp
@@ -34,8 +34,6 @@ using G3D::Vector3;
using G3D::Ray;
using G3D::AABox;
-#ifndef NO_CORE_FUNCS
-
struct GameobjectModelData
{
GameobjectModelData(const std::string& name_, const AABox& box) :
@@ -50,11 +48,14 @@ ModelList model_list;
void LoadGameObjectModelList()
{
+#ifndef NO_CORE_FUNCS
uint32 oldMSTime = getMSTime();
+#endif
+
FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
if (!model_list_file)
{
- sLog->outError(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS);
return;
}
@@ -73,19 +74,18 @@ void LoadGameObjectModelList()
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
{
- sLog->outError(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
break;
}
model_list.insert
(
- ModelList::value_type( displayId, GameobjectModelData(std::string(buff,name_length),AABox(v1,v2)) )
+ ModelList::value_type( displayId, GameobjectModelData(std::string(buff, name_length), AABox(v1, v2)) )
);
}
fclose(model_list_file);
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime));
-
+ VMAP_INFO_LOG(LOG_FILTER_SERVER_LOADING, ">> Loaded %u GameObject models in %u ms", uint32(model_list.size()), GetMSTimeDiffToNow(oldMSTime));
}
GameObjectModel::~GameObjectModel()
@@ -104,7 +104,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
// ignore models with no bounds
if (mdl_box == G3D::AABox::zero())
{
- sLog->outError(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str());
+ VMAP_ERROR_LOG(LOG_FILTER_GENERAL, "GameObject model %s has zero bounds, loading skipped", it->second.name.c_str());
return false;
}
@@ -184,5 +184,3 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
}
return hit;
}
-
-#endif
diff --git a/src/server/collision/Models/ModelInstance.h b/src/server/collision/Models/ModelInstance.h
index 5af02a1d1b1..f26089bb46c 100644
--- a/src/server/collision/Models/ModelInstance.h
+++ b/src/server/collision/Models/ModelInstance.h
@@ -74,6 +74,8 @@ namespace VMAP
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
+ public:
+ WorldModel* getWorldModel();
};
} // namespace VMAP
diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h
index 8e046e561f7..9d588316cce 100644
--- a/src/server/collision/Models/WorldModel.h
+++ b/src/server/collision/Models/WorldModel.h
@@ -36,8 +36,8 @@ namespace VMAP
class MeshTriangle
{
public:
- MeshTriangle(){};
- MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) {};
+ MeshTriangle(){}
+ MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) {}
uint32 idx0;
uint32 idx1;
@@ -47,11 +47,11 @@ namespace VMAP
class WmoLiquid
{
public:
- WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type);
+ WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type);
WmoLiquid(const WmoLiquid &other);
~WmoLiquid();
WmoLiquid& operator=(const WmoLiquid &other);
- bool GetLiquidHeight(const Vector3 &pos, float &liqHeight) const;
+ bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const;
uint32 GetType() const { return iType; }
float *GetHeightStorage() { return iHeight; }
uint8 *GetFlagsStorage() { return iFlags; }
@@ -59,13 +59,15 @@ namespace VMAP
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid* &liquid);
private:
- WmoLiquid(): iHeight(0), iFlags(0) {};
- uint32 iTilesX; //!< number of tiles in x direction, each
+ WmoLiquid(): iHeight(0), iFlags(0) {}
+ uint32 iTilesX; //!< number of tiles in x direction, each
uint32 iTilesY;
- Vector3 iCorner; //!< the lower corner
- uint32 iType; //!< liquid type
- float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
- uint8 *iFlags; //!< info if liquid tile is used
+ G3D::Vector3 iCorner; //!< the lower corner
+ uint32 iType; //!< liquid type
+ float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
+ uint8 *iFlags; //!< info if liquid tile is used
+ public:
+ void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const;
};
/*! holding additional info for WMO group files */
@@ -74,16 +76,16 @@ namespace VMAP
public:
GroupModel(): iLiquid(0) {}
GroupModel(const GroupModel &other);
- GroupModel(uint32 mogpFlags, uint32 groupWMOID, const AABox &bound):
+ GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound):
iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) {}
~GroupModel() { delete iLiquid; }
//! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
- void setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri);
+ void setMeshData(std::vector<G3D::Vector3> &vert, std::vector<MeshTriangle> &tri);
void setLiquidData(WmoLiquid*& liquid) { iLiquid = liquid; liquid = NULL; }
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
- bool IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const;
- bool GetLiquidLevel(const Vector3 &pos, float &liqHeight) const;
+ bool IsInsideObject(const G3D::Vector3 &pos, const G3D::Vector3 &down, float &z_dist) const;
+ bool GetLiquidLevel(const G3D::Vector3 &pos, float &liqHeight) const;
uint32 GetLiquidType() const;
bool writeToFile(FILE* wf);
bool readFromFile(FILE* rf);
@@ -94,10 +96,12 @@ namespace VMAP
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
uint32 iGroupWMOID;
- std::vector<Vector3> vertices;
+ std::vector<G3D::Vector3> vertices;
std::vector<MeshTriangle> triangles;
BIH meshTree;
WmoLiquid* iLiquid;
+ 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
@@ -117,6 +121,8 @@ namespace VMAP
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
+ public:
+ void getGroupModels(std::vector<GroupModel> &groupModels);
};
} // namespace VMAP
diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h
index 5b7d1d74987..d1832c1ea06 100644
--- a/src/server/collision/RegularGrid.h
+++ b/src/server/collision/RegularGrid.h
@@ -3,18 +3,12 @@
#include <G3D/Ray.h>
-#include <G3D/AABox.h>
#include <G3D/Table.h>
#include <G3D/BoundsTrait.h>
#include <G3D/PositionTrait.h>
#include "Errors.h"
-using G3D::Vector2;
-using G3D::Vector3;
-using G3D::AABox;
-using G3D::Ray;
-
template<class Node>
struct NodeCreator{
static Node * makeNode(int /*x*/, int /*y*/) { return new Node();}
@@ -54,7 +48,7 @@ public:
void insert(const T& value)
{
- Vector3 pos;
+ G3D::Vector3 pos;
PositionFunc::getPosition(value, pos);
Node& node = getGridFor(pos.x, pos.y);
node.insert(value);
@@ -104,18 +98,18 @@ public:
{
ASSERT(x < CELL_NUMBER && y < CELL_NUMBER);
if (!nodes[x][y])
- nodes[x][y] = NodeCreatorFunc::makeNode(x,y);
+ nodes[x][y] = NodeCreatorFunc::makeNode(x, y);
return *nodes[x][y];
}
template<typename RayCallback>
- void intersectRay(const Ray& ray, RayCallback& intersectCallback, float max_dist)
+ void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float max_dist)
{
intersectRay(ray, intersectCallback, max_dist, ray.origin() + ray.direction() * max_dist);
}
template<typename RayCallback>
- void intersectRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist, const Vector3& end)
+ void intersectRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist, const G3D::Vector3& end)
{
Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
if (!cell.isValid())
@@ -191,7 +185,7 @@ public:
}
template<typename IsectCallback>
- void intersectPoint(const Vector3& point, IsectCallback& intersectCallback)
+ void intersectPoint(const G3D::Vector3& point, IsectCallback& intersectCallback)
{
Cell cell = Cell::ComputeCell(point.x, point.y);
if (!cell.isValid())
@@ -202,7 +196,7 @@ public:
// Optimized verson of intersectRay function for rays with vertical directions
template<typename RayCallback>
- void intersectZAllignedRay(const Ray& ray, RayCallback& intersectCallback, float& max_dist)
+ void intersectZAllignedRay(const G3D::Ray& ray, RayCallback& intersectCallback, float& max_dist)
{
Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
if (!cell.isValid())
diff --git a/src/server/collision/VMapDefinitions.h b/src/server/collision/VMapDefinitions.h
index 609d00cd00f..bb0766dc8ff 100644
--- a/src/server/collision/VMapDefinitions.h
+++ b/src/server/collision/VMapDefinitions.h
@@ -31,4 +31,16 @@ namespace VMAP
// defined in TileAssembler.cpp currently...
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len);
}
+
+// Set of helper macros for extractors (VMAP and MMAP)
+#ifndef NO_CORE_FUNCS
+#define VMAP_ERROR_LOG(FILTER, ...) sLog->outError(FILTER, __VA_ARGS__)
+#define VMAP_DEBUG_LOG(FILTER, ...) sLog->outDebug(FILTER, __VA_ARGS__)
+#define VMAP_INFO_LOG(FILTER, ...) sLog->outInfo(FILTER, __VA_ARGS__)
+#else
+#define VMAP_ERROR_LOG(FILTER, ...) (void)sizeof(FILTER)
+#define VMAP_DEBUG_LOG(FILTER, ...) (void)sizeof(FILTER)
+#define VMAP_INFO_LOG(FILTER, ...) (void)sizeof(FILTER)
+#endif
+
#endif