diff options
author | click <none@none> | 2010-06-05 00:59:25 +0200 |
---|---|---|
committer | click <none@none> | 2010-06-05 00:59:25 +0200 |
commit | e77716188861d4aa83b227a90e04a66b63baeb1f (patch) | |
tree | ce72764181a760314ec851f7535052dcf75649db /dep/src/g3dlite/AABox.cpp | |
parent | 1426c2970f42a2d065198806f750bf5dd28d580b (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.cpp | 308 |
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; +} + +} |