28 const int BoundingBox::plane_def[6][3] = {
70 PN_stdfloat BoundingBox::
78 return (_max[0] - _min[0]) * (_max[1] - _min[1]) * (_max[2] - _min[2]);
85 get_approx_center()
const {
86 nassertr(!
is_empty(), LPoint3::zero());
88 return (_min + _max) * 0.5f;
95 xform(
const LMatrix4 &mat) {
96 nassertv(!mat.is_nan());
103 for (
int i = 1; i < 8; ++i) {
105 n.set(min(n[0], p[0]), min(n[1], p[1]), min(n[2], p[2]));
106 x.set(max(x[0], p[0]), max(x[1], p[1]), max(x[2], p[2]));
117 output(std::ostream &out)
const {
119 out <<
"bbox, empty";
121 out <<
"bbox, infinite";
123 out <<
"bbox, (" << _min <<
") to (" << _max <<
")";
141 return other->extend_by_box(
this);
151 return other->around_boxes(first, last);
159 return other->contains_box(
this);
167 extend_by_point(
const LPoint3 &point) {
168 nassertr(!point.is_nan(),
false);
176 _min.set(min(_min[0], point[0]), min(_min[1], point[1]), min(_min[2], point[2]));
177 _max.set(max(_max[0], point[0]), max(_max[1], point[1]), max(_max[2], point[2]));
197 _min.set(min(_min[0], box->_min[0]),
198 min(_min[1], box->_min[1]),
199 min(_min[2], box->_min[2]));
200 _max.set(max(_max[0], box->_max[0]),
201 max(_max[1], box->_max[1]),
202 max(_max[2], box->_max[2]));
214 LVector3 min1 = volume->get_min();
215 LVector3 max1 = volume->get_max();
223 _min.set(min(_min[0], min1[0]),
224 min(_min[1], min1[1]),
225 min(_min[2], min1[2]));
226 _max.set(max(_max[0], max1[0]),
227 max(_max[1], max1[1]),
228 max(_max[2], max1[2]));
238 around_points(
const LPoint3 *first,
const LPoint3 *last) {
239 nassertr(first != last,
false);
242 const LPoint3 *p = first;
247 while (p != last && (*p).is_nan()) {
252 mathutil_cat.warning()
253 <<
"BoundingBox around NaN\n";
264 while (p != last && (*p).is_nan()) {
278 _min.set(min(_min[0], (*p)[0]),
279 min(_min[1], (*p)[1]),
280 min(_min[2], (*p)[2]));
281 _max.set(max(_max[0], (*p)[0]),
282 max(_max[1], (*p)[1]),
283 max(_max[2], (*p)[2]));
289 if (skipped_nan != 0) {
290 mathutil_cat.warning()
291 <<
"BoundingBox ignored " << skipped_nan <<
" NaN points of " 292 << (last - first) <<
" total.\n";
307 nassertr(first != last,
false);
314 nassertr(!(*p)->is_empty() && !(*p)->is_infinite(),
false);
316 _min = vol->get_min();
317 _max = vol->get_max();
319 for (++p; p != last; ++p) {
320 nassertr(!(*p)->is_infinite(),
false);
321 if (!(*p)->is_empty()) {
323 LPoint3 min1 = vol->get_min();
324 LPoint3 max1 = vol->get_max();
325 _min.set(min(_min[0], min1[0]),
326 min(_min[1], min1[1]),
327 min(_min[2], min1[2]));
328 _max.set(max(_max[0], max1[0]),
329 max(_max[1], max1[1]),
330 max(_max[2], max1[2]));
342 contains_point(
const LPoint3 &point)
const {
343 nassertr(!point.is_nan(), IF_no_intersection);
346 return IF_no_intersection;
349 return IF_possible | IF_some | IF_all;
352 if (point[0] >= _min[0] && point[0] <= _max[0] &&
353 point[1] >= _min[1] && point[1] <= _max[1] &&
354 point[2] >= _min[2] && point[2] <= _max[2]) {
355 return IF_possible | IF_some | IF_all;
357 return IF_no_intersection;
366 contains_lineseg(
const LPoint3 &a,
const LPoint3 &b)
const {
367 nassertr(!a.is_nan() && !b.is_nan(), IF_no_intersection);
370 return contains_point(a);
373 return IF_no_intersection;
376 return IF_possible | IF_some | IF_all;
380 unsigned int a_bits = 0;
382 if (a[0] < _min[0]) {
384 }
else if (a[0] > _max[0]) {
388 if (a[1] < _min[1]) {
390 }
else if (a[1] > _max[1]) {
394 if (a[2] < _min[2]) {
396 }
else if (a[2] > _max[2]) {
400 unsigned int b_bits = 0;
402 if (b[0] < _min[0]) {
404 }
else if (b[0] > _max[0]) {
408 if (b[1] < _min[1]) {
410 }
else if (b[1] > _max[1]) {
414 if (b[2] < _min[2]) {
416 }
else if (b[2] > _max[2]) {
420 if ((a_bits & b_bits) != 0) {
423 return IF_no_intersection;
425 }
else if ((a_bits | b_bits) == 0) {
427 return IF_possible | IF_some | IF_all;
429 }
else if (a_bits == 0 || b_bits == 0) {
432 return IF_possible | IF_some;
435 unsigned int differ = (a_bits ^ b_bits);
436 if (differ == 0x03 || differ == 0x0c || differ == 0x30) {
439 return IF_possible | IF_some;
458 const LPoint3 &min1 = box->
get_minq();
459 const LPoint3 &max1 = box->
get_maxq();
461 if (min1[0] >= _min[0] && max1[0] <= _max[0] &&
462 min1[1] >= _min[1] && max1[1] <= _max[1] &&
463 min1[2] >= _min[2] && max1[2] <= _max[2]) {
465 return IF_possible | IF_some | IF_all;
467 }
else if (max1[0] >= _min[0] && min1[0] <= _max[0] &&
468 max1[1] >= _min[1] && min1[1] <= _max[1] &&
469 max1[2] >= _min[2] && min1[2] <= _max[2]) {
475 return IF_no_intersection;
487 int result = contains_finite(hexahedron);
488 if (result == IF_no_intersection || ((result & IF_all) != 0)) {
494 return hexahedron->contains_box(
this) & ~IF_all;
503 return line->contains_box(
this) & ~IF_all;
512 return plane->contains_box(
this) & ~IF_all;
523 LPoint3 min1 = volume->get_min();
524 LPoint3 max1 = volume->get_max();
526 if (min1[0] >= _min[0] && max1[0] <= _max[0] &&
527 min1[1] >= _min[1] && max1[1] <= _max[1] &&
528 min1[2] >= _min[2] && max1[2] <= _max[2]) {
530 return IF_possible | IF_some | IF_all;
532 }
else if (max1[0] >= _min[0] && min1[0] <= _max[0] &&
533 max1[1] >= _min[1] && min1[1] <= _max[1] &&
534 max1[2] >= _min[2] && min1[2] <= _max[2]) {
540 return IF_no_intersection;
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
get_point
Returns the nth vertex of the rectangular solid.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_empty() const
Any kind of volume might be empty.
virtual const BoundingBox * as_bounding_box() const
Virtual downcast method.
bool is_infinite() const
The other side of the empty coin is an infinite volume.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This funny bounding volume is an infinite plane that divides space into two regions: the part behind ...
This is an abstract class for any volume in any sense which can be said to define the locality of ref...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
const LPoint3 & get_maxq() const
An inline accessor for the maximum value.
A special kind of GeometricBoundingVolume that is known to be finite.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BoundingBox()
Constructs an empty box object.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
This defines a bounding convex hexahedron.
This funny bounding volume is an infinite line with no thickness and extending to infinity in both di...
const LPoint3 & get_minq() const
An inline accessor for the minimum value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.