mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-23 05:36:23 +00:00
refactor(Core/Misc): add braces and impove codestyle (#6402)
This commit is contained in:
@@ -47,7 +47,9 @@ void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildDat
|
||||
// perform quick consistency checks
|
||||
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++)
|
||||
{
|
||||
if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
|
||||
@@ -76,7 +78,9 @@ void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildDat
|
||||
// stay left
|
||||
i++;
|
||||
if (clipL < maxb)
|
||||
{
|
||||
clipL = maxb;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -86,7 +90,9 @@ void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildDat
|
||||
dat.indices[right] = t;
|
||||
right--;
|
||||
if (clipR > minb)
|
||||
{
|
||||
clipR = minb;
|
||||
}
|
||||
}
|
||||
nodeL = std::min(nodeL, minb);
|
||||
nodeR = std::max(nodeR, maxb);
|
||||
@@ -212,7 +218,9 @@ void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildDat
|
||||
tempTree.push_back(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextIndex -= 3;
|
||||
}
|
||||
// allocate right node
|
||||
if (nr > 0)
|
||||
{
|
||||
@@ -233,13 +241,21 @@ void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildDat
|
||||
nodeBoxR.lo[axis] = clipR;
|
||||
// recurse
|
||||
if (nl > 0)
|
||||
{
|
||||
subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
}
|
||||
if (nr > 0)
|
||||
{
|
||||
subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.updateLeaf(depth + 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool BIH::writeToFile(FILE* wf) const
|
||||
|
||||
@@ -90,11 +90,15 @@ public:
|
||||
BuildStats stats;
|
||||
buildHierarchy(tempTree, dat, stats);
|
||||
if (printStats)
|
||||
{
|
||||
stats.printStats();
|
||||
}
|
||||
|
||||
objects.resize(dat.numPrims);
|
||||
for (uint32 i = 0; i < dat.numPrims; ++i)
|
||||
{
|
||||
objects[i] = dat.indices[i];
|
||||
}
|
||||
//nObjects = dat.numPrims;
|
||||
tree = tempTree;
|
||||
delete[] dat.primBound;
|
||||
@@ -118,20 +122,30 @@ public:
|
||||
float t1 = (bounds.low()[i] - org[i]) * invDir[i];
|
||||
float t2 = (bounds.high()[i] - org[i]) * invDir[i];
|
||||
if (t1 > t2)
|
||||
{
|
||||
std::swap(t1, t2);
|
||||
}
|
||||
if (t1 > intervalMin)
|
||||
{
|
||||
intervalMin = t1;
|
||||
}
|
||||
if (t2 < intervalMax || intervalMax < 0.f)
|
||||
{
|
||||
intervalMax = t2;
|
||||
}
|
||||
// intervalMax can only become smaller for other axis,
|
||||
// and intervalMin only larger respectively, so stop early
|
||||
if (intervalMax <= 0 || intervalMin >= maxDist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intervalMin > intervalMax)
|
||||
{
|
||||
return;
|
||||
}
|
||||
intervalMin = std::max(intervalMin, 0.f);
|
||||
intervalMax = std::min(intervalMax, maxDist);
|
||||
|
||||
@@ -174,7 +188,9 @@ public:
|
||||
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
|
||||
// ray passes between clip zones
|
||||
if (tf < intervalMin && tb > intervalMax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
int back = offset + offsetBack3[axis];
|
||||
node = back;
|
||||
// ray passes through far node only
|
||||
@@ -207,7 +223,7 @@ public:
|
||||
while (n > 0)
|
||||
{
|
||||
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirstHit);
|
||||
if (stopAtFirstHit && hit) return;
|
||||
if (stopAtFirstHit && hit) { return; }
|
||||
--n;
|
||||
++offset;
|
||||
}
|
||||
@@ -217,14 +233,18 @@ public:
|
||||
else
|
||||
{
|
||||
if (axis > 2)
|
||||
return; // should not happen
|
||||
{
|
||||
return; // should not happen
|
||||
}
|
||||
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
|
||||
float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
|
||||
node = offset;
|
||||
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
|
||||
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
|
||||
if (intervalMin > intervalMax)
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} // traversal loop
|
||||
@@ -232,12 +252,16 @@ public:
|
||||
{
|
||||
// stack is empty?
|
||||
if (stackPos == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// move back up the stack
|
||||
stackPos--;
|
||||
intervalMin = stack[stackPos].tnear;
|
||||
if (maxDist < intervalMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
node = stack[stackPos].node;
|
||||
intervalMax = stack[stackPos].tfar;
|
||||
break;
|
||||
@@ -249,7 +273,9 @@ public:
|
||||
void intersectPoint(const G3D::Vector3& p, IsectCallback& intersectCallback) const
|
||||
{
|
||||
if (!bounds.contains(p))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StackNode stack[MAX_STACK_SIZE];
|
||||
int stackPos = 0;
|
||||
@@ -272,7 +298,9 @@ public:
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
// point is between clip zones
|
||||
if (tl < p[axis] && tr > p[axis])
|
||||
{
|
||||
break;
|
||||
}
|
||||
int right = offset + 3;
|
||||
node = right;
|
||||
// point is in right node only
|
||||
@@ -308,19 +336,25 @@ public:
|
||||
else // BVH2 node (empty space cut off left and right)
|
||||
{
|
||||
if (axis > 2)
|
||||
return; // should not happen
|
||||
{
|
||||
return; // should not happen
|
||||
}
|
||||
float tl = intBitsToFloat(tree[node + 1]);
|
||||
float tr = intBitsToFloat(tree[node + 2]);
|
||||
node = offset;
|
||||
if (tl > p[axis] || tr < p[axis])
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} // traversal loop
|
||||
|
||||
// stack is empty?
|
||||
if (stackPos == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// move back up the stack
|
||||
stackPos--;
|
||||
node = stack[stackPos].node;
|
||||
@@ -366,7 +400,7 @@ protected:
|
||||
public:
|
||||
BuildStats()
|
||||
{
|
||||
for (int & i : numLeavesN) i = 0;
|
||||
for (int& i : numLeavesN) { i = 0; }
|
||||
}
|
||||
|
||||
void updateInner() { numNodes++; }
|
||||
|
||||
@@ -28,9 +28,13 @@ class BIHWrap
|
||||
bool operator() (const G3D::Ray& ray, uint32 idx, float& maxDist, bool stopAtFirstHit)
|
||||
{
|
||||
if (idx >= objects_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (const T* obj = objects[idx])
|
||||
{
|
||||
return _callback(ray, *obj, maxDist, stopAtFirstHit);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -38,9 +42,13 @@ class BIHWrap
|
||||
void operator() (const G3D::Vector3& p, uint32 idx)
|
||||
{
|
||||
if (idx >= objects_size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (const T* obj = objects[idx])
|
||||
{
|
||||
_callback(p, *obj);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,15 +75,21 @@ public:
|
||||
uint32 Idx = 0;
|
||||
const T* temp;
|
||||
if (m_obj2Idx.getRemove(&obj, temp, Idx))
|
||||
{
|
||||
m_objects[Idx] = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_objects_to_push.remove(&obj);
|
||||
}
|
||||
}
|
||||
|
||||
void balance()
|
||||
{
|
||||
if (unbalanced_times == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unbalanced_times = 0;
|
||||
m_objects.fastClear();
|
||||
|
||||
@@ -72,14 +72,18 @@ struct DynTreeImpl : public ParentTree
|
||||
void update(uint32 difftime)
|
||||
{
|
||||
if (!size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rebalance_timer.Update(difftime);
|
||||
if (rebalance_timer.Passed())
|
||||
{
|
||||
rebalance_timer.Reset(CHECK_TREE_PERIOD);
|
||||
if (unbalanced_times > 0)
|
||||
{
|
||||
balance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +137,9 @@ struct DynamicTreeIntersectionCallback
|
||||
{
|
||||
bool result = obj.intersectRay(r, distance, stopAtFirstHit, phase_mask);
|
||||
if (result)
|
||||
{
|
||||
did_hit = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool didHit() const { return did_hit;}
|
||||
@@ -146,7 +152,9 @@ bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray&
|
||||
DynamicTreeIntersectionCallback callback(phasemask);
|
||||
impl->intersectRay(ray, callback, distance, endPos, false);
|
||||
if (callback.didHit())
|
||||
{
|
||||
maxDist = distance;
|
||||
}
|
||||
return callback.didHit();
|
||||
}
|
||||
|
||||
@@ -173,12 +181,18 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3&
|
||||
if (modifyDist < 0)
|
||||
{
|
||||
if ((resultHit - startPos).magnitude() > -modifyDist)
|
||||
{
|
||||
resultHit = resultHit + dir * modifyDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultHit = startPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resultHit = resultHit + dir * modifyDist;
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
@@ -197,7 +211,9 @@ bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, flo
|
||||
float maxDist = (v2 - v1).magnitude();
|
||||
|
||||
if (!G3D::fuzzyGt(maxDist, 0) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
G3D::Ray r(v1, (v2 - v1) / maxDist);
|
||||
DynamicTreeIntersectionCallback callback(phasemask);
|
||||
@@ -214,7 +230,11 @@ float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist,
|
||||
impl->intersectZAllignedRay(r, callback, maxSearchDist);
|
||||
|
||||
if (callback.didHit())
|
||||
{
|
||||
return v.z - maxSearchDist;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -G3D::finf();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
~DynamicMapTree();
|
||||
|
||||
[[nodiscard]] bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2,
|
||||
float z2, uint32 phasemask) const;
|
||||
float z2, uint32 phasemask) const;
|
||||
|
||||
bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray,
|
||||
const G3D::Vector3& endPos, float& maxDist) const;
|
||||
|
||||
@@ -18,7 +18,9 @@ namespace MMAP
|
||||
MMapManager* MMapFactory::createOrGetMMapManager()
|
||||
{
|
||||
if (g_MMapManager == nullptr)
|
||||
{
|
||||
g_MMapManager = new MMapManager();
|
||||
}
|
||||
|
||||
return g_MMapManager;
|
||||
}
|
||||
@@ -29,7 +31,9 @@ namespace MMAP
|
||||
int32 f[] = {616 /*EoE*/, 649 /*ToC25*/, 650 /*ToC5*/, -1};
|
||||
uint32 i = 0;
|
||||
while (f[i] >= 0)
|
||||
{
|
||||
forbiddenMaps[f[i++]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MMapFactory::clear()
|
||||
|
||||
@@ -20,7 +20,9 @@ namespace MMAP
|
||||
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!
|
||||
@@ -30,7 +32,9 @@ namespace MMAP
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
@@ -40,7 +44,9 @@ namespace MMAP
|
||||
// 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;
|
||||
}
|
||||
@@ -52,14 +58,20 @@ namespace MMAP
|
||||
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
|
||||
@@ -107,7 +119,9 @@ namespace MMAP
|
||||
{
|
||||
// make sure the mmap is loaded and ready to load tiles
|
||||
if (!loadMapData(mapId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// get this mmap data
|
||||
MMapData* mmap = loadedMMaps[mapId];
|
||||
@@ -243,7 +257,9 @@ namespace MMAP
|
||||
uint32 y = (i.first & 0x0000FFFF);
|
||||
|
||||
if (dtStatusFailed(mmap->navMesh->removeTile(i.second, nullptr, nullptr)))
|
||||
{
|
||||
LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
--loadedTiles;
|
||||
@@ -289,7 +305,9 @@ namespace MMAP
|
||||
{
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return itr->second->navMesh;
|
||||
}
|
||||
@@ -298,7 +316,9 @@ namespace MMAP
|
||||
{
|
||||
MMapDataSet::const_iterator itr = GetMMapData(mapId);
|
||||
if (itr == loadedMMaps.end())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MMapData* mmap = itr->second;
|
||||
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
|
||||
|
||||
@@ -40,10 +40,14 @@ namespace MMAP
|
||||
~MMapData()
|
||||
{
|
||||
for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
|
||||
{
|
||||
dtFreeNavMeshQuery(i->second);
|
||||
}
|
||||
|
||||
if (navMesh)
|
||||
{
|
||||
dtFreeNavMesh(navMesh);
|
||||
}
|
||||
}
|
||||
|
||||
// we have to use single dtNavMeshQuery for every instance, since those are not thread safe
|
||||
|
||||
@@ -16,7 +16,9 @@ namespace VMAP
|
||||
VMapManager2* VMapFactory::createOrGetVMapManager()
|
||||
{
|
||||
if (!gVMapManager)
|
||||
{
|
||||
gVMapManager = new VMapManager2();
|
||||
}
|
||||
|
||||
return gVMapManager;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,9 @@ namespace VMAP
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
@@ -78,7 +80,9 @@ namespace VMAP
|
||||
// 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;
|
||||
}
|
||||
@@ -99,9 +103,13 @@ namespace VMAP
|
||||
if (isMapLoadingEnabled())
|
||||
{
|
||||
if (_loadMap(mapId, basePath, x, y))
|
||||
{
|
||||
result = VMAP_LOAD_RESULT_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = VMAP_LOAD_RESULT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -114,10 +122,12 @@ namespace VMAP
|
||||
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);
|
||||
mapId, tileX, tileY);
|
||||
}
|
||||
|
||||
if (!instanceTree->second)
|
||||
@@ -167,7 +177,9 @@ namespace VMAP
|
||||
{
|
||||
#if defined(ENABLE_VMAP_CHECKS)
|
||||
if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId);
|
||||
@@ -232,7 +244,9 @@ namespace VMAP
|
||||
Vector3 pos = convertPositionToInternalRep(x, y, z);
|
||||
float height = instanceTree->second->getHeight(pos, maxSearchDist);
|
||||
if (!(height < G3D::finf()))
|
||||
return height = VMAP_INVALID_HEIGHT_VALUE; // No height
|
||||
{
|
||||
return height = VMAP_INVALID_HEIGHT_VALUE; // No height
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
@@ -278,9 +292,13 @@ namespace VMAP
|
||||
ASSERT(floor < std::numeric_limits<float>::max());
|
||||
type = info.hitModel->GetLiquidType(); // entry from LiquidType.dbc
|
||||
if (reqLiquidType && !(GetLiquidFlagsPtr(type) & reqLiquidType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (info.hitInstance->GetLiquidLevel(pos, info, level))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ struct MmapTileHeader
|
||||
uint32 mmapVersion{MMAP_VERSION};
|
||||
uint32 size{0};
|
||||
char usesLiquids{true};
|
||||
char padding[3]{};
|
||||
char padding[3] {};
|
||||
|
||||
MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) { }
|
||||
};
|
||||
|
||||
@@ -27,7 +27,9 @@ namespace VMAP
|
||||
{
|
||||
bool result = prims[entry].intersectRay(ray, distance, StopAtFirstHit);
|
||||
if (result)
|
||||
{
|
||||
hit = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
bool didHit() { return hit; }
|
||||
@@ -62,7 +64,9 @@ namespace VMAP
|
||||
LOG_DEBUG("maps", "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
|
||||
#endif
|
||||
if (prims[entry].GetLocationInfo(point, locInfo))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
ModelInstance* prims;
|
||||
@@ -133,7 +137,9 @@ namespace VMAP
|
||||
MapRayCallback intersectionCallBack(iTreeValues);
|
||||
iTree.intersectRay(pRay, intersectionCallBack, distance, StopAtFirstHit);
|
||||
if (intersectionCallBack.didHit())
|
||||
{
|
||||
pMaxDist = distance;
|
||||
}
|
||||
return intersectionCallBack.didHit();
|
||||
}
|
||||
//=========================================================
|
||||
@@ -143,17 +149,23 @@ namespace VMAP
|
||||
float maxDist = (pos2 - pos1).magnitude();
|
||||
// return false if distance is over max float, in case of cheater teleporting to the end of the universe
|
||||
if (maxDist == std::numeric_limits<float>::max() || !std::isfinite(maxDist))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
|
||||
ASSERT(maxDist < std::numeric_limits<float>::max());
|
||||
// prevent NaN values which can cause BIH intersection to enter infinite loop
|
||||
if (maxDist < 1e-10f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// direction with length of 1
|
||||
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1) / maxDist);
|
||||
if (getIntersectionTime(ray, maxDist, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -227,12 +239,16 @@ namespace VMAP
|
||||
{
|
||||
std::string basePath = vmapPath;
|
||||
if (basePath.length() > 0 && basePath[basePath.length() - 1] != '/' && basePath[basePath.length() - 1] != '\\')
|
||||
{
|
||||
basePath.push_back('/');
|
||||
}
|
||||
std::string fullname = basePath + VMapManager2::getMapFileName(mapID);
|
||||
bool success = true;
|
||||
FILE* rf = fopen(fullname.c_str(), "rb");
|
||||
if (!rf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// TODO: check magic number when implemented...
|
||||
char tiled;
|
||||
char chunk[8];
|
||||
@@ -246,11 +262,15 @@ namespace VMAP
|
||||
std::string tilefile = basePath + getTileFileName(mapID, tileX, tileY);
|
||||
FILE* tf = fopen(tilefile.c_str(), "rb");
|
||||
if (!tf)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
fclose(tf);
|
||||
}
|
||||
}
|
||||
@@ -267,7 +287,9 @@ namespace VMAP
|
||||
std::string fullname = iBasePath + fname;
|
||||
FILE* rf = fopen(fullname.c_str(), "rb");
|
||||
if (!rf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char chunk[8];
|
||||
char tiled = '\0';
|
||||
@@ -317,7 +339,9 @@ namespace VMAP
|
||||
{
|
||||
iTreeValues[i->first].setUnloaded();
|
||||
for (uint32 refCount = 0; refCount < i->second; ++refCount)
|
||||
{
|
||||
vm->releaseModelInstance(iTreeValues[i->first].name);
|
||||
}
|
||||
}
|
||||
iLoadedSpawns.clear();
|
||||
iLoadedTiles.clear();
|
||||
@@ -348,10 +372,14 @@ namespace VMAP
|
||||
char chunk[8];
|
||||
|
||||
if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
uint32 numSpawns = 0;
|
||||
if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
for (uint32 i = 0; i < numSpawns && result; ++i)
|
||||
{
|
||||
// read model spawns
|
||||
@@ -362,7 +390,9 @@ namespace VMAP
|
||||
// acquire model instance
|
||||
WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
|
||||
if (!model)
|
||||
{
|
||||
LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);
|
||||
}
|
||||
|
||||
// update tree
|
||||
uint32 referencedVal;
|
||||
@@ -386,21 +416,29 @@ namespace VMAP
|
||||
++iLoadedSpawns[referencedVal];
|
||||
#if defined(VMAP_DEBUG)
|
||||
if (iTreeValues[referencedVal].ID != spawn.ID)
|
||||
{
|
||||
LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node");
|
||||
}
|
||||
else if (iTreeValues[referencedVal].name != spawn.name)
|
||||
{
|
||||
LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = true;
|
||||
fclose(tf);
|
||||
}
|
||||
else
|
||||
{
|
||||
iLoadedTiles[packTileID(tileX, tileY)] = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -424,10 +462,14 @@ namespace VMAP
|
||||
bool result = true;
|
||||
char chunk[8];
|
||||
if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
uint32 numSpawns;
|
||||
if (fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
for (uint32 i = 0; i < numSpawns && result; ++i)
|
||||
{
|
||||
// read model spawns
|
||||
@@ -442,11 +484,15 @@ namespace VMAP
|
||||
uint32 referencedNode;
|
||||
|
||||
if (fread(&referencedNode, sizeof(uint32), 1, tf) != 1)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!iLoadedSpawns.count(referencedNode))
|
||||
{
|
||||
LOG_ERROR("maps", "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();
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace VMAP
|
||||
{
|
||||
bool readChunk(FILE* rf, char* dest, const char* compare, uint32 len)
|
||||
{
|
||||
if (fread(dest, sizeof(char), len, rf) != len) return false;
|
||||
if (fread(dest, sizeof(char), len, rf) != len) { return false; }
|
||||
return memcmp(dest, compare, len) == 0;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ namespace VMAP
|
||||
{
|
||||
bool success = readMapSpawns();
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// export Map data
|
||||
for (MapData::iterator map_iter = mapData.begin(); map_iter != mapData.end() && success; ++map_iter)
|
||||
@@ -71,7 +73,9 @@ namespace VMAP
|
||||
if (entry->second.flags & MOD_M2)
|
||||
{
|
||||
if (!calculateTransformedBound(entry->second))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (entry->second.flags & MOD_WORLDSPAWN) // WMO maps and terrain maps use different origin, so we need to adapt :/
|
||||
{
|
||||
@@ -99,7 +103,9 @@ namespace VMAP
|
||||
// ===> possibly move this code to StaticMapTree class
|
||||
std::map<uint32, uint32> modelNodeIdx;
|
||||
for (uint32 i = 0; i < mapSpawns.size(); ++i)
|
||||
{
|
||||
modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
|
||||
}
|
||||
|
||||
// write map tree file
|
||||
std::stringstream mapfilename;
|
||||
@@ -113,16 +119,16 @@ namespace VMAP
|
||||
}
|
||||
|
||||
//general info
|
||||
if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) success = false;
|
||||
if (success && fwrite(VMAP_MAGIC, 1, 8, mapfile) != 8) { success = false; }
|
||||
uint32 globalTileID = StaticMapTree::packTileID(65, 65);
|
||||
pair<TileMap::iterator, TileMap::iterator> globalRange = map_iter->second->TileEntries.equal_range(globalTileID);
|
||||
char isTiled = globalRange.first == globalRange.second; // only maps without terrain (tiles) have global WMO
|
||||
if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) success = false;
|
||||
if (success && fwrite(&isTiled, sizeof(char), 1, mapfile) != 1) { success = false; }
|
||||
// Nodes
|
||||
if (success && fwrite("NODE", 4, 1, mapfile) != 1) success = false;
|
||||
if (success) success = pTree.writeToFile(mapfile);
|
||||
if (success && fwrite("NODE", 4, 1, mapfile) != 1) { success = false; }
|
||||
if (success) { success = pTree.writeToFile(mapfile); }
|
||||
// global map spawns (WDT), if any (most instances)
|
||||
if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
|
||||
if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) { success = false; }
|
||||
|
||||
for (TileMap::iterator glob = globalRange.first; glob != globalRange.second && success; ++glob)
|
||||
{
|
||||
@@ -140,7 +146,9 @@ namespace VMAP
|
||||
{
|
||||
const ModelSpawn& spawn = map_iter->second->UniqueEntries[tile->second];
|
||||
if (spawn.flags & MOD_WORLDSPAWN) // WDT spawn, saved as tile 65/65 currently...
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint32 nSpawns = tileEntries.count(tile->first);
|
||||
std::stringstream tilefilename;
|
||||
tilefilename.fill('0');
|
||||
@@ -151,19 +159,21 @@ namespace VMAP
|
||||
if (FILE* tilefile = fopen(tilefilename.str().c_str(), "wb"))
|
||||
{
|
||||
// file header
|
||||
if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) success = false;
|
||||
if (success && fwrite(VMAP_MAGIC, 1, 8, tilefile) != 8) { success = false; }
|
||||
// write number of tile spawns
|
||||
if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
|
||||
if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) { success = false; }
|
||||
// write tile spawns
|
||||
for (uint32 s = 0; s < nSpawns; ++s)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
++tile;
|
||||
}
|
||||
const ModelSpawn& spawn2 = map_iter->second->UniqueEntries[tile->second];
|
||||
success = success && ModelSpawn::writeToFile(tilefile, spawn2);
|
||||
// MapTree nodes to update when loading tile:
|
||||
std::map<uint32, uint32>::iterator nIdx = modelNodeIdx.find(spawn2.ID);
|
||||
if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) success = false;
|
||||
if (success && fwrite(&nIdx->second, sizeof(uint32), 1, tilefile) != 1) { success = false; }
|
||||
}
|
||||
fclose(tilefile);
|
||||
}
|
||||
@@ -212,11 +222,15 @@ namespace VMAP
|
||||
// read mapID, tileX, tileY, Flags, NameSet, UniqueId, Pos, Rot, Scale, Bound_lo, Bound_hi, name
|
||||
check = fread(&mapID, sizeof(uint32), 1, dirf);
|
||||
if (check == 0) // EoF...
|
||||
{
|
||||
break;
|
||||
}
|
||||
check += fread(&tileX, sizeof(uint32), 1, dirf);
|
||||
check += fread(&tileY, sizeof(uint32), 1, dirf);
|
||||
if (!ModelSpawn::readFromFile(dirf, spawn))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
MapSpawns* current;
|
||||
MapData::iterator map_iter = mapData.find(mapID);
|
||||
@@ -226,7 +240,9 @@ namespace VMAP
|
||||
mapData[mapID] = current = new MapSpawns();
|
||||
}
|
||||
else
|
||||
{
|
||||
current = map_iter->second;
|
||||
}
|
||||
|
||||
current->UniqueEntries.emplace(spawn.ID, spawn);
|
||||
current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
|
||||
@@ -249,11 +265,15 @@ namespace VMAP
|
||||
|
||||
WorldModel_Raw raw_model;
|
||||
if (!raw_model.Read(modelFilename.c_str()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 groups = raw_model.groupsArray.size();
|
||||
if (groups != 1)
|
||||
{
|
||||
printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
|
||||
}
|
||||
|
||||
AABox modelBound;
|
||||
bool boundEmpty = true;
|
||||
@@ -274,9 +294,13 @@ namespace VMAP
|
||||
Vector3 v = modelPosition.transform(vertices[i]);
|
||||
|
||||
if (boundEmpty)
|
||||
{
|
||||
modelBound = AABox(v, v), boundEmpty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
modelBound.merge(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
spawn.iBound = modelBound + spawn.iPos;
|
||||
@@ -300,12 +324,16 @@ namespace VMAP
|
||||
bool success = true;
|
||||
std::string filename = iSrcDir;
|
||||
if (filename.length() > 0)
|
||||
{
|
||||
filename.push_back('/');
|
||||
}
|
||||
filename.append(pModelFilename);
|
||||
|
||||
WorldModel_Raw raw_model;
|
||||
if (!raw_model.Read(filename.c_str()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// write WorldModel
|
||||
WorldModel model;
|
||||
@@ -335,11 +363,15 @@ namespace VMAP
|
||||
{
|
||||
FILE* model_list = fopen((iSrcDir + "/" + "temp_gameobject_models").c_str(), "rb");
|
||||
if (!model_list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char ident[8];
|
||||
if (fread(ident, 1, 8, model_list) != 8 || memcmp(ident, VMAP::RAW_VMAP_MAGIC, 8) != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* model_list_copy = fopen((iDestDir + "/" + GAMEOBJECT_MODELS).c_str(), "wb");
|
||||
if (!model_list_copy)
|
||||
@@ -357,12 +389,14 @@ namespace VMAP
|
||||
{
|
||||
if (fread(&displayId, sizeof(uint32), 1, model_list) != 1)
|
||||
if (feof(model_list)) // EOF flag is only set after failed reading attempt
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (fread(&isWmo, sizeof(uint8), 1, model_list) != 1
|
||||
|| fread(&name_length, sizeof(uint32), 1, model_list) != 1
|
||||
|| name_length >= sizeof(buff)
|
||||
|| fread(&buff, sizeof(char), name_length, model_list) != name_length)
|
||||
|| fread(&name_length, sizeof(uint32), 1, model_list) != 1
|
||||
|| name_length >= sizeof(buff)
|
||||
|| fread(&buff, sizeof(char), name_length, model_list) != name_length)
|
||||
{
|
||||
std::cout << "\nFile 'temp_gameobject_models' seems to be corrupted" << std::endl;
|
||||
break;
|
||||
@@ -372,7 +406,9 @@ namespace VMAP
|
||||
|
||||
WorldModel_Raw raw_model;
|
||||
if ( !raw_model.Read((iSrcDir + "/" + model_name).c_str()) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
spawnedModelFiles.insert(model_name);
|
||||
AABox bounds;
|
||||
@@ -386,9 +422,13 @@ namespace VMAP
|
||||
{
|
||||
Vector3& v = vertices[i];
|
||||
if (boundEmpty)
|
||||
{
|
||||
bounds = AABox(v, v), boundEmpty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds.merge(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +494,9 @@ namespace VMAP
|
||||
READ_OR_RETURN_WITH_DELETE(indexarray, nindexes * sizeof(uint16));
|
||||
triangles.reserve(nindexes / 3);
|
||||
for (uint32 i = 0; i < nindexes; i += 3)
|
||||
{
|
||||
triangles.push_back(MeshTriangle(indexarray[i], indexarray[i + 1], indexarray[i + 2]));
|
||||
}
|
||||
|
||||
delete[] indexarray;
|
||||
}
|
||||
@@ -471,7 +513,9 @@ namespace VMAP
|
||||
float* vectorarray = new float[nvectors * 3];
|
||||
READ_OR_RETURN_WITH_DELETE(vectorarray, nvectors * sizeof(float) * 3);
|
||||
for (uint32 i = 0; i < nvectors; ++i)
|
||||
{
|
||||
vertexArray.push_back( Vector3(vectorarray + 3 * i) );
|
||||
}
|
||||
|
||||
delete[] vectorarray;
|
||||
}
|
||||
@@ -526,10 +570,14 @@ namespace VMAP
|
||||
groupsArray.resize(groups);
|
||||
bool succeed = true;
|
||||
for (uint32 g = 0; g < groups && succeed; ++g)
|
||||
{
|
||||
succeed = groupsArray[g].Read(rf);
|
||||
}
|
||||
|
||||
if (succeed) /// rf will be freed inside Read if the function had any errors.
|
||||
{
|
||||
fclose(rf);
|
||||
}
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,23 +80,23 @@ namespace VMAP
|
||||
|
||||
class TileAssembler
|
||||
{
|
||||
private:
|
||||
std::string iDestDir;
|
||||
std::string iSrcDir;
|
||||
G3D::Table<std::string, unsigned int > iUniqueNameIds;
|
||||
MapData mapData;
|
||||
std::set<std::string> spawnedModelFiles;
|
||||
private:
|
||||
std::string iDestDir;
|
||||
std::string iSrcDir;
|
||||
G3D::Table<std::string, unsigned int > iUniqueNameIds;
|
||||
MapData mapData;
|
||||
std::set<std::string> spawnedModelFiles;
|
||||
|
||||
public:
|
||||
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
|
||||
virtual ~TileAssembler();
|
||||
public:
|
||||
TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName);
|
||||
virtual ~TileAssembler();
|
||||
|
||||
bool convertWorld2();
|
||||
bool readMapSpawns();
|
||||
bool calculateTransformedBound(ModelSpawn &spawn);
|
||||
void exportGameobjectModels();
|
||||
bool convertWorld2();
|
||||
bool readMapSpawns();
|
||||
bool calculateTransformedBound(ModelSpawn& spawn);
|
||||
void exportGameobjectModels();
|
||||
|
||||
bool convertRawFile(const std::string& pModelFilename);
|
||||
bool convertRawFile(const std::string& pModelFilename);
|
||||
};
|
||||
|
||||
} // VMAP
|
||||
|
||||
@@ -55,14 +55,16 @@ void LoadGameObjectModelList(std::string const& dataPath)
|
||||
Vector3 v1, v2;
|
||||
if (fread(&displayId, sizeof(uint32), 1, model_list_file) != 1)
|
||||
if (feof(model_list_file)) // EOF flag is only set after failed reading attempt
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (fread(&isWmo, sizeof(uint8), 1, model_list_file) != 1
|
||||
|| fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
|
||||
|| name_length >= sizeof(buff)
|
||||
|| fread(&buff, sizeof(char), name_length, model_list_file) != name_length
|
||||
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|
||||
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
|
||||
|| fread(&name_length, sizeof(uint32), 1, model_list_file) != 1
|
||||
|| name_length >= sizeof(buff)
|
||||
|| fread(&buff, sizeof(char), name_length, model_list_file) != name_length
|
||||
|| fread(&v1, sizeof(Vector3), 1, model_list_file) != 1
|
||||
|| fread(&v2, sizeof(Vector3), 1, model_list_file) != 1)
|
||||
{
|
||||
LOG_ERROR("maps", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
|
||||
fclose(model_list_file);
|
||||
@@ -72,7 +74,7 @@ void LoadGameObjectModelList(std::string const& dataPath)
|
||||
if (v1.isNaN() || v2.isNaN())
|
||||
{
|
||||
LOG_ERROR("maps", "File '%s' Model '%s' has invalid v1%s v2%s values!",
|
||||
VMAP::GAMEOBJECT_MODELS, std::string(buff, name_length).c_str(), v1.toString().c_str(), v2.toString().c_str());
|
||||
VMAP::GAMEOBJECT_MODELS, std::string(buff, name_length).c_str(), v1.toString().c_str(), v2.toString().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -88,14 +90,18 @@ void LoadGameObjectModelList(std::string const& dataPath)
|
||||
GameObjectModel::~GameObjectModel()
|
||||
{
|
||||
if (iModel)
|
||||
{
|
||||
VMAP::VMapFactory::createOrGetVMapManager()->releaseModelInstance(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath)
|
||||
{
|
||||
ModelList::const_iterator it = model_list.find(modelOwner->GetDisplayId());
|
||||
if (it == model_list.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
G3D::AABox mdl_box(it->second.bound);
|
||||
// ignore models with no bounds
|
||||
@@ -108,7 +114,9 @@ bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> model
|
||||
iModel = VMAP::VMapFactory::createOrGetVMapManager()->acquireModelInstance(dataPath + "vmaps/", it->second.name);
|
||||
|
||||
if (!iModel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
name = it->second.name;
|
||||
iPos = modelOwner->GetPosition();
|
||||
@@ -122,7 +130,9 @@ bool GameObjectModel::initialize(std::unique_ptr<GameObjectModelOwnerBase> model
|
||||
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));
|
||||
}
|
||||
|
||||
iBound = rotated_bounds + iPos;
|
||||
|
||||
@@ -154,11 +164,15 @@ GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBas
|
||||
bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const
|
||||
{
|
||||
if (!(phasemask & ph_mask) || !owner->IsSpawned())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float time = ray.intersectionTime(iBound);
|
||||
if (time == G3D::inf())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// child bounds are defined in object space:
|
||||
Vector3 p = iInvRot * (ray.origin() - iPos) * iInvScale;
|
||||
@@ -176,11 +190,15 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
|
||||
bool GameObjectModel::UpdatePosition()
|
||||
{
|
||||
if (!iModel)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ModelList::const_iterator it = model_list.find(owner->GetDisplayId());
|
||||
if (it == model_list.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
G3D::AABox mdl_box(it->second.bound);
|
||||
|
||||
@@ -200,7 +218,9 @@ bool GameObjectModel::UpdatePosition()
|
||||
AABox rotated_bounds;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
rotated_bounds.merge(iRotation * mdl_box.corner(i));
|
||||
}
|
||||
|
||||
iBound = rotated_bounds + iPos;
|
||||
#ifdef SPAWN_CORNERS
|
||||
|
||||
@@ -65,9 +65,13 @@ namespace VMAP
|
||||
|
||||
// M2 files don't contain area info, only WMO files
|
||||
if (flags & MOD_M2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!iBound.contains(p))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
@@ -99,9 +103,13 @@ namespace VMAP
|
||||
|
||||
// M2 files don't contain area info, only WMO files
|
||||
if (flags & MOD_M2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!iBound.contains(p))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// child bounds are defined in object space:
|
||||
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
|
||||
Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||
@@ -147,7 +155,9 @@ namespace VMAP
|
||||
if (!check)
|
||||
{
|
||||
if (ferror(rf))
|
||||
{
|
||||
std::cout << "Error reading ModelSpawn!\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
check += fread(&spawn.adtId, sizeof(uint16), 1, rf);
|
||||
@@ -202,9 +212,9 @@ namespace VMAP
|
||||
}
|
||||
uint32 nameLen = spawn.name.length();
|
||||
check += fwrite(&nameLen, sizeof(uint32), 1, wf);
|
||||
if (check != uint32(has_bound ? 17 : 11)) return false;
|
||||
if (check != uint32(has_bound ? 17 : 11)) { return false; }
|
||||
check = fwrite(spawn.name.c_str(), sizeof(char), nameLen, wf);
|
||||
if (check != nameLen) return false;
|
||||
if (check != nameLen) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,9 @@ namespace VMAP
|
||||
WmoLiquid& WmoLiquid::operator=(const WmoLiquid& other)
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
iTilesX = other.iTilesX;
|
||||
iTilesY = other.iTilesY;
|
||||
iCorner = other.iCorner;
|
||||
@@ -126,14 +128,18 @@ namespace VMAP
|
||||
memcpy(iHeight, other.iHeight, (iTilesX + 1) * (iTilesY + 1)*sizeof(float));
|
||||
}
|
||||
else
|
||||
{
|
||||
iHeight = 0;
|
||||
}
|
||||
if (other.iFlags)
|
||||
{
|
||||
iFlags = new uint8[iTilesX * iTilesY];
|
||||
memcpy(iFlags, other.iFlags, iTilesX * iTilesY);
|
||||
}
|
||||
else
|
||||
{
|
||||
iFlags = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -142,16 +148,22 @@ namespace VMAP
|
||||
float tx_f = (pos.x - iCorner.x) / LIQUID_TILE_SIZE;
|
||||
uint32 tx = uint32(tx_f);
|
||||
if (tx_f < 0.0f || tx >= iTilesX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
float ty_f = (pos.y - iCorner.y) / LIQUID_TILE_SIZE;
|
||||
uint32 ty = uint32(ty_f);
|
||||
if (ty_f < 0.0f || ty >= iTilesY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if tile shall be used for liquid level
|
||||
// checking for 0x08 *might* be enough, but disabled tiles always are 0x?F:
|
||||
if ((iFlags[tx + ty * iTilesX] & 0x0F) == 0x0F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// (dx, dy) coordinates inside tile, in [0, 1]^2
|
||||
float dx = tx_f - (float)tx;
|
||||
@@ -234,9 +246,13 @@ namespace VMAP
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
delete liquid;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = liquid;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -255,7 +271,9 @@ namespace VMAP
|
||||
vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
|
||||
{
|
||||
if (other.iLiquid)
|
||||
{
|
||||
iLiquid = new WmoLiquid(*other.iLiquid);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupModel::setMeshData(std::vector<Vector3>& vert, std::vector<MeshTriangle>& tri)
|
||||
@@ -271,43 +289,45 @@ namespace VMAP
|
||||
bool result = true;
|
||||
uint32 chunkSize, count;
|
||||
|
||||
if (result && fwrite(&iBound, sizeof(G3D::AABox), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iMogpFlags, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iGroupWMOID, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&iBound, sizeof(G3D::AABox), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&iMogpFlags, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&iGroupWMOID, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
|
||||
// write vertices
|
||||
if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
|
||||
if (result && fwrite("VERT", 1, 4, wf) != 4) { result = false; }
|
||||
count = vertices.size();
|
||||
chunkSize = sizeof(uint32) + sizeof(Vector3) * count;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (!count) // models without (collision) geometry end here, unsure if they are useful
|
||||
{
|
||||
return result;
|
||||
if (result && fwrite(&vertices[0], sizeof(Vector3), count, wf) != count) result = false;
|
||||
}
|
||||
if (result && fwrite(&vertices[0], sizeof(Vector3), count, wf) != count) { result = false; }
|
||||
|
||||
// write triangle mesh
|
||||
if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
|
||||
if (result && fwrite("TRIM", 1, 4, wf) != 4) { result = false; }
|
||||
count = triangles.size();
|
||||
chunkSize = sizeof(uint32) + sizeof(MeshTriangle) * count;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) result = false;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&triangles[0], sizeof(MeshTriangle), count, wf) != count) { result = false; }
|
||||
|
||||
// write mesh BIH
|
||||
if (result && fwrite("MBIH", 1, 4, wf) != 4) result = false;
|
||||
if (result) result = meshTree.writeToFile(wf);
|
||||
if (result && fwrite("MBIH", 1, 4, wf) != 4) { result = false; }
|
||||
if (result) { result = meshTree.writeToFile(wf); }
|
||||
|
||||
// write liquid data
|
||||
if (result && fwrite("LIQU", 1, 4, wf) != 4) result = false;
|
||||
if (result && fwrite("LIQU", 1, 4, wf) != 4) { result = false; }
|
||||
if (!iLiquid)
|
||||
{
|
||||
chunkSize = 0;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
return result;
|
||||
}
|
||||
chunkSize = iLiquid->GetFileSize();
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result) result = iLiquid->writeToFile(wf);
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result) { result = iLiquid->writeToFile(wf); }
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -323,35 +343,39 @@ namespace VMAP
|
||||
delete iLiquid;
|
||||
iLiquid = nullptr;
|
||||
|
||||
if (result && fread(&iBound, sizeof(G3D::AABox), 1, rf) != 1) result = false;
|
||||
if (result && fread(&iMogpFlags, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&iGroupWMOID, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&iBound, sizeof(G3D::AABox), 1, rf) != 1) { result = false; }
|
||||
if (result && fread(&iMogpFlags, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result && fread(&iGroupWMOID, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
|
||||
// read vertices
|
||||
if (result && !readChunk(rf, chunk, "VERT", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && !readChunk(rf, chunk, "VERT", 4)) { result = false; }
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (!count) // models without (collision) geometry end here, unsure if they are useful
|
||||
{
|
||||
return result;
|
||||
if (result) vertices.resize(count);
|
||||
if (result && fread(&vertices[0], sizeof(Vector3), count, rf) != count) result = false;
|
||||
}
|
||||
if (result) { vertices.resize(count); }
|
||||
if (result && fread(&vertices[0], sizeof(Vector3), count, rf) != count) { result = false; }
|
||||
|
||||
// read triangle mesh
|
||||
if (result && !readChunk(rf, chunk, "TRIM", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result) triangles.resize(count);
|
||||
if (result && fread(&triangles[0], sizeof(MeshTriangle), count, rf) != count) result = false;
|
||||
if (result && !readChunk(rf, chunk, "TRIM", 4)) { result = false; }
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result) { triangles.resize(count); }
|
||||
if (result && fread(&triangles[0], sizeof(MeshTriangle), count, rf) != count) { result = false; }
|
||||
|
||||
// read mesh BIH
|
||||
if (result && !readChunk(rf, chunk, "MBIH", 4)) result = false;
|
||||
if (result) result = meshTree.readFromFile(rf);
|
||||
if (result && !readChunk(rf, chunk, "MBIH", 4)) { result = false; }
|
||||
if (result) { result = meshTree.readFromFile(rf); }
|
||||
|
||||
// write liquid data
|
||||
if (result && !readChunk(rf, chunk, "LIQU", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && !readChunk(rf, chunk, "LIQU", 4)) { result = false; }
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result && chunkSize > 0)
|
||||
{
|
||||
result = WmoLiquid::readFromFile(rf, iLiquid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -362,7 +386,7 @@ namespace VMAP
|
||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool /*StopAtFirstHit*/)
|
||||
{
|
||||
bool result = IntersectTriangle(triangles[entry], vertices, ray, distance);
|
||||
if (result) hit = true;
|
||||
if (result) { hit = true; }
|
||||
return hit;
|
||||
}
|
||||
std::vector<Vector3>::const_iterator vertices;
|
||||
@@ -373,7 +397,9 @@ namespace VMAP
|
||||
bool GroupModel::IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const
|
||||
{
|
||||
if (triangles.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GModelRayCallback callback(triangles, vertices);
|
||||
meshTree.intersectRay(ray, callback, distance, stopAtFirstHit);
|
||||
@@ -383,28 +409,36 @@ namespace VMAP
|
||||
bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const
|
||||
{
|
||||
if (triangles.empty() || !iBound.contains(pos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GModelRayCallback callback(triangles, vertices);
|
||||
Vector3 rPos = pos - 0.1f * down;
|
||||
float dist = G3D::inf();
|
||||
G3D::Ray ray(rPos, down);
|
||||
bool hit = IntersectRay(ray, dist, false);
|
||||
if (hit)
|
||||
{
|
||||
z_dist = dist - 0.1f;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const
|
||||
{
|
||||
if (iLiquid)
|
||||
{
|
||||
return iLiquid->GetLiquidHeight(pos, liqHeight);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GroupModel::GetLiquidType() const
|
||||
{
|
||||
if (iLiquid)
|
||||
{
|
||||
return iLiquid->GetType();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -429,7 +463,7 @@ namespace VMAP
|
||||
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
|
||||
{
|
||||
bool result = models[entry].IntersectRay(ray, distance, StopAtFirstHit);
|
||||
if (result) hit = true;
|
||||
if (result) { hit = true; }
|
||||
return hit;
|
||||
}
|
||||
std::vector<GroupModel>::const_iterator models;
|
||||
@@ -441,7 +475,9 @@ namespace VMAP
|
||||
// small M2 workaround, maybe better make separate class with virtual intersection funcs
|
||||
// in any case, there's no need to use a bound tree if we only have one submodel
|
||||
if (groupModels.size() == 1)
|
||||
{
|
||||
return groupModels[0].IntersectRay(ray, distance, stopAtFirstHit);
|
||||
}
|
||||
|
||||
WModelRayCallBack isc(groupModels);
|
||||
groupTree.intersectRay(ray, isc, distance, stopAtFirstHit);
|
||||
@@ -489,7 +525,9 @@ namespace VMAP
|
||||
bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const
|
||||
{
|
||||
if (groupModels.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
@@ -508,7 +546,9 @@ namespace VMAP
|
||||
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const
|
||||
{
|
||||
if (groupModels.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
WModelAreaCallback callback(groupModels, down);
|
||||
groupTree.intersectPoint(p, callback);
|
||||
@@ -525,29 +565,33 @@ namespace VMAP
|
||||
{
|
||||
FILE* wf = fopen(filename.c_str(), "wb");
|
||||
if (!wf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 chunkSize, count;
|
||||
bool result = fwrite(VMAP_MAGIC, 1, 8, wf) == 8;
|
||||
if (result && fwrite("WMOD", 1, 4, wf) != 4) result = false;
|
||||
if (result && fwrite("WMOD", 1, 4, wf) != 4) { result = false; }
|
||||
chunkSize = sizeof(uint32) + sizeof(uint32);
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
|
||||
// write group models
|
||||
count = groupModels.size();
|
||||
if (count)
|
||||
{
|
||||
if (result && fwrite("GMOD", 1, 4, wf) != 4) result = false;
|
||||
if (result && fwrite("GMOD", 1, 4, wf) != 4) { result = false; }
|
||||
//chunkSize = sizeof(uint32)+ sizeof(GroupModel)*count;
|
||||
//if (result && fwrite(&chunkSize, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) result = false;
|
||||
if (result && fwrite(&count, sizeof(uint32), 1, wf) != 1) { result = false; }
|
||||
for (uint32 i = 0; i < groupModels.size() && result; ++i)
|
||||
{
|
||||
result = groupModels[i].writeToFile(wf);
|
||||
}
|
||||
|
||||
// write group BIH
|
||||
if (result && fwrite("GBIH", 1, 4, wf) != 4) result = false;
|
||||
if (result) result = groupTree.writeToFile(wf);
|
||||
if (result && fwrite("GBIH", 1, 4, wf) != 4) { result = false; }
|
||||
if (result) { result = groupTree.writeToFile(wf); }
|
||||
}
|
||||
|
||||
fclose(wf);
|
||||
@@ -558,32 +602,36 @@ namespace VMAP
|
||||
{
|
||||
FILE* rf = fopen(filename.c_str(), "rb");
|
||||
if (!rf)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
uint32 chunkSize = 0;
|
||||
uint32 count = 0;
|
||||
char chunk[8]; // Ignore the added magic header
|
||||
if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) result = false;
|
||||
if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) { result = false; }
|
||||
|
||||
if (result && !readChunk(rf, chunk, "WMOD", 4)) result = false;
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && fread(&RootWMOID, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result && !readChunk(rf, chunk, "WMOD", 4)) { result = false; }
|
||||
if (result && fread(&chunkSize, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result && fread(&RootWMOID, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
|
||||
// read group models
|
||||
if (result && readChunk(rf, chunk, "GMOD", 4))
|
||||
{
|
||||
//if (fread(&chunkSize, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) result = false;
|
||||
if (result) groupModels.resize(count);
|
||||
if (result && fread(&count, sizeof(uint32), 1, rf) != 1) { result = false; }
|
||||
if (result) { groupModels.resize(count); }
|
||||
//if (result && fread(&groupModels[0], sizeof(GroupModel), count, rf) != count) result = false;
|
||||
for (uint32 i = 0; i < count && result; ++i)
|
||||
{
|
||||
result = groupModels[i].readFromFile(rf);
|
||||
}
|
||||
|
||||
// read group BIH
|
||||
if (result && !readChunk(rf, chunk, "GBIH", 4)) result = false;
|
||||
if (result) result = groupTree.readFromFile(rf);
|
||||
if (result && !readChunk(rf, chunk, "GBIH", 4)) { result = false; }
|
||||
if (result) { result = groupTree.readFromFile(rf); }
|
||||
}
|
||||
|
||||
fclose(rf);
|
||||
|
||||
@@ -22,7 +22,9 @@ public:
|
||||
return;
|
||||
}
|
||||
else if (_nodes[i] == n)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
Node* _nodes[9];
|
||||
};
|
||||
@@ -64,7 +66,9 @@ public:
|
||||
{
|
||||
for (int x = 0; x < CELL_NUMBER; ++x)
|
||||
for (int y = 0; y < CELL_NUMBER; ++y)
|
||||
{
|
||||
delete nodes[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
void insert(const T& value)
|
||||
@@ -85,7 +89,9 @@ public:
|
||||
{
|
||||
Cell c = Cell::ComputeCell(pos[i].x, pos[i].y);
|
||||
if (!c.isValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Node& node = getGridFor(pos[i].x, pos[i].y);
|
||||
na.AddNode(&node);
|
||||
}
|
||||
@@ -93,9 +99,13 @@ public:
|
||||
for (uint8 i = 0; i < 9; ++i)
|
||||
{
|
||||
if (na._nodes[i])
|
||||
{
|
||||
na._nodes[i]->insert(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memberTable.set(&value, na);
|
||||
@@ -107,9 +117,13 @@ public:
|
||||
for (uint8 i = 0; i < 9; ++i)
|
||||
{
|
||||
if (na._nodes[i])
|
||||
{
|
||||
na._nodes[i]->remove(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the member
|
||||
@@ -121,7 +135,9 @@ public:
|
||||
for (int x = 0; x < CELL_NUMBER; ++x)
|
||||
for (int y = 0; y < CELL_NUMBER; ++y)
|
||||
if (Node* n = nodes[x][y])
|
||||
{
|
||||
n->balance();
|
||||
}
|
||||
}
|
||||
|
||||
bool contains(const T& value) const { return memberTable.containsKey(&value); }
|
||||
@@ -151,7 +167,9 @@ public:
|
||||
{
|
||||
ASSERT(x < CELL_NUMBER && y < CELL_NUMBER);
|
||||
if (!nodes[x][y])
|
||||
{
|
||||
nodes[x][y] = NodeCreatorFunc::makeNode(x, y);
|
||||
}
|
||||
return *nodes[x][y];
|
||||
}
|
||||
|
||||
@@ -166,14 +184,18 @@ public:
|
||||
{
|
||||
Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
|
||||
if (!cell.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Cell last_cell = Cell::ComputeCell(end.x, end.y);
|
||||
|
||||
if (cell == last_cell)
|
||||
{
|
||||
if (Node* node = nodes[cell.x][cell.y])
|
||||
{
|
||||
node->intersectRay(ray, intersectCallback, max_dist, stopAtFirstHit);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,7 +244,9 @@ public:
|
||||
node->intersectRay(ray, intersectCallback, max_dist, stopAtFirstHit);
|
||||
}
|
||||
if (cell == last_cell)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (tMaxX < tMaxY)
|
||||
{
|
||||
tMaxX += tDeltaX;
|
||||
@@ -242,9 +266,13 @@ public:
|
||||
{
|
||||
Cell cell = Cell::ComputeCell(point.x, point.y);
|
||||
if (!cell.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Node* node = nodes[cell.x][cell.y])
|
||||
{
|
||||
node->intersectPoint(point, intersectCallback);
|
||||
}
|
||||
}
|
||||
|
||||
// Optimized verson of intersectRay function for rays with vertical directions
|
||||
@@ -253,9 +281,13 @@ public:
|
||||
{
|
||||
Cell cell = Cell::ComputeCell(ray.origin().x, ray.origin().y);
|
||||
if (!cell.isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Node* node = nodes[cell.x][cell.y])
|
||||
{
|
||||
node->intersectRay(ray, intersectCallback, max_dist, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user