Panda3D
Loading...
Searching...
No Matches
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"
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
27using std::istream;
28using std::ostream;
29using std::string;
30
31TypeHandle 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 */
40around(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 */
80void BoundingVolume::
81write(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 */
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 */
117as_bounding_sphere() const {
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 */
126as_bounding_box() const {
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 */
144as_bounding_line() const {
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 */
153as_bounding_plane() const {
154 return nullptr;
155}
156
157/**
158 * Returns the BoundsType corresponding to the indicated string.
159 */
160BoundingVolume::BoundsType BoundingVolume::
161string_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 */
185bool BoundingVolume::
186extend_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 */
194bool BoundingVolume::
195extend_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 */
203bool BoundingVolume::
204extend_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 */
212bool BoundingVolume::
213extend_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 */
221bool BoundingVolume::
222extend_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 */
230bool BoundingVolume::
231extend_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 */
239bool BoundingVolume::
240extend_by_intersection(const IntersectionBoundingVolume *intersection) {
241 return extend_by_geometric(intersection);
242}
243
244/**
245 * Generic handler for a FiniteBoundingVolume.
246 */
247bool BoundingVolume::
248extend_by_finite(const FiniteBoundingVolume *volume) {
249 return extend_by_geometric(volume);
250}
251
252/**
253 * Generic handler for a GeometricBoundingVolume.
254 */
255bool BoundingVolume::
256extend_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 */
267bool BoundingVolume::
268around_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 */
276bool BoundingVolume::
277around_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 */
285bool BoundingVolume::
286around_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 */
294bool BoundingVolume::
295around_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 */
303bool BoundingVolume::
304around_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 */
312bool BoundingVolume::
313around_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 */
321bool BoundingVolume::
322around_intersections(const BoundingVolume **first, const BoundingVolume **last) {
323 return around_geometric(first, last);
324}
325
326/**
327 * Generic handler for a FiniteBoundingVolume.
328 */
329bool BoundingVolume::
330around_finite(const BoundingVolume **first, const BoundingVolume **last) {
331 return around_geometric(first, last);
332}
333
334/**
335 * Generic handler for a GeometricBoundingVolume.
336 */
337bool BoundingVolume::
338around_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 */
349int BoundingVolume::
350contains_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 */
358int BoundingVolume::
359contains_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 */
367int BoundingVolume::
368contains_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 */
376int BoundingVolume::
377contains_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 */
385int BoundingVolume::
386contains_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 */
394int BoundingVolume::
395contains_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 */
403int BoundingVolume::
404contains_intersection(const IntersectionBoundingVolume *intersection) const {
405 return intersection->other_contains_intersection(this);
406}
407
408/**
409 * Generic handler for a FiniteBoundingVolume.
410 */
411int BoundingVolume::
412contains_finite(const FiniteBoundingVolume *volume) const {
413 return contains_geometric(volume);
414}
415
416/**
417 * Generic handler for a GeometricBoundingVolume.
418 */
419int BoundingVolume::
420contains_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
426ostream &
427operator << (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
451istream &
452operator >> (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}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition boundingBox.h:29
This defines a bounding convex hexahedron.
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
This funny bounding volume is an infinite plane that divides space into two regions: the part behind ...
This defines a bounding sphere, consisting of a center and a radius.
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
virtual const BoundingPlane * as_bounding_plane() const
Virtual downcast method.
static BoundsType string_bounds_type(const std::string &str)
Returns the BoundsType corresponding to the indicated string.
bool is_empty() const
Any kind of volume might be empty.
virtual const BoundingSphere * as_bounding_sphere() const
Virtual downcast method.
virtual const BoundingBox * as_bounding_box() const
Virtual downcast method.
virtual GeometricBoundingVolume * as_geometric_bounding_volume()
Virtual downcast method.
virtual const FiniteBoundingVolume * as_finite_bounding_volume() const
Virtual downcast method.
virtual const BoundingHexahedron * as_bounding_hexahedron() const
Virtual downcast method.
virtual const BoundingLine * as_bounding_line() const
Virtual downcast method.
bool around(const BoundingVolume **first, const BoundingVolume **last)
Resets the volume to enclose only the volumes indicated.
A special kind of GeometricBoundingVolume that is known to be finite.
This is another abstract class, for a general class of bounding volumes that actually enclose points ...
This special bounding volume is the intersection of all of its constituent bounding volumes.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This special bounding volume is the union of all of its constituent bounding volumes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition indent.cxx:20
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.