mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
Applied new coding standard, see http://github.com/mangos/mangos/wikis/codingstandards for more.
This commit is contained in:
parent
800ee76535
commit
9116f0286b
29 changed files with 253 additions and 254 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
||||||
|
compile
|
||||||
|
FILES
|
||||||
INSTALL
|
INSTALL
|
||||||
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
/**
|
/**
|
||||||
@file AABSPTree.h
|
@file AABSPTree.h
|
||||||
|
|
||||||
@maintainer Morgan McGuire, matrix@graphics3d.com
|
@maintainer Morgan McGuire, matrix@graphics3d.com
|
||||||
|
|
||||||
@created 2004-01-11
|
@created 2004-01-11
|
||||||
@edited 2007-02-16
|
@edited 2007-02-16
|
||||||
|
|
||||||
Copyright 2000-2007, Morgan McGuire.
|
Copyright 2000-2007, Morgan McGuire.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef G3D_AABSPTREE_H
|
#ifndef G3D_AABSPTREE_H
|
||||||
|
|
@ -89,7 +89,7 @@ namespace G3D {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Wraps a pointer value so that it can be treated as the instance itself;
|
Wraps a pointer value so that it can be treated as the instance itself;
|
||||||
convenient for inserting pointers into a Table but using the
|
convenient for inserting pointers into a Table but using the
|
||||||
object equality instead of pointer equality.
|
object equality instead of pointer equality.
|
||||||
*/
|
*/
|
||||||
template<class Type>
|
template<class Type>
|
||||||
|
|
@ -136,9 +136,9 @@ namespace G3D {
|
||||||
AABSPTree is as powerful as but more general than a Quad Tree, Oct
|
AABSPTree is as powerful as but more general than a Quad Tree, Oct
|
||||||
Tree, or KD Tree, but less general than an unconstrained BSP tree
|
Tree, or KD Tree, but less general than an unconstrained BSP tree
|
||||||
(which is much slower to create).
|
(which is much slower to create).
|
||||||
|
|
||||||
Internally, objects
|
Internally, objects
|
||||||
are arranged into an axis-aligned BSP-tree according to their
|
are arranged into an axis-aligned BSP-tree according to their
|
||||||
axis-aligned bounds. This increases the cost of insertion to
|
axis-aligned bounds. This increases the cost of insertion to
|
||||||
O(log n) but allows fast overlap queries.
|
O(log n) but allows fast overlap queries.
|
||||||
|
|
||||||
|
|
@ -158,13 +158,13 @@ namespace G3D {
|
||||||
<B>Moving %Set Members</B>
|
<B>Moving %Set Members</B>
|
||||||
<DT>It is important that objects do not move without updating the
|
<DT>It is important that objects do not move without updating the
|
||||||
AABSPTree. If the axis-aligned bounds of an object are about
|
AABSPTree. If the axis-aligned bounds of an object are about
|
||||||
to change, AABSPTree::remove it before they change and
|
to change, AABSPTree::remove it before they change and
|
||||||
AABSPTree::insert it again afterward. For objects
|
AABSPTree::insert it again afterward. For objects
|
||||||
where the hashCode and == operator are invariant with respect
|
where the hashCode and == operator are invariant with respect
|
||||||
to the 3D position,
|
to the 3D position,
|
||||||
you can use the AABSPTree::update method as a shortcut to
|
you can use the AABSPTree::update method as a shortcut to
|
||||||
insert/remove an object in one step after it has moved.
|
insert/remove an object in one step after it has moved.
|
||||||
|
|
||||||
|
|
||||||
Note: Do not mutate any value once it has been inserted into AABSPTree. Values
|
Note: Do not mutate any value once it has been inserted into AABSPTree. Values
|
||||||
are copied interally. All AABSPTree iterators convert to pointers to constant
|
are copied interally. All AABSPTree iterators convert to pointers to constant
|
||||||
|
|
@ -185,9 +185,9 @@ namespace G3D {
|
||||||
*/
|
*/
|
||||||
namespace _AABSPTree {
|
namespace _AABSPTree {
|
||||||
|
|
||||||
/** Wrapper for a value that includes a cache of its bounds.
|
/** Wrapper for a value that includes a cache of its bounds.
|
||||||
Except for the test value used in a set-query operation, there
|
Except for the test value used in a set-query operation, there
|
||||||
is only ever one instance of the handle associated with any
|
is only ever one instance of the handle associated with any
|
||||||
value and the memberTable and Nodes maintain pointers to that
|
value and the memberTable and Nodes maintain pointers to that
|
||||||
heap-allocated value.
|
heap-allocated value.
|
||||||
*/
|
*/
|
||||||
|
|
@ -261,10 +261,10 @@ public:
|
||||||
|
|
||||||
/** Returns the bounds of the sub array. Used by makeNode. */
|
/** Returns the bounds of the sub array. Used by makeNode. */
|
||||||
static AABox computeBounds(
|
static AABox computeBounds(
|
||||||
const Array<_AABSPTree::Handle<T>*>& point,
|
const Array<_AABSPTree::Handle<T>*>& point,
|
||||||
int beginIndex,
|
int beginIndex,
|
||||||
int endIndex) {
|
int endIndex) {
|
||||||
|
|
||||||
Vector3 lo = Vector3::inf();
|
Vector3 lo = Vector3::inf();
|
||||||
Vector3 hi = -lo;
|
Vector3 hi = -lo;
|
||||||
|
|
||||||
|
|
@ -279,11 +279,11 @@ public:
|
||||||
/** Compares centers */
|
/** Compares centers */
|
||||||
class CenterComparator {
|
class CenterComparator {
|
||||||
public:
|
public:
|
||||||
Vector3::Axis sortAxis;
|
Vector3::Axis sortAxis;
|
||||||
|
|
||||||
CenterComparator(Vector3::Axis a) : sortAxis(a) {}
|
CenterComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||||
|
|
||||||
inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
|
inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
|
||||||
float a = A->center[sortAxis];
|
float a = A->center[sortAxis];
|
||||||
float b = B->center[sortAxis];
|
float b = B->center[sortAxis];
|
||||||
|
|
||||||
|
|
@ -294,18 +294,18 @@ public:
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Compares bounds for strict >, <, or overlap*/
|
/** Compares bounds for strict >, <, or overlap*/
|
||||||
class BoundsComparator {
|
class BoundsComparator {
|
||||||
public:
|
public:
|
||||||
Vector3::Axis sortAxis;
|
Vector3::Axis sortAxis;
|
||||||
|
|
||||||
BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
|
BoundsComparator(Vector3::Axis a) : sortAxis(a) {}
|
||||||
|
|
||||||
inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
|
inline int operator()(_AABSPTree::Handle<T>* A, const _AABSPTree::Handle<T>* B) const {
|
||||||
const AABox& a = A->bounds;
|
const AABox& a = A->bounds;
|
||||||
const AABox& b = B->bounds;
|
const AABox& b = B->bounds;
|
||||||
|
|
||||||
|
|
@ -316,33 +316,33 @@ public:
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Compares bounds to the sort location */
|
/** Compares bounds to the sort location */
|
||||||
class Comparator {
|
class Comparator {
|
||||||
public:
|
public:
|
||||||
Vector3::Axis sortAxis;
|
Vector3::Axis sortAxis;
|
||||||
float sortLocation;
|
float sortLocation;
|
||||||
|
|
||||||
Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
|
Comparator(Vector3::Axis a, float l) : sortAxis(a), sortLocation(l) {}
|
||||||
|
|
||||||
inline int operator()(_AABSPTree::Handle<T>* /*ignore*/, const _AABSPTree::Handle<T>* handle) const {
|
inline int operator()(_AABSPTree::Handle<T>* /*ignore*/, const _AABSPTree::Handle<T>* handle) const {
|
||||||
const AABox& box = handle->bounds;
|
const AABox& box = handle->bounds;
|
||||||
debugAssert(ignore == NULL);
|
debugAssert(ignore == NULL);
|
||||||
|
|
||||||
if (box.high()[sortAxis] < sortLocation) {
|
if (box.high()[sortAxis] < sortLocation) {
|
||||||
// Box is strictly below the sort location
|
// Box is strictly below the sort location
|
||||||
return -1;
|
return -1;
|
||||||
} else if (box.low()[sortAxis] > sortLocation) {
|
} else if (box.low()[sortAxis] > sortLocation) {
|
||||||
// Box is strictly above the sort location
|
// Box is strictly above the sort location
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
// Box overlaps the sort location
|
// Box overlaps the sort location
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Using System::malloc with this class provided no speed improvement.
|
// Using System::malloc with this class provided no speed improvement.
|
||||||
|
|
@ -357,8 +357,8 @@ public:
|
||||||
|
|
||||||
/** Location along the specified axis */
|
/** Location along the specified axis */
|
||||||
float splitLocation;
|
float splitLocation;
|
||||||
|
|
||||||
/** child[0] contains all values strictly
|
/** child[0] contains all values strictly
|
||||||
smaller than splitLocation along splitAxis.
|
smaller than splitLocation along splitAxis.
|
||||||
|
|
||||||
child[1] contains all values strictly
|
child[1] contains all values strictly
|
||||||
|
|
@ -371,15 +371,15 @@ public:
|
||||||
|
|
||||||
/** Array of values at this node (i.e., values
|
/** Array of values at this node (i.e., values
|
||||||
straddling the split plane + all values if
|
straddling the split plane + all values if
|
||||||
this is a leaf node).
|
this is a leaf node).
|
||||||
|
|
||||||
This is an array of pointers because that minimizes
|
This is an array of pointers because that minimizes
|
||||||
data movement during tree building, which accounts
|
data movement during tree building, which accounts
|
||||||
for about 15% of the time cost of tree building.
|
for about 15% of the time cost of tree building.
|
||||||
*/
|
*/
|
||||||
Array<_AABSPTree::Handle<T> * > valueArray;
|
Array<_AABSPTree::Handle<T> * > valueArray;
|
||||||
|
|
||||||
/** For each object in the value array, a copy of its bounds.
|
/** For each object in the value array, a copy of its bounds.
|
||||||
Packing these into an array at the node level
|
Packing these into an array at the node level
|
||||||
instead putting them in the valueArray improves
|
instead putting them in the valueArray improves
|
||||||
cache coherence, which is about a 3x performance
|
cache coherence, which is about a 3x performance
|
||||||
|
|
@ -403,7 +403,7 @@ public:
|
||||||
Node(const Node& other) : valueArray(other.valueArray), boundsArray(other.boundsArray) {
|
Node(const Node& other) : valueArray(other.valueArray), boundsArray(other.boundsArray) {
|
||||||
splitAxis = other.splitAxis;
|
splitAxis = other.splitAxis;
|
||||||
splitLocation = other.splitLocation;
|
splitLocation = other.splitLocation;
|
||||||
splitBounds = other.splitBounds;
|
splitBounds = other.splitBounds;
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
child[i] = NULL;
|
child[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -450,47 +450,47 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void verifyNode(const Vector3& lo, const Vector3& hi) {
|
void verifyNode(const Vector3& lo, const Vector3& hi) {
|
||||||
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
// debugPrintf("Verifying: split %d @ %f [%f, %f, %f], [%f, %f, %f]\n",
|
||||||
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
// splitAxis, splitLocation, lo.x, lo.y, lo.z, hi.x, hi.y, hi.z);
|
||||||
|
|
||||||
debugAssert(lo == splitBounds.low());
|
debugAssert(lo == splitBounds.low());
|
||||||
debugAssert(hi == splitBounds.high());
|
debugAssert(hi == splitBounds.high());
|
||||||
|
|
||||||
for (int i = 0; i < valueArray.length(); ++i) {
|
for (int i = 0; i < valueArray.length(); ++i) {
|
||||||
const AABox& b = valueArray[i]->bounds;
|
const AABox& b = valueArray[i]->bounds;
|
||||||
debugAssert(b == boundsArray[i]);
|
debugAssert(b == boundsArray[i]);
|
||||||
|
|
||||||
for(int axis = 0; axis < 3; ++axis) {
|
for(int axis = 0; axis < 3; ++axis) {
|
||||||
debugAssert(b.low()[axis] <= b.high()[axis]);
|
debugAssert(b.low()[axis] <= b.high()[axis]);
|
||||||
debugAssert(b.low()[axis] >= lo[axis]);
|
debugAssert(b.low()[axis] >= lo[axis]);
|
||||||
debugAssert(b.high()[axis] <= hi[axis]);
|
debugAssert(b.high()[axis] <= hi[axis]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child[0] || child[1]) {
|
if (child[0] || child[1]) {
|
||||||
debugAssert(lo[splitAxis] < splitLocation);
|
debugAssert(lo[splitAxis] < splitLocation);
|
||||||
debugAssert(hi[splitAxis] > splitLocation);
|
debugAssert(hi[splitAxis] > splitLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 newLo = lo;
|
Vector3 newLo = lo;
|
||||||
newLo[splitAxis] = splitLocation;
|
newLo[splitAxis] = splitLocation;
|
||||||
Vector3 newHi = hi;
|
Vector3 newHi = hi;
|
||||||
newHi[splitAxis] = splitLocation;
|
newHi[splitAxis] = splitLocation;
|
||||||
|
|
||||||
if (child[0] != NULL) {
|
if (child[0] != NULL) {
|
||||||
child[0]->verifyNode(lo, newHi);
|
child[0]->verifyNode(lo, newHi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child[1] != NULL) {
|
if (child[1] != NULL) {
|
||||||
child[1]->verifyNode(newLo, hi);
|
child[1]->verifyNode(newLo, hi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
Stores the locations of the splitting planes (the structure but not the content)
|
Stores the locations of the splitting planes (the structure but not the content)
|
||||||
so that the tree can be quickly rebuilt from a previous configuration without
|
so that the tree can be quickly rebuilt from a previous configuration without
|
||||||
calling balance.
|
calling balance.
|
||||||
*/
|
*/
|
||||||
static void serializeStructure(const Node* n, BinaryOutput& bo) {
|
static void serializeStructure(const Node* n, BinaryOutput& bo) {
|
||||||
|
|
@ -546,7 +546,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Appends all members that intersect the box.
|
/** Appends all members that intersect the box.
|
||||||
If useSphere is true, members that pass the box test
|
If useSphere is true, members that pass the box test
|
||||||
face a second test against the sphere. */
|
face a second test against the sphere. */
|
||||||
void getIntersectingMembers(
|
void getIntersectingMembers(
|
||||||
|
|
@ -604,11 +604,11 @@ public:
|
||||||
// See if the ray will ever hit this node or its children
|
// See if the ray will ever hit this node or its children
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
bool alreadyInsideBounds = false;
|
bool alreadyInsideBounds = false;
|
||||||
bool rayWillHitBounds =
|
bool rayWillHitBounds =
|
||||||
VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
||||||
ray.origin, ray.direction, splitBounds, location, alreadyInsideBounds);
|
ray.origin, ray.direction, splitBounds, location, alreadyInsideBounds);
|
||||||
|
|
||||||
bool canHitThisNode = (alreadyInsideBounds ||
|
bool canHitThisNode = (alreadyInsideBounds ||
|
||||||
(rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
|
(rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
|
||||||
|
|
||||||
return canHitThisNode;
|
return canHitThisNode;
|
||||||
|
|
@ -616,20 +616,20 @@ public:
|
||||||
|
|
||||||
template<typename RayCallback>
|
template<typename RayCallback>
|
||||||
void intersectRay(
|
void intersectRay(
|
||||||
const Ray& ray,
|
const Ray& ray,
|
||||||
RayCallback& intersectCallback,
|
RayCallback& intersectCallback,
|
||||||
float& distance,
|
float& distance,
|
||||||
bool pStopAtFirstHit,
|
bool pStopAtFirstHit,
|
||||||
bool intersectCallbackIsFast) const {
|
bool intersectCallbackIsFast) const {
|
||||||
float enterDistance = distance;
|
float enterDistance = distance;
|
||||||
|
|
||||||
if (! intersects(ray, distance)) {
|
if (! intersects(ray, distance)) {
|
||||||
// The ray doesn't hit this node, so it can't hit the children of the node.
|
// The ray doesn't hit this node, so it can't hit the children of the node.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for intersection against every object at this node.
|
// Test for intersection against every object at this node.
|
||||||
for (int v = 0; v < valueArray.size(); ++v) {
|
for (int v = 0; v < valueArray.size(); ++v) {
|
||||||
bool canHitThisObject = true;
|
bool canHitThisObject = true;
|
||||||
|
|
||||||
if (! intersectCallbackIsFast) {
|
if (! intersectCallbackIsFast) {
|
||||||
|
|
@ -637,11 +637,11 @@ public:
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
const AABox& bounds = boundsArray[v];
|
const AABox& bounds = boundsArray[v];
|
||||||
bool alreadyInsideBounds = false;
|
bool alreadyInsideBounds = false;
|
||||||
bool rayWillHitBounds =
|
bool rayWillHitBounds =
|
||||||
VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
VMAP::MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
||||||
ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
|
ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
|
||||||
|
|
||||||
canHitThisObject = (alreadyInsideBounds ||
|
canHitThisObject = (alreadyInsideBounds ||
|
||||||
(rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
|
(rayWillHitBounds && ((location - ray.origin).squaredLength() < square(distance))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -656,7 +656,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are three cases to consider next:
|
// There are three cases to consider next:
|
||||||
//
|
//
|
||||||
// 1. the ray can start on one side of the splitting plane and never enter the other,
|
// 1. the ray can start on one side of the splitting plane and never enter the other,
|
||||||
// 2. the ray can start on one side and enter the other, and
|
// 2. the ray can start on one side and enter the other, and
|
||||||
// 3. the ray can travel exactly down the splitting plane
|
// 3. the ray can travel exactly down the splitting plane
|
||||||
|
|
@ -666,7 +666,7 @@ public:
|
||||||
int secondChild = NONE;
|
int secondChild = NONE;
|
||||||
|
|
||||||
if (ray.origin[splitAxis] < splitLocation) {
|
if (ray.origin[splitAxis] < splitLocation) {
|
||||||
|
|
||||||
// The ray starts on the small side
|
// The ray starts on the small side
|
||||||
firstChild = 0;
|
firstChild = 0;
|
||||||
|
|
||||||
|
|
@ -702,7 +702,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ray.direction[splitAxis] != 0) {
|
if (ray.direction[splitAxis] != 0) {
|
||||||
// See if there was an intersection before hitting the splitting plane.
|
// See if there was an intersection before hitting the splitting plane.
|
||||||
// If so, there is no need to look on the far side and recursion terminates.
|
// If so, there is no need to look on the far side and recursion terminates.
|
||||||
float distanceToSplittingPlane = (splitLocation - ray.origin[splitAxis]) / ray.direction[splitAxis];
|
float distanceToSplittingPlane = (splitLocation - ray.origin[splitAxis]) / ray.direction[splitAxis];
|
||||||
if (distanceToSplittingPlane > distance) {
|
if (distanceToSplittingPlane > distance) {
|
||||||
|
|
@ -724,43 +724,43 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Recursively subdivides the subarray.
|
Recursively subdivides the subarray.
|
||||||
|
|
||||||
Clears the source array as soon as it is no longer needed.
|
Clears the source array as soon as it is no longer needed.
|
||||||
|
|
||||||
Call assignSplitBounds() on the root node after making a tree.
|
Call assignSplitBounds() on the root node after making a tree.
|
||||||
*/
|
*/
|
||||||
Node* makeNode(
|
Node* makeNode(
|
||||||
Array<_AABSPTree::Handle<T> * >& source,
|
Array<_AABSPTree::Handle<T> * >& source,
|
||||||
int valuesPerNode,
|
int valuesPerNode,
|
||||||
int numMeanSplits,
|
int numMeanSplits,
|
||||||
Array<_AABSPTree::Handle<T> * >& temp) {
|
Array<_AABSPTree::Handle<T> * >& temp) {
|
||||||
|
|
||||||
Node* node = NULL;
|
Node* node = NULL;
|
||||||
|
|
||||||
if (source.size() <= valuesPerNode) {
|
if (source.size() <= valuesPerNode) {
|
||||||
// Make a new leaf node
|
// Make a new leaf node
|
||||||
node = new Node(source);
|
node = new Node(source);
|
||||||
|
|
||||||
// Set the pointers in the memberTable
|
// Set the pointers in the memberTable
|
||||||
for (int i = 0; i < source.size(); ++i) {
|
for (int i = 0; i < source.size(); ++i) {
|
||||||
memberTable.set(Member(source[i]), node);
|
memberTable.set(Member(source[i]), node);
|
||||||
}
|
}
|
||||||
source.clear();
|
source.clear();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Make a new internal node
|
// Make a new internal node
|
||||||
node = new Node();
|
node = new Node();
|
||||||
|
|
||||||
const AABox bounds = computeBounds(source, 0, source.size() - 1);
|
const AABox bounds = computeBounds(source, 0, source.size() - 1);
|
||||||
const Vector3 extent = bounds.high() - bounds.low();
|
const Vector3 extent = bounds.high() - bounds.low();
|
||||||
|
|
||||||
Vector3::Axis splitAxis = extent.primaryAxis();
|
Vector3::Axis splitAxis = extent.primaryAxis();
|
||||||
|
|
||||||
float splitLocation;
|
float splitLocation;
|
||||||
|
|
||||||
// Arrays for holding the children
|
// Arrays for holding the children
|
||||||
Array<_AABSPTree::Handle<T> * > lt, gt;
|
Array<_AABSPTree::Handle<T> * > lt, gt;
|
||||||
|
|
||||||
if (numMeanSplits <= 0) {
|
if (numMeanSplits <= 0) {
|
||||||
|
|
||||||
source.medianPartition(lt, node->valueArray, gt, temp, CenterComparator(splitAxis));
|
source.medianPartition(lt, node->valueArray, gt, temp, CenterComparator(splitAxis));
|
||||||
|
|
@ -788,13 +788,13 @@ public:
|
||||||
// is swapped in in its place.
|
// is swapped in in its place.
|
||||||
gt.fastRemove(i); --i;
|
gt.fastRemove(i); --i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node->valueArray.size() > (source.size() / 2)) &&
|
if ((node->valueArray.size() > (source.size() / 2)) &&
|
||||||
(source.size() > 6)) {
|
(source.size() > 6)) {
|
||||||
// This was a bad partition; we ended up putting the splitting plane right in the middle of most of the
|
// This was a bad partition; we ended up putting the splitting plane right in the middle of most of the
|
||||||
// objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean,
|
// objects. We could try to split on a different axis, or use a different partition (e.g., the extents mean,
|
||||||
// or geometric mean). This implementation falls back on the extents mean, since that case is already handled
|
// or geometric mean). This implementation falls back on the extents mean, since that case is already handled
|
||||||
// below.
|
// below.
|
||||||
numMeanSplits = 1;
|
numMeanSplits = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -805,9 +805,9 @@ public:
|
||||||
|
|
||||||
if (numMeanSplits > 0) {
|
if (numMeanSplits > 0) {
|
||||||
// Split along the mean
|
// Split along the mean
|
||||||
splitLocation = (bounds.high()[splitAxis] +
|
splitLocation = (bounds.high()[splitAxis] +
|
||||||
bounds.low()[splitAxis]) / 2.0;
|
bounds.low()[splitAxis]) / 2.0;
|
||||||
|
|
||||||
source.partition(NULL, lt, node->valueArray, gt, Comparator(splitAxis, splitLocation));
|
source.partition(NULL, lt, node->valueArray, gt, Comparator(splitAxis, splitLocation));
|
||||||
|
|
||||||
// The Comparator ensures that elements are strictly on the correct side of the split
|
// The Comparator ensures that elements are strictly on the correct side of the split
|
||||||
|
|
@ -817,7 +817,7 @@ public:
|
||||||
# if defined(G3D_DEBUG) && defined(VERIFY_TREE)
|
# if defined(G3D_DEBUG) && defined(VERIFY_TREE)
|
||||||
debugAssert(lt.size() + node->valueArray.size() + gt.size() == source.size());
|
debugAssert(lt.size() + node->valueArray.size() + gt.size() == source.size());
|
||||||
// Verify that all objects ended up on the correct side of the split.
|
// Verify that all objects ended up on the correct side of the split.
|
||||||
// (i.e., make sure that the Array partition was correct)
|
// (i.e., make sure that the Array partition was correct)
|
||||||
for (int i = 0; i < lt.size(); ++i) {
|
for (int i = 0; i < lt.size(); ++i) {
|
||||||
const AABox& bounds = lt[i]->bounds;
|
const AABox& bounds = lt[i]->bounds;
|
||||||
debugAssert(bounds.high()[splitAxis] < splitLocation);
|
debugAssert(bounds.high()[splitAxis] < splitLocation);
|
||||||
|
|
@ -846,20 +846,20 @@ public:
|
||||||
for (int i = 0; i < node->valueArray.size(); ++i) {
|
for (int i = 0; i < node->valueArray.size(); ++i) {
|
||||||
_AABSPTree::Handle<T> * v = node->valueArray[i];
|
_AABSPTree::Handle<T> * v = node->valueArray[i];
|
||||||
node->boundsArray[i] = v->bounds;
|
node->boundsArray[i] = v->bounds;
|
||||||
memberTable.set(Member(v), node);
|
memberTable.set(Member(v), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lt.size() > 0) {
|
if (lt.size() > 0) {
|
||||||
node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
|
node->child[0] = makeNode(lt, valuesPerNode, numMeanSplits - 1, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gt.size() > 0) {
|
if (gt.size() > 0) {
|
||||||
node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
|
node->child[1] = makeNode(gt, valuesPerNode, numMeanSplits - 1, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -927,7 +927,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void clear() {
|
void clear() {
|
||||||
typedef typename Table<_internal::Indirector<_AABSPTree::Handle<T> >, Node* >::Iterator It;
|
typedef typename Table<_internal::Indirector<_AABSPTree::Handle<T> >, Node* >::Iterator It;
|
||||||
|
|
||||||
// Delete all handles stored in the member table
|
// Delete all handles stored in the member table
|
||||||
It cur = memberTable.begin();
|
It cur = memberTable.begin();
|
||||||
It end = memberTable.end();
|
It end = memberTable.end();
|
||||||
|
|
@ -970,7 +970,7 @@ public:
|
||||||
// Insert into the node
|
// Insert into the node
|
||||||
node->valueArray.append(h);
|
node->valueArray.append(h);
|
||||||
node->boundsArray.append(h->bounds);
|
node->boundsArray.append(h->bounds);
|
||||||
|
|
||||||
// Insert into the node table
|
// Insert into the node table
|
||||||
Member m(h);
|
Member m(h);
|
||||||
memberTable.set(m, node);
|
memberTable.set(m, node);
|
||||||
|
|
@ -1022,8 +1022,8 @@ public:
|
||||||
/**
|
/**
|
||||||
Removes an object from the set in O(1) time.
|
Removes an object from the set in O(1) time.
|
||||||
It is an error to remove members that are not already
|
It is an error to remove members that are not already
|
||||||
present. May unbalance the tree.
|
present. May unbalance the tree.
|
||||||
|
|
||||||
Removing an element never causes a node (split plane) to be removed...
|
Removing an element never causes a node (split plane) to be removed...
|
||||||
nodes are only changed when the tree is rebalanced. This behavior
|
nodes are only changed when the tree is rebalanced. This behavior
|
||||||
is desirable because it allows the split planes to be serialized,
|
is desirable because it allows the split planes to be serialized,
|
||||||
|
|
@ -1075,7 +1075,7 @@ public:
|
||||||
on <I>T</I> are independent of the bounds. In
|
on <I>T</I> are independent of the bounds. In
|
||||||
that case, you may call update(v) to insert an
|
that case, you may call update(v) to insert an
|
||||||
element for the first time and call update(v)
|
element for the first time and call update(v)
|
||||||
again every time it moves to keep the tree
|
again every time it moves to keep the tree
|
||||||
up to date.
|
up to date.
|
||||||
*/
|
*/
|
||||||
void update(const T& value) {
|
void update(const T& value) {
|
||||||
|
|
@ -1091,15 +1091,15 @@ public:
|
||||||
have moved substantially from their original positions
|
have moved substantially from their original positions
|
||||||
(which unbalances the tree and causes the spatial
|
(which unbalances the tree and causes the spatial
|
||||||
queries to be slow).
|
queries to be slow).
|
||||||
|
|
||||||
@param valuesPerNode Maximum number of elements to put at
|
@param valuesPerNode Maximum number of elements to put at
|
||||||
a node.
|
a node.
|
||||||
|
|
||||||
@param numMeanSplits numMeanSplits = 0 gives a
|
@param numMeanSplits numMeanSplits = 0 gives a
|
||||||
fully axis aligned BSP-tree, where the balance operation attempts to balance
|
fully axis aligned BSP-tree, where the balance operation attempts to balance
|
||||||
the tree so that every splitting plane has an equal number of left
|
the tree so that every splitting plane has an equal number of left
|
||||||
and right children (i.e. it is a <B>median</B> split along that axis).
|
and right children (i.e. it is a <B>median</B> split along that axis).
|
||||||
This tends to maximize average performance.
|
This tends to maximize average performance.
|
||||||
|
|
||||||
You can override this behavior by
|
You can override this behavior by
|
||||||
setting a number of <B>mean</B> (average) splits. numMeanSplits = MAX_INT
|
setting a number of <B>mean</B> (average) splits. numMeanSplits = MAX_INT
|
||||||
|
|
@ -1126,7 +1126,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<_AABSPTree::Handle<T> * > temp;
|
Array<_AABSPTree::Handle<T> * > temp;
|
||||||
// Make a new root. Work with a copy of the value array because
|
// Make a new root. Work with a copy of the value array because
|
||||||
// makeNode clears the source array as it progresses
|
// makeNode clears the source array as it progresses
|
||||||
Array<_AABSPTree::Handle<T> * > copy(oldRoot->valueArray);
|
Array<_AABSPTree::Handle<T> * > copy(oldRoot->valueArray);
|
||||||
root = makeNode(copy, valuesPerNode, numMeanSplits, temp);
|
root = makeNode(copy, valuesPerNode, numMeanSplits, temp);
|
||||||
|
|
@ -1195,7 +1195,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns all members inside the set of planes.
|
Returns all members inside the set of planes.
|
||||||
@param members The results are appended to this array.
|
@param members The results are appended to this array.
|
||||||
*/
|
*/
|
||||||
void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
|
void getIntersectingMembers(const Array<Plane>& plane, Array<T>& members) const {
|
||||||
|
|
@ -1221,7 +1221,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
|
void getIntersectingMembers(const GCamera::Frustum& frustum, Array<T>& members) const {
|
||||||
Array<Plane> plane;
|
Array<Plane> plane;
|
||||||
|
|
||||||
for (int i = 0; i < frustum.faceArray.size(); ++i) {
|
for (int i = 0; i < frustum.faceArray.size(); ++i) {
|
||||||
plane.append(frustum.faceArray[i].plane);
|
plane.append(frustum.faceArray[i].plane);
|
||||||
}
|
}
|
||||||
|
|
@ -1260,14 +1260,14 @@ public:
|
||||||
// caller uses post increment (which they shouldn't!).
|
// caller uses post increment (which they shouldn't!).
|
||||||
Array<Node*> stack;
|
Array<Node*> stack;
|
||||||
|
|
||||||
/** The next index of current->valueArray to return.
|
/** The next index of current->valueArray to return.
|
||||||
Undefined when isEnd is true.*/
|
Undefined when isEnd is true.*/
|
||||||
int nextValueArrayIndex;
|
int nextValueArrayIndex;
|
||||||
|
|
||||||
BoxIntersectionIterator() : isEnd(true) {}
|
BoxIntersectionIterator() : isEnd(true) {}
|
||||||
|
|
||||||
BoxIntersectionIterator(const AABox& b, const Node* root) :
|
BoxIntersectionIterator(const AABox& b, const Node* root) :
|
||||||
isEnd(root == NULL), box(b),
|
isEnd(root == NULL), box(b),
|
||||||
node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
|
node(const_cast<Node*>(root)), nextValueArrayIndex(-1) {
|
||||||
|
|
||||||
// We intentionally start at the "-1" index of the current
|
// We intentionally start at the "-1" index of the current
|
||||||
|
|
@ -1290,10 +1290,10 @@ public:
|
||||||
} else if (other.isEnd) {
|
} else if (other.isEnd) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Two non-end iterators; see if they match. This is kind of
|
// Two non-end iterators; see if they match. This is kind of
|
||||||
// silly; users shouldn't call == on iterators in general unless
|
// silly; users shouldn't call == on iterators in general unless
|
||||||
// one of them is the end iterator.
|
// one of them is the end iterator.
|
||||||
if ((box != other.box) || (node != other.node) ||
|
if ((box != other.box) || (node != other.node) ||
|
||||||
(nextValueArrayIndex != other.nextValueArrayIndex) ||
|
(nextValueArrayIndex != other.nextValueArrayIndex) ||
|
||||||
(stack.length() != other.stack.length())) {
|
(stack.length() != other.stack.length())) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1317,51 +1317,51 @@ public:
|
||||||
BoxIntersectionIterator& operator++() {
|
BoxIntersectionIterator& operator++() {
|
||||||
++nextValueArrayIndex;
|
++nextValueArrayIndex;
|
||||||
|
|
||||||
bool foundIntersection = false;
|
bool foundIntersection = false;
|
||||||
while (! isEnd && ! foundIntersection) {
|
while (! isEnd && ! foundIntersection) {
|
||||||
|
|
||||||
// Search for the next node if we've exhausted this one
|
// Search for the next node if we've exhausted this one
|
||||||
while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
|
while ((! isEnd) && (nextValueArrayIndex >= node->valueArray.length())) {
|
||||||
// If we entered this loop, then the iterator has exhausted the elements at
|
// If we entered this loop, then the iterator has exhausted the elements at
|
||||||
// node (possibly because it just switched to a child node with no members).
|
// node (possibly because it just switched to a child node with no members).
|
||||||
// This loop continues until it finds a node with members or reaches
|
// This loop continues until it finds a node with members or reaches
|
||||||
// the end of the whole intersection search.
|
// the end of the whole intersection search.
|
||||||
|
|
||||||
// If the right child overlaps the box, push it onto the stack for
|
// If the right child overlaps the box, push it onto the stack for
|
||||||
// processing.
|
// processing.
|
||||||
if ((node->child[1] != NULL) &&
|
if ((node->child[1] != NULL) &&
|
||||||
(box.high()[node->splitAxis] > node->splitLocation)) {
|
(box.high()[node->splitAxis] > node->splitLocation)) {
|
||||||
stack.push(node->child[1]);
|
stack.push(node->child[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the left child overlaps the box, push it onto the stack for
|
|
||||||
// processing.
|
|
||||||
if ((node->child[0] != NULL) &&
|
|
||||||
(box.low()[node->splitAxis] < node->splitLocation)) {
|
|
||||||
stack.push(node->child[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack.length() > 0) {
|
// If the left child overlaps the box, push it onto the stack for
|
||||||
// Go on to the next node (which may be either one of the ones we
|
// processing.
|
||||||
// just pushed, or one from farther back the tree).
|
if ((node->child[0] != NULL) &&
|
||||||
node = stack.pop();
|
(box.low()[node->splitAxis] < node->splitLocation)) {
|
||||||
nextValueArrayIndex = 0;
|
stack.push(node->child[0]);
|
||||||
} else {
|
}
|
||||||
// That was the last node; we're done iterating
|
|
||||||
isEnd = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for the next intersection at this node until we run out of children
|
if (stack.length() > 0) {
|
||||||
while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
|
// Go on to the next node (which may be either one of the ones we
|
||||||
if (box.intersects(node->boundsArray[nextValueArrayIndex])) {
|
// just pushed, or one from farther back the tree).
|
||||||
foundIntersection = true;
|
node = stack.pop();
|
||||||
} else {
|
nextValueArrayIndex = 0;
|
||||||
++nextValueArrayIndex;
|
} else {
|
||||||
// If we exhaust this node, we'll loop around the master loop
|
// That was the last node; we're done iterating
|
||||||
// to find a new node.
|
isEnd = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for the next intersection at this node until we run out of children
|
||||||
|
while (! isEnd && ! foundIntersection && (nextValueArrayIndex < node->valueArray.length())) {
|
||||||
|
if (box.intersects(node->boundsArray[nextValueArrayIndex])) {
|
||||||
|
foundIntersection = true;
|
||||||
|
} else {
|
||||||
|
++nextValueArrayIndex;
|
||||||
|
// If we exhaust this node, we'll loop around the master loop
|
||||||
|
// to find a new node.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -1431,7 +1431,7 @@ public:
|
||||||
Invoke a callback for every member along a ray until the closest intersection is found.
|
Invoke a callback for every member along a ray until the closest intersection is found.
|
||||||
|
|
||||||
@param callback either a function or an instance of a class with an overloaded operator() of the form:
|
@param callback either a function or an instance of a class with an overloaded operator() of the form:
|
||||||
|
|
||||||
<code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
|
<code>void callback(const Ray& ray, const T& object, float& distance)</code>. If the ray hits the object
|
||||||
before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
|
before travelling distance <code>distance</code>, updates <code>distance</code> with the new distance to
|
||||||
the intersection, otherwise leaves it unmodified. A common example is:
|
the intersection, otherwise leaves it unmodified. A common example is:
|
||||||
|
|
@ -1482,12 +1482,12 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename RayCallback>
|
template<typename RayCallback>
|
||||||
void intersectRay(
|
void intersectRay(
|
||||||
const Ray& ray,
|
const Ray& ray,
|
||||||
RayCallback& intersectCallback,
|
RayCallback& intersectCallback,
|
||||||
float& distance,
|
float& distance,
|
||||||
bool pStopAtFirstHit,
|
bool pStopAtFirstHit,
|
||||||
bool intersectCallbackIsFast = false) const {
|
bool intersectCallbackIsFast = false) const {
|
||||||
|
|
||||||
root->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast);
|
root->intersectRay(ray, intersectCallback, distance, pStopAtFirstHit, intersectCallbackIsFast);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1509,7 +1509,7 @@ public:
|
||||||
#if 0
|
#if 0
|
||||||
/**
|
/**
|
||||||
Stores the locations of the splitting planes (the structure but not the content)
|
Stores the locations of the splitting planes (the structure but not the content)
|
||||||
so that the tree can be quickly rebuilt from a previous configuration without
|
so that the tree can be quickly rebuilt from a previous configuration without
|
||||||
calling balance.
|
calling balance.
|
||||||
*/
|
*/
|
||||||
void serializeStructure(BinaryOutput& bo) const {
|
void serializeStructure(BinaryOutput& bo) const {
|
||||||
|
|
@ -1593,9 +1593,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
C++ STL style iterator method. Returns the first member.
|
C++ STL style iterator method. Returns the first member.
|
||||||
Use preincrement (++entry) to get to the next element (iteration
|
Use preincrement (++entry) to get to the next element (iteration
|
||||||
order is arbitrary).
|
order is arbitrary).
|
||||||
Do not modify the set while iterating.
|
Do not modify the set while iterating.
|
||||||
*/
|
*/
|
||||||
Iterator begin() const {
|
Iterator begin() const {
|
||||||
|
|
@ -1615,6 +1615,3 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -82,11 +82,11 @@ namespace VMAP
|
||||||
// See if the ray will ever hit this node or its children
|
// See if the ray will ever hit this node or its children
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
bool alreadyInsideBounds = false;
|
bool alreadyInsideBounds = false;
|
||||||
bool rayWillHitBounds =
|
bool rayWillHitBounds =
|
||||||
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
||||||
pRay.origin, pRay.direction, pBox, location, alreadyInsideBounds);
|
pRay.origin, pRay.direction, pBox, location, alreadyInsideBounds);
|
||||||
|
|
||||||
bool canHitThisNode = (alreadyInsideBounds ||
|
bool canHitThisNode = (alreadyInsideBounds ||
|
||||||
(rayWillHitBounds && ((location - pRay.origin).squaredLength() < (pMaxDist * pMaxDist))));
|
(rayWillHitBounds && ((location - pRay.origin).squaredLength() < (pMaxDist * pMaxDist))));
|
||||||
|
|
||||||
return canHitThisNode;
|
return canHitThisNode;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -23,7 +23,7 @@ using namespace G3D;
|
||||||
namespace VMAP
|
namespace VMAP
|
||||||
{
|
{
|
||||||
|
|
||||||
bool CommandFileRW::appendCmd(const Command&
|
bool CommandFileRW::appendCmd(const Command&
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
pCommand
|
pCommand
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -53,7 +53,7 @@ namespace VMAP
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
|
||||||
bool CommandFileRW::appendCmds(const Array<Command>&
|
bool CommandFileRW::appendCmds(const Array<Command>&
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
pCmdArray
|
pCmdArray
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -27,30 +27,30 @@ AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(sr
|
||||||
noinst_LIBRARIES = libmangosvmaps.a
|
noinst_LIBRARIES = libmangosvmaps.a
|
||||||
|
|
||||||
libmangosvmaps_a_SOURCES = \
|
libmangosvmaps_a_SOURCES = \
|
||||||
AABSPTree.h \
|
AABSPTree.h \
|
||||||
BaseModel.cpp \
|
BaseModel.cpp \
|
||||||
BaseModel.h \
|
BaseModel.h \
|
||||||
CoordModelMapping.cpp \
|
CoordModelMapping.cpp \
|
||||||
CoordModelMapping.h \
|
CoordModelMapping.h \
|
||||||
DebugCmdLogger.cpp \
|
DebugCmdLogger.cpp \
|
||||||
DebugCmdLogger.h \
|
DebugCmdLogger.h \
|
||||||
IVMapManager.h \
|
IVMapManager.h \
|
||||||
ManagedModelContainer.cpp \
|
ManagedModelContainer.cpp \
|
||||||
ManagedModelContainer.h \
|
ManagedModelContainer.h \
|
||||||
ModelContainer.cpp \
|
ModelContainer.cpp \
|
||||||
ModelContainer.h \
|
ModelContainer.h \
|
||||||
NodeValueAccess.h \
|
NodeValueAccess.h \
|
||||||
ShortBox.h \
|
ShortBox.h \
|
||||||
ShortVector.h \
|
ShortVector.h \
|
||||||
SubModel.cpp \
|
SubModel.cpp \
|
||||||
SubModel.h \
|
SubModel.h \
|
||||||
TileAssembler.cpp \
|
TileAssembler.cpp \
|
||||||
TileAssembler.h \
|
TileAssembler.h \
|
||||||
TreeNode.cpp \
|
TreeNode.cpp \
|
||||||
TreeNode.h \
|
TreeNode.h \
|
||||||
VMapDefinitions.h \
|
VMapDefinitions.h \
|
||||||
VMapFactory.cpp \
|
VMapFactory.cpp \
|
||||||
VMapFactory.h \
|
VMapFactory.h \
|
||||||
VMapManager.cpp \
|
VMapManager.cpp \
|
||||||
VMapManager.h \
|
VMapManager.h \
|
||||||
VMapTools.h
|
VMapTools.h
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -66,7 +66,7 @@ namespace VMAP
|
||||||
nSubModels += pNode.valueArray.size();
|
nSubModels += pNode.valueArray.size();
|
||||||
for(int i=0;i<pNode.valueArray.size(); i++)
|
for(int i=0;i<pNode.valueArray.size(); i++)
|
||||||
{
|
{
|
||||||
G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i];
|
G3D::_AABSPTree::Handle<SubModel*>* h= pNode.valueArray[i];
|
||||||
SubModel *m = h->value;
|
SubModel *m = h->value;
|
||||||
// add the internal nodes as well
|
// add the internal nodes as well
|
||||||
nNodes += m->getNNodes();
|
nNodes += m->getNNodes();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -107,11 +107,11 @@ namespace VMAP
|
||||||
// See if the ray will ever hit this node or its children
|
// See if the ray will ever hit this node or its children
|
||||||
G3D::Vector3 location;
|
G3D::Vector3 location;
|
||||||
bool alreadyInsideBounds = false;
|
bool alreadyInsideBounds = false;
|
||||||
bool rayWillHitBounds =
|
bool rayWillHitBounds =
|
||||||
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
||||||
ray.origin, ray.direction, iBounds, location, alreadyInsideBounds);
|
ray.origin, ray.direction, iBounds, location, alreadyInsideBounds);
|
||||||
|
|
||||||
bool canHitThisNode = (alreadyInsideBounds ||
|
bool canHitThisNode = (alreadyInsideBounds ||
|
||||||
(rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
|
(rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
|
||||||
|
|
||||||
return canHitThisNode;
|
return canHitThisNode;
|
||||||
|
|
@ -119,8 +119,8 @@ namespace VMAP
|
||||||
|
|
||||||
template<typename RayCallback, typename TNode, typename TValue>
|
template<typename RayCallback, typename TNode, typename TValue>
|
||||||
void intersectRay(
|
void intersectRay(
|
||||||
const G3D::Ray& ray,
|
const G3D::Ray& ray,
|
||||||
RayCallback& intersectCallback,
|
RayCallback& intersectCallback,
|
||||||
float& distance,
|
float& distance,
|
||||||
const NodeValueAccess<TNode, TValue>& pNodeValueAccess,
|
const NodeValueAccess<TNode, TValue>& pNodeValueAccess,
|
||||||
bool pStopAtFirstHit,
|
bool pStopAtFirstHit,
|
||||||
|
|
@ -132,7 +132,7 @@ namespace VMAP
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for intersection against every object at this node.
|
// Test for intersection against every object at this node.
|
||||||
for (unsigned int v = iStartPosition; v < (iNumberOfValues+iStartPosition); ++v) {
|
for (unsigned int v = iStartPosition; v < (iNumberOfValues+iStartPosition); ++v) {
|
||||||
const TValue& nodeValue = pNodeValueAccess.getValue(v);
|
const TValue& nodeValue = pNodeValueAccess.getValue(v);
|
||||||
bool canHitThisObject = true;
|
bool canHitThisObject = true;
|
||||||
if (! intersectCallbackIsFast) {
|
if (! intersectCallbackIsFast) {
|
||||||
|
|
@ -140,11 +140,11 @@ namespace VMAP
|
||||||
G3D::Vector3 location;
|
G3D::Vector3 location;
|
||||||
const G3D::AABox& bounds = nodeValue.getAABoxBounds();
|
const G3D::AABox& bounds = nodeValue.getAABoxBounds();
|
||||||
bool alreadyInsideBounds = false;
|
bool alreadyInsideBounds = false;
|
||||||
bool rayWillHitBounds =
|
bool rayWillHitBounds =
|
||||||
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
MyCollisionDetection::collisionLocationForMovingPointFixedAABox(
|
||||||
ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
|
ray.origin, ray.direction, bounds, location, alreadyInsideBounds);
|
||||||
|
|
||||||
canHitThisObject = (alreadyInsideBounds ||
|
canHitThisObject = (alreadyInsideBounds ||
|
||||||
(rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
|
(rayWillHitBounds && ((location - ray.origin).squaredLength() < (distance*distance))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ namespace VMAP
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are three cases to consider next:
|
// There are three cases to consider next:
|
||||||
//
|
//
|
||||||
// 1. the ray can start on one side of the splitting plane and never enter the other,
|
// 1. the ray can start on one side of the splitting plane and never enter the other,
|
||||||
// 2. the ray can start on one side and enter the other, and
|
// 2. the ray can start on one side and enter the other, and
|
||||||
// 3. the ray can travel exactly down the splitting plane
|
// 3. the ray can travel exactly down the splitting plane
|
||||||
|
|
@ -203,7 +203,7 @@ namespace VMAP
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ray.direction[iSplitAxis] != 0) {
|
if (ray.direction[iSplitAxis] != 0) {
|
||||||
// See if there was an intersection before hitting the splitting plane.
|
// See if there was an intersection before hitting the splitting plane.
|
||||||
// If so, there is no need to look on the far side and recursion terminates.
|
// If so, there is no need to look on the far side and recursion terminates.
|
||||||
float distanceToSplittingPlane = (iSplitLocation - ray.origin[iSplitAxis]) / ray.direction[iSplitAxis];
|
float distanceToSplittingPlane = (iSplitLocation - ray.origin[iSplitAxis]) / ray.direction[iSplitAxis];
|
||||||
if (distanceToSplittingPlane > distance) {
|
if (distanceToSplittingPlane > distance) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
* Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
@ -32,7 +32,7 @@ The collision detection is modified to return true, if we are inside an object.
|
||||||
|
|
||||||
namespace VMAP
|
namespace VMAP
|
||||||
{
|
{
|
||||||
template<class TValue>
|
template<class TValue>
|
||||||
class IntersectionCallBack {
|
class IntersectionCallBack {
|
||||||
public:
|
public:
|
||||||
TValue* closestEntity;
|
TValue* closestEntity;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue