UnionBoundingVolume, IntersectionBoundingVolume, Camera::set_cull_bounds()

This commit is contained in:
David Rose
2012-02-09 21:55:31 +00:00
parent 880fb62a15
commit d34c964e53
21 changed files with 1746 additions and 207 deletions
+1 -1
View File
@@ -1153,7 +1153,7 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
// First, we have to get the current viewing frustum, which comes
// from the lens.
PT(BoundingVolume) bv = scene_setup->get_lens()->make_bounds();
PT(BoundingVolume) bv = scene_setup->get_cull_bounds();
if (bv != (BoundingVolume *)NULL &&
bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
+9 -3
View File
@@ -20,6 +20,7 @@
fftCompressor.h finiteBoundingVolume.h frustum.h \
frustum_src.I frustum_src.h geometricBoundingVolume.I \
geometricBoundingVolume.h \
intersectionBoundingVolume.h intersectionBoundingVolume.I \
linmath_events.h \
look_at.h look_at_src.I \
look_at_src.cxx look_at_src.h \
@@ -38,7 +39,8 @@
rotate_to.h rotate_to_src.cxx \
stackedPerlinNoise2.h stackedPerlinNoise2.I \
stackedPerlinNoise3.h stackedPerlinNoise3.I \
triangulator.h triangulator.I
triangulator.h triangulator.I \
unionBoundingVolume.h unionBoundingVolume.I
#define INCLUDED_SOURCES \
boundingHexahedron.cxx boundingLine.cxx \
@@ -47,6 +49,7 @@
boundingSphere.cxx \
boundingVolume.cxx config_mathutil.cxx fftCompressor.cxx \
finiteBoundingVolume.cxx geometricBoundingVolume.cxx \
intersectionBoundingVolume.cxx \
look_at.cxx \
linmath_events.cxx \
mersenne.cxx \
@@ -62,7 +65,8 @@
rotate_to.cxx \
stackedPerlinNoise2.cxx \
stackedPerlinNoise3.cxx \
triangulator.cxx
triangulator.cxx \
unionBoundingVolume.cxx
#define INSTALL_HEADERS \
boundingHexahedron.I boundingHexahedron.h boundingLine.I \
@@ -75,6 +79,7 @@
pta_LVecBase4.h pta_LVecBase2.h \
finiteBoundingVolume.h frustum.h frustum_src.I frustum_src.h \
geometricBoundingVolume.I geometricBoundingVolume.h look_at.h \
intersectionBoundingVolume.h intersectionBoundingVolume.I \
look_at_src.I look_at_src.h \
linmath_events.h \
mersenne.h \
@@ -88,7 +93,8 @@
rotate_to.h rotate_to_src.cxx \
stackedPerlinNoise2.h stackedPerlinNoise2.I \
stackedPerlinNoise3.h stackedPerlinNoise3.I \
triangulator.h triangulator.I
triangulator.h triangulator.I \
unionBoundingVolume.h unionBoundingVolume.I
+5 -70
View File
@@ -203,16 +203,6 @@ extend_by_point(const LPoint3 &point) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::extend_by_sphere
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
extend_by_sphere(const BoundingSphere *sphere) {
return extend_by_finite(sphere);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::extend_by_box
// Access: Protected, Virtual
@@ -240,23 +230,13 @@ extend_by_box(const BoundingBox *box) {
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::extend_by_hexahedron
// Function: BoundingBox::extend_by_finite
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
extend_by_hexahedron(const BoundingHexahedron *hexahedron) {
return extend_by_finite(hexahedron);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::extend_by_finite
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
extend_by_finite(const FiniteBoundingVolume *volume) {
nassertr(!volume->is_empty(), false);
nassertr(!volume->is_empty() && !volume->is_infinite(), false);
LVector3 min1 = volume->get_min();
LVector3 max1 = volume->get_max();
@@ -347,47 +327,14 @@ around_points(const LPoint3 *first, const LPoint3 *last) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::around_spheres
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
around_spheres(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::around_boxes
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
around_boxes(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::around_hexahedrons
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
around_hexahedrons(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::around_finite
// Access: Protected
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingBox::
around_finite(const BoundingVolume **first,
const BoundingVolume **last) {
const BoundingVolume **last) {
nassertr(first != last, false);
// We're given a set of bounding volumes, at least the first one of
@@ -538,18 +485,6 @@ contains_lineseg(const LPoint3 &a, const LPoint3 &b) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::contains_sphere
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a sphere.
////////////////////////////////////////////////////////////////////
int BoundingBox::
contains_sphere(const BoundingSphere *sphere) const {
return contains_finite(sphere);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::contains_box
// Access: Protected, Virtual
@@ -630,7 +565,7 @@ contains_plane(const BoundingPlane *plane) const {
////////////////////////////////////////////////////////////////////
// Function: BoundingBox::contains_finite
// Access: Protected
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int BoundingBox::
+4 -13
View File
@@ -71,30 +71,21 @@ protected:
virtual bool extend_by_point(const LPoint3 &point);
virtual bool extend_by_sphere(const BoundingSphere *sphere);
virtual bool extend_by_box(const BoundingBox *box);
virtual bool extend_by_hexahedron(const BoundingHexahedron *hexahedron);
bool extend_by_finite(const FiniteBoundingVolume *volume);
virtual bool extend_by_finite(const FiniteBoundingVolume *volume);
virtual bool around_points(const LPoint3 *first,
const LPoint3 *last);
virtual bool around_spheres(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_boxes(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_hexahedrons(const BoundingVolume **first,
const BoundingVolume **last);
bool around_finite(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_finite(const BoundingVolume **first,
const BoundingVolume **last);
virtual int contains_point(const LPoint3 &point) const;
virtual int contains_lineseg(const LPoint3 &a, const LPoint3 &b) const;
virtual int contains_hexahedron(const BoundingHexahedron *hexahedron) const;
virtual int contains_sphere(const BoundingSphere *sphere) const;
virtual int contains_box(const BoundingBox *box) const;
virtual int contains_line(const BoundingLine *line) const;
virtual int contains_plane(const BoundingPlane *plane) const;
int contains_finite(const FiniteBoundingVolume *volume) const;
virtual int contains_finite(const FiniteBoundingVolume *volume) const;
private:
LPoint3 _min;
+6 -39
View File
@@ -42,8 +42,8 @@ make_copy() const {
////////////////////////////////////////////////////////////////////
LPoint3 BoundingSphere::
get_min() const {
nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_empty(), LPoint3::zero());
nassertr(!is_infinite(), LPoint3::zero());
return LPoint3(_center[0] - _radius,
_center[1] - _radius,
_center[2] - _radius);
@@ -56,8 +56,8 @@ get_min() const {
////////////////////////////////////////////////////////////////////
LPoint3 BoundingSphere::
get_max() const {
nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_empty(), LPoint3::zero());
nassertr(!is_infinite(), LPoint3::zero());
return LPoint3(_center[0] + _radius,
_center[1] + _radius,
_center[2] + _radius);
@@ -86,8 +86,8 @@ get_volume() const {
////////////////////////////////////////////////////////////////////
LPoint3 BoundingSphere::
get_approx_center() const {
nassertr(!is_empty(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_infinite(), LPoint3(0.0f, 0.0f, 0.0f));
nassertr(!is_empty(), LPoint3::zero());
nassertr(!is_infinite(), LPoint3::zero());
return get_center();
}
@@ -384,39 +384,6 @@ around_points(const LPoint3 *first, const LPoint3 *last) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: BoundingSphere::around_spheres
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingSphere::
around_spheres(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingSphere::around_boxes
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingSphere::
around_boxes(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingSphere::around_hexahedrons
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool BoundingSphere::
around_hexahedrons(const BoundingVolume **first,
const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingSphere::around_finite
// Access: Protected
+3 -9
View File
@@ -62,18 +62,12 @@ protected:
virtual bool extend_by_sphere(const BoundingSphere *sphere);
virtual bool extend_by_box(const BoundingBox *box);
virtual bool extend_by_hexahedron(const BoundingHexahedron *hexahedron);
bool extend_by_finite(const FiniteBoundingVolume *volume);
virtual bool extend_by_finite(const FiniteBoundingVolume *volume);
virtual bool around_points(const LPoint3 *first,
const LPoint3 *last);
virtual bool around_spheres(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_boxes(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_hexahedrons(const BoundingVolume **first,
const BoundingVolume **last);
bool around_finite(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_finite(const BoundingVolume **first,
const BoundingVolume **last);
virtual int contains_point(const LPoint3 &point) const;
virtual int contains_lineseg(const LPoint3 &a, const LPoint3 &b) const;
+164 -70
View File
@@ -14,6 +14,8 @@
#include "boundingVolume.h"
#include "finiteBoundingVolume.h"
#include "unionBoundingVolume.h"
#include "intersectionBoundingVolume.h"
#include "indent.h"
@@ -192,11 +194,8 @@ string_bounds_type(const string &str) {
// sphere.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_sphere(const BoundingSphere *) {
mathutil_cat.warning()
<< get_type() << "::extend_by_sphere() called\n";
_flags = F_infinite;
return false;
extend_by_sphere(const BoundingSphere *sphere) {
return extend_by_finite(sphere);
}
////////////////////////////////////////////////////////////////////
@@ -207,11 +206,8 @@ extend_by_sphere(const BoundingSphere *) {
// box.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_box(const BoundingBox *) {
mathutil_cat.warning()
<< get_type() << "::extend_by_box() called\n";
_flags = F_infinite;
return false;
extend_by_box(const BoundingBox *box) {
return extend_by_finite(box);
}
////////////////////////////////////////////////////////////////////
@@ -222,11 +218,8 @@ extend_by_box(const BoundingBox *) {
// hexahedron.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_hexahedron(const BoundingHexahedron *) {
mathutil_cat.warning()
<< get_type() << "::extend_by_hexahedron() called\n";
_flags = F_infinite;
return false;
extend_by_hexahedron(const BoundingHexahedron *hexahedron) {
return extend_by_finite(hexahedron);
}
////////////////////////////////////////////////////////////////////
@@ -237,11 +230,8 @@ extend_by_hexahedron(const BoundingHexahedron *) {
// line.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_line(const BoundingLine *) {
mathutil_cat.warning()
<< get_type() << "::extend_by_line() called\n";
_flags = F_infinite;
return false;
extend_by_line(const BoundingLine *line) {
return extend_by_geometric(line);
}
////////////////////////////////////////////////////////////////////
@@ -252,9 +242,53 @@ extend_by_line(const BoundingLine *) {
// plane.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_plane(const BoundingPlane *) {
extend_by_plane(const BoundingPlane *plane) {
return extend_by_geometric(plane);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::extend_by_union
// Access: Protected, Virtual
// Description: Double-dispatch support: called by extend_other()
// when the type we're extending by is known to be a
// union.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_union(const UnionBoundingVolume *unionv) {
return extend_by_geometric(unionv);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::extend_by_intersection
// Access: Protected, Virtual
// Description: Double-dispatch support: called by extend_other()
// when the type we're extending by is known to be a
// intersection.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_intersection(const IntersectionBoundingVolume *intersection) {
return extend_by_geometric(intersection);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::extend_by_finite
// Access: Protected, Virtual
// Description: Generic handler for a FiniteBoundingVolume.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_finite(const FiniteBoundingVolume *volume) {
return extend_by_geometric(volume);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::extend_by_geometric
// Access: Protected, Virtual
// Description: Generic handler for a GeometricBoundingVolume.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
extend_by_geometric(const GeometricBoundingVolume *volume) {
mathutil_cat.warning()
<< get_type() << "::extend_by_plane() called\n";
<< get_type() << "::extend_by_geometric() called with " << volume->get_type() << "\n";
_flags = F_infinite;
return false;
}
@@ -267,11 +301,8 @@ extend_by_plane(const BoundingPlane *) {
// known to be a nonempty sphere.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_spheres(const BoundingVolume **, const BoundingVolume **) {
mathutil_cat.warning()
<< get_type() << "::around_spheres() called\n";
_flags = F_infinite;
return false;
around_spheres(const BoundingVolume **first, const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
@@ -282,11 +313,8 @@ around_spheres(const BoundingVolume **, const BoundingVolume **) {
// known to be a nonempty box.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_boxes(const BoundingVolume **, const BoundingVolume **) {
mathutil_cat.warning()
<< get_type() << "::around_boxes() called\n";
_flags = F_infinite;
return false;
around_boxes(const BoundingVolume **first, const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
@@ -297,11 +325,8 @@ around_boxes(const BoundingVolume **, const BoundingVolume **) {
// known to be a nonempty hexahedron.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_hexahedrons(const BoundingVolume **, const BoundingVolume **) {
mathutil_cat.warning()
<< get_type() << "::around_hexahedrons() called\n";
_flags = F_infinite;
return false;
around_hexahedrons(const BoundingVolume **first, const BoundingVolume **last) {
return around_finite(first, last);
}
////////////////////////////////////////////////////////////////////
@@ -312,15 +337,8 @@ around_hexahedrons(const BoundingVolume **, const BoundingVolume **) {
// known to be a nonempty line.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_lines(const BoundingVolume **, const BoundingVolume **) {
_flags = F_infinite;
mathutil_cat.warning()
<< get_type() << "::around_lines() called\n";
// If we get here, the function isn't defined by a subclass, so we
// return false to indicate this.
return false;
around_lines(const BoundingVolume **first, const BoundingVolume **last) {
return around_geometric(first, last);
}
////////////////////////////////////////////////////////////////////
@@ -331,14 +349,54 @@ around_lines(const BoundingVolume **, const BoundingVolume **) {
// known to be a nonempty plane.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_planes(const BoundingVolume **, const BoundingVolume **) {
_flags = F_infinite;
around_planes(const BoundingVolume **first, const BoundingVolume **last) {
return around_geometric(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::around_unions
// Access: Protected, Virtual
// Description: Double-dispatch support: called by around_other()
// when the type of the first element in the list is
// known to be a union object.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_unions(const BoundingVolume **first, const BoundingVolume **last) {
return around_geometric(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::around_intersections
// Access: Protected, Virtual
// Description: Double-dispatch support: called by around_other()
// when the type of the first element in the list is
// known to be an intersection object.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_intersections(const BoundingVolume **first, const BoundingVolume **last) {
return around_geometric(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::around_finite
// Access: Protected, Virtual
// Description: Generic handler for a FiniteBoundingVolume.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_finite(const BoundingVolume **first, const BoundingVolume **last) {
return around_geometric(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::around_geometric
// Access: Protected, Virtual
// Description: Generic handler for a GeometricBoundingVolume.
////////////////////////////////////////////////////////////////////
bool BoundingVolume::
around_geometric(const BoundingVolume **first, const BoundingVolume **last) {
mathutil_cat.warning()
<< get_type() << "::around_planes() called\n";
// If we get here, the function isn't defined by a subclass, so we
// return false to indicate this.
<< get_type() << "::extend_by_geometric() called with " << first[0]->get_type() << "\n";
_flags = F_infinite;
return false;
}
@@ -350,10 +408,8 @@ around_planes(const BoundingVolume **, const BoundingVolume **) {
// to be a sphere.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_sphere(const BoundingSphere *) const {
mathutil_cat.warning()
<< get_type() << "::contains_sphere() called\n";
return IF_dont_understand;
contains_sphere(const BoundingSphere *sphere) const {
return contains_finite(sphere);
}
////////////////////////////////////////////////////////////////////
@@ -364,10 +420,8 @@ contains_sphere(const BoundingSphere *) const {
// to be a box.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_box(const BoundingBox *) const {
mathutil_cat.warning()
<< get_type() << "::contains_box() called\n";
return IF_dont_understand;
contains_box(const BoundingBox *box) const {
return contains_finite(box);
}
////////////////////////////////////////////////////////////////////
@@ -378,10 +432,8 @@ contains_box(const BoundingBox *) const {
// to be a hexahedron.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_hexahedron(const BoundingHexahedron *) const {
mathutil_cat.warning()
<< get_type() << "::contains_hexahedron() called\n";
return IF_dont_understand;
contains_hexahedron(const BoundingHexahedron *hexahedron) const {
return contains_finite(hexahedron);
}
////////////////////////////////////////////////////////////////////
@@ -392,10 +444,8 @@ contains_hexahedron(const BoundingHexahedron *) const {
// to be a line.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_line(const BoundingLine *) const {
mathutil_cat.warning()
<< get_type() << "::contains_line() called\n";
return IF_dont_understand;
contains_line(const BoundingLine *line) const {
return contains_geometric(line);
}
////////////////////////////////////////////////////////////////////
@@ -406,9 +456,53 @@ contains_line(const BoundingLine *) const {
// to be a plane.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_plane(const BoundingPlane *) const {
contains_plane(const BoundingPlane *plane) const {
return contains_geometric(plane);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::contains_union
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a union object.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_union(const UnionBoundingVolume *unionv) const {
return unionv->other_contains_union(this);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::contains_intersection
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be an intersection object.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_intersection(const IntersectionBoundingVolume *intersection) const {
return intersection->other_contains_intersection(this);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::contains_finite
// Access: Protected, Virtual
// Description: Generic handler for a FiniteBoundingVolume.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_finite(const FiniteBoundingVolume *volume) const {
return contains_geometric(volume);
}
////////////////////////////////////////////////////////////////////
// Function: BoundingVolume::contains_geometric
// Access: Protected, Virtual
// Description: Generic handler for a GeometricBoundingVolume.
////////////////////////////////////////////////////////////////////
int BoundingVolume::
contains_geometric(const GeometricBoundingVolume *volume) const {
mathutil_cat.warning()
<< get_type() << "::contains_plane() called\n";
<< get_type() << "::contains_geometric() called with " << volume->get_type() << "\n";
return IF_dont_understand;
}
+21 -1
View File
@@ -28,6 +28,8 @@ class BoundingBox;
class BoundingHexahedron;
class BoundingLine;
class BoundingPlane;
class UnionBoundingVolume;
class IntersectionBoundingVolume;
////////////////////////////////////////////////////////////////////
@@ -143,6 +145,10 @@ protected:
virtual bool extend_by_hexahedron(const BoundingHexahedron *hexahedron);
virtual bool extend_by_line(const BoundingLine *line);
virtual bool extend_by_plane(const BoundingPlane *plane);
virtual bool extend_by_union(const UnionBoundingVolume *unionv);
virtual bool extend_by_intersection(const IntersectionBoundingVolume *intersection);
virtual bool extend_by_finite(const FiniteBoundingVolume *volume);
virtual bool extend_by_geometric(const GeometricBoundingVolume *volume);
virtual bool around_spheres(const BoundingVolume **first,
const BoundingVolume **last);
@@ -153,13 +159,25 @@ protected:
virtual bool around_lines(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_planes(const BoundingVolume **first,
const BoundingVolume **last);
const BoundingVolume **last);
virtual bool around_unions(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_intersections(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_finite(const BoundingVolume **first,
const BoundingVolume **last);
virtual bool around_geometric(const BoundingVolume **first,
const BoundingVolume **last);
virtual int contains_sphere(const BoundingSphere *sphere) const;
virtual int contains_box(const BoundingBox *box) const;
virtual int contains_hexahedron(const BoundingHexahedron *hexahedron) const;
virtual int contains_line(const BoundingLine *line) const;
virtual int contains_plane(const BoundingPlane *plane) const;
virtual int contains_union(const UnionBoundingVolume *unionv) const;
virtual int contains_intersection(const IntersectionBoundingVolume *intersection) const;
virtual int contains_finite(const FiniteBoundingVolume *volume) const;
virtual int contains_geometric(const GeometricBoundingVolume *volume) const;
public:
@@ -184,6 +202,8 @@ private:
friend class BoundingHexahedron;
friend class BoundingLine;
friend class BoundingPlane;
friend class UnionBoundingVolume;
friend class IntersectionBoundingVolume;
};
INLINE_MATHUTIL ostream &operator << (ostream &out, const BoundingVolume &bound);
+24 -1
View File
@@ -22,6 +22,8 @@
#include "boundingHexahedron.h"
#include "boundingLine.h"
#include "boundingPlane.h"
#include "unionBoundingVolume.h"
#include "intersectionBoundingVolume.h"
#include "linmath_events.h"
#include "dconfig.h"
#include "pandaSystem.h"
@@ -29,6 +31,10 @@
Configure(config_mathutil);
NotifyCategoryDef(mathutil, "");
ConfigureFn(config_mathutil) {
init_libmathutil();
}
ConfigVariableDouble fft_offset
("fft-offset", 0.001);
@@ -47,7 +53,22 @@ ConfigVariableEnum<BoundingVolume::BoundsType> bounds_type
"by Panda to enclose geometry. Use 'sphere' or 'box', or use "
"'best' to let Panda decide which is most appropriate."));
ConfigureFn(config_mathutil) {
////////////////////////////////////////////////////////////////////
// Function: init_libmathutil
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libmathutil() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
BoundingHexahedron::init_type();
BoundingSphere::init_type();
BoundingBox::init_type();
@@ -55,6 +76,8 @@ ConfigureFn(config_mathutil) {
FiniteBoundingVolume::init_type();
GeometricBoundingVolume::init_type();
OmniBoundingVolume::init_type();
UnionBoundingVolume::init_type();
IntersectionBoundingVolume::init_type();
BoundingLine::init_type();
BoundingPlane::init_type();
EventStoreVec2::init_type("EventStoreVec2");
+2
View File
@@ -29,6 +29,8 @@ extern ConfigVariableDouble fft_exponent;
extern ConfigVariableDouble fft_error_threshold;
extern EXPCL_PANDA_MATHUTIL ConfigVariableEnum<BoundingVolume::BoundsType> bounds_type;
extern EXPCL_PANDA_MATHUTIL void init_libmathutil();
#endif
@@ -0,0 +1,46 @@
// Filename: intersectionBoundingVolume.I
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::Constructor
// Access: Published
// Description: Constructs an empty intersection.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL IntersectionBoundingVolume::
IntersectionBoundingVolume() {
_flags = F_infinite;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::get_num_components
// Access: Published
// Description: Returns the number of components in the intersection.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL int IntersectionBoundingVolume::
get_num_components() const {
return (int)_components.size();
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::get_component
// Access: Published
// Description: Returns the nth component in the intersection.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL const GeometricBoundingVolume *IntersectionBoundingVolume::
get_component(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), NULL);
return _components[n];
}
@@ -0,0 +1,592 @@
// Filename: intersectionBoundingVolume.cxx
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "intersectionBoundingVolume.h"
#include "unionBoundingVolume.h"
#include "config_mathutil.h"
#include "dcast.h"
TypeHandle IntersectionBoundingVolume::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
IntersectionBoundingVolume::
IntersectionBoundingVolume(const IntersectionBoundingVolume &copy) :
GeometricBoundingVolume(copy),
_components(copy._components)
{
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::make_copy
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
BoundingVolume *IntersectionBoundingVolume::
make_copy() const {
return new IntersectionBoundingVolume(*this);
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::get_approx_center
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LPoint3 IntersectionBoundingVolume::
get_approx_center() const {
nassertr(!is_empty(), LPoint3::zero());
nassertr(!is_infinite(), LPoint3::zero());
LPoint3 center = LPoint3::zero();
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
center += (*ci)->get_approx_center();
}
return center / (PN_stdfloat)_components.size();
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::xform
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IntersectionBoundingVolume::
xform(const LMatrix4 &mat) {
nassertv(!mat.is_nan());
for (Components::iterator ci = _components.begin();
ci != _components.end();
++ci) {
PT(GeometricBoundingVolume) copy = DCAST(GeometricBoundingVolume, (*ci)->make_copy());
copy->xform(mat);
(*ci) = copy;
}
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IntersectionBoundingVolume::
output(ostream &out) const {
if (is_empty()) {
out << "intersection, empty";
} else if (is_infinite()) {
out << "intersection, infinite";
} else {
out << "intersection [";
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
out << " " << *(*ci);
}
out << " ]";
}
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void IntersectionBoundingVolume::
write(ostream &out, int indent_level) const {
if (is_empty()) {
indent(out, indent_level) << "intersection, empty\n";
} else if (is_infinite()) {
indent(out, indent_level) << "intersection, infinite\n";
} else {
indent(out, indent_level) << "intersection {\n";
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
(*ci)->write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::clear_components
// Access: Published
// Description: Removes all components from the volume.
////////////////////////////////////////////////////////////////////
void IntersectionBoundingVolume::
clear_components() {
_components.clear();
_flags = F_infinite;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::add_component
// Access: Published
// Description: Adds a new component to the volume. This does not
// necessarily increase the total number of components
// by one, and you may or may not be able to find this
// component in the volume by a subsequent call to
// get_component(); certain optimizations may prevent
// the component from being added, or have other
// unexpected effects on the total set of components.
////////////////////////////////////////////////////////////////////
void IntersectionBoundingVolume::
add_component(const GeometricBoundingVolume *component) {
CPT(GeometricBoundingVolume) gbv;
if (component->is_exact_type(UnionBoundingVolume::get_class_type())) {
// Here's a special case. We'll construct a new union that
// includes only those components that have some intersection with
// our existing components. (No need to include the components
// that have no intersection.)
PT(UnionBoundingVolume) unionv = DCAST(UnionBoundingVolume, component->make_copy());
unionv->filter_intersection(this);
// Save the modified union in a PT() so it won't be destructed.
gbv = unionv.p();
if (unionv->get_num_components() == 1) {
// If there's only one component left, use just that one.
gbv = unionv->get_component(0);
}
component = gbv;
}
if (component->is_empty()) {
_flags = F_empty;
_components.clear();
} else if (component->is_infinite() || is_empty()) {
// No-op.
} else if (component->is_exact_type(IntersectionBoundingVolume::get_class_type())) {
// Another special case. Just more components.
const IntersectionBoundingVolume *other = DCAST(IntersectionBoundingVolume, component);
for (Components::const_iterator ci = other->_components.begin();
ci != other->_components.end();
++ci) {
add_component(*ci);
}
} else {
// The general case.
size_t i = 0;
while (i < _components.size()) {
const GeometricBoundingVolume *existing = _components[i];
++i;
int result = component->contains(existing);
if ((result & IF_all) != 0) {
// The existing component is entirely within this one; no need
// to do anything with it.
return;
} else if (result == 0) {
// No intersection between these components; we're now empty.
_flags = F_empty;
_components.clear();
return;
}
result = existing->contains(component);
if ((result & IF_all) != 0) {
// This new component is entirely within an existing
// component; no need to keep the existing one.
--i;
_components.erase(_components.begin() + i);
} else if (result == 0) {
// No intersection between these components; we're now empty.
_flags = F_empty;
_components.clear();
return;
}
}
_flags &= ~F_infinite;
_components.push_back(component);
}
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::extend_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool IntersectionBoundingVolume::
extend_other(BoundingVolume *other) const {
return other->extend_by_intersection(this);
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::around_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool IntersectionBoundingVolume::
around_other(BoundingVolume *other,
const BoundingVolume **first,
const BoundingVolume **last) const {
return other->around_intersections(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_other(const BoundingVolume *other) const {
return other->contains_intersection(this);
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_point
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_point(const LPoint3 &point) const {
nassertr(!point.is_nan(), IF_no_intersection);
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains(point);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_lineseg
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_lineseg(const LPoint3 &a, const LPoint3 &b) const {
nassertr(!a.is_nan() && !b.is_nan(), IF_no_intersection);
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains(a, b);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_sphere
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a sphere.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_sphere(const BoundingSphere *sphere) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_sphere(sphere);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_box
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a box.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_box(const BoundingBox *box) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_box(box);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_hexahedron
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a hexahedron.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_hexahedron(const BoundingHexahedron *hexahedron) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_hexahedron(hexahedron);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_line
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a line.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_line(const BoundingLine *line) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_line(line);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_plane
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a plane.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_plane(const BoundingPlane *plane) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_plane(plane);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_union
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a union object.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_union(const UnionBoundingVolume *unionv) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_union(unionv);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_intersection
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be an intersection object.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_intersection(const IntersectionBoundingVolume *intersection) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_intersection(intersection);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_finite
// Access: Protected, Virtual
// Description: Generic handler for a FiniteBoundingVolume.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_finite(const FiniteBoundingVolume *volume) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_finite(volume);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::contains_geometric
// Access: Protected, Virtual
// Description: Generic handler for a GeometricBoundingVolume.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
contains_geometric(const GeometricBoundingVolume *volume) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = (*ci)->contains_geometric(volume);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: IntersectionBoundingVolume::other_contains_intersection
// Access: Protected, Virtual
// Description: Generic reverse-direction comparison. Called by
// BoundingVolumes that do not implement
// contains_intersection() explicitly. This returns the test
// of whether the other volume contains this volume.
////////////////////////////////////////////////////////////////////
int IntersectionBoundingVolume::
other_contains_intersection(const BoundingVolume *volume) const {
int result = IF_possible | IF_some | IF_all;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = volume->contains(*ci);
if ((this_result & IF_dont_understand) != 0) {
result |= IF_dont_understand;
break;
}
result &= this_result;
if ((result & IF_possible) == 0) {
// No point in looking further.
break;
}
}
return result;
}
@@ -0,0 +1,104 @@
// Filename: intersectionBoundingVolume.h
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef INTERSECTIONBOUNDINGVOLUME_H
#define INTERSECTIONBOUNDINGVOLUME_H
#include "pandabase.h"
#include "geometricBoundingVolume.h"
#include "pvector.h"
////////////////////////////////////////////////////////////////////
// Class : IntersectionBoundingVolume
// Description : This special bounding volume is the intersection of all of
// its constituent bounding volumes.
//
// A point is defined to be within an
// IntersectionBoundingVolume if it is within all of its
// component bounding volumes.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_MATHUTIL IntersectionBoundingVolume : public GeometricBoundingVolume {
PUBLISHED:
INLINE_MATHUTIL IntersectionBoundingVolume();
ALLOC_DELETED_CHAIN(IntersectionBoundingVolume);
public:
IntersectionBoundingVolume(const IntersectionBoundingVolume &copy);
public:
virtual BoundingVolume *make_copy() const;
virtual LPoint3 get_approx_center() const;
virtual void xform(const LMatrix4 &mat);
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;
PUBLISHED:
INLINE_MATHUTIL int get_num_components() const;
INLINE_MATHUTIL const GeometricBoundingVolume *get_component(int n) const;
MAKE_SEQ(get_components, get_num_components, get_component);
void clear_components();
void add_component(const GeometricBoundingVolume *component);
protected:
virtual bool extend_other(BoundingVolume *other) const;
virtual bool around_other(BoundingVolume *other,
const BoundingVolume **first,
const BoundingVolume **last) const;
virtual int contains_other(const BoundingVolume *other) const;
virtual int contains_point(const LPoint3 &point) const;
virtual int contains_lineseg(const LPoint3 &a, const LPoint3 &b) const;
virtual int contains_sphere(const BoundingSphere *sphere) const;
virtual int contains_box(const BoundingBox *box) const;
virtual int contains_hexahedron(const BoundingHexahedron *hexahedron) const;
virtual int contains_line(const BoundingLine *line) const;
virtual int contains_plane(const BoundingPlane *plane) const;
virtual int contains_union(const UnionBoundingVolume *unionv) const;
virtual int contains_intersection(const IntersectionBoundingVolume *intersection) const;
virtual int contains_finite(const FiniteBoundingVolume *volume) const;
virtual int contains_geometric(const GeometricBoundingVolume *volume) const;
int other_contains_intersection(const BoundingVolume *other) const;
private:
typedef pvector<CPT(GeometricBoundingVolume) > Components;
Components _components;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GeometricBoundingVolume::init_type();
register_type(_type_handle, "IntersectionBoundingVolume",
GeometricBoundingVolume::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class BoundingVolume;
};
#include "intersectionBoundingVolume.I"
#endif
@@ -6,6 +6,8 @@
#include "boundingVolume.cxx"
#include "finiteBoundingVolume.cxx"
#include "geometricBoundingVolume.cxx"
#include "intersectionBoundingVolume.cxx"
#include "omniBoundingVolume.cxx"
#include "unionBoundingVolume.cxx"
#include "parabola.cxx"
#include "config_mathutil.cxx"
+44
View File
@@ -0,0 +1,44 @@
// Filename: unionBoundingVolume.I
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::Constructor
// Access: Published
// Description: Constructs an empty union.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL UnionBoundingVolume::
UnionBoundingVolume() {
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::get_num_components
// Access: Published
// Description: Returns the number of components in the union.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL int UnionBoundingVolume::
get_num_components() const {
return (int)_components.size();
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::get_component
// Access: Published
// Description: Returns the nth component in the union.
////////////////////////////////////////////////////////////////////
INLINE_MATHUTIL const GeometricBoundingVolume *UnionBoundingVolume::
get_component(int n) const {
nassertr(n >= 0 && n < (int)_components.size(), NULL);
return _components[n];
}
+559
View File
@@ -0,0 +1,559 @@
// Filename: unionBoundingVolume.cxx
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "unionBoundingVolume.h"
#include "config_mathutil.h"
#include "dcast.h"
#include "indent.h"
TypeHandle UnionBoundingVolume::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
UnionBoundingVolume::
UnionBoundingVolume(const UnionBoundingVolume &copy) :
GeometricBoundingVolume(copy),
_components(copy._components)
{
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::make_copy
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
BoundingVolume *UnionBoundingVolume::
make_copy() const {
return new UnionBoundingVolume(*this);
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::get_approx_center
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
LPoint3 UnionBoundingVolume::
get_approx_center() const {
nassertr(!is_empty(), LPoint3::zero());
nassertr(!is_infinite(), LPoint3::zero());
LPoint3 center = LPoint3::zero();
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
center += (*ci)->get_approx_center();
}
return center / (PN_stdfloat)_components.size();
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::xform
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
xform(const LMatrix4 &mat) {
nassertv(!mat.is_nan());
for (Components::iterator ci = _components.begin();
ci != _components.end();
++ci) {
PT(GeometricBoundingVolume) copy = DCAST(GeometricBoundingVolume, (*ci)->make_copy());
copy->xform(mat);
(*ci) = copy;
}
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
output(ostream &out) const {
if (is_empty()) {
out << "union, empty";
} else if (is_infinite()) {
out << "union, infinite";
} else {
out << "union [";
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
out << " " << *(*ci);
}
out << " ]";
}
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::write
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
write(ostream &out, int indent_level) const {
if (is_empty()) {
indent(out, indent_level) << "union, empty\n";
} else if (is_infinite()) {
indent(out, indent_level) << "union, infinite\n";
} else {
indent(out, indent_level) << "union {\n";
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
(*ci)->write(out, indent_level + 2);
}
indent(out, indent_level) << "}\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::clear_components
// Access: Published
// Description: Removes all components from the volume.
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
clear_components() {
_components.clear();
_flags = F_empty;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::add_component
// Access: Published
// Description: Adds a new component to the volume. This does not
// necessarily increase the total number of components
// by one, and you may or may not be able to find this
// component in the volume by a subsequent call to
// get_component(); certain optimizations may prevent
// the component from being added, or have other
// unexpected effects on the total set of components.
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
add_component(const GeometricBoundingVolume *component) {
if (component->is_infinite()) {
_flags = F_infinite;
_components.clear();
} else if (component->is_empty() || is_infinite()) {
// No-op.
} else {
size_t i = 0;
while (i < _components.size()) {
const GeometricBoundingVolume *existing = _components[i];
++i;
int result = existing->contains(component);
if ((result & IF_all) != 0) {
// This new component is entirely within an existing
// component; no need to do anything with it.
return;
}
result = component->contains(existing);
if ((result & IF_all) != 0) {
// The existing component is entirely within this one; no need
// to keep the existing one.
--i;
_components.erase(_components.begin() + i);
}
}
_flags &= ~F_empty;
_components.push_back(component);
}
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::filter_intersection
// Access: Published
// Description: Removes from the union any components that have no
// intersection with the indicated volume.
////////////////////////////////////////////////////////////////////
void UnionBoundingVolume::
filter_intersection(const BoundingVolume *volume) {
size_t i = 0;
while (i < _components.size()) {
const GeometricBoundingVolume *existing = _components[i];
++i;
int result = volume->contains(existing);
if ((result & IF_possible) == 0) {
// There is no intersection. Remove this component.
--i;
_components.erase(_components.begin() + i);
}
}
if (_components.empty()) {
_flags |= F_empty;
}
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::extend_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool UnionBoundingVolume::
extend_other(BoundingVolume *other) const {
return other->extend_by_union(this);
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::around_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
bool UnionBoundingVolume::
around_other(BoundingVolume *other,
const BoundingVolume **first,
const BoundingVolume **last) const {
return other->around_unions(first, last);
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_other
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_other(const BoundingVolume *other) const {
return other->contains_union(this);
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::extend_by_geometric
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
bool UnionBoundingVolume::
extend_by_geometric(const GeometricBoundingVolume *volume) {
add_component(volume);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::around_geometric
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
bool UnionBoundingVolume::
around_geometric(const BoundingVolume **first,
const BoundingVolume **last) {
nassertr(first != last, false);
clear_components();
const BoundingVolume **p = first;
while (p != last) {
nassertr(!(*p)->is_infinite(), false);
if (!(*p)->is_empty()) {
const GeometricBoundingVolume *volume = (*p)->as_geometric_bounding_volume();
if (volume != (GeometricBoundingVolume *)NULL) {
add_component(volume);
} else {
set_infinite();
_components.clear();
return false;
}
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_point
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_point(const LPoint3 &point) const {
nassertr(!point.is_nan(), IF_no_intersection);
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains(point);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_lineseg
// Access: Protected, Virtual
// Description:
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_lineseg(const LPoint3 &a, const LPoint3 &b) const {
nassertr(!a.is_nan() && !b.is_nan(), IF_no_intersection);
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains(a, b);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_sphere
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a sphere.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_sphere(const BoundingSphere *sphere) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_sphere(sphere);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_box
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a box.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_box(const BoundingBox *box) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_box(box);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_hexahedron
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a hexahedron.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_hexahedron(const BoundingHexahedron *hexahedron) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_hexahedron(hexahedron);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_line
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a line.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_line(const BoundingLine *line) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_line(line);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_plane
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a plane.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_plane(const BoundingPlane *plane) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_plane(plane);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_union
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be a union object.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_union(const UnionBoundingVolume *unionv) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_union(unionv);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_intersection
// Access: Protected, Virtual
// Description: Double-dispatch support: called by contains_other()
// when the type we're testing for intersection is known
// to be an intersection object.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_intersection(const IntersectionBoundingVolume *intersection) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_intersection(intersection);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_finite
// Access: Protected, Virtual
// Description: Generic handler for a FiniteBoundingVolume.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_finite(const FiniteBoundingVolume *volume) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_finite(volume);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::contains_geometric
// Access: Protected, Virtual
// Description: Generic handler for a GeometricBoundingVolume.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
contains_geometric(const GeometricBoundingVolume *volume) const {
int result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
result |= (*ci)->contains_geometric(volume);
if ((result & (IF_all | IF_dont_understand)) != 0) {
// No point in looking further.
break;
}
}
return result;
}
////////////////////////////////////////////////////////////////////
// Function: UnionBoundingVolume::other_contains_union
// Access: Protected, Virtual
// Description: Generic reverse-direction comparison. Called by
// BoundingVolumes that do not implement
// contains_union() explicitly. This returns the test
// of whether the other volume contains this volume.
////////////////////////////////////////////////////////////////////
int UnionBoundingVolume::
other_contains_union(const BoundingVolume *volume) const {
int all_result = IF_possible | IF_some | IF_all;
int some_result = 0;
for (Components::const_iterator ci = _components.begin();
ci != _components.end();
++ci) {
int this_result = volume->contains(*ci);
if ((this_result & IF_dont_understand) != 0) {
some_result |= IF_dont_understand;
break;
}
all_result &= this_result;
some_result |= this_result;
}
some_result &= ~IF_all;
return some_result | all_result;
}
+108
View File
@@ -0,0 +1,108 @@
// Filename: unionBoundingVolume.h
// Created by: drose (08Feb12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef UNIONBOUNDINGVOLUME_H
#define UNIONBOUNDINGVOLUME_H
#include "pandabase.h"
#include "geometricBoundingVolume.h"
#include "pvector.h"
////////////////////////////////////////////////////////////////////
// Class : UnionBoundingVolume
// Description : This special bounding volume is the union of all of
// its constituent bounding volumes.
//
// A point is defined to be within a UnionBoundingVolume
// if it is within any one or more of its component
// bounding volumes.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_MATHUTIL UnionBoundingVolume : public GeometricBoundingVolume {
PUBLISHED:
INLINE_MATHUTIL UnionBoundingVolume();
ALLOC_DELETED_CHAIN(UnionBoundingVolume);
public:
UnionBoundingVolume(const UnionBoundingVolume &copy);
virtual BoundingVolume *make_copy() const;
virtual LPoint3 get_approx_center() const;
virtual void xform(const LMatrix4 &mat);
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;
PUBLISHED:
INLINE_MATHUTIL int get_num_components() const;
INLINE_MATHUTIL const GeometricBoundingVolume *get_component(int n) const;
MAKE_SEQ(get_components, get_num_components, get_component);
void clear_components();
void add_component(const GeometricBoundingVolume *component);
void filter_intersection(const BoundingVolume *volume);
protected:
virtual bool extend_other(BoundingVolume *other) const;
virtual bool around_other(BoundingVolume *other,
const BoundingVolume **first,
const BoundingVolume **last) const;
virtual int contains_other(const BoundingVolume *other) const;
virtual bool extend_by_geometric(const GeometricBoundingVolume *volume);
virtual bool around_geometric(const BoundingVolume **first,
const BoundingVolume **last);
virtual int contains_point(const LPoint3 &point) const;
virtual int contains_lineseg(const LPoint3 &a, const LPoint3 &b) const;
virtual int contains_sphere(const BoundingSphere *sphere) const;
virtual int contains_box(const BoundingBox *box) const;
virtual int contains_hexahedron(const BoundingHexahedron *hexahedron) const;
virtual int contains_line(const BoundingLine *line) const;
virtual int contains_plane(const BoundingPlane *plane) const;
virtual int contains_union(const UnionBoundingVolume *unionv) const;
virtual int contains_intersection(const IntersectionBoundingVolume *intersection) const;
virtual int contains_finite(const FiniteBoundingVolume *volume) const;
virtual int contains_geometric(const GeometricBoundingVolume *volume) const;
int other_contains_union(const BoundingVolume *other) const;
private:
typedef pvector<CPT(GeometricBoundingVolume) > Components;
Components _components;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
GeometricBoundingVolume::init_type();
register_type(_type_handle, "UnionBoundingVolume",
GeometricBoundingVolume::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class BoundingVolume;
};
#include "unionBoundingVolume.I"
#endif
+28
View File
@@ -148,6 +148,34 @@ get_cull_center() const {
return _cull_center;
}
////////////////////////////////////////////////////////////////////
// Function: Camera::set_cull_bounds
// Access: Published
// Description: Specifies the bounding volume that should be used to
// perform culling from this camera. Normally, this is
// the bounding volume returned from the active lens'
// make_bounds() call, but you may override this to
// specify a custom volume if you require. The
// specified bounding volume will be understood to be in
// the coordinate space of the get_cull_center() node.
////////////////////////////////////////////////////////////////////
INLINE void Camera::
set_cull_bounds(BoundingVolume *cull_bounds) {
_cull_bounds = cull_bounds;
}
////////////////////////////////////////////////////////////////////
// Function: Camera::get_cull_bounds
// Access: Published
// Description: Returns the custom cull volume that was set by
// set_cull_bounds(), if any, or NULL if no custom cull
// volume was set.
////////////////////////////////////////////////////////////////////
INLINE BoundingVolume *Camera::
get_cull_bounds() const {
return _cull_bounds;
}
////////////////////////////////////////////////////////////////////
// Function: Camera::set_lod_center
// Access: Published
+4
View File
@@ -63,6 +63,9 @@ PUBLISHED:
INLINE void set_cull_center(const NodePath &cull_center);
INLINE const NodePath &get_cull_center() const;
INLINE void set_cull_bounds(BoundingVolume *cull_bounds);
INLINE BoundingVolume *get_cull_bounds() const;
INLINE void set_lod_center(const NodePath &lod_center);
INLINE const NodePath &get_lod_center() const;
@@ -90,6 +93,7 @@ private:
bool _active;
NodePath _scene;
NodePath _cull_center;
PT(BoundingVolume) _cull_bounds;
NodePath _lod_center;
DrawMask _camera_mask;
+19
View File
@@ -206,6 +206,25 @@ get_cull_center() const {
}
}
////////////////////////////////////////////////////////////////////
// Function: SceneSetup::get_cull_bounds
// Access: Published
// Description: Returns the bounding volume that should be used to
// perform view-frustum culling (in the space of
// get_cull_center()). This is normally the current
// lens' bounding volume, but it may be overridden with
// Camera::set_cull_bounds().
////////////////////////////////////////////////////////////////////
INLINE PT(BoundingVolume) SceneSetup::
get_cull_bounds() const {
PT(BoundingVolume) bounds = _camera_node->get_cull_bounds();
if (bounds != (BoundingVolume *)NULL) {
return bounds;
}
return _lens->make_bounds();
}
////////////////////////////////////////////////////////////////////
// Function: SceneSetup::set_initial_state
// Access: Published
+1
View File
@@ -60,6 +60,7 @@ PUBLISHED:
INLINE bool get_inverted() const;
INLINE const NodePath &get_cull_center() const;
INLINE PT(BoundingVolume) get_cull_bounds() const;
INLINE void set_initial_state(const RenderState *initial_state);
INLINE const RenderState *get_initial_state() const;