aboutsummaryrefslogtreecommitdiff
path: root/dep/src/g3dlite/AABox.cpp
diff options
context:
space:
mode:
authorclick <none@none>2010-06-05 00:59:25 +0200
committerclick <none@none>2010-06-05 00:59:25 +0200
commite77716188861d4aa83b227a90e04a66b63baeb1f (patch)
treece72764181a760314ec851f7535052dcf75649db /dep/src/g3dlite/AABox.cpp
parent1426c2970f42a2d065198806f750bf5dd28d580b (diff)
HIGHLY EXPERIMENTAL - USE AT YOUR OWN RISK
Implement the use of the new vmap3-format by Lynx3d (mad props to you for this, and thanks for the talks earlier) + reduced Vmap size to less than one third, and improve precision + indoor/outdoor check which allows automatic unmounting of players + additional area information from WMOAreaTable.dbc, removed existing "hacks" + WMO liquid information for swimming and fishing correctly in buildings/cities/caves/instances (lava and slime WILL hurt from now on!) - buildfiles for windows are not properly done, and will need to be sorted out NOTE: Do NOT annoy Lynx3d about this, any issues with this "port" is entirely our fault ! THIS REVISION IS CONSIDERED UNSTABLE AND CONTAINS WORK IN PROGRESS - USE AT YOUR OWN RISK! --HG-- branch : trunk
Diffstat (limited to 'dep/src/g3dlite/AABox.cpp')
-rw-r--r--dep/src/g3dlite/AABox.cpp308
1 files changed, 193 insertions, 115 deletions
diff --git a/dep/src/g3dlite/AABox.cpp b/dep/src/g3dlite/AABox.cpp
index 2279e9a51f0..035497aa3c4 100644
--- a/dep/src/g3dlite/AABox.cpp
+++ b/dep/src/g3dlite/AABox.cpp
@@ -1,30 +1,61 @@
/**
@file AABox.cpp
- @maintainer Morgan McGuire, matrix@graphics3d.com
+ @maintainer Morgan McGuire, http://graphics.cs.williams.edu
@created 2004-01-10
@edited 2006-01-11
*/
#include "G3D/platform.h"
-# if defined(_MSC_VER) && (_MSC_VER <= 1200)
- // VC6 std:: has signed/unsigned problems
-# pragma warning (disable : 4018)
-# endif
-
-#include <assert.h>
#include "G3D/AABox.h"
#include "G3D/Box.h"
#include "G3D/Plane.h"
#include "G3D/Sphere.h"
+#include "G3D/BinaryInput.h"
+#include "G3D/BinaryOutput.h"
+
namespace G3D {
-Box AABox::toBox() const {
- return Box(lo, hi);
+const AABox& AABox::maxFinite() {
+ static const AABox b = AABox(Vector3::minFinite(),
+ Vector3::maxFinite());
+ return b;
+}
+
+
+const AABox& AABox::large() {
+ static const AABox b = AABox(Vector3::minFinite() * 0.5f,
+ Vector3::maxFinite() * 0.5f);
+ return b;
+}
+
+
+const AABox& AABox::inf() {
+ static const AABox b = AABox(-Vector3::inf(), Vector3::inf());
+ return b;
+}
+
+
+const AABox& AABox::zero() {
+ static const AABox b = AABox(Vector3::zero(), Vector3::zero());
+ return b;
+}
+
+
+void AABox::serialize(class BinaryOutput& b) const {
+ b.writeVector3(lo);
+ b.writeVector3(hi);
+}
+
+
+void AABox::deserialize(class BinaryInput& b) {
+ lo = b.readVector3();
+ hi = b.readVector3();
}
+
void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox& high) const {
// Low, medium, and high along the chosen axis
float L = G3D::min(location, lo[axis]);
@@ -41,51 +72,52 @@ void AABox::split(const Vector3::Axis& axis, float location, AABox& low, AABox&
high.hi[axis] = H;
}
-#if 0
+
Vector3 AABox::randomSurfacePoint() const {
Vector3 extent = hi - lo;
float aXY = extent.x * extent.y;
float aYZ = extent.y * extent.z;
float aZX = extent.z * extent.x;
- float r = (float)random(0, aXY + aYZ + aZX);
+ float r = (float)uniformRandom(0.0f, aXY + aYZ + aZX);
// Choose evenly between positive and negative face planes
- float d = ((float)random(0, 1) < 0.5f) ? 0.0f : 1.0f;
+ float d = ((float)uniformRandom(0, 1) < 0.5f) ? 0.0f : 1.0f;
// The probability of choosing a given face is proportional to
// its area.
if (r < aXY) {
- return
- lo +
+ return
+ lo +
Vector3(
- (float)random(0, extent.x),
- (float)random(0, extent.y),
+ (float)uniformRandom(0.0f, extent.x),
+ (float)uniformRandom(0.0f, extent.y),
d * extent.z);
} else if (r < aYZ) {
- return
- lo +
+ return
+ lo +
Vector3(
d * extent.x,
- (float)random(0, extent.y),
- (float)random(0, extent.z));
+ (float)uniformRandom(0, extent.y),
+ (float)uniformRandom(0, extent.z));
} else {
- return
- lo +
+ return
+ lo +
Vector3(
- (float)random(0, extent.x),
+ (float)uniformRandom(0, extent.x),
d * extent.y,
- (float)random(0, extent.z));
+ (float)uniformRandom(0, extent.z));
}
}
+
Vector3 AABox::randomInteriorPoint() const {
return Vector3(
- (float)random(lo.x, hi.x),
- (float)random(lo.y, hi.y),
- (float)random(lo.z, hi.z));
+ (float)uniformRandom(lo.x, hi.x),
+ (float)uniformRandom(lo.y, hi.y),
+ (float)uniformRandom(lo.z, hi.z));
}
-#endif
+
bool AABox::intersects(const AABox& other) const {
// Must be overlap along all three axes.
@@ -105,53 +137,35 @@ bool AABox::intersects(const AABox& other) const {
return true;
}
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask,
- uint32& outMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
-}
-
-bool AABox::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask) const {
-
- return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
-}
-
int AABox::dummy = 0;
bool AABox::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask,
+ const Array<Plane>& plane,
+ int& cullingPlane,
+ const uint32 _inMask,
uint32& childMask) const {
uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ assert(plane.size() < 31);
childMask = 0;
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
+ const bool finite =
+ (abs(lo.x) < G3D::finf()) &&
+ (abs(hi.x) < G3D::finf()) &&
+ (abs(lo.y) < G3D::finf()) &&
+ (abs(hi.y) < G3D::finf()) &&
+ (abs(lo.z) < G3D::finf()) &&
+ (abs(hi.z) < G3D::finf());
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- Vector3 corner;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ Vector3 corner;
int numContained = 0;
int v = 0;
@@ -159,13 +173,13 @@ bool AABox::culledBy(
// We can early-out only if we have found one point on each
// side of the plane (i.e. if we are straddling). That
// occurs when (numContained < v) && (numContained > 0)
- for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
+ for (v = 0; (v < 8) && ((numContained == v) || (numContained == 0)); ++v) {
// Unrolling these 3 if's into a switch decreases performance
// by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
+ corner.x = (v & 1) ? hi.x : lo.x;
+ corner.y = (v & 2) ? hi.y : lo.y;
+ corner.z = (v & 4) ? hi.z : lo.z;
+
if (finite) { // this branch is highly predictable
if (plane[p].halfSpaceContainsFinite(corner)) {
++numContained;
@@ -175,101 +189,102 @@ bool AABox::culledBy(
++numContained;
}
}
- }
+ }
- if (numContained == 0) {
- // Plane p culled the box
- cullingPlane = p;
+ if (numContained == 0) {
+ // Plane p culled the box
+ cullingPlane = p;
// The caller should not recurse into the children,
// since the parent is culled. If they do recurse,
// make them only test against this one plane, which
// will immediately cull the volume.
childMask = 1 << p;
- return true;
+ return true;
} else if (numContained < v) {
// The bounding volume straddled the plane; we have
// to keep testing against this plane
childMask |= (1 << p);
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
-bool AABox::culledBy(
- const class Plane* plane,
- int numPlanes,
- int& cullingPlane,
- const uint32 _inMask) const {
-
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
- const bool finite =
- (abs(lo.x) < G3D::inf()) &&
- (abs(hi.x) < G3D::inf()) &&
- (abs(lo.y) < G3D::inf()) &&
- (abs(hi.y) < G3D::inf()) &&
- (abs(lo.z) < G3D::inf()) &&
- (abs(hi.z) < G3D::inf());
+bool AABox::culledBy(
+ const Array<Plane>& plane,
+ int& cullingPlane,
+ const uint32 _inMask) const {
+
+ uint32 inMask = _inMask;
+ assert(plane.size() < 31);
+
+ const bool finite =
+ (abs(lo.x) < G3D::finf()) &&
+ (abs(hi.x) < G3D::finf()) &&
+ (abs(lo.y) < G3D::finf()) &&
+ (abs(hi.y) < G3D::finf()) &&
+ (abs(lo.z) < G3D::finf()) &&
+ (abs(hi.z) < G3D::finf());
// See if there is one plane for which all of the
- // vertices are in the negative half space.
- for (int p = 0; p < numPlanes; p++) {
-
- // Only test planes that are not masked
- if ((inMask & 1) != 0) {
+ // vertices are in the negative half space.
+ for (int p = 0; p < plane.size(); ++p) {
- bool culled = true;
- Vector3 corner;
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
+ bool culled = true;
+ Vector3 corner;
int v;
- // Assume this plane culls all points. See if there is a point
- // not culled by the plane... early out when at least one point
+ // Assume this plane culls all points. See if there is a point
+ // not culled by the plane... early out when at least one point
// is in the positive half space.
- for (v = 0; (v < 8) && culled; ++v) {
+ for (v = 0; (v < 8) && culled; ++v) {
// Unrolling these 3 if's into a switch decreases performance
// by about 2x
- corner.x = (v & 1) ? hi.x : lo.x;
- corner.y = (v & 2) ? hi.y : lo.y;
- corner.z = (v & 4) ? hi.z : lo.z;
-
+ corner.x = (v & 1) ? hi.x : lo.x;
+ corner.y = (v & 2) ? hi.y : lo.y;
+ corner.z = (v & 4) ? hi.z : lo.z;
+
if (finite) { // this branch is highly predictable
culled = ! plane[p].halfSpaceContainsFinite(corner);
} else {
culled = ! plane[p].halfSpaceContains(corner);
}
- }
+ }
- if (culled) {
- // Plane p culled the box
- cullingPlane = p;
+ if (culled) {
+ // Plane p culled the box
+ cullingPlane = p;
- return true;
+ return true;
}
- }
+ }
// Move on to the next bit.
- inMask = inMask >> 1;
+ inMask = inMask >> 1;
}
// None of the planes could cull this box
- cullingPlane = -1;
+ cullingPlane = -1;
return false;
}
+
bool AABox::intersects(const class Sphere& sphere) const {
- double d = 0;
+ double d = 0;
//find the square of the distance
//from the sphere to the box
@@ -284,5 +299,68 @@ bool AABox::intersects(const class Sphere& sphere) const {
return d <= square(sphere.radius);
}
-} // namespace
+Vector3 AABox::corner(int index) const {
+
+ // default constructor inits all components to 0
+ Vector3 v;
+
+ switch (index)
+ {
+ case 0:
+ v.x = lo.x;
+ v.y = lo.y;
+ v.z = hi.z;
+ break;
+
+ case 1:
+ v.x = hi.x;
+ v.y = lo.y;
+ v.z = hi.z;
+ break;
+
+ case 2:
+ v.x = hi.x;
+ v.y = hi.y;
+ v.z = hi.z;
+ break;
+
+ case 3:
+ v.x = lo.x;
+ v.y = hi.y;
+ v.z = hi.z;
+ break;
+
+ case 4:
+ v.x = lo.x;
+ v.y = lo.y;
+ v.z = lo.z;
+ break;
+
+ case 5:
+ v.x = hi.x;
+ v.y = lo.y;
+ v.z = lo.z;
+ break;
+
+ case 6:
+ v.x = hi.x;
+ v.y = hi.y;
+ v.z = lo.z;
+ break;
+
+ case 7:
+ v.x = lo.x;
+ v.y = hi.y;
+ v.z = lo.z;
+ break;
+
+ default:
+ debugAssertM(false, "Invalid corner index");
+ break;
+ }
+
+ return v;
+}
+
+}