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;