refactor(Core/Common): restyle common lib with astyle (#3461)

This commit is contained in:
Kargatum
2020-09-12 03:50:48 +07:00
committed by GitHub
parent e15a493927
commit 3a0b0356ac
101 changed files with 4524 additions and 4418 deletions

View File

@@ -7,12 +7,12 @@
#include "BoundingIntervalHierarchy.h"
#ifdef _MSC_VER
#define isnan _isnan
#define isnan _isnan
#else
#define isnan std::isnan
#define isnan std::isnan
#endif
void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats)
void BIH::buildHierarchy(std::vector<uint32>& tempTree, buildData& dat, BuildStats& stats)
{
// create space for the first node
tempTree.push_back(uint32(3 << 30)); // dummy leaf
@@ -26,7 +26,7 @@ void BIH::buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildSta
subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
}
void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
void BIH::subdivide(int left, int right, std::vector<uint32>& tempTree, buildData& dat, AABound& gridBox, AABound& nodeBox, int nodeIndex, int depth, BuildStats& stats)
{
if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
{
@@ -121,13 +121,15 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
if (right == rightOrig)
{
// all left
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
{
// we are stuck here - create a leaf
stats.updateLeaf(depth, right - left + 1);
createNode(tempTree, nodeIndex, left, right);
return;
}
if (clipL <= split) {
if (clipL <= split)
{
// keep looping on left half
gridBox.hi[axis] = split;
prevClip = clipL;
@@ -140,14 +142,16 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
else if (left > right)
{
// all right
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
{
// we are stuck here - create a leaf
stats.updateLeaf(depth, right - left + 1);
createNode(tempTree, nodeIndex, left, right);
return;
}
right = rightOrig;
if (clipR >= split) {
if (clipR >= split)
{
// keep looping on right half
gridBox.lo[axis] = split;
prevClip = clipR;
@@ -169,14 +173,17 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
if (wasLeft) {
if (wasLeft)
{
// create a node with a left child
// write leaf node
stats.updateInner();
tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::inf());
} else {
}
else
{
// create a node with a right child
// write leaf node
stats.updateInner();
@@ -198,14 +205,17 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
// allocate left node
int nl = right - left + 1;
int nr = rightOrig - (right + 1) + 1;
if (nl > 0) {
if (nl > 0)
{
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
} else
}
else
nextIndex -= 3;
// allocate right node
if (nr > 0) {
if (nr > 0)
{
tempTree.push_back(0);
tempTree.push_back(0);
tempTree.push_back(0);
@@ -235,7 +245,7 @@ void BIH::subdivide(int left, int right, std::vector<uint32> &tempTree, buildDat
bool BIH::writeToFile(FILE* wf) const
{
uint32 treeSize = tree.size();
uint32 check=0, count;
uint32 check = 0, count;
check += fwrite(&bounds.low(), sizeof(float), 3, wf);
check += fwrite(&bounds.high(), sizeof(float), 3, wf);
check += fwrite(&treeSize, sizeof(uint32), 1, wf);
@@ -250,7 +260,7 @@ bool BIH::readFromFile(FILE* rf)
{
uint32 treeSize;
G3D::Vector3 lo, hi;
uint32 check=0, count=0;
uint32 check = 0, count = 0;
check += fread(&lo, sizeof(float), 3, rf);
check += fread(&hi, sizeof(float), 3, rf);
bounds = G3D::AABox(lo, hi);

View File

@@ -54,332 +54,340 @@ struct AABound
class BIH
{
private:
void init_empty()
private:
void init_empty()
{
tree.clear();
objects.clear();
// create space for the first node
tree.push_back(3u << 30u); // dummy leaf
tree.insert(tree.end(), 2, 0);
}
public:
BIH() { init_empty(); }
template< class BoundsFunc, class PrimArray >
void build(const PrimArray& primitives, BoundsFunc& getBounds, uint32 leafSize = 3, bool printStats = false)
{
if (primitives.size() == 0)
{
tree.clear();
objects.clear();
// create space for the first node
tree.push_back(3u << 30u); // dummy leaf
tree.insert(tree.end(), 2, 0);
init_empty();
return;
}
public:
BIH() { init_empty(); }
template< class BoundsFunc, class PrimArray >
void build(const PrimArray &primitives, BoundsFunc &getBounds, uint32 leafSize = 3, bool printStats=false)
buildData dat;
dat.maxPrims = leafSize;
dat.numPrims = primitives.size();
dat.indices = new uint32[dat.numPrims];
dat.primBound = new G3D::AABox[dat.numPrims];
getBounds(primitives[0], bounds);
for (uint32 i = 0; i < dat.numPrims; ++i)
{
if (primitives.size() == 0)
{
init_empty();
return;
}
buildData dat;
dat.maxPrims = leafSize;
dat.numPrims = primitives.size();
dat.indices = new uint32[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;
getBounds(primitives[i], dat.primBound[i]);
bounds.merge(dat.primBound[i]);
}
std::vector<uint32> tempTree;
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;
delete[] dat.indices;
dat.indices[i] = i;
getBounds(primitives[i], dat.primBound[i]);
bounds.merge(dat.primBound[i]);
}
uint32 primCount() const { return objects.size(); }
std::vector<uint32> tempTree;
BuildStats stats;
buildHierarchy(tempTree, dat, stats);
if (printStats)
stats.printStats();
template<typename RayCallback>
void intersectRay(const G3D::Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirstHit) const
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;
delete[] dat.indices;
}
uint32 primCount() const { return objects.size(); }
template<typename RayCallback>
void intersectRay(const G3D::Ray& r, RayCallback& intersectCallback, float& maxDist, bool stopAtFirstHit) const
{
float intervalMin = -1.f;
float intervalMax = -1.f;
G3D::Vector3 org = r.origin();
G3D::Vector3 dir = r.direction();
G3D::Vector3 invDir;
for (int i = 0; i < 3; ++i)
{
float intervalMin = -1.f;
float intervalMax = -1.f;
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];
if (G3D::fuzzyNe(dir[i], 0.0f))
{
invDir[i] = 1.f / dir[i];
if (G3D::fuzzyNe(dir[i], 0.0f))
{
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;
}
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);
if (intervalMin > intervalMax)
return;
intervalMin = std::max(intervalMin, 0.f);
intervalMax = std::min(intervalMax, maxDist);
uint32 offsetFront[3];
uint32 offsetBack[3];
uint32 offsetFront3[3];
uint32 offsetBack3[3];
// compute custom offsets from direction sign bit
uint32 offsetFront[3];
uint32 offsetBack[3];
uint32 offsetFront3[3];
uint32 offsetBack3[3];
// compute custom offsets from direction sign bit
for (int i=0; i<3; ++i)
for (int i = 0; i < 3; ++i)
{
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
offsetBack[i] = offsetFront[i] ^ 1;
offsetFront3[i] = offsetFront[i] * 3;
offsetBack3[i] = offsetBack[i] * 3;
// avoid always adding 1 during the inner loop
++offsetFront[i];
++offsetBack[i];
}
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true)
{
while (true)
{
offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
offsetBack[i] = offsetFront[i] ^ 1;
offsetFront3[i] = offsetFront[i] * 3;
offsetBack3[i] = offsetBack[i] * 3;
// avoid always adding 1 during the inner loop
++offsetFront[i];
++offsetBack[i];
}
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true) {
while (true)
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
if (axis < 3)
{
if (axis < 3)
// "normal" interior node
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
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
if (tf < intervalMin)
{
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetFront3[axis]; // front
// ray passes through near node only
if (tb > intervalMax)
{
// "normal" interior node
float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
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
if (tf < intervalMin) {
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetFront3[axis]; // front
// ray passes through near node only
if (tb > intervalMax) {
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].tfar = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0) {
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirstHit);
if (stopAtFirstHit && hit) return;
--n;
++offset;
}
break;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].tfar = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
else
{
if (axis>2)
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
do
{
// 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;
} while (true);
}
}
template<typename IsectCallback>
void intersectPoint(const G3D::Vector3 &p, IsectCallback& intersectCallback) const
{
if (!bounds.contains(p))
return;
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
while (true) {
while (true)
{
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
if (axis < 3)
// leaf - test some objects
int n = tree[node + 1];
while (n > 0)
{
// "normal" interior node
float tl = intBitsToFloat(tree[node + 1]);
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
if (tl < p[axis]) {
continue;
}
node = offset; // left
// point is in left node only
if (tr > p[axis]) {
continue;
}
// point is in both nodes
// push back right node
stack[stackPos].node = right;
stackPos++;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0) {
intersectCallback(p, objects[offset]); // !!!
--n;
++offset;
}
break;
bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirstHit);
if (stopAtFirstHit && hit) return;
--n;
++offset;
}
break;
}
else // BVH2 node (empty space cut off left and right)
{
if (axis>2)
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
}
else
{
if (axis > 2)
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
do
{
// 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;
} while (true);
}
}
bool writeToFile(FILE* wf) const;
bool readFromFile(FILE* rf);
template<typename IsectCallback>
void intersectPoint(const G3D::Vector3& p, IsectCallback& intersectCallback) const
{
if (!bounds.contains(p))
return;
protected:
std::vector<uint32> tree;
std::vector<uint32> objects;
G3D::AABox bounds;
StackNode stack[MAX_STACK_SIZE];
int stackPos = 0;
int node = 0;
struct buildData
while (true)
{
uint32 *indices;
G3D::AABox *primBound;
uint32 numPrims;
int maxPrims;
};
struct StackNode
{
uint32 node;
float tnear;
float tfar;
};
class BuildStats
{
private:
int numNodes;
int numLeaves;
int sumObjects;
int minObjects;
int maxObjects;
int sumDepth;
int minDepth;
int maxDepth;
int numLeavesN[6];
int numBVH2;
public:
BuildStats():
numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
maxDepth(0xFFFFFFFF), numBVH2(0)
while (true)
{
for (int i=0; i<6; ++i) numLeavesN[i] = 0;
}
uint32 tn = tree[node];
uint32 axis = (tn & (3 << 30)) >> 30;
bool BVH2 = tn & (1 << 29);
int offset = tn & ~(7 << 29);
if (!BVH2)
{
if (axis < 3)
{
// "normal" interior node
float tl = intBitsToFloat(tree[node + 1]);
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
if (tl < p[axis])
{
continue;
}
node = offset; // left
// point is in left node only
if (tr > p[axis])
{
continue;
}
// point is in both nodes
// push back right node
stack[stackPos].node = right;
stackPos++;
continue;
}
else
{
// leaf - test some objects
int n = tree[node + 1];
while (n > 0)
{
intersectCallback(p, objects[offset]); // !!!
--n;
++offset;
}
break;
}
}
else // BVH2 node (empty space cut off left and right)
{
if (axis > 2)
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
void updateInner() { numNodes++; }
void updateBVH2() { numBVH2++; }
void updateLeaf(int depth, int n);
void printStats();
};
// stack is empty?
if (stackPos == 0)
return;
// move back up the stack
stackPos--;
node = stack[stackPos].node;
}
}
void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
bool writeToFile(FILE* wf) const;
bool readFromFile(FILE* rf);
void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) const
protected:
std::vector<uint32> tree;
std::vector<uint32> objects;
G3D::AABox bounds;
struct buildData
{
uint32* indices;
G3D::AABox* primBound;
uint32 numPrims;
int maxPrims;
};
struct StackNode
{
uint32 node;
float tnear;
float tfar;
};
class BuildStats
{
private:
int numNodes;
int numLeaves;
int sumObjects;
int minObjects;
int maxObjects;
int sumDepth;
int minDepth;
int maxDepth;
int numLeavesN[6];
int numBVH2;
public:
BuildStats():
numNodes(0), numLeaves(0), sumObjects(0), minObjects(0x0FFFFFFF),
maxObjects(0xFFFFFFFF), sumDepth(0), minDepth(0x0FFFFFFF),
maxDepth(0xFFFFFFFF), numBVH2(0)
{
// write leaf node
tempTree[nodeIndex + 0] = (3 << 30) | left;
tempTree[nodeIndex + 1] = right - left + 1;
for (int i = 0; i < 6; ++i) numLeavesN[i] = 0;
}
void subdivide(int left, int right, std::vector<uint32> &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats);
void updateInner() { numNodes++; }
void updateBVH2() { numBVH2++; }
void updateLeaf(int depth, int n);
void printStats();
};
void buildHierarchy(std::vector<uint32>& tempTree, buildData& dat, BuildStats& stats);
void createNode(std::vector<uint32>& tempTree, int nodeIndex, uint32 left, uint32 right) const
{
// write leaf node
tempTree[nodeIndex + 0] = (3 << 30) | left;
tempTree[nodeIndex + 1] = right - left + 1;
}
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

View File

@@ -66,7 +66,7 @@ public:
{
++unbalanced_times;
uint32 Idx = 0;
const T * temp;
const T* temp;
if (m_obj2Idx.getRemove(&obj, temp, Idx))
m_objects[Idx] = NULL;
else

View File

@@ -21,21 +21,25 @@
using VMAP::ModelInstance;
namespace {
namespace
{
int CHECK_TREE_PERIOD = 200;
int CHECK_TREE_PERIOD = 200;
} // namespace
template<> struct HashTrait< GameObjectModel>{
template<> struct HashTrait< GameObjectModel>
{
static size_t hashCode(const GameObjectModel& g) { return (size_t)(void*)&g; }
};
template<> struct PositionTrait< GameObjectModel> {
template<> struct PositionTrait< GameObjectModel>
{
static void getPosition(const GameObjectModel& g, G3D::Vector3& p) { p = g.getPosition(); }
};
template<> struct BoundsTrait< GameObjectModel> {
template<> struct BoundsTrait< GameObjectModel>
{
static void getBounds(const GameObjectModel& g, G3D::AABox& out) { out = g.getBounds();}
static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();}
};
@@ -148,7 +152,7 @@ struct DynamicTreeIntersectionCallback
};
bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray,
const G3D::Vector3& endPos, float& maxDist) const
const G3D::Vector3& endPos, float& maxDist) const
{
float distance = maxDist;
DynamicTreeIntersectionCallback callback(phasemask);
@@ -172,7 +176,7 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3&
resultHit = endPos;
return false;
}
G3D::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))
@@ -181,12 +185,12 @@ bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const G3D::Vector3&
if (modifyDist < 0)
{
if ((resultHit - startPos).magnitude() > -modifyDist)
resultHit = resultHit + dir*modifyDist;
resultHit = resultHit + dir * modifyDist;
else
resultHit = startPos;
}
else
resultHit = resultHit + dir*modifyDist;
resultHit = resultHit + dir * modifyDist;
result = true;
}
@@ -207,7 +211,7 @@ bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, flo
if (!G3D::fuzzyGt(maxDist, 0) )
return true;
G3D::Ray r(v1, (v2-v1) / maxDist);
G3D::Ray r(v1, (v2 - v1) / maxDist);
DynamicTreeIntersectionCallback callback(phasemask);
impl->intersectRay(r, callback, maxDist, v2, true);

View File

@@ -20,7 +20,7 @@ struct DynTreeImpl;
class DynamicMapTree
{
DynTreeImpl *impl;
DynTreeImpl* impl;
public:

View File

@@ -22,16 +22,16 @@ namespace MMAP
class IMMapManager
{
private:
bool iEnablePathFinding;
private:
bool iEnablePathFinding;
public:
IMMapManager() : iEnablePathFinding(true) {}
virtual ~IMMapManager(void) {}
public:
IMMapManager() : iEnablePathFinding(true) {}
virtual ~IMMapManager(void) {}
//Enabled/Disabled Pathfinding
void setEnablePathFinding(bool value) { iEnablePathFinding = value; }
bool isEnablePathFinding() const { return (iEnablePathFinding); }
//Enabled/Disabled Pathfinding
void setEnablePathFinding(bool value) { iEnablePathFinding = value; }
bool isEnablePathFinding() const { return (iEnablePathFinding); }
};
}

View File

@@ -26,62 +26,62 @@ namespace VMAP
VMAP_LOAD_RESULT_IGNORED
};
#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
#define VMAP_INVALID_HEIGHT -100000.0f // for check
#define VMAP_INVALID_HEIGHT_VALUE -200000.0f // real assigned value in unknown height case
//===========================================================
class IVMapManager
{
private:
bool iEnableLineOfSightCalc;
bool iEnableHeightCalc;
private:
bool iEnableLineOfSightCalc;
bool iEnableHeightCalc;
public:
IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) { }
public:
IVMapManager() : iEnableLineOfSightCalc(true), iEnableHeightCalc(true) { }
virtual ~IVMapManager(void) { }
virtual ~IVMapManager(void) { }
virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual int loadMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual bool existsMap(const char* pBasePath, unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId) = 0;
virtual void unloadMap(unsigned int pMapId, int x, int y) = 0;
virtual void unloadMap(unsigned int pMapId) = 0;
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
virtual float getHeight(unsigned int pMapId, float x, float y, float z, float maxSearchDist) = 0;
/**
test if we hit an object. return true if we hit one. rx, ry, rz will hold the hit position or the dest position, if no intersection was found
return a position, that is pReduceDist closer to the origin
*/
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float pModifyDist) = 0;
/**
send debug commands
*/
virtual bool processCommand(char *pCommand)= 0;
virtual bool isInLineOfSight(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2) = 0;
virtual float getHeight(unsigned int pMapId, float x, float y, float z, float maxSearchDist) = 0;
/**
test if we hit an object. return true if we hit one. rx, ry, rz will hold the hit position or the dest position, if no intersection was found
return a position, that is pReduceDist closer to the origin
*/
virtual bool getObjectHitPos(unsigned int pMapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float pModifyDist) = 0;
/**
send debug commands
*/
virtual bool processCommand(char* pCommand) = 0;
/**
Enable/disable LOS calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
/**
Enable/disable model height calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
/**
Enable/disable LOS calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableLineOfSightCalc(bool pVal) { iEnableLineOfSightCalc = pVal; }
/**
Enable/disable model height calculation
It is enabled by default. If it is enabled in mid game the maps have to loaded manualy
*/
void setEnableHeightCalc(bool pVal) { iEnableHeightCalc = pVal; }
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
bool isLineOfSightCalcEnabled() const { return(iEnableLineOfSightCalc); }
bool isHeightCalcEnabled() const { return(iEnableHeightCalc); }
bool isMapLoadingEnabled() const { return(iEnableLineOfSightCalc || iEnableHeightCalc ); }
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const =0;
/**
Query world model area info.
\param z gets adjusted to the ground height for which this are info is valid
*/
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float &z, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const=0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float &level, float &floor, uint32 &type) const=0;
virtual std::string getDirFileName(unsigned int pMapId, int x, int y) const = 0;
/**
Query world model area info.
\param z gets adjusted to the ground height for which this are info is valid
*/
virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0;
virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type) const = 0;
};
}

View File

@@ -12,7 +12,7 @@ namespace MMAP
{
// ######################## MMapFactory ########################
// our global singleton copy
MMapManager *g_MMapManager = NULL;
MMapManager* g_MMapManager = NULL;
bool MMapFactory::forbiddenMaps[1000] = {0};
MMapManager* MMapFactory::createOrGetMMapManager()

View File

@@ -28,12 +28,12 @@ namespace MMAP
// access point to MMapManager singleton
class MMapFactory
{
public:
static MMapManager* createOrGetMMapManager();
static void clear();
static bool IsPathfindingEnabled(const Map* map);
static void InitializeDisabledMaps();
static bool forbiddenMaps[1000];
public:
static MMapManager* createOrGetMMapManager();
static void clear();
static bool IsPathfindingEnabled(const Map* map);
static void InitializeDisabledMaps();
static bool forbiddenMaps[1000];
};
}

View File

@@ -27,9 +27,9 @@ namespace MMAP
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);
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)
@@ -112,11 +112,11 @@ namespace MMAP
}
// 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);
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");
FILE* file = fopen(fileName, "rb");
if (!file)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
@@ -139,7 +139,7 @@ namespace MMAP
if (fileHeader.mmapVersion != MMAP_VERSION)
{
sLog->outError("MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
fclose(file);
return false;
}
@@ -345,26 +345,26 @@ namespace MMAP
MMapData* mmap = loadedMMaps[mapId];
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// pussywizard: different instances of the same map shouldn't access this simultaneously
ACORE_WRITE_GUARD(ACE_RW_Thread_Mutex, GetMMapLock(mapId));
// check again after acquiring mutex
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
// pussywizard: different instances of the same map shouldn't access this simultaneously
ACORE_WRITE_GUARD(ACE_RW_Thread_Mutex, GetMMapLock(mapId));
// check again after acquiring mutex
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
{
dtFreeNavMeshQuery(query);
sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
return NULL;
}
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
{
dtFreeNavMeshQuery(query);
sLog->outError("MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
return NULL;
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
sLog->outDetail("MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
#endif
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
}
}
return mmap->navMeshQueries[instanceId];

View File

@@ -57,34 +57,34 @@ namespace MMAP
// holds all all access to mmap loading unloading and meshes
class MMapManager
{
public:
MMapManager() : loadedTiles(0) {}
~MMapManager();
public:
MMapManager() : loadedTiles(0) {}
~MMapManager();
bool loadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId);
bool unloadMapInstance(uint32 mapId, uint32 instanceId);
bool loadMap(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);
// 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(); }
uint32 getLoadedTilesCount() const { return loadedTiles; }
uint32 getLoadedMapsCount() const { return loadedMMaps.size(); }
ACE_RW_Thread_Mutex& GetMMapLock(uint32 mapId);
ACE_RW_Thread_Mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex& GetManagerLock() { return MMapManagerLock; }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
ACE_RW_Thread_Mutex& GetMMapLock(uint32 mapId);
ACE_RW_Thread_Mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex& GetManagerLock() { return MMapManagerLock; }
private:
bool loadMapData(uint32 mapId);
uint32 packTileID(int32 x, int32 y);
MMapDataSet loadedMMaps;
uint32 loadedTiles;
MMapDataSet loadedMMaps;
uint32 loadedTiles;
ACE_RW_Thread_Mutex MMapManagerLock;
ACE_RW_Thread_Mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
ACE_RW_Thread_Mutex MMapManagerLock;
ACE_RW_Thread_Mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen
};
}

View File

@@ -16,7 +16,7 @@ namespace VMAP
IVMapManager* VMapFactory::createOrGetVMapManager()
{
if (gVMapManager == 0)
gVMapManager= new VMapManager2(); // should be taken from config ... Please change if you like :-)
gVMapManager = new VMapManager2(); // should be taken from config ... Please change if you like :-)
return gVMapManager;
}

View File

@@ -19,9 +19,9 @@ namespace VMAP
class VMapFactory
{
public:
static IVMapManager* createOrGetVMapManager();
static void clear();
public:
static IVMapManager* createOrGetVMapManager();
static void clear();
};
}

View File

@@ -95,10 +95,10 @@ namespace VMAP
std::string mapFileName = getMapFileName(mapId);
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
if (!newTree->InitMap(mapFileName, this))
{
delete newTree;
{
delete newTree;
return false;
}
}
instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first;
}
@@ -158,7 +158,7 @@ namespace VMAP
get the hit position and return true if we hit something
otherwise the result pos will be the dest pos
*/
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist)
bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS)
if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, NULL, VMAP_DISABLE_LOS))
@@ -283,7 +283,7 @@ namespace VMAP
return model->second.getModel();
}
void VMapManager2::releaseModelInstance(const std::string &filename)
void VMapManager2::releaseModelInstance(const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
ACORE_GUARD(ACE_Thread_Mutex, LoadedModelFilesLock);

View File

@@ -51,15 +51,15 @@ namespace VMAP
class ManagedModel
{
public:
ManagedModel() : iModel(0), iRefCount(0) { }
void setModel(WorldModel* model) { iModel = model; }
WorldModel* getModel() { return iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel* iModel;
int iRefCount;
public:
ManagedModel() : iModel(0), iRefCount(0) { }
void setModel(WorldModel* model) { iModel = model; }
WorldModel* getModel() { return iModel; }
void incRefCount() { ++iRefCount; }
int decRefCount() { return --iRefCount; }
protected:
WorldModel* iModel;
int iRefCount;
};
typedef std::unordered_map<uint32, StaticMapTree*> InstanceTreeMap;
@@ -67,57 +67,57 @@ namespace VMAP
class VMapManager2 : public IVMapManager
{
protected:
// Tree to check collision
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
// Mutex for iLoadedModelFiles
ACE_Thread_Mutex LoadedModelFilesLock;
protected:
// Tree to check collision
ModelFileMap iLoadedModelFiles;
InstanceTreeMap iInstanceMapTrees;
// Mutex for iLoadedModelFiles
ACE_Thread_Mutex LoadedModelFilesLock;
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
bool _loadMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
/* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
static uint32 GetLiquidFlagsDummy(uint32) { return 0; }
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
static std::string getMapFileName(unsigned int mapId);
public:
// public for debug
G3D::Vector3 convertPositionToInternalRep(float x, float y, float z) const;
static std::string getMapFileName(unsigned int mapId);
VMapManager2();
~VMapManager2(void);
VMapManager2();
~VMapManager2(void);
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y);
int loadMap(const char* pBasePath, unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId);
void unloadMap(unsigned int mapId, int x, int y);
void unloadMap(unsigned int mapId);
bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
/**
fill the hit pos and return true, if an object was hit
*/
bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist);
float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist);
bool isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) ;
/**
fill the hit pos and return true, if an object was hit
*/
bool getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist);
float getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist);
bool processCommand(char* /*command*/) { return false; } // for debug and extensions
bool processCommand(char* /*command*/) { return false; } // for debug and extensions
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const;
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const;
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename);
void releaseModelInstance(const std::string& filename);
WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename);
void releaseModelInstance(const std::string& filename);
// what's the use of this? o.O
virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const
{
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y);
public:
void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
// what's the use of this? o.O
virtual std::string getDirFileName(unsigned int mapId, int /*x*/, int /*y*/) const
{
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y);
public:
void getInstanceMapTree(InstanceTreeMap& instanceMapTree);
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
GetLiquidFlagsFn GetLiquidFlagsPtr;
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
GetLiquidFlagsFn GetLiquidFlagsPtr;
};
}

View File

@@ -23,15 +23,15 @@ namespace VMAP
class MapRayCallback
{
public:
MapRayCallback(ModelInstance* val): prims(val), hit(false) {}
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
{
bool result = prims[entry].intersectRay(ray, distance, StopAtFirstHit);
if (result)
hit = true;
return result;
}
public:
MapRayCallback(ModelInstance* val): prims(val), hit(false) {}
bool operator()(const G3D::Ray& ray, uint32 entry, float& distance, bool StopAtFirstHit)
{
bool result = prims[entry].intersectRay(ray, distance, StopAtFirstHit);
if (result)
hit = true;
return result;
}
bool didHit() { return hit; }
protected:
ModelInstance* prims;
@@ -40,36 +40,36 @@ namespace VMAP
class AreaInfoCallback
{
public:
AreaInfoCallback(ModelInstance* val): prims(val) {}
void operator()(const Vector3& point, uint32 entry)
{
public:
AreaInfoCallback(ModelInstance* val): prims(val) {}
void operator()(const Vector3& point, uint32 entry)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) && defined(VMAP_DEBUG)
sLog->outDebug(LOG_FILTER_MAPS, "AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
sLog->outDebug(LOG_FILTER_MAPS, "AreaInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
#endif
prims[entry].intersectPoint(point, aInfo);
}
prims[entry].intersectPoint(point, aInfo);
}
ModelInstance* prims;
AreaInfo aInfo;
ModelInstance* prims;
AreaInfo aInfo;
};
class LocationInfoCallback
{
public:
LocationInfoCallback(ModelInstance* val, LocationInfo &info): prims(val), locInfo(info), result(false) {}
void operator()(const Vector3& point, uint32 entry)
{
public:
LocationInfoCallback(ModelInstance* val, LocationInfo& info): prims(val), locInfo(info), result(false) {}
void operator()(const Vector3& point, uint32 entry)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) && defined(VMAP_DEBUG)
sLog->outDebug(LOG_FILTER_MAPS, "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
sLog->outDebug(LOG_FILTER_MAPS, "LocationInfoCallback: trying to intersect '%s'", prims[entry].name.c_str());
#endif
if (prims[entry].GetLocationInfo(point, locInfo))
result = true;
}
if (prims[entry].GetLocationInfo(point, locInfo))
result = true;
}
ModelInstance* prims;
LocationInfo &locInfo;
bool result;
ModelInstance* prims;
LocationInfo& locInfo;
bool result;
};
//=========================================================
@@ -84,7 +84,7 @@ namespace VMAP
return tilefilename.str();
}
bool StaticMapTree::getAreaInfo(Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const
bool StaticMapTree::getAreaInfo(Vector3& pos, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const
{
AreaInfoCallback intersectionCallBack(iTreeValues);
iTree.intersectPoint(pos, intersectionCallBack);
@@ -100,17 +100,17 @@ namespace VMAP
return false;
}
bool StaticMapTree::GetLocationInfo(const Vector3 &pos, LocationInfo &info) const
bool StaticMapTree::GetLocationInfo(const Vector3& pos, LocationInfo& info) const
{
LocationInfoCallback intersectionCallBack(iTreeValues, info);
iTree.intersectPoint(pos, intersectionCallBack);
return intersectionCallBack.result;
}
StaticMapTree::StaticMapTree(uint32 mapID, const std::string &basePath)
StaticMapTree::StaticMapTree(uint32 mapID, const std::string& basePath)
: iMapID(mapID), iIsTiled(false), iTreeValues(0), iBasePath(basePath)
{
if (iBasePath.length() > 0 && iBasePath[iBasePath.length()-1] != '/' && iBasePath[iBasePath.length()-1] != '\\')
if (iBasePath.length() > 0 && iBasePath[iBasePath.length() - 1] != '/' && iBasePath[iBasePath.length() - 1] != '\\')
{
iBasePath.push_back('/');
}
@@ -129,7 +129,7 @@ namespace VMAP
Else, pMaxDist is not modified and returns false;
*/
bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool StopAtFirstHit) const
bool StaticMapTree::getIntersectionTime(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const
{
float distance = pMaxDist;
MapRayCallback intersectionCallBack(iTreeValues);
@@ -153,7 +153,7 @@ namespace VMAP
if (maxDist < 1e-10f)
return true;
// direction with length of 1
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1)/maxDist);
G3D::Ray ray = G3D::Ray::fromOriginAndDirection(pos1, (pos2 - pos1) / maxDist);
if (getIntersectionTime(ray, maxDist, true))
return false;
@@ -167,7 +167,7 @@ namespace VMAP
bool StaticMapTree::getObjectHitPos(const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const
{
bool result=false;
bool result = false;
float maxDist = (pPos2 - pPos1).magnitude();
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
ASSERT(maxDist < std::numeric_limits<float>::max());
@@ -177,7 +177,7 @@ namespace VMAP
pResultHitPos = pPos2;
return false;
}
Vector3 dir = (pPos2 - pPos1)/maxDist; // direction with length of 1
Vector3 dir = (pPos2 - pPos1) / maxDist; // direction with length of 1
G3D::Ray ray(pPos1, dir);
float dist = maxDist;
if (getIntersectionTime(ray, dist, false))
@@ -187,7 +187,7 @@ namespace VMAP
{
if ((pResultHitPos - pPos1).magnitude() > -pModifyDist)
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
pResultHitPos = pResultHitPos + dir * pModifyDist;
}
else
{
@@ -196,7 +196,7 @@ namespace VMAP
}
else
{
pResultHitPos = pResultHitPos + dir*pModifyDist;
pResultHitPos = pResultHitPos + dir * pModifyDist;
}
result = true;
}
@@ -225,10 +225,10 @@ namespace VMAP
//=========================================================
bool StaticMapTree::CanLoadMap(const std::string &vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
bool StaticMapTree::CanLoadMap(const std::string& vmapPath, uint32 mapID, uint32 tileX, uint32 tileY)
{
std::string basePath = vmapPath;
if (basePath.length() > 0 && basePath[basePath.length()-1] != '/' && basePath[basePath.length()-1] != '\\')
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;
@@ -262,7 +262,7 @@ namespace VMAP
//=========================================================
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm)
bool StaticMapTree::InitMap(const std::string& fname, VMapManager2* vm)
{
//VMAP_DEBUG_LOG(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
bool success = false;
@@ -275,7 +275,7 @@ namespace VMAP
char tiled = '\0';
if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 &&
readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf))
{
iNTreeValues = iTree.primCount();
iTreeValues = new ModelInstance[iNTreeValues];
@@ -354,7 +354,7 @@ namespace VMAP
uint32 numSpawns = 0;
if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
result = false;
for (uint32 i=0; i<numSpawns && result; ++i)
for (uint32 i = 0; i < numSpawns && result; ++i)
{
// read model spawns
ModelSpawn spawn;
@@ -423,14 +423,14 @@ namespace VMAP
FILE* tf = fopen(tilefile.c_str(), "rb");
if (tf)
{
bool result=true;
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)
for (uint32 i = 0; i < numSpawns && result; ++i)
{
// read model spawns
ModelSpawn spawn;
@@ -448,7 +448,7 @@ namespace VMAP
else
{
if (!iLoadedSpawns.count(referencedNode))
sLog->outError("StaticMapTree::UnloadMapTile() : trying to unload non-referenced model '%s' (ID:%u)", spawn.name.c_str(), spawn.ID);
sLog->outError("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();

View File

@@ -29,46 +29,46 @@ namespace VMAP
{
typedef std::unordered_map<uint32, bool> loadedTileMap;
typedef std::unordered_map<uint32, uint32> loadedSpawnMap;
private:
uint32 iMapID;
bool iIsTiled;
BIH iTree;
ModelInstance* iTreeValues; // the tree entries
uint32 iNTreeValues;
private:
uint32 iMapID;
bool iIsTiled;
BIH iTree;
ModelInstance* iTreeValues; // the tree entries
uint32 iNTreeValues;
// Store all the map tile idents that are loaded for that map
// some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
// empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
loadedTileMap iLoadedTiles;
// stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
loadedSpawnMap iLoadedSpawns;
std::string iBasePath;
// Store all the map tile idents that are loaded for that map
// some maps are not splitted into tiles and we have to make sure, not removing the map before all tiles are removed
// empty tiles have no tile file, hence map with bool instead of just a set (consistency check)
loadedTileMap iLoadedTiles;
// stores <tree_index, reference_count> to invalidate tree values, unload map, and to be able to report errors
loadedSpawnMap iLoadedSpawns;
std::string iBasePath;
private:
bool getIntersectionTime(const G3D::Ray& pRay, float &pMaxDist, bool StopAtFirstHit) const;
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
public:
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX<<16 | tileY; }
static void unpackTileID(uint32 ID, uint32 &tileX, uint32 &tileY) { tileX = ID>>16; tileY = ID&0xFF; }
static bool CanLoadMap(const std::string &basePath, uint32 mapID, uint32 tileX, uint32 tileY);
private:
bool getIntersectionTime(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
//bool containsLoadedMapTile(unsigned int pTileIdent) const { return(iLoadedMapTiles.containsKey(pTileIdent)); }
public:
static std::string getTileFileName(uint32 mapID, uint32 tileX, uint32 tileY);
static uint32 packTileID(uint32 tileX, uint32 tileY) { return tileX << 16 | tileY; }
static void unpackTileID(uint32 ID, uint32& tileX, uint32& tileY) { tileX = ID >> 16; tileY = ID & 0xFF; }
static bool CanLoadMap(const std::string& basePath, uint32 mapID, uint32 tileX, uint32 tileY);
StaticMapTree(uint32 mapID, const std::string &basePath);
~StaticMapTree();
StaticMapTree(uint32 mapID, const std::string& basePath);
~StaticMapTree();
bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
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 G3D::Vector3 &pos, LocationInfo &info) const;
bool isInLineOfSight(const G3D::Vector3& pos1, const G3D::Vector3& pos2) const;
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 G3D::Vector3& pos, LocationInfo& info) const;
bool InitMap(const std::string &fname, VMapManager2* vm);
void UnloadMap(VMapManager2* vm);
bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
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);
bool InitMap(const std::string& fname, VMapManager2* vm);
void UnloadMap(VMapManager2* vm);
bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
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

View File

@@ -22,12 +22,12 @@ using std::pair;
template<> struct BoundsTrait<VMAP::ModelSpawn*>
{
static void getBounds(const VMAP::ModelSpawn* const &obj, G3D::AABox& out) { out = obj->getBounds(); }
static void getBounds(const VMAP::ModelSpawn* const& obj, G3D::AABox& out) { out = obj->getBounds(); }
};
namespace VMAP
{
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len)
bool readChunk(FILE* rf, char* dest, const char* compare, uint32 len)
{
if (fread(dest, sizeof(char), len, rf) != len) return false;
return memcmp(dest, compare, len) == 0;
@@ -79,7 +79,7 @@ namespace VMAP
{
/// @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);
entry->second.iBound = entry->second.iBound + Vector3(533.33333f * 32, 533.33333f * 32, 0.f);
}
mapSpawns.push_back(&(entry->second));
spawnedModelFiles.insert(entry->second.name);
@@ -100,7 +100,7 @@ namespace VMAP
// ===> possibly move this code to StaticMapTree class
std::map<uint32, uint32> modelNodeIdx;
for (uint32 i=0; i<mapSpawns.size(); ++i)
for (uint32 i = 0; i < mapSpawns.size(); ++i)
modelNodeIdx.insert(pair<uint32, uint32>(mapSpawns[i]->ID, i));
// write map tree file
@@ -126,7 +126,7 @@ namespace VMAP
// global map spawns (WDT), if any (most instances)
if (success && fwrite("GOBJ", 4, 1, mapfile) != 1) success = false;
for (TileMap::iterator glob=globalRange.first; glob != globalRange.second && success; ++glob)
for (TileMap::iterator glob = globalRange.first; glob != globalRange.second && success; ++glob)
{
success = ModelSpawn::writeToFile(mapfile, map_iter->second->UniqueEntries[glob->second]);
}
@@ -136,11 +136,11 @@ namespace VMAP
// <====
// write map tile files, similar to ADT files, only with extra BSP tree node info
TileMap &tileEntries = map_iter->second->TileEntries;
TileMap& tileEntries = map_iter->second->TileEntries;
TileMap::iterator tile;
for (tile = tileEntries.begin(); tile != tileEntries.end(); ++tile)
{
const ModelSpawn &spawn = map_iter->second->UniqueEntries[tile->second];
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);
@@ -157,11 +157,11 @@ namespace VMAP
// write number of tile spawns
if (success && fwrite(&nSpawns, sizeof(uint32), 1, tilefile) != 1) success = false;
// write tile spawns
for (uint32 s=0; s<nSpawns; ++s)
for (uint32 s = 0; s < nSpawns; ++s)
{
if (s)
++tile;
const ModelSpawn &spawn2 = map_iter->second->UniqueEntries[tile->second];
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);
@@ -206,7 +206,7 @@ namespace VMAP
return false;
}
printf("Read coordinate mapping...\n");
uint32 mapID, tileX, tileY, check=0;
uint32 mapID, tileX, tileY, check = 0;
G3D::Vector3 v1, v2;
ModelSpawn spawn;
while (!feof(dirf))
@@ -221,7 +221,7 @@ namespace VMAP
if (!ModelSpawn::readFromFile(dirf, spawn))
break;
MapSpawns *current;
MapSpawns* current;
MapData::iterator map_iter = mapData.find(mapID);
if (map_iter == mapData.end())
{
@@ -237,7 +237,7 @@ namespace VMAP
return success;
}
bool TileAssembler::calculateTransformedBound(ModelSpawn &spawn)
bool TileAssembler::calculateTransformedBound(ModelSpawn& spawn)
{
std::string modelFilename(iSrcDir);
modelFilename.push_back('/');
@@ -257,9 +257,9 @@ namespace VMAP
printf("Warning: '%s' does not seem to be a M2 model!\n", modelFilename.c_str());
AABox modelBound;
bool boundEmpty=true;
bool boundEmpty = true;
for (uint32 g=0; g<groups; ++g) // should be only one for M2 files...
for (uint32 g = 0; g < groups; ++g) // should be only one for M2 files...
{
std::vector<Vector3>& vertices = raw_model.groupsArray[g].vertexArray;
@@ -275,7 +275,7 @@ namespace VMAP
Vector3 v = modelPosition.transform(vertices[i]);
if (boundEmpty)
modelBound = AABox(v, v), boundEmpty=false;
modelBound = AABox(v, v), boundEmpty = false;
else
modelBound.merge(v);
}
@@ -298,7 +298,7 @@ namespace VMAP
{
bool success = true;
std::string filename = iSrcDir;
if (filename.length() >0)
if (filename.length() > 0)
filename.push_back('/');
filename.append(pModelFilename);
@@ -348,9 +348,9 @@ namespace VMAP
while (!feof(model_list))
{
if (fread(&displayId, sizeof(uint32), 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;
@@ -390,12 +390,12 @@ namespace VMAP
fclose(model_list);
fclose(model_list_copy);
}
// temporary use defines to simplify read/check code (close file and return at fail)
#define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
// temporary use defines to simplify read/check code (close file and return at fail)
#define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }
#define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
#define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); };
#define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
#define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
bool GroupModel_Raw::Read(FILE* rf)
@@ -423,7 +423,7 @@ namespace VMAP
CMP_OR_RETURN(blockId, "GRP ");
READ_OR_RETURN(&blocksize, sizeof(int));
READ_OR_RETURN(&branches, sizeof(uint32));
for (uint32 b=0; b<branches; ++b)
for (uint32 b = 0; b < branches; ++b)
{
uint32 indexes;
// indexes for each branch (not used jet)
@@ -436,13 +436,13 @@ namespace VMAP
READ_OR_RETURN(&blocksize, sizeof(int));
uint32 nindexes;
READ_OR_RETURN(&nindexes, sizeof(uint32));
if (nindexes >0)
if (nindexes > 0)
{
uint16 *indexarray = new uint16[nindexes];
READ_OR_RETURN_WITH_DELETE(indexarray, nindexes*sizeof(uint16));
uint16* indexarray = new uint16[nindexes];
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]));
for (uint32 i = 0; i < nindexes; i += 3)
triangles.push_back(MeshTriangle(indexarray[i], indexarray[i + 1], indexarray[i + 2]));
delete[] indexarray;
}
@@ -454,18 +454,18 @@ namespace VMAP
uint32 nvectors;
READ_OR_RETURN(&nvectors, sizeof(uint32));
if (nvectors >0)
if (nvectors > 0)
{
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) );
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;
}
// ----- liquid
liquid = 0;
if (liquidflags& 1)
if (liquidflags & 1)
{
WMOLiquidHeader hlq;
READ_OR_RETURN(&blockId, 4);
@@ -473,9 +473,9 @@ namespace VMAP
READ_OR_RETURN(&blocksize, sizeof(int));
READ_OR_RETURN(&hlq, sizeof(WMOLiquidHeader));
liquid = new WmoLiquid(hlq.xtiles, hlq.ytiles, Vector3(hlq.pos_x, hlq.pos_y, hlq.pos_z), hlq.type);
uint32 size = hlq.xverts*hlq.yverts;
READ_OR_RETURN(liquid->GetHeightStorage(), size*sizeof(float));
size = hlq.xtiles*hlq.ytiles;
uint32 size = hlq.xverts * hlq.yverts;
READ_OR_RETURN(liquid->GetHeightStorage(), size * sizeof(float));
size = hlq.xtiles * hlq.ytiles;
READ_OR_RETURN(liquid->GetFlagsStorage(), size);
}
@@ -488,7 +488,7 @@ namespace VMAP
delete liquid;
}
bool WorldModel_Raw::Read(const char * path)
bool WorldModel_Raw::Read(const char* path)
{
FILE* rf = fopen(path, "rb");
if (!rf)
@@ -523,6 +523,6 @@ namespace VMAP
}
// drop of temporary use defines
#undef READ_OR_RETURN
#undef CMP_OR_RETURN
#undef READ_OR_RETURN
#undef CMP_OR_RETURN
}

View File

@@ -25,19 +25,19 @@ namespace VMAP
class ModelPosition
{
private:
G3D::Matrix3 iRotation;
public:
ModelPosition(): iScale(0.0f) { }
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
void init()
{
iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif()*iDir.y/180.f, G3D::pif()*iDir.x/180.f, G3D::pif()*iDir.z/180.f);
}
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
private:
G3D::Matrix3 iRotation;
public:
ModelPosition(): iScale(0.0f) { }
G3D::Vector3 iPos;
G3D::Vector3 iDir;
float iScale;
void init()
{
iRotation = G3D::Matrix3::fromEulerAnglesZYX(G3D::pif() * iDir.y / 180.f, G3D::pif() * iDir.x / 180.f, G3D::pif() * iDir.z / 180.f);
}
G3D::Vector3 transform(const G3D::Vector3& pIn) const;
void moveToBasePos(const G3D::Vector3& pBasePos) { iPos -= pBasePos; }
};
typedef std::map<uint32, ModelSpawn> UniqueEntryMap;
@@ -75,32 +75,32 @@ namespace VMAP
uint32 RootWMOID;
std::vector<GroupModel_Raw> groupsArray;
bool Read(const char * path);
bool Read(const char* path);
};
class TileAssembler
{
private:
std::string iDestDir;
std::string iSrcDir;
bool (*iFilterMethod)(char *pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
MapData mapData;
std::set<std::string> spawnedModelFiles;
private:
std::string iDestDir;
std::string iSrcDir;
bool (*iFilterMethod)(char* pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
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);
void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
bool convertRawFile(const std::string& pModelFilename);
void setModelNameFilterMethod(bool (*pFilterMethod)(char* pName)) { iFilterMethod = pFilterMethod; }
std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
};
} // VMAP

View File

@@ -36,9 +36,9 @@ ModelList model_list;
void LoadGameObjectModelList()
{
//#ifndef NO_CORE_FUNCS
//#ifndef NO_CORE_FUNCS
uint32 oldMSTime = getMSTime();
//#endif
//#endif
FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb");
if (!model_list_file)
@@ -57,10 +57,10 @@ void LoadGameObjectModelList()
break;
if (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)
|| 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)
{
sLog->outError("File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS);
break;
@@ -108,7 +108,7 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn
//ID = 0;
iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ());
// pussywizard:
// pussywizard:
phasemask = (go.GetGoState() == GO_STATE_READY || go.IsTransport()) ? go.GetPhaseMask() : 0;
iScale = go.GetFloatValue(OBJECT_FIELD_SCALE_X);

View File

@@ -14,10 +14,10 @@ using G3D::Ray;
namespace VMAP
{
ModelInstance::ModelInstance(const ModelSpawn &spawn, WorldModel* model): ModelSpawn(spawn), iModel(model)
ModelInstance::ModelInstance(const ModelSpawn& spawn, WorldModel* model): ModelSpawn(spawn), iModel(model)
{
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi()*iRot.y/180.f, G3D::pi()*iRot.x/180.f, G3D::pi()*iRot.z/180.f).inverse();
iInvScale = 1.f/iScale;
iInvRot = G3D::Matrix3::fromEulerAnglesZYX(G3D::pi() * iRot.y / 180.f, G3D::pi() * iRot.x / 180.f, G3D::pi() * iRot.z / 180.f).inverse();
iInvScale = 1.f / iScale;
}
bool ModelInstance::intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const
@@ -30,16 +30,16 @@ namespace VMAP
float time = pRay.intersectionTime(iBound);
if (time == G3D::inf())
{
// std::cout << "Ray does not hit '" << name << "'\n";
// std::cout << "Ray does not hit '" << name << "'\n";
return false;
}
// std::cout << "Ray crosses bound of '" << name << "'\n";
/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
<< " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
<< " t/tmax:" << time << '/' << pMaxDist;
std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
<< iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
// std::cout << "Ray crosses bound of '" << name << "'\n";
/* std::cout << "ray from:" << pRay.origin().x << ", " << pRay.origin().y << ", " << pRay.origin().z
<< " dir:" << pRay.direction().x << ", " << pRay.direction().y << ", " << pRay.direction().z
<< " t/tmax:" << time << '/' << pMaxDist;
std::cout << "\nBound lo:" << iBound.low().x << ", " << iBound.low().y << ", " << iBound.low().z << " hi: "
<< iBound.high().x << ", " << iBound.high().y << ", " << iBound.high().z << std::endl; */
// child bounds are defined in object space:
Vector3 p = iInvRot * (pRay.origin() - iPos) * iInvScale;
Ray modRay(p, iInvRot * pRay.direction());
@@ -53,7 +53,7 @@ namespace VMAP
return hit;
}
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo &info) const
void ModelInstance::intersectPoint(const G3D::Vector3& p, AreaInfo& info) const
{
if (!iModel)
{
@@ -87,7 +87,7 @@ namespace VMAP
}
}
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const
bool ModelInstance::GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const
{
if (!iModel)
{
@@ -123,7 +123,7 @@ namespace VMAP
return false;
}
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const
bool ModelInstance::GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const
{
// child bounds are defined in object space:
Vector3 pModel = iInvRot * (p - iPos) * iInvScale;
@@ -139,7 +139,7 @@ namespace VMAP
return false;
}
bool ModelSpawn::readFromFile(FILE* rf, ModelSpawn &spawn)
bool ModelSpawn::readFromFile(FILE* rf, ModelSpawn& spawn)
{
uint32 check = 0, nameLen;
check += fread(&spawn.flags, sizeof(uint32), 1, rf);
@@ -185,9 +185,9 @@ namespace VMAP
return true;
}
bool ModelSpawn::writeToFile(FILE* wf, const ModelSpawn &spawn)
bool ModelSpawn::writeToFile(FILE* wf, const ModelSpawn& spawn)
{
uint32 check=0;
uint32 check = 0;
check += fwrite(&spawn.flags, sizeof(uint32), 1, wf);
check += fwrite(&spawn.adtId, sizeof(uint16), 1, wf);
check += fwrite(&spawn.ID, sizeof(uint32), 1, wf);

View File

@@ -23,47 +23,47 @@ namespace VMAP
enum ModelFlags
{
MOD_M2 = 1,
MOD_WORLDSPAWN = 1<<1,
MOD_HAS_BOUND = 1<<2
MOD_WORLDSPAWN = 1 << 1,
MOD_HAS_BOUND = 1 << 2
};
class ModelSpawn
{
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
uint32 flags;
uint16 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
std::string name;
bool operator==(const ModelSpawn &other) const { return ID == other.ID; }
//uint32 hashCode() const { return ID; }
// temp?
const G3D::AABox& getBounds() const { return iBound; }
public:
//mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
uint32 flags;
uint16 adtId;
uint32 ID;
G3D::Vector3 iPos;
G3D::Vector3 iRot;
float iScale;
G3D::AABox iBound;
std::string name;
bool operator==(const ModelSpawn& other) const { return ID == other.ID; }
//uint32 hashCode() const { return ID; }
// temp?
const G3D::AABox& getBounds() const { return iBound; }
static bool readFromFile(FILE* rf, ModelSpawn &spawn);
static bool writeToFile(FILE* rw, const ModelSpawn &spawn);
static bool readFromFile(FILE* rf, ModelSpawn& spawn);
static bool writeToFile(FILE* rw, const ModelSpawn& spawn);
};
class ModelInstance: public ModelSpawn
{
public:
ModelInstance(): iInvScale(0.0f), iModel(0) { }
ModelInstance(const ModelSpawn &spawn, WorldModel* model);
void setUnloaded() { iModel = 0; }
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
protected:
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
public:
WorldModel* getWorldModel();
public:
ModelInstance(): iInvScale(0.0f), iModel(0) { }
ModelInstance(const ModelSpawn& spawn, WorldModel* model);
void setUnloaded() { iModel = 0; }
bool intersectRay(const G3D::Ray& pRay, float& pMaxDist, bool StopAtFirstHit) const;
void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const;
protected:
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
public:
WorldModel* getWorldModel();
};
} // namespace VMAP

View File

@@ -19,7 +19,7 @@ template<> struct BoundsTrait<VMAP::GroupModel>
namespace VMAP
{
bool IntersectTriangle(const MeshTriangle &tri, std::vector<Vector3>::const_iterator points, const G3D::Ray &ray, float &distance)
bool IntersectTriangle(const MeshTriangle& tri, std::vector<Vector3>::const_iterator points, const G3D::Ray& ray, float& distance)
{
static const float EPS = 1e-5f;
@@ -30,7 +30,8 @@ namespace VMAP
const Vector3 p(ray.direction().cross(e2));
const float a = e1.dot(p);
if (fabs(a) < EPS) {
if (fabs(a) < EPS)
{
// Determinant is ill-conditioned; abort early
return false;
}
@@ -39,7 +40,8 @@ namespace VMAP
const Vector3 s(ray.origin() - points[tri.idx0]);
const float u = f * s.dot(p);
if ((u < 0.0f) || (u > 1.0f)) {
if ((u < 0.0f) || (u > 1.0f))
{
// We hit the plane of the m_geometry, but outside the m_geometry
return false;
}
@@ -47,7 +49,8 @@ namespace VMAP
const Vector3 q(s.cross(e1));
const float v = f * ray.direction().dot(q);
if ((v < 0.0f) || ((u + v) > 1.0f)) {
if ((v < 0.0f) || ((u + v) > 1.0f))
{
// We hit the plane of the triangle, but outside the triangle
return false;
}
@@ -71,32 +74,32 @@ namespace VMAP
class TriBoundFunc
{
public:
TriBoundFunc(std::vector<Vector3> &vert): vertices(vert.begin()) { }
void operator()(const MeshTriangle &tri, G3D::AABox &out) const
{
G3D::Vector3 lo = vertices[tri.idx0];
G3D::Vector3 hi = lo;
public:
TriBoundFunc(std::vector<Vector3>& vert): vertices(vert.begin()) { }
void operator()(const MeshTriangle& tri, G3D::AABox& out) const
{
G3D::Vector3 lo = vertices[tri.idx0];
G3D::Vector3 hi = lo;
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
lo = (lo.min(vertices[tri.idx1])).min(vertices[tri.idx2]);
hi = (hi.max(vertices[tri.idx1])).max(vertices[tri.idx2]);
out = G3D::AABox(lo, hi);
}
protected:
const std::vector<Vector3>::const_iterator vertices;
out = G3D::AABox(lo, hi);
}
protected:
const std::vector<Vector3>::const_iterator vertices;
};
// ===================== WmoLiquid ==================================
WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3 &corner, uint32 type):
WmoLiquid::WmoLiquid(uint32 width, uint32 height, const Vector3& corner, uint32 type):
iTilesX(width), iTilesY(height), iCorner(corner), iType(type)
{
iHeight = new float[(width+1)*(height+1)];
iFlags = new uint8[width*height];
iHeight = new float[(width + 1) * (height + 1)];
iFlags = new uint8[width * height];
}
WmoLiquid::WmoLiquid(const WmoLiquid &other): iHeight(0), iFlags(0)
WmoLiquid::WmoLiquid(const WmoLiquid& other): iHeight(0), iFlags(0)
{
*this = other; // use assignment operator...
}
@@ -107,7 +110,7 @@ namespace VMAP
delete[] iFlags;
}
WmoLiquid& WmoLiquid::operator=(const WmoLiquid &other)
WmoLiquid& WmoLiquid::operator=(const WmoLiquid& other)
{
if (this == &other)
return *this;
@@ -119,8 +122,8 @@ namespace VMAP
delete[] iFlags;
if (other.iHeight)
{
iHeight = new float[(iTilesX+1)*(iTilesY+1)];
memcpy(iHeight, other.iHeight, (iTilesX+1)*(iTilesY+1)*sizeof(float));
iHeight = new float[(iTilesX + 1) * (iTilesY + 1)];
memcpy(iHeight, other.iHeight, (iTilesX + 1) * (iTilesY + 1)*sizeof(float));
}
else
iHeight = 0;
@@ -134,20 +137,20 @@ namespace VMAP
return *this;
}
bool WmoLiquid::GetLiquidHeight(const Vector3 &pos, float &liqHeight) const
bool WmoLiquid::GetLiquidHeight(const Vector3& pos, float& liqHeight) const
{
float tx_f = (pos.x - iCorner.x)/LIQUID_TILE_SIZE;
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;
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)
if ((iFlags[tx + ty * iTilesX] & 0x0F) == 0x0F)
return false;
// (dx, dy) coordinates inside tile, in [0, 1]^2
@@ -170,14 +173,14 @@ namespace VMAP
const uint32 rowOffset = iTilesX + 1;
if (dx > dy) // case (a)
{
float sx = iHeight[tx+1 + ty * rowOffset] - iHeight[tx + ty * rowOffset];
float sy = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx+1 + ty * rowOffset];
float sx = iHeight[tx + 1 + ty * rowOffset] - iHeight[tx + ty * rowOffset];
float sy = iHeight[tx + 1 + (ty + 1) * rowOffset] - iHeight[tx + 1 + ty * rowOffset];
liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
}
else // case (b)
{
float sx = iHeight[tx+1 + (ty+1) * rowOffset] - iHeight[tx + (ty+1) * rowOffset];
float sy = iHeight[tx + (ty+1) * rowOffset] - iHeight[tx + ty * rowOffset];
float sx = iHeight[tx + 1 + (ty + 1) * rowOffset] - iHeight[tx + (ty + 1) * rowOffset];
float sy = iHeight[tx + (ty + 1) * rowOffset] - iHeight[tx + ty * rowOffset];
liqHeight = iHeight[tx + ty * rowOffset] + dx * sx + dy * sy;
}
return true;
@@ -186,23 +189,23 @@ namespace VMAP
uint32 WmoLiquid::GetFileSize()
{
return 2 * sizeof(uint32) +
sizeof(Vector3) +
(iTilesX + 1)*(iTilesY + 1) * sizeof(float) +
iTilesX * iTilesY;
sizeof(Vector3) +
(iTilesX + 1) * (iTilesY + 1) * sizeof(float) +
iTilesX * iTilesY;
}
bool WmoLiquid::writeToFile(FILE* wf)
{
bool result = false;
if (fwrite(&iTilesX, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
fwrite(&iType, sizeof(uint32), 1, wf) == 1)
fwrite(&iTilesY, sizeof(uint32), 1, wf) == 1 &&
fwrite(&iCorner, sizeof(Vector3), 1, wf) == 1 &&
fwrite(&iType, sizeof(uint32), 1, wf) == 1)
{
uint32 size = (iTilesX + 1) * (iTilesY + 1);
if (fwrite(iHeight, sizeof(float), size, wf) == size)
{
size = iTilesX*iTilesY;
size = iTilesX * iTilesY;
result = fwrite(iFlags, sizeof(uint8), size, wf) == size;
}
}
@@ -210,15 +213,15 @@ namespace VMAP
return result;
}
bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid* &out)
bool WmoLiquid::readFromFile(FILE* rf, WmoLiquid*& out)
{
bool result = false;
WmoLiquid* liquid = new WmoLiquid();
if (fread(&liquid->iTilesX, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
fread(&liquid->iTilesY, sizeof(uint32), 1, rf) == 1 &&
fread(&liquid->iCorner, sizeof(Vector3), 1, rf) == 1 &&
fread(&liquid->iType, sizeof(uint32), 1, rf) == 1)
{
uint32 size = (liquid->iTilesX + 1) * (liquid->iTilesY + 1);
liquid->iHeight = new float[size];
@@ -240,7 +243,7 @@ namespace VMAP
// ===================== GroupModel ==================================
GroupModel::GroupModel(const GroupModel &other):
GroupModel::GroupModel(const GroupModel& other):
iBound(other.iBound), iMogpFlags(other.iMogpFlags), iGroupWMOID(other.iGroupWMOID),
vertices(other.vertices), triangles(other.triangles), meshTree(other.meshTree), iLiquid(0)
{
@@ -248,7 +251,7 @@ namespace VMAP
iLiquid = new WmoLiquid(*other.iLiquid);
}
void GroupModel::setMeshData(std::vector<Vector3> &vert, std::vector<MeshTriangle> &tri)
void GroupModel::setMeshData(std::vector<Vector3>& vert, std::vector<MeshTriangle>& tri)
{
vertices.swap(vert);
triangles.swap(tri);
@@ -268,7 +271,7 @@ namespace VMAP
// write vertices
if (result && fwrite("VERT", 1, 4, wf) != 4) result = false;
count = vertices.size();
chunkSize = sizeof(uint32)+ sizeof(Vector3)*count;
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 (!count) // models without (collision) geometry end here, unsure if they are useful
@@ -278,7 +281,7 @@ namespace VMAP
// write triangle mesh
if (result && fwrite("TRIM", 1, 4, wf) != 4) result = false;
count = triangles.size();
chunkSize = sizeof(uint32)+ sizeof(MeshTriangle)*count;
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;
@@ -347,12 +350,12 @@ namespace VMAP
struct GModelRayCallback
{
GModelRayCallback(const std::vector<MeshTriangle> &tris, const std::vector<Vector3> &vert):
GModelRayCallback(const std::vector<MeshTriangle>& tris, const std::vector<Vector3>& vert):
vertices(vert.begin()), triangles(tris.begin()), hit(false) { }
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;
@@ -360,7 +363,7 @@ namespace VMAP
bool hit;
};
bool GroupModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool GroupModel::IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const
{
if (triangles.empty())
return false;
@@ -370,7 +373,7 @@ namespace VMAP
return callback.hit;
}
bool GroupModel::IsInsideObject(const Vector3 &pos, const Vector3 &down, float &z_dist) const
bool GroupModel::IsInsideObject(const Vector3& pos, const Vector3& down, float& z_dist) const
{
if (triangles.empty() || !iBound.contains(pos))
return false;
@@ -384,7 +387,7 @@ namespace VMAP
return hit;
}
bool GroupModel::GetLiquidLevel(const Vector3 &pos, float &liqHeight) const
bool GroupModel::GetLiquidLevel(const Vector3& pos, float& liqHeight) const
{
if (iLiquid)
return iLiquid->GetLiquidHeight(pos, liqHeight);
@@ -400,7 +403,7 @@ namespace VMAP
// ===================== WorldModel ==================================
void WorldModel::setGroupModels(std::vector<GroupModel> &models)
void WorldModel::setGroupModels(std::vector<GroupModel>& models)
{
groupModels.swap(models);
groupTree.build(groupModels, BoundsTrait<GroupModel>::getBounds, 1);
@@ -408,18 +411,18 @@ namespace VMAP
struct WModelRayCallBack
{
WModelRayCallBack(const std::vector<GroupModel> &mod): models(mod.begin()), hit(false) { }
WModelRayCallBack(const std::vector<GroupModel>& mod): models(mod.begin()), hit(false) { }
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;
bool hit;
};
bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
bool WorldModel::IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const
{
// 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
@@ -431,44 +434,45 @@ namespace VMAP
return isc.hit;
}
class WModelAreaCallback {
public:
WModelAreaCallback(const std::vector<GroupModel> &vals, const Vector3 &down):
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
std::vector<GroupModel>::const_iterator prims;
std::vector<GroupModel>::const_iterator hit;
float minVol;
float zDist;
Vector3 zVec;
void operator()(const Vector3& point, uint32 entry)
class WModelAreaCallback
{
public:
WModelAreaCallback(const std::vector<GroupModel>& vals, const Vector3& down):
prims(vals.begin()), hit(vals.end()), minVol(G3D::inf()), zDist(G3D::inf()), zVec(down) { }
std::vector<GroupModel>::const_iterator prims;
std::vector<GroupModel>::const_iterator hit;
float minVol;
float zDist;
Vector3 zVec;
void operator()(const Vector3& point, uint32 entry)
{
float group_Z;
//float pVol = prims[entry].GetBound().volume();
//if (pVol < minVol)
//{
/* if (prims[entry].iBound.contains(point)) */
if (prims[entry].IsInsideObject(point, zVec, group_Z))
{
float group_Z;
//float pVol = prims[entry].GetBound().volume();
//if (pVol < minVol)
//{
/* if (prims[entry].iBound.contains(point)) */
if (prims[entry].IsInsideObject(point, zVec, group_Z))
{
//minVol = pVol;
//hit = prims + entry;
if (group_Z < zDist)
{
zDist = group_Z;
hit = prims + entry;
}
//minVol = pVol;
//hit = prims + entry;
if (group_Z < zDist)
{
zDist = group_Z;
hit = prims + entry;
}
#ifdef VMAP_DEBUG
const GroupModel &gm = prims[entry];
printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
const GroupModel& gm = prims[entry];
printf("%10u %8X %7.3f, %7.3f, %7.3f | %7.3f, %7.3f, %7.3f | z=%f, p_z=%f\n", gm.GetWmoID(), gm.GetMogpFlags(),
gm.GetBound().low().x, gm.GetBound().low().y, gm.GetBound().low().z,
gm.GetBound().high().x, gm.GetBound().high().y, gm.GetBound().high().z, group_Z, point.z);
#endif
}
//}
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
}
//}
//std::cout << "trying to intersect '" << prims[entry].name << "'\n";
}
};
bool WorldModel::IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const
bool WorldModel::IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const
{
if (groupModels.empty())
return false;
@@ -487,7 +491,7 @@ namespace VMAP
return false;
}
bool WorldModel::GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const
bool WorldModel::GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const
{
if (groupModels.empty())
return false;
@@ -503,7 +507,7 @@ namespace VMAP
return false;
}
bool WorldModel::writeFile(const std::string &filename)
bool WorldModel::writeFile(const std::string& filename)
{
FILE* wf = fopen(filename.c_str(), "wb");
if (!wf)
@@ -517,14 +521,14 @@ namespace VMAP
if (result && fwrite(&RootWMOID, sizeof(uint32), 1, wf) != 1) result = false;
// write group models
count=groupModels.size();
count = groupModels.size();
if (count)
{
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;
for (uint32 i=0; i<groupModels.size() && result; ++i)
for (uint32 i = 0; i < groupModels.size() && result; ++i)
result = groupModels[i].writeToFile(wf);
// write group BIH
@@ -536,7 +540,7 @@ namespace VMAP
return result;
}
bool WorldModel::readFile(const std::string &filename)
bool WorldModel::readFile(const std::string& filename)
{
FILE* rf = fopen(filename.c_str(), "rb");
if (!rf)
@@ -560,7 +564,7 @@ namespace VMAP
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)
for (uint32 i = 0; i < count && result; ++i)
result = groupModels[i].readFromFile(rf);
// read group BIH

View File

@@ -23,94 +23,94 @@ namespace VMAP
class MeshTriangle
{
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) { }
public:
MeshTriangle() : idx0(0), idx1(0), idx2(0) { }
MeshTriangle(uint32 na, uint32 nb, uint32 nc): idx0(na), idx1(nb), idx2(nc) { }
uint32 idx0;
uint32 idx1;
uint32 idx2;
uint32 idx0;
uint32 idx1;
uint32 idx2;
};
class WmoLiquid
{
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3 &corner, uint32 type);
WmoLiquid(const WmoLiquid &other);
~WmoLiquid();
WmoLiquid& operator=(const WmoLiquid &other);
bool GetLiquidHeight(const G3D::Vector3 &pos, float &liqHeight) const;
uint32 GetType() const { return iType; }
float *GetHeightStorage() { return iHeight; }
uint8 *GetFlagsStorage() { return iFlags; }
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid* &liquid);
private:
WmoLiquid(): iTilesX(0), iTilesY(0), iType(0), iHeight(0), iFlags(0) { }
uint32 iTilesX; //!< number of tiles in x direction, each
uint32 iTilesY;
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;
public:
WmoLiquid(uint32 width, uint32 height, const G3D::Vector3& corner, uint32 type);
WmoLiquid(const WmoLiquid& other);
~WmoLiquid();
WmoLiquid& operator=(const WmoLiquid& other);
bool GetLiquidHeight(const G3D::Vector3& pos, float& liqHeight) const;
uint32 GetType() const { return iType; }
float* GetHeightStorage() { return iHeight; }
uint8* GetFlagsStorage() { return iFlags; }
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid*& liquid);
private:
WmoLiquid(): iTilesX(0), iTilesY(0), iType(0), iHeight(0), iFlags(0) { }
uint32 iTilesX; //!< number of tiles in x direction, each
uint32 iTilesY;
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 */
class GroupModel
{
public:
GroupModel(): iMogpFlags(0), iGroupWMOID(0), iLiquid(0) { }
GroupModel(const GroupModel &other);
GroupModel(uint32 mogpFlags, uint32 groupWMOID, const G3D::AABox &bound):
iBound(bound), iMogpFlags(mogpFlags), iGroupWMOID(groupWMOID), iLiquid(0) { }
~GroupModel() { delete iLiquid; }
public:
GroupModel(): iMogpFlags(0), iGroupWMOID(0), iLiquid(0) { }
GroupModel(const GroupModel& other);
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<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 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);
const G3D::AABox& GetBound() const { return iBound; }
uint32 GetMogpFlags() const { return iMogpFlags; }
uint32 GetWmoID() const { return iGroupWMOID; }
protected:
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
uint32 iGroupWMOID;
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);
//! pass mesh data to object and create BIH. Passed vectors get get swapped with old geometry!
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 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);
const G3D::AABox& GetBound() const { return iBound; }
uint32 GetMogpFlags() const { return iMogpFlags; }
uint32 GetWmoID() const { return iGroupWMOID; }
protected:
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
uint32 iGroupWMOID;
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
{
public:
WorldModel(): RootWMOID(0) { }
public:
WorldModel(): RootWMOID(0) { }
//! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
void setGroupModels(std::vector<GroupModel> &models);
void setRootWmoID(uint32 id) { RootWMOID = id; }
bool IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const;
bool IntersectPoint(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
bool writeFile(const std::string &filename);
bool readFile(const std::string &filename);
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
public:
void getGroupModels(std::vector<GroupModel> &groupModels);
//! pass group models to WorldModel and create BIH. Passed vector is swapped with old geometry!
void setGroupModels(std::vector<GroupModel>& models);
void setRootWmoID(uint32 id) { RootWMOID = id; }
bool IntersectRay(const G3D::Ray& ray, float& distance, bool stopAtFirstHit) const;
bool IntersectPoint(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, AreaInfo& info) const;
bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const;
bool writeFile(const std::string& filename);
bool readFile(const std::string& filename);
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
public:
void getGroupModels(std::vector<GroupModel>& groupModels);
};
} // namespace VMAP

View File

@@ -16,7 +16,7 @@ public:
explicit NodeArray() { memset(&_nodes, 0, sizeof(_nodes)); }
void AddNode(Node* n)
{
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
if (_nodes[i] == 0)
{
_nodes[i] = n;
@@ -29,37 +29,41 @@ public:
};
template<class Node>
struct NodeCreator{
static Node * makeNode(int /*x*/, int /*y*/) { return new Node();}
struct NodeCreator
{
static Node* makeNode(int /*x*/, int /*y*/) { return new Node();}
};
template<class T,
class Node,
class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
class Node,
class NodeCreatorFunc = NodeCreator<Node>,
/*class BoundsFunc = BoundsTrait<T>,*/
class PositionFunc = PositionTrait<T>
>
class RegularGrid2D
{
public:
enum{
enum
{
CELL_NUMBER = 64,
};
#define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
#define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
#define HGRID_MAP_SIZE (533.33333f * 64.f) // shouldn't be changed
#define CELL_SIZE float(HGRID_MAP_SIZE/(float)CELL_NUMBER)
typedef G3D::Table<const T*, NodeArray<Node> > MemberTable;
MemberTable memberTable;
Node* nodes[CELL_NUMBER][CELL_NUMBER];
RegularGrid2D(){
RegularGrid2D()
{
memset(nodes, 0, sizeof(nodes));
}
~RegularGrid2D(){
~RegularGrid2D()
{
for (int x = 0; x < CELL_NUMBER; ++x)
for (int y = 0; y < CELL_NUMBER; ++y)
delete nodes[x][y];
@@ -72,14 +76,14 @@ public:
pos[1] = value.getBounds().corner(1);
pos[2] = value.getBounds().corner(2);
pos[3] = value.getBounds().corner(3);
pos[4] = (pos[0] + pos[1])/2.0f;
pos[5] = (pos[1] + pos[2])/2.0f;
pos[6] = (pos[2] + pos[3])/2.0f;
pos[7] = (pos[3] + pos[0])/2.0f;
pos[8] = (pos[0] + pos[2])/2.0f;
pos[4] = (pos[0] + pos[1]) / 2.0f;
pos[5] = (pos[1] + pos[2]) / 2.0f;
pos[6] = (pos[2] + pos[3]) / 2.0f;
pos[7] = (pos[3] + pos[0]) / 2.0f;
pos[8] = (pos[0] + pos[2]) / 2.0f;
NodeArray<Node> na;
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
Cell c = Cell::ComputeCell(pos[i].x, pos[i].y);
if (!c.isValid())
@@ -88,7 +92,7 @@ public:
na.AddNode(&node);
}
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
if (na._nodes[i])
na._nodes[i]->insert(value);
@@ -102,7 +106,7 @@ public:
void remove(const T& value)
{
NodeArray<Node>& na = memberTable[&value];
for (uint8 i=0; i<9; ++i)
for (uint8 i = 0; i < 9; ++i)
{
if (na._nodes[i])
na._nodes[i]->remove(value);
@@ -132,7 +136,7 @@ public:
static Cell ComputeCell(float fx, float fy)
{
Cell c = { int(fx * (1.f/CELL_SIZE) + (CELL_NUMBER/2)), int(fy * (1.f/CELL_SIZE) + (CELL_NUMBER/2)) };
Cell c = { int(fx * (1.f / CELL_SIZE) + (CELL_NUMBER / 2)), int(fy * (1.f / CELL_SIZE) + (CELL_NUMBER / 2)) };
return c;
}
@@ -185,26 +189,26 @@ public:
if (kx_inv >= 0)
{
stepX = 1;
float x_border = (cell.x+1) * voxel;
float x_border = (cell.x + 1) * voxel;
tMaxX = (x_border - bx) * kx_inv;
}
else
{
stepX = -1;
float x_border = (cell.x-1) * voxel;
float x_border = (cell.x - 1) * voxel;
tMaxX = (x_border - bx) * kx_inv;
}
if (ky_inv >= 0)
{
stepY = 1;
float y_border = (cell.y+1) * voxel;
float y_border = (cell.y + 1) * voxel;
tMaxY = (y_border - by) * ky_inv;
}
else
{
stepY = -1;
float y_border = (cell.y-1) * voxel;
float y_border = (cell.y - 1) * voxel;
tMaxY = (y_border - by) * ky_inv;
}

View File

@@ -17,6 +17,6 @@ namespace VMAP
const char GAMEOBJECT_MODELS[] = "GameObjectModels.dtree";
// defined in TileAssembler.cpp currently...
bool readChunk(FILE* rf, char *dest, const char *compare, uint32 len);
bool readChunk(FILE* rf, char* dest, const char* compare, uint32 len);
}
#endif

View File

@@ -21,13 +21,15 @@ The collision detection is modified to return true, if we are inside an object.
namespace VMAP
{
template<class TValue>
class IntersectionCallBack {
class IntersectionCallBack
{
public:
TValue* closestEntity;
G3D::Vector3 hitLocation;
G3D::Vector3 hitNormal;
void operator()(const G3D::Ray& ray, const TValue* entity, bool StopAtFirstHit, float& distance) {
void operator()(const G3D::Ray& ray, const TValue* entity, bool StopAtFirstHit, float& distance)
{
entity->intersect(ray, distance, StopAtFirstHit, hitLocation, hitNormal);
}
};
@@ -116,7 +118,7 @@ namespace VMAP
{
location[i] = origin[i] + MaxT[WhichPlane] * dir[i];
if ((location[i] < MinB[i]) ||
(location[i] > MaxB[i]))
(location[i] > MaxB[i]))
{
// On this plane we're outside the box extents, so
// we miss the box