aboutsummaryrefslogtreecommitdiff
path: root/dep/g3dlite/source/Sphere.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/g3dlite/source/Sphere.cpp')
-rw-r--r--dep/g3dlite/source/Sphere.cpp122
1 files changed, 78 insertions, 44 deletions
diff --git a/dep/g3dlite/source/Sphere.cpp b/dep/g3dlite/source/Sphere.cpp
index 4ed0811cb29..5c2eb91cd2a 100644
--- a/dep/g3dlite/source/Sphere.cpp
+++ b/dep/g3dlite/source/Sphere.cpp
@@ -1,12 +1,12 @@
/**
- @file Sphere.cpp
+ \file G3D.lib/source/Sphere.cpp
Sphere class
- @maintainer Morgan McGuire, http://graphics.cs.williams.edu
+ \maintainer Morgan McGuire, http://graphics.cs.williams.edu
- @created 2001-04-17
- @edited 2009-01-20
+ \created 2001-04-17
+ \edited 2011-02-10
*/
#include "G3D/platform.h"
@@ -16,11 +16,37 @@
#include "G3D/BinaryInput.h"
#include "G3D/AABox.h"
#include "G3D/Plane.h"
+#include "G3D/Any.h"
namespace G3D {
int32 Sphere::dummy;
+Sphere::Sphere(const Any& a) : radius(0) {
+ a.verifyName("Sphere");
+ a.verifyType(Any::ARRAY);
+ if (a.size() == 1) {
+ radius = a[0];
+ } else if (a.size() == 2) {
+ center = a[0];
+ radius = a[1];
+ } else {
+ a.verify(false, "Sphere must recieve exactly 1 or two arguments.");
+ }
+}
+
+
+Any Sphere::toAny() const {
+ Any a(Any::ARRAY, "Sphere");
+ if (center != Point3::zero()) {
+ a.append(center);
+ }
+
+ a.append(radius);
+ return a;
+}
+
+
Sphere::Sphere(class BinaryInput& b) {
deserialize(b);
}
@@ -38,6 +64,12 @@ void Sphere::deserialize(class BinaryInput& b) {
}
+const Sphere& Sphere::inf() {
+ static const Sphere s(Point3::zero(), finf());
+ return s;
+}
+
+
std::string Sphere::toString() const {
return format("Sphere(<%g, %g, %g>, %g)",
center.x, center.y, center.z, radius);
@@ -82,19 +114,19 @@ void Sphere::merge(const Sphere& other) {
bool Sphere::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask,
- uint32& outMask) const {
+ const Array<Plane>& plane,
+ int& cullingPlaneIndex,
+ const uint32 inMask,
+ uint32& outMask) const {
return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask, outMask);
}
bool Sphere::culledBy(
- const Array<Plane>& plane,
- int& cullingPlaneIndex,
- const uint32 inMask) const {
+ const Array<Plane>& plane,
+ int& cullingPlaneIndex,
+ const uint32 inMask) const {
return culledBy(plane.getCArray(), plane.size(), cullingPlaneIndex, inMask);
}
@@ -103,8 +135,8 @@ bool Sphere::culledBy(
bool Sphere::culledBy(
const class Plane* plane,
int numPlanes,
- int& cullingPlane,
- const uint32 _inMask,
+ int& cullingPlane,
+ const uint32 _inMask,
uint32& childMask) const {
if (radius == finf()) {
@@ -112,45 +144,45 @@ bool Sphere::culledBy(
return false;
}
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ uint32 inMask = _inMask;
+ assert(numPlanes < 31);
childMask = 0;
// 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++) {
+ // 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) {
-
+ // Only test planes that are not masked
+ if ((inMask & 1) != 0) {
+
bool culledLow = ! plane[p].halfSpaceContainsFinite(center + plane[p].normal() * radius);
bool culledHigh = ! plane[p].halfSpaceContainsFinite(center - plane[p].normal() * radius);
- if (culledLow) {
- // Plane p culled the sphere
- cullingPlane = p;
+ if (culledLow) {
+ // Plane p culled the sphere
+ 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 (culledHigh) {
// 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;
}
@@ -158,32 +190,34 @@ bool Sphere::culledBy(
bool Sphere::culledBy(
const class Plane* plane,
int numPlanes,
- int& cullingPlane,
- const uint32 _inMask) const {
+ int& cullingPlane,
+ const uint32 _inMask) const {
+ // Don't cull if the sphere has infinite radius
+ if(!isFinite(radius)) return false;
- uint32 inMask = _inMask;
- assert(numPlanes < 31);
+ uint32 inMask = _inMask;
+ assert(numPlanes < 31);
// 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) {
- bool culled = ! plane[p].halfSpaceContains(center + plane[p].normal() * radius);
- if (culled) {
- // Plane p culled the sphere
- cullingPlane = p;
- return true;
+ // 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) {
+ bool culled = ! plane[p].halfSpaceContains(center + plane[p].normal() * radius);
+ if (culled) {
+ // Plane p culled the sphere
+ cullingPlane = p;
+ 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;
}