Panda3D
boundingVolume.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file boundingVolume.cxx
10  * @author drose
11  * @date 1999-10-01
12  */
13 
14 #include "boundingVolume.h"
15 #include "finiteBoundingVolume.h"
16 #include "unionBoundingVolume.h"
18 #include "boundingBox.h"
19 #include "boundingLine.h"
20 #include "boundingPlane.h"
21 #include "boundingSphere.h"
22 #include "boundingHexahedron.h"
23 #include "config_mathutil.h"
24 
25 #include "indent.h"
26 
27 using std::istream;
28 using std::ostream;
29 using std::string;
30 
31 TypeHandle BoundingVolume::_type_handle;
32 
33 
34 /**
35  * Resets the volume to enclose only the volumes indicated. Returns true if
36  * successful, false if the volume doesn't know how to do that or can't do
37  * that.
38  */
40 around(const BoundingVolume **first, const BoundingVolume **last) {
41  _flags = F_empty;
42 
43  // Skip any empty volumes at the beginning of the list. We want to get to
44  // the first real volume.
45  while (first != last && (*first)->is_empty()) {
46  if ((*first)->is_infinite()) {
47  // If we go around an infinite volume, we're infinite too.
48  _flags = F_infinite;
49  return true;
50  }
51  ++first;
52  }
53 
54  bool okflag = true;
55 
56  if (first != last) {
57  // Check for more infinite bounding volumes in the list.
58  const BoundingVolume **bvi;
59  for (bvi = first; bvi != last; ++bvi) {
60  if ((*bvi)->is_infinite()) {
61  _flags = F_infinite;
62  return true;
63  }
64  }
65 
66  // This is a double-dispatch. We call this virtual function on the volume
67  // we were given, which will in turn call the appropriate virtual function
68  // in our own class to perform the operation.
69  if (!(*first)->around_other(this, first, last)) {
70  okflag = false;
71  }
72  }
73 
74  return okflag;
75 }
76 
77 /**
78  *
79  */
80 void BoundingVolume::
81 write(ostream &out, int indent_level) const {
82  indent(out, indent_level) << *this << "\n";
83 }
84 
85 /**
86  * Virtual downcast method. Returns this object as a pointer of the indicated
87  * type, if it is in fact that type. Returns NULL if it is not that type.
88  */
91  return nullptr;
92 }
93 
94 /**
95  * Virtual downcast method. Returns this object as a pointer of the indicated
96  * type, if it is in fact that type. Returns NULL if it is not that type.
97  */
100  return nullptr;
101 }
102 
103 /**
104  * Virtual downcast method. Returns this object as a pointer of the indicated
105  * type, if it is in fact that type. Returns NULL if it is not that type.
106  */
109  return nullptr;
110 }
111 
112 /**
113  * Virtual downcast method. Returns this object as a pointer of the indicated
114  * type, if it is in fact that type. Returns NULL if it is not that type.
115  */
118  return nullptr;
119 }
120 
121 /**
122  * Virtual downcast method. Returns this object as a pointer of the indicated
123  * type, if it is in fact that type. Returns NULL if it is not that type.
124  */
127  return nullptr;
128 }
129 
130 /**
131  * Virtual downcast method. Returns this object as a pointer of the indicated
132  * type, if it is in fact that type. Returns NULL if it is not that type.
133  */
136  return nullptr;
137 }
138 
139 /**
140  * Virtual downcast method. Returns this object as a pointer of the indicated
141  * type, if it is in fact that type. Returns NULL if it is not that type.
142  */
145  return nullptr;
146 }
147 
148 /**
149  * Virtual downcast method. Returns this object as a pointer of the indicated
150  * type, if it is in fact that type. Returns NULL if it is not that type.
151  */
154  return nullptr;
155 }
156 
157 /**
158  * Returns the BoundsType corresponding to the indicated string.
159  */
160 BoundingVolume::BoundsType BoundingVolume::
161 string_bounds_type(const string &str) {
162  if (strcmp(str.c_str(), "default") == 0) {
163  return BT_default;
164 
165  } else if (strcmp(str.c_str(), "best") == 0) {
166  return BT_best;
167 
168  } else if (strcmp(str.c_str(), "fastest") == 0) {
169  return BT_fastest;
170 
171  } else if (strcmp(str.c_str(), "sphere") == 0) {
172  return BT_sphere;
173 
174  } else if (strcmp(str.c_str(), "box") == 0) {
175  return BT_box;
176  }
177 
178  return BT_default;
179 }
180 
181 /**
182  * Double-dispatch support: called by extend_other() when the type we're
183  * extending by is known to be a sphere.
184  */
185 bool BoundingVolume::
186 extend_by_sphere(const BoundingSphere *sphere) {
187  return extend_by_finite(sphere);
188 }
189 
190 /**
191  * Double-dispatch support: called by extend_other() when the type we're
192  * extending by is known to be a box.
193  */
194 bool BoundingVolume::
195 extend_by_box(const BoundingBox *box) {
196  return extend_by_finite(box);
197 }
198 
199 /**
200  * Double-dispatch support: called by extend_other() when the type we're
201  * extending by is known to be a hexahedron.
202  */
203 bool BoundingVolume::
204 extend_by_hexahedron(const BoundingHexahedron *hexahedron) {
205  return extend_by_finite(hexahedron);
206 }
207 
208 /**
209  * Double-dispatch support: called by extend_other() when the type we're
210  * extending by is known to be a line.
211  */
212 bool BoundingVolume::
213 extend_by_line(const BoundingLine *line) {
214  return extend_by_geometric(line);
215 }
216 
217 /**
218  * Double-dispatch support: called by extend_other() when the type we're
219  * extending by is known to be a plane.
220  */
221 bool BoundingVolume::
222 extend_by_plane(const BoundingPlane *plane) {
223  return extend_by_geometric(plane);
224 }
225 
226 /**
227  * Double-dispatch support: called by extend_other() when the type we're
228  * extending by is known to be a union.
229  */
230 bool BoundingVolume::
231 extend_by_union(const UnionBoundingVolume *unionv) {
232  return extend_by_geometric(unionv);
233 }
234 
235 /**
236  * Double-dispatch support: called by extend_other() when the type we're
237  * extending by is known to be a intersection.
238  */
239 bool BoundingVolume::
240 extend_by_intersection(const IntersectionBoundingVolume *intersection) {
241  return extend_by_geometric(intersection);
242 }
243 
244 /**
245  * Generic handler for a FiniteBoundingVolume.
246  */
247 bool BoundingVolume::
248 extend_by_finite(const FiniteBoundingVolume *volume) {
249  return extend_by_geometric(volume);
250 }
251 
252 /**
253  * Generic handler for a GeometricBoundingVolume.
254  */
255 bool BoundingVolume::
256 extend_by_geometric(const GeometricBoundingVolume *volume) {
257  mathutil_cat.warning()
258  << get_type() << "::extend_by_geometric() called with " << volume->get_type() << "\n";
259  _flags = F_infinite;
260  return false;
261 }
262 
263 /**
264  * Double-dispatch support: called by around_other() when the type of the
265  * first element in the list is known to be a nonempty sphere.
266  */
267 bool BoundingVolume::
268 around_spheres(const BoundingVolume **first, const BoundingVolume **last) {
269  return around_finite(first, last);
270 }
271 
272 /**
273  * Double-dispatch support: called by around_other() when the type of the
274  * first element in the list is known to be a nonempty box.
275  */
276 bool BoundingVolume::
277 around_boxes(const BoundingVolume **first, const BoundingVolume **last) {
278  return around_finite(first, last);
279 }
280 
281 /**
282  * Double-dispatch support: called by around_other() when the type of the
283  * first element in the list is known to be a nonempty hexahedron.
284  */
285 bool BoundingVolume::
286 around_hexahedrons(const BoundingVolume **first, const BoundingVolume **last) {
287  return around_finite(first, last);
288 }
289 
290 /**
291  * Double-dispatch support: called by around_other() when the type of the
292  * first element in the list is known to be a nonempty line.
293  */
294 bool BoundingVolume::
295 around_lines(const BoundingVolume **first, const BoundingVolume **last) {
296  return around_geometric(first, last);
297 }
298 
299 /**
300  * Double-dispatch support: called by around_other() when the type of the
301  * first element in the list is known to be a nonempty plane.
302  */
303 bool BoundingVolume::
304 around_planes(const BoundingVolume **first, const BoundingVolume **last) {
305  return around_geometric(first, last);
306 }
307 
308 /**
309  * Double-dispatch support: called by around_other() when the type of the
310  * first element in the list is known to be a union object.
311  */
312 bool BoundingVolume::
313 around_unions(const BoundingVolume **first, const BoundingVolume **last) {
314  return around_geometric(first, last);
315 }
316 
317 /**
318  * Double-dispatch support: called by around_other() when the type of the
319  * first element in the list is known to be an intersection object.
320  */
321 bool BoundingVolume::
322 around_intersections(const BoundingVolume **first, const BoundingVolume **last) {
323  return around_geometric(first, last);
324 }
325 
326 /**
327  * Generic handler for a FiniteBoundingVolume.
328  */
329 bool BoundingVolume::
330 around_finite(const BoundingVolume **first, const BoundingVolume **last) {
331  return around_geometric(first, last);
332 }
333 
334 /**
335  * Generic handler for a GeometricBoundingVolume.
336  */
337 bool BoundingVolume::
338 around_geometric(const BoundingVolume **first, const BoundingVolume **last) {
339  mathutil_cat.warning()
340  << get_type() << "::extend_by_geometric() called with " << first[0]->get_type() << "\n";
341  _flags = F_infinite;
342  return false;
343 }
344 
345 /**
346  * Double-dispatch support: called by contains_other() when the type we're
347  * testing for intersection is known to be a sphere.
348  */
349 int BoundingVolume::
350 contains_sphere(const BoundingSphere *sphere) const {
351  return contains_finite(sphere);
352 }
353 
354 /**
355  * Double-dispatch support: called by contains_other() when the type we're
356  * testing for intersection is known to be a box.
357  */
358 int BoundingVolume::
359 contains_box(const BoundingBox *box) const {
360  return contains_finite(box);
361 }
362 
363 /**
364  * Double-dispatch support: called by contains_other() when the type we're
365  * testing for intersection is known to be a hexahedron.
366  */
367 int BoundingVolume::
368 contains_hexahedron(const BoundingHexahedron *hexahedron) const {
369  return contains_finite(hexahedron);
370 }
371 
372 /**
373  * Double-dispatch support: called by contains_other() when the type we're
374  * testing for intersection is known to be a line.
375  */
376 int BoundingVolume::
377 contains_line(const BoundingLine *line) const {
378  return contains_geometric(line);
379 }
380 
381 /**
382  * Double-dispatch support: called by contains_other() when the type we're
383  * testing for intersection is known to be a plane.
384  */
385 int BoundingVolume::
386 contains_plane(const BoundingPlane *plane) const {
387  return contains_geometric(plane);
388 }
389 
390 /**
391  * Double-dispatch support: called by contains_other() when the type we're
392  * testing for intersection is known to be a union object.
393  */
394 int BoundingVolume::
395 contains_union(const UnionBoundingVolume *unionv) const {
396  return unionv->other_contains_union(this);
397 }
398 
399 /**
400  * Double-dispatch support: called by contains_other() when the type we're
401  * testing for intersection is known to be an intersection object.
402  */
403 int BoundingVolume::
404 contains_intersection(const IntersectionBoundingVolume *intersection) const {
405  return intersection->other_contains_intersection(this);
406 }
407 
408 /**
409  * Generic handler for a FiniteBoundingVolume.
410  */
411 int BoundingVolume::
412 contains_finite(const FiniteBoundingVolume *volume) const {
413  return contains_geometric(volume);
414 }
415 
416 /**
417  * Generic handler for a GeometricBoundingVolume.
418  */
419 int BoundingVolume::
420 contains_geometric(const GeometricBoundingVolume *volume) const {
421  mathutil_cat.warning()
422  << get_type() << "::contains_geometric() called with " << volume->get_type() << "\n";
423  return IF_dont_understand;
424 }
425 
426 ostream &
427 operator << (ostream &out, BoundingVolume::BoundsType type) {
428  switch (type) {
429  case BoundingVolume::BT_default:
430  return out << "default";
431 
432  case BoundingVolume::BT_best:
433  return out << "best";
434 
435  case BoundingVolume::BT_fastest:
436  return out << "fastest";
437 
438  case BoundingVolume::BT_sphere:
439  return out << "sphere";
440 
441  case BoundingVolume::BT_box:
442  return out << "box";
443  }
444 
445  mathutil_cat.error()
446  << "Invalid BoundingVolume::BoundsType value: " << (int)type << "\n";
447  nassertr(false, out);
448  return out;
449 }
450 
451 istream &
452 operator >> (istream &in, BoundingVolume::BoundsType &type) {
453  string word;
454  in >> word;
456  if (type == BoundingVolume::BT_default) {
457  mathutil_cat->error()
458  << "Invalid BoundingVolume::BoundsType string: " << word << "\n";
459  }
460  return in;
461 }
boundingPlane.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
BoundingVolume::as_bounding_sphere
virtual const BoundingSphere * as_bounding_sphere() const
Virtual downcast method.
Definition: boundingVolume.cxx:117
BoundingSphere
This defines a bounding sphere, consisting of a center and a radius.
Definition: boundingSphere.h:25
FiniteBoundingVolume
A special kind of GeometricBoundingVolume that is known to be finite.
Definition: finiteBoundingVolume.h:27
BoundingVolume::around
bool around(const BoundingVolume **first, const BoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
Definition: boundingVolume.cxx:40
boundingLine.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingBox
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition: boundingBox.h:29
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
BoundingVolume::as_geometric_bounding_volume
virtual GeometricBoundingVolume * as_geometric_bounding_volume()
Virtual downcast method.
Definition: boundingVolume.cxx:90
UnionBoundingVolume
This special bounding volume is the union of all of its constituent bounding volumes.
Definition: unionBoundingVolume.h:29
boundingHexahedron.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingVolume::string_bounds_type
static BoundsType string_bounds_type(const std::string &str)
Returns the BoundsType corresponding to the indicated string.
Definition: boundingVolume.cxx:161
GeometricBoundingVolume
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
Definition: geometricBoundingVolume.h:29
boundingSphere.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingVolume::as_bounding_plane
virtual const BoundingPlane * as_bounding_plane() const
Virtual downcast method.
Definition: boundingVolume.cxx:153
BoundingLine
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
Definition: boundingLine.h:29
config_mathutil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingVolume::as_bounding_line
virtual const BoundingLine * as_bounding_line() const
Virtual downcast method.
Definition: boundingVolume.cxx:144
BoundingVolume::as_finite_bounding_volume
virtual const FiniteBoundingVolume * as_finite_bounding_volume() const
Virtual downcast method.
Definition: boundingVolume.cxx:108
intersectionBoundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingHexahedron
This defines a bounding convex hexahedron.
Definition: boundingHexahedron.h:32
BoundingVolume::as_bounding_box
virtual const BoundingBox * as_bounding_box() const
Virtual downcast method.
Definition: boundingVolume.cxx:126
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingVolume::is_empty
bool is_empty() const
Any kind of volume might be empty.
Definition: boundingVolume.I:29
BoundingVolume
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
Definition: boundingVolume.h:41
finiteBoundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
IntersectionBoundingVolume
This special bounding volume is the intersection of all of its constituent bounding volumes.
Definition: intersectionBoundingVolume.h:29
boundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingPlane
This funny bounding volume is an infinite plane that divides space into two regions: the part behind ...
Definition: boundingPlane.h:28
unionBoundingVolume.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingVolume::as_bounding_hexahedron
virtual const BoundingHexahedron * as_bounding_hexahedron() const
Virtual downcast method.
Definition: boundingVolume.cxx:135
boundingBox.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.