HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_BoundingBox.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __UT_BoundingBox_h__
9 #define __UT_BoundingBox_h__
10 
11 #include "UT_API.h"
12 #include "UT_Assert.h"
13 #include "UT_Vector3.h"
14 #include "UT_Vector4.h"
15 #include <SYS/SYS_Inline.h>
16 #include <SYS/SYS_Math.h>
17 #include <SYS/SYS_Types.h>
18 #include <iosfwd>
19 #include <limits>
20 #include <stdio.h>
21 
22 class UT_JSONParser;
23 class UT_JSONValue;
24 class UT_JSONWriter;
25 
26 /// Axis-aligned bounding box (AABB).
27 template <typename T>
28 class UT_BoundingBoxT
29 {
30 public:
32 
34  // Default copy constructor is fine.
35  // UT_BoundingBoxT(const UT_BoundingBoxT &);
36  UT_BoundingBoxT(T axmin, T aymin, T azmin,
37  T axmax, T aymax, T azmax)
38  {
39  setBounds(axmin, aymin, azmin, axmax, aymax, azmax);
40  }
41 
42  UT_BoundingBoxT(const UT_Vector3T<T> &lowerbound,
43  const UT_Vector3T<T> &upperbound)
44  {
45  vals[0][0] = lowerbound[0];
46  vals[0][1] = upperbound[0];
47  vals[1][0] = lowerbound[1];
48  vals[1][1] = upperbound[1];
49  vals[2][0] = lowerbound[2];
50  vals[2][1] = upperbound[2];
51  }
52 
53  template <typename S>
55  {
56  vals[0][0] = bbox.vals[0][0];
57  vals[0][1] = bbox.vals[0][1];
58  vals[1][0] = bbox.vals[1][0];
59  vals[1][1] = bbox.vals[1][1];
60  vals[2][0] = bbox.vals[2][0];
61  vals[2][1] = bbox.vals[2][1];
62  }
63 
64  template <typename S>
66  {
67  vals[0][0] = bbox.vals[0][0];
68  vals[0][1] = bbox.vals[0][1];
69  vals[1][0] = bbox.vals[1][0];
70  vals[1][1] = bbox.vals[1][1];
71  vals[2][0] = bbox.vals[2][0];
72  vals[2][1] = bbox.vals[2][1];
73  return *this;
74  }
75 
76  T operator()(unsigned m, unsigned n) const
77  {
78  UT_ASSERT_P( m < 3 && n < 2 );
79  return vals[m][n];
80  }
81  T &operator()(unsigned m, unsigned n)
82  {
83  UT_ASSERT_P( m < 3 && n < 2 );
84  return vals[m][n];
85  }
86  bool operator==(const UT_BoundingBoxT<T> &bbox) const
87  {
88  return vals[0][0] == bbox.vals[0][0] &&
89  vals[0][1] == bbox.vals[0][1] &&
90  vals[1][0] == bbox.vals[1][0] &&
91  vals[1][1] == bbox.vals[1][1] &&
92  vals[2][0] == bbox.vals[2][0] &&
93  vals[2][1] == bbox.vals[2][1];
94  }
95  bool operator!=(const UT_BoundingBoxT<T> &bbox) const
96  {
97  return !(*this == bbox);
98  }
99 
100  bool isEqual(const UT_BoundingBoxT<T> &bbox,
101  T tol = SYS_FTOLERANCE_R) const
102  {
103  return SYSisEqual(vals[0][0], bbox.vals[0][0], tol) &&
104  SYSisEqual(vals[0][1], bbox.vals[0][1], tol) &&
105  SYSisEqual(vals[1][0], bbox.vals[1][0], tol) &&
106  SYSisEqual(vals[1][1], bbox.vals[1][1], tol) &&
107  SYSisEqual(vals[2][0], bbox.vals[2][0], tol) &&
108  SYSisEqual(vals[2][1], bbox.vals[2][1], tol);
109  }
110 
111  T xmin() const { return vals[0][0]; }
112  T xmax() const { return vals[0][1]; }
113  T ymin() const { return vals[1][0]; }
114  T ymax() const { return vals[1][1]; }
115  T zmin() const { return vals[2][0]; }
116  T zmax() const { return vals[2][1]; }
117 
119  { return UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][0]); }
121  { return UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][1]); }
122 
123  int isInside(const UT_Vector3T<T> &pt) const;
124  int isInside(const UT_Vector4T<T> &pt) const;
125  int isInside(T x, T y, T z) const;
126 
127  /// Am I totally enclosed in the bounding box passed in
128  /// ("intersects" method tests for partially inside)
129  int isInside(const UT_BoundingBoxT<T> &bbox) const;
130 
131  /// Determine whether a line intersects the box. v0 is one end-point of
132  /// the line, and idir is the inverse direction vector along the line.
133  int isLineInside(const UT_Vector3T<T> &v0,
134  const UT_Vector3T<T> &idir) const;
135 
136  /// Determine the minimum distance of the box to a line segment, or 0
137  /// if the line segment overlaps the box. v0 is one end-point of the
138  /// line, and dir is the direction vector along the line. This method
139  /// conservatively underestimates the distance, so the true line/box
140  /// distance may be greater than the reported value.
142  const UT_Vector3T<T> &dir) const;
143 
144  /// Check whether the bounding box contains at least one point.
146  bool isValid() const;
148  void makeInvalid() { initBounds(); }
149 
150  /// Efficient test for an invalid bounding box (one comparison instead of
151  /// 3 for a valid bounding box). This only checks X, not Y or Z ranges, so
152  /// only works if the box is fully invalid.
154  bool isInvalidFast() const { return vals[0][0] > vals[0][1]; }
155 
156  void setBounds(T x_min, T y_min, T z_min,
157  T x_max, T y_max, T z_max)
158  {
159  vals[0][0] = x_min;
160  vals[1][0] = y_min;
161  vals[2][0] = z_min;
162  vals[0][1] = x_max;
163  vals[1][1] = y_max;
164  vals[2][1] = z_max;
165  }
166 
168  bool hasVolume() const
169  {
170  return vals[0][1] > vals[0][0] &&
171  vals[1][1] > vals[1][0] &&
172  vals[2][1] > vals[2][0];
173  }
174 
175  /// @{
176  /// Set/Get bounds in "serialized" fashion. The serialized order is
177  /// (xmin, xmax, ymin, ymax, zmin, zmax).
178  void setSerialized(const fpreal32 floats[6])
179  {
180  for (int i = 0; i < 6; ++i)
181  myFloats[i] = floats[i];
182  }
183  void setSerialized(const fpreal64 floats[6])
184  {
185  for (int i = 0; i < 6; ++i)
186  myFloats[i] = floats[i];
187  }
188  const T *getSerialized() const { return myFloats; }
189  /// @}
190 
191  /// @{
192  /// Access to the serialized data
193  const T *data() const { return myFloats; }
194  T *data() { return myFloats; }
195  /// @}
196 
197  /// @{
198  /// Iterate over the data serially
199  const T *begin() const { return &myFloats[0]; }
200  const T *end() const { return &myFloats[6]; }
201  T *begin() { return &myFloats[0]; }
202  T *end() { return &myFloats[6]; }
203  /// @}
204 
205  /// @{
206  /// Compute a hash
207  uint64 hash() const;
208  friend std::size_t hash_value(const this_type &t) { return t.hash(); }
209  /// @}
210 
211  /// Initialize the box to the largest size
212  void initMaxBounds();
213 
214  /// Initialize the box such that
215  /// - No points are contained in the box
216  /// - The box occupies no position in space
218  void initBounds();
219 
220  /// Initialize the bounds with the bounds given in min and max. No check
221  /// is made to ensure that min is smaller than max.
222  void initBounds(const UT_Vector3T<T> &min,
223  const UT_Vector3T<T> &max);
224 
225  /// Initialize zero-sized bounds at the location of the point given by pt.
227  void initBounds(const UT_Vector3T<T> &pt);
228 
229  /// Initialize zero-sized bounds at the location of the point given by pt.
230  void initBounds(const UT_Vector4T<T> &pt);
231 
232  /// Initialize zero-sized bounds at the location of the point defined by
233  /// x, y, and z;
235  void initBounds(T x, T y, T z);
236 
237  /// Initialize zero-sized bounds at the location of the point given by v.
238  void initBounds(const fpreal32 *v)
239  { initBounds(v[0], v[1], v[2]); }
240 
241  /// Initialize zero-sized bounds at the location of the point given by v.
242  void initBounds(const fpreal64 *v)
243  { initBounds(v[0], v[1], v[2]); }
244 
245  /// Initialize the bounds to the same as given by box.
246  void initBounds(const UT_BoundingBoxT<T> &box);
247 
248  /// Enlarge the existing bounds to encompass the bounds given by min and
249  /// max.
250  void enlargeBounds(const UT_Vector3T<T> &min,
251  const UT_Vector3T<T> &max);
252 
253  /// Enlarge the existing bounds to encompass the point given by pt.
255  void enlargeBounds(const UT_Vector3T<T> &pt);
256 
257  /// Enlarge the existing bounds to encompass the point given by pt.
258  void enlargeBounds(const UT_Vector4T<T> &pt);
259 
260  /// Enlarge the existing bounds to encompass the point defined by
261  /// x, y, and z.
263  void enlargeBounds(T x, T y, T z);
264 
265  /// Enlarge the existing bounds to encompass the point given in v.
266  void enlargeBounds(const fpreal32 *v)
267  { enlargeBounds(v[0], v[1], v[2]); }
268 
269  /// Enlarge the existing bounds to encompass the point given in v.
270  void enlargeBounds(const fpreal64 *v)
271  { enlargeBounds(v[0], v[1], v[2]); }
272 
273  /// Enlarge the existing bounds to encompass the bounds given by box.
275  void enlargeBounds(const UT_BoundingBoxT<T> &box);
276 
277  /// Expand the bounding box on all axes, as a relative fraction of the
278  /// current bbox dimensions, and/or using an absolute offset.
280  void expandBounds(T relative, T absolute);
281 
282  /// Expand the bounding box on all sides using separate absolute offsets
283  /// for each axis.
285  void expandBounds(T dltx, T dlty, T dlyz);
286 
287  /// Perform a minimal enlargement of the floating point values in this
288  /// bounding box. This enlargement guarantees that the new floating
289  /// point values are always different from the prior ones. The number
290  /// of mantissa bits to be changed can be adjusted using the bits
291  /// parameter, and a minimum enlargement amount can be specified in min.
292  void enlargeFloats(int bits = 1, T min = 1e-5);
293 
294  /// Find the intersections of two bounding boxes
295  void clipBounds(const UT_BoundingBoxT<T> &box);
296 
297  /// Splits a box into two disjoint subboxes at the given splitting
298  /// point. This box is set to the left subbox for splitLeft() and the
299  /// right subbox for splitRight().
301  {
302  box = *this;
303  box.vals[axis][0] = split;
304  vals[axis][1] = split;
305  }
307  {
308  box = *this;
309  box.vals[axis][1] = split;
310  vals[axis][0] = split;
311  }
312 
313  template <typename MATRIX>
314  void transform(const MATRIX &mat);
315  template <typename MATRIX>
316  void transform(const MATRIX &mat,
317  UT_BoundingBoxT<T> &newbbox) const;
318 
319  /// Adds the given translate to each component of the bounding box.
320  void translate(const UT_Vector3T<T> &delta);
321 
322  T xsize() const { return sizeX(); }
323  T ysize() const { return sizeY(); }
324  T zsize() const { return sizeZ(); }
325  T sizeX() const { return vals[0][1] - vals[0][0]; }
326  T sizeY() const { return vals[1][1] - vals[1][0]; }
327  T sizeZ() const { return vals[2][1] - vals[2][0]; }
328 
330  { return UT_Vector3T<T>(vals[0][1] - vals[0][0],
331  vals[1][1] - vals[1][0],
332  vals[2][1] - vals[2][0]); }
333  T sizeAxis(int axis) const
334  {
335  UT_ASSERT(axis >= 0 && axis < 3);
336  return vals[axis][1] - vals[axis][0];
337  }
338 
339  /// Return the size of the largest dimension
340  T sizeMax() const;
341  /// Return the size of the largest dimension, and store the dimension
342  /// index in "axis"
343  T sizeMax(int &axis) const;
344  /// Returns the minimum delta vector from the point to the bounding
345  /// box or between two bounding boxes.
348  /// Returns the maximum delta vector from the bounding box to the point.
350  /// Returns minimum distance from point to bounding box squared.
351  /// Returns 0 if point in bouding box.
352  T minDist2(const UT_Vector3T<T> &p) const
353  { return minDistDelta(p).length2(); }
354  /// Minimum disance between two bboxes squared.
356  { return minDistDelta(box).length2(); }
357  /// Returns maximum distance between point and bounding box squared.
358  T maxDist2(const UT_Vector3T<T> &p) const
359  { return maxDistDelta(p).length2(); }
360 
361  /// Returns the smallest absolute translation from this to box that
362  /// produces the maximum overlap between the two boxes.
364 
365  /// Returns the radius of a sphere that would fully enclose the box.
366  T getRadius() const { return 0.5*size().length(); }
367 
368  /// Finds the out code of the point relative to this box:
369  int getOutCode(const UT_Vector3T<T> &pt) const;
370 
371  T xcenter() const { return centerX(); }
372  T ycenter() const { return centerY(); }
373  T zcenter() const { return centerZ(); }
374  T centerX() const { return (vals[0][0] + vals[0][1])*0.5; }
375  T centerY() const { return (vals[1][0] + vals[1][1])*0.5; }
376  T centerZ() const { return (vals[2][0] + vals[2][1])*0.5; }
377  T centerAxis(int axis) const
378  { return (vals[axis][0] + vals[axis][1])*0.5; }
380  { return UT_Vector3T<T>((vals[0][0] + vals[0][1])*0.5,
381  (vals[1][0] + vals[1][1])*0.5,
382  (vals[2][0] + vals[2][1])*0.5); }
383 
384  T area() const;
385  T volume() const { return xsize()*ysize()*zsize(); }
386  void addToMin(const UT_Vector3T<T> &vec);
387  void addToMax(const UT_Vector3T<T> &vec);
388 
389  /// Scale then offset a bounding box.
390  void scaleOffset(const UT_Vector3T<T> &scale,
391  const UT_Vector3T<T> &offset);
392  int maxAxis() const;
393  int minAxis() const;
394 
395  /// Intersect a ray with the box. Returns 0 if no intersection found.
396  /// distance will be set to the intersection distance (between 0 & tmax)
397  /// The normal will also be set. The direction of the normal is
398  /// indeterminant (to fix it, you might want to dot(dir, *nml) to check
399  /// the orientation.
400  int intersectRay(const UT_Vector3T<T> &org,
401  const UT_Vector3T<T> &dir,
402  T tmax=1E17F,
403  T *distance=0, UT_Vector3T<T> *nml=0) const;
404  int intersectRange(const UT_Vector3T<T> &org,
405  const UT_Vector3T<T> &dir,
406  T &min, T &max) const;
407 
408  /// This determines if the tube, capped at distances tmin & tmax,
409  /// intersects this.
410  int intersectTube(const UT_Vector3T<T> &org,
411  const UT_Vector3T<T> &dir,
412  T radius,
413  T tmin=-1E17f, T tmax=1E17f) const;
414 
415  int intersects(const UT_BoundingBoxT<T> &box) const;
416 
417  /// Changes the bounds to be those of the intersection of this box
418  /// and the supplied BBox. Returns 1 if intersects, 0 otherwise.
420 
421  /// Here's the data for the bounding box
422  union {
423  T vals[3][2];
425  };
426 
427  void getBBoxPoints(UT_Vector3T<T> (&ptarray)[8]) const;
428  void getBBoxPoints(UT_Vector4T<T> (&ptarray)[8]) const;
429  template <typename MATRIX>
430  int getBBoxPoints(UT_Vector3T<T> (&ptarray)[8],
431  const MATRIX &transform_matrix) const;
432 
433  /// Dump the bounding box to stderr. The msg is printed before the bounds
434  UT_API void dump(const char *msg=0) const;
435  /// Dump the bounding box geometry to a draw file
436  UT_API void dumpGeo(FILE *fp) const;
437 
438  /// @{
439  /// Methods to serialize to a JSON stream. The vector is stored as an
440  /// array of 6 reals (xmin, xmax, ymin, ymax, zmin, zmax)
441  UT_API bool save(UT_JSONWriter &w) const;
442  UT_API bool save(UT_JSONValue &v) const;
443  UT_API bool load(UT_JSONParser &p);
444  /// @}
445 
446 
447 protected:
448  friend
449  std::ostream &operator<<(std::ostream &os, const UT_BoundingBoxT<T> &box)
450  {
451  box.outTo(os);
452  return os;
453  }
454 
455  UT_API void outTo(std::ostream &os) const;
456  // Ugly helper function to allow instantation with int64.
457  static bool SYSisEqual(int64 a, int64 b, int64) { return a==b; }
458 
459 private:
460 
461  static T computeDelta(T bmin, T bmax, T val);
462  static T computeDelta(T amin, T amax, T bmin, T bmax);
463 
464  template <typename Y> static Y getMinMantissa(Y val, int bits);
465 
466  static T computeMaxDelta(T bmin, T bmax, T val);
467 
468  static T computeOverlapDelta(T amin, T amax, T bmin, T bmax);
469 
470 };
471 
477 
478 template <typename T>
479 UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingBoxT<T> &v);
480 
481 
482 //////////////////////////////////////////////////////////////////////////////
483 //
484 // Inline Implementations
485 //
486 
487 template <typename T>
488 inline bool
490 {
491  return vals[0][0] <= vals[0][1] &&
492  vals[1][0] <= vals[1][1] &&
493  vals[2][0] <= vals[2][1];
494 }
495 
496 template <typename T>
497 inline void
499 {
500  // Initialize with min and max reversed, so that it's empty
501  const T maxv = 0.5*std::numeric_limits<T>::max();
502  const T minv = -maxv;
503  vals[0][0] = maxv;
504  vals[0][1] = minv;
505  vals[1][0] = maxv;
506  vals[1][1] = minv;
507  vals[2][0] = maxv;
508  vals[2][1] = minv;
509 }
510 
511 template <typename T>
512 inline void
514 {
515  vals[0][0] = pt.x();
516  vals[0][1] = pt.x();
517  vals[1][0] = pt.y();
518  vals[1][1] = pt.y();
519  vals[2][0] = pt.z();
520  vals[2][1] = pt.z();
521 }
522 
523 template <typename T>
524 inline void
526 {
527  vals[0][0] = x;
528  vals[0][1] = x;
529  vals[1][0] = y;
530  vals[1][1] = y;
531  vals[2][0] = z;
532  vals[2][1] = z;
533 }
534 
535 template <typename T>
536 inline void
538 {
539  vals[0][0] = SYSmin(vals[0][0], pt.x());
540  vals[0][1] = SYSmax(vals[0][1], pt.x());
541  vals[1][0] = SYSmin(vals[1][0], pt.y());
542  vals[1][1] = SYSmax(vals[1][1], pt.y());
543  vals[2][0] = SYSmin(vals[2][0], pt.z());
544  vals[2][1] = SYSmax(vals[2][1], pt.z());
545 }
546 
547 template <typename T>
548 inline void
550 {
551  vals[0][0] = SYSmin(vals[0][0], x);
552  vals[0][1] = SYSmax(vals[0][1], x);
553  vals[1][0] = SYSmin(vals[1][0], y);
554  vals[1][1] = SYSmax(vals[1][1], y);
555  vals[2][0] = SYSmin(vals[2][0], z);
556  vals[2][1] = SYSmax(vals[2][1], z);
557 }
558 
559 template <typename T>
560 inline void
562 {
563  vals[0][0] = SYSmin(vals[0][0], box(0, 0));
564  vals[0][1] = SYSmax(vals[0][1], box(0, 1));
565  vals[1][0] = SYSmin(vals[1][0], box(1, 0));
566  vals[1][1] = SYSmax(vals[1][1], box(1, 1));
567  vals[2][0] = SYSmin(vals[2][0], box(2, 0));
568  vals[2][1] = SYSmax(vals[2][1], box(2, 1));
569 }
570 
571 template <typename T>
572 inline void
573 UT_BoundingBoxT<T>::expandBounds(T relative, T absolute)
574 {
575  T d;
576 
577  // Don't factor out percent for improved numerical stability when
578  // dealing with large boxes.
579  d = absolute + vals[0][1]*relative - vals[0][0]*relative;
580  vals[0][0] -= d; vals[0][1] += d;
581  d = absolute + vals[1][1]*relative - vals[1][0]*relative;
582  vals[1][0] -= d; vals[1][1] += d;
583  d = absolute + vals[2][1]*relative - vals[2][0]*relative;
584  vals[2][0] -= d; vals[2][1] += d;
585 }
586 
587 template <typename T>
588 inline void
589 UT_BoundingBoxT<T>::expandBounds(T dltx, T dlty, T dltz)
590 {
591  vals[0][0] -= dltx; vals[0][1] += dltx;
592  vals[1][0] -= dlty; vals[1][1] += dlty;
593  vals[2][0] -= dltz; vals[2][1] += dltz;
594 }
595 
596 template <typename T>
597 inline int
599 {
600  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
601  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
602  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
603  return 1;
604 }
605 
606 template <typename T>
607 inline int
609 {
610  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
611  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
612  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
613  return 1;
614 }
615 
616 template <typename T>
617 inline int
619 {
620  if (vals[0][0] > x || vals[0][1] < x) return 0;
621  if (vals[1][0] > y || vals[1][1] < y) return 0;
622  if (vals[2][0] > z || vals[2][1] < z) return 0;
623  return 1;
624 }
625 
626 template <typename T>
627 inline int
629 {
630  if (vals[0][0] < box.vals[0][0] || vals[0][1] > box.vals[0][1]) return 0;
631  if (vals[1][0] < box.vals[1][0] || vals[1][1] > box.vals[1][1]) return 0;
632  if (vals[2][0] < box.vals[2][0] || vals[2][1] > box.vals[2][1]) return 0;
633  return 1;
634 }
635 
636 template <typename T>
637 inline int
639 {
640  if (vals[0][0] > box.vals[0][1] || vals[0][1] < box.vals[0][0]) return 0;
641  if (vals[1][0] > box.vals[1][1] || vals[1][1] < box.vals[1][0]) return 0;
642  if (vals[2][0] > box.vals[2][1] || vals[2][1] < box.vals[2][0]) return 0;
643  return 1;
644 }
645 
646 template <typename T>
647 inline int
649 {
650  if (!intersects(box))
651  return 0;
652 
653  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
654  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
655  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
656  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
657  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
658  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
659  return 1;
660 }
661 
662 #define UT_TESTMAX tmax = t1 < tmax ? t1 : tmax;
663 #define UT_TESTMIN tmin = t1 > tmin ? t1 : tmin;
664 
665 #define UT_FASTBOX(idx) \
666  positive = (idir(idx) > 0.0); \
667  t1 = (vals[idx][ positive] - v0(idx))*idir(idx); UT_TESTMAX \
668  t1 = (vals[idx][!positive] - v0(idx))*idir(idx); UT_TESTMIN \
669  /**/
670 
671 template <typename T>
672 inline int
674  const UT_Vector3T<T> &v0, const UT_Vector3T<T> &idir) const
675 {
676  T tmin, tmax;
677  int positive;
678  T t1;
679 
680  tmin = 0;
681  tmax = 1;
682 
683  UT_FASTBOX(0)
684  UT_FASTBOX(1)
685  UT_FASTBOX(2)
686 
687  return tmin <= tmax;
688 }
689 
690 #undef UT_FASTBOX
691 #undef UT_TESTMIN
692 #undef UT_TESTMAX
693 
694 template <typename T>
695 inline T
697  const UT_Vector3T<T> &v0,
698  const UT_Vector3T<T> &dir) const
699 {
700  T dist;
701 
702  // Approximate the box with a sphere, then find the distance from the
703  // line to the sphere.
704  dist = segmentPointDist2(center(), v0, v0+dir);
705  dist = SYSmax(SYSsqrt(dist) - getRadius(), 0.0);
706  return dist*dist;
707 }
708 
709 template <typename T>
710 inline void
712 {
713  vals[0][0] = vals[1][0] = vals[2][0] = -0.5*std::numeric_limits<T>::max();
714  vals[0][1] = vals[1][1] = vals[2][1] = 0.5*std::numeric_limits<T>::max();
715 }
716 
717 template <typename T>
718 inline void
720  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
721 {
722  vals[0][0] = min.x(); vals[0][1] = max.x();
723  vals[1][0] = min.y(); vals[1][1] = max.y();
724  vals[2][0] = min.z(); vals[2][1] = max.z();
725 }
726 
727 template <typename T>
728 inline void
730 {
731  vals[0][0] = vals[0][1] = pt.x();
732  vals[1][0] = vals[1][1] = pt.y();
733  vals[2][0] = vals[2][1] = pt.z();
734 }
735 
736 template <typename T>
737 inline void
739 {
740  vals[0][0] = box(0, 0);
741  vals[0][1] = box(0, 1);
742  vals[1][0] = box(1, 0);
743  vals[1][1] = box(1, 1);
744  vals[2][0] = box(2, 0);
745  vals[2][1] = box(2, 1);
746 }
747 
748 template <typename T>
749 inline void
751  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
752 {
753  vals[0][0] = SYSmin(vals[0][0], min.x());
754  vals[0][1] = SYSmax(vals[0][1], max.x());
755  vals[1][0] = SYSmin(vals[1][0], min.y());
756  vals[1][1] = SYSmax(vals[1][1], max.y());
757  vals[2][0] = SYSmin(vals[2][0], min.z());
758  vals[2][1] = SYSmax(vals[2][1], max.z());
759 }
760 
761 template <typename T>
762 inline void
764 {
765  vals[0][0] = SYSmin(vals[0][0], pt.x());
766  vals[0][1] = SYSmax(vals[0][1], pt.x());
767  vals[1][0] = SYSmin(vals[1][0], pt.y());
768  vals[1][1] = SYSmax(vals[1][1], pt.y());
769  vals[2][0] = SYSmin(vals[2][0], pt.z());
770  vals[2][1] = SYSmax(vals[2][1], pt.z());
771 }
772 
773 // Extract the exponent of val and create a floating point value that is
774 // the minimum mantissa value for that exponent. If bits is larger than 0,
775 // we'll use that mantissa bit.
776 template <typename T>
777 template <typename Y>
778 inline Y
780 {
781  typedef SYS_FPRealUnionT<Y> FPRealUnion;
782  typedef typename FPRealUnion::uint_type UInt;
783 
784  static const int exponent_bits = FPRealUnion::EXPONENT_BITS;
785  static const int mantissa_bits = FPRealUnion::MANTISSA_BITS;
786  FPRealUnion tmp;
787 
788  tmp.fval = val;
789  tmp.uval >>= mantissa_bits;
790  tmp.uval &= ((UInt(1) << exponent_bits) - UInt(1)); // extract exponent
791  tmp.uval -= mantissa_bits - bits;
792  tmp.uval <<= mantissa_bits;
793  return tmp.fval;
794 }
795 
796 template <typename T>
797 inline void
799 {
800  T val;
801  int i;
802 
803  UT_ASSERT(bits >= 0 && bits < 128);
804  for (i = 0; i < 3; i++)
805  {
806  val = SYSmax(getMinMantissa(vals[i][0], bits),
807  getMinMantissa(vals[i][1], bits), min);
808 
809  UT_ASSERT(val > 0);
810  vals[i][0] -= val;
811  vals[i][1] += val;
812  }
813 }
814 
815 template <>
816 inline void
818 {
819  UT_ASSERT(!"enlargeFloats is no-op for int64");
820 }
821 
822 
823 template <typename T>
824 inline void
826 {
827  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
828  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
829  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
830  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
831  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
832  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
833 }
834 
835 template <typename T>
836 template <typename MATRIX>
837 inline void
839 {
840  UT_BoundingBoxT<T> newbox;
841  transform(mat, newbox);
842  *this = newbox;
843 }
844 
845 template <typename T>
846 template <typename MATRIX>
847 inline void
849  const MATRIX &mat, UT_BoundingBoxT<T> &newbox) const
850 {
851  newbox.initBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][0]) * mat);
852  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][1]) * mat);
853  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][0]) * mat);
854  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][1]) * mat);
855  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][0]) * mat);
856  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][1]) * mat);
857  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][0]) * mat);
858  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][1]) * mat);
859 }
860 
861 template <typename T>
862 inline void
864 {
865  vals[0][0] += delta.x();
866  vals[0][1] += delta.x();
867  vals[1][0] += delta.y();
868  vals[1][1] += delta.y();
869  vals[2][0] += delta.z();
870  vals[2][1] += delta.z();
871 }
872 
873 #define UT_TESTMAX(face) if (t < tmax) { \
874  if (t < tmin) return 0; \
875  tmax = t; \
876  foundmax = face; \
877  }
878 #define UT_TESTMIN(face) if (t > tmin) { \
879  if (t > tmax) return 0; \
880  tmin = t; \
881  foundmin = face; \
882  }
883 #define UT_FASTBOX(face) \
884  ray = 1.0 / d(face); \
885  positive = (ray > 0.0); \
886  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX(face) \
887  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN(face) \
888  /**/
889 
890 template <typename T>
891 int
893  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
894  T maxdist, T *distance, UT_Vector3T<T> *nml) const
895 {
896  T t, tmin, tmax;
897  T ray;
898  int positive, foundmin, foundmax;
899 
900  foundmin = -1;
901  foundmax = -1;
902  tmin = 0;
903  tmax = maxdist;
904 
905  UT_FASTBOX(0)
906  UT_FASTBOX(1)
907  UT_FASTBOX(2)
908 
909  if (foundmin != -1)
910  {
911  // We intersect the minimum.
912  if(nml)
913  {
914  if(foundmin == 0) nml->assign(1.0, 0.0, 0.0);
915  else if(foundmin == 1) nml->assign(0.0, 1.0, 0.0);
916  else nml->assign(0.0, 0.0, 1.0);
917  }
918 
919  if(distance) *distance = tmin;
920  return 1;
921  }
922  else if (foundmax != -1)
923  {
924  // We did not intersect any minimum planes, therefore are
925  // inside provided we intersected a maximum plane and weren't
926  // trivially rejected.
927  if(nml)
928  {
929  if(foundmax == 0) nml->assign(1.0, 0.0, 0.0);
930  else if(foundmax == 1) nml->assign(0.0, 1.0, 0.0);
931  else nml->assign(0.0, 0.0, 1.0);
932  }
933 
934  if(distance) *distance = tmax;
935  return 1;
936  }
937  return 0;
938 }
939 
940 #undef UT_FASTBOX
941 #undef UT_TESTMIN
942 #undef UT_TESTMAX
943 
944 #define UT_TESTMAX if(t < tmax) { if(t < tmin) return 0; tmax = t; }
945 #define UT_TESTMIN if(t > tmin) { if(t > tmax) return 0; tmin = t; }
946 
947 #define UT_FASTBOX(face) \
948  ray = 1.0 / d(face); \
949  positive = (ray > 0.0); \
950  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX \
951  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN \
952  /**/
953 
954 template <typename T>
955 inline int
957  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
958  T &tmin, T &tmax) const
959 {
960  T t;
961  T ray;
962  int positive;
963 
964  tmin = -std::numeric_limits<T>::max();
965  tmax = +std::numeric_limits<T>::max();
966 
967  UT_FASTBOX(0)
968  UT_FASTBOX(1)
969  UT_FASTBOX(2)
970 
971  return 1;
972 }
973 
974 #undef UT_FASTBOX
975 #undef UT_TESTMIN
976 #undef UT_TESTMAX
977 
978 template <typename T>
979 inline int
981  const UT_Vector3T<T> &org, const UT_Vector3T<T> &dir,
982  T radius, T mint, T maxt) const
983 {
984  UT_BoundingBoxT<T> tmp;
985  T tmin, tmax;
986 
987  tmp = *this;
988 
989  tmp.expandBounds(radius, radius, radius);
990  if (!tmp.intersectRange(org, dir, tmin, tmax))
991  {
992  // No hit at all.
993  return 0;
994  }
995 
996  // Check if it is within our tube.
997  if (tmax < mint)
998  return 0;
999  if (tmin > maxt)
1000  return 0;
1001 
1002  return 1;
1003 }
1004 
1005 template <typename T>
1006 inline T
1008 {
1009  T t = vals[0][1] - vals[0][0];
1010  T d = vals[1][1] - vals[1][0];
1011 
1012  if (t < d) t = d;
1013  d = vals[2][1] - vals[2][0];
1014  if (t < d) t = d;
1015  return t;
1016 }
1017 
1018 template <typename T>
1019 inline T
1021 {
1022  T t = vals[0][1] - vals[0][0];
1023  T d = vals[1][1] - vals[1][0];
1024 
1025  axis = 0;
1026  if (t < d) { t = d; axis = 1; }
1027  d = vals[2][1] - vals[2][0];
1028  if (t < d) { t = d; axis = 2; }
1029  return t;
1030 }
1031 
1032 template <typename T>
1033 inline T
1034 UT_BoundingBoxT<T>::computeDelta(T bmin, T bmax, T val)
1035 {
1036  return (val > bmax) ? val - bmax : SYSmin(val - bmin, T(0));
1037 }
1038 
1039 template <typename T>
1040 inline UT_Vector3T<T>
1042 {
1043  UT_Vector3T<T> delta;
1044 
1045  delta.x() = computeDelta(vals[0][0], vals[0][1], p.x());
1046  delta.y() = computeDelta(vals[1][0], vals[1][1], p.y());
1047  delta.z() = computeDelta(vals[2][0], vals[2][1], p.z());
1048 
1049  return delta;
1050 }
1051 
1052 template <typename T>
1053 inline T
1054 UT_BoundingBoxT<T>::computeDelta(T amin, T amax, T bmin, T bmax)
1055 {
1056  T d1, d2;
1057 
1058  d1 = SYSmax(bmin - amax, T(0));
1059  d2 = SYSmax(amin - bmax, T(0));
1060  return d1 > d2 ? d1 : -d2;
1061 }
1062 
1063 template <typename T>
1064 inline UT_Vector3T<T>
1066 {
1067  UT_Vector3T<T> delta;
1068 
1069  delta.x() = computeDelta(
1070  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1071  delta.y() = computeDelta(
1072  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1073  delta.z() = computeDelta(
1074  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1075 
1076  return delta;
1077 }
1078 
1079 template <typename T>
1080 inline T
1081 UT_BoundingBoxT<T>::computeMaxDelta(T bmin, T bmax, T val)
1082 {
1083  if (SYSabs(val - bmin) > SYSabs(val - bmax))
1084  return val - bmin;
1085  else
1086  return val - bmax;
1087 }
1088 
1089 template <typename T>
1090 inline UT_Vector3T<T>
1092 {
1093  UT_Vector3T<T> delta;
1094 
1095  delta.x() = computeMaxDelta(vals[0][0], vals[0][1], p.x());
1096  delta.y() = computeMaxDelta(vals[1][0], vals[1][1], p.y());
1097  delta.z() = computeMaxDelta(vals[2][0], vals[2][1], p.z());
1098 
1099  return delta;
1100 }
1101 
1102 template <typename T>
1103 inline T
1104 UT_BoundingBoxT<T>::computeOverlapDelta(T amin, T amax, T bmin, T bmax)
1105 {
1106  T d1, d2;
1107 
1108  d1 = bmax - amax;
1109  d2 = bmin - amin;
1110 
1111  // Opposite signs imply that one box is already enclosed in the other
1112  return ((d1 < 0) != (d2 < 0)) ? 0 : (SYSabs(d1) < SYSabs(d2) ? d1 : d2);
1113 }
1114 
1115 template <typename T>
1116 inline UT_Vector3T<T>
1118 {
1119  UT_Vector3T<T> delta;
1120 
1121  delta.x() = computeOverlapDelta(
1122  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1123  delta.y() = computeOverlapDelta(
1124  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1125  delta.z() = computeOverlapDelta(
1126  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1127 
1128  return delta;
1129 }
1130 
1131 template <typename T>
1132 inline int
1134 {
1135  int code = 0;
1136 
1137  if (pt.x() < vals[0][0]) code |= 1;
1138  else if (pt.x() > vals[0][1]) code |= 2;
1139  if (pt.y() < vals[1][0]) code |= 4;
1140  else if (pt.y() > vals[1][1]) code |= 8;
1141  if (pt.z() < vals[2][0]) code |= 16;
1142  else if (pt.z() > vals[2][1]) code |= 32;
1143 
1144  return code;
1145 }
1146 
1147 template <typename T>
1148 inline T
1150 {
1151  T xlen, ylen, zlen;
1152 
1153  xlen = sizeX(); ylen = sizeY(); zlen = sizeZ();
1154  return 2*(xlen*ylen+ylen*zlen+zlen*xlen);
1155 }
1156 
1157 template <typename T>
1158 inline void
1160 {
1161  vals[0][0] += vec[0];
1162  vals[1][0] += vec[1];
1163  vals[2][0] += vec[2];
1164 }
1165 
1166 template <typename T>
1167 inline void
1169 {
1170  vals[0][1] += vec[0];
1171  vals[1][1] += vec[1];
1172  vals[2][1] += vec[2];
1173 }
1174 
1175 template <typename T>
1176 inline void
1178  const UT_Vector3T<T> &offset)
1179 {
1180  vals[0][0] *= scale[0]; vals[0][1] *= scale[0];
1181  vals[1][0] *= scale[1]; vals[1][1] *= scale[1];
1182  vals[2][0] *= scale[2]; vals[2][1] *= scale[2];
1183  vals[0][0] += offset[0]; vals[0][1] += offset[0];
1184  vals[1][0] += offset[1]; vals[1][1] += offset[1];
1185  vals[2][0] += offset[2]; vals[2][1] += offset[2];
1186 }
1187 
1188 template <typename T>
1189 inline int
1191 {
1192  return sizeX() > sizeY() ? (sizeX() > sizeZ() ? 0 : 2) :
1193  sizeY() > sizeZ() ? 1 : 2;
1194 }
1195 
1196 template <typename T>
1197 inline int
1199 {
1200  return sizeX() < sizeY() ? (sizeX() < sizeZ() ? 0 : 2) :
1201  sizeY() < sizeZ() ? 1 : 2;
1202 }
1203 
1204 template <typename T>
1205 inline void
1207 {
1208  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1209  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1210  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1211  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1212  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1213  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1214  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1215  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1216 }
1217 
1218 template <typename T>
1219 inline void
1221 {
1222  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0], 1.0);
1223  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1], 1.0);
1224  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0], 1.0);
1225  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1], 1.0);
1226  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0], 1.0);
1227  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1], 1.0);
1228  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0], 1.0);
1229  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1], 1.0);
1230 }
1231 
1232 template <typename T>
1233 template <typename MATRIX>
1234 inline int
1236  UT_Vector3T<T> (&ptarray)[8],
1237  const MATRIX &transform_matrix) const
1238 {
1239  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1240  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1241  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1242  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1243  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1244  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1245  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1246  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1247 
1248  if ( transform_matrix.isIdentity() )
1249  return 0;
1250 
1251  ptarray[0] *= transform_matrix;
1252  ptarray[1] *= transform_matrix;
1253  ptarray[2] *= transform_matrix;
1254  ptarray[3] *= transform_matrix;
1255  ptarray[4] *= transform_matrix;
1256  ptarray[5] *= transform_matrix;
1257  ptarray[6] *= transform_matrix;
1258  ptarray[7] *= transform_matrix;
1259 
1260  return 1;
1261 }
1262 
1263 
1264 #endif
int intersectRay(const UT_Vector3T< T > &org, const UT_Vector3T< T > &dir, T tmax=1E17F, T *distance=0, UT_Vector3T< T > *nml=0) const
#define SYSmax(a, b)
Definition: SYS_Math.h:1535
GA_API const UT_StringHolder dist
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
bool operator==(const UT_BoundingBoxT< T > &bbox) const
int intersects(const UT_BoundingBoxT< T > &box) const
SYS_FORCE_INLINE bool hasVolume() const
GLenum GLuint GLsizei bufsize
Definition: glcorearb.h:1817
T zsize() const
T centerZ() const
UT_Vector3T< T > maxDistDelta(const UT_Vector3T< T > &p) const
Returns the maximum delta vector from the bounding box to the point.
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:14163
T minDist2(const UT_Vector3T< T > &p) const
SYS_FORCE_INLINE void makeInvalid()
Axis-aligned bounding box (AABB).
Definition: GEO_Detail.h:43
UT_API void dump(const char *msg=0) const
Dump the bounding box to stderr. The msg is printed before the bounds.
void transform(const MATRIX &mat)
const T * end() const
T centerY() const
T approxLineDist2(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &dir) const
UT_Vector3T< T > maxvec() const
#define SYSabs(a)
Definition: SYS_Math.h:1537
UT_Vector3T< T > minDistDelta(const UT_Vector3T< T > &p) const
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:76
#define UT_API
Definition: UT_API.h:14
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glew.h:12900
void setBounds(T x_min, T y_min, T z_min, T x_max, T y_max, T z_max)
T ycenter() const
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:35
T ysize() const
void addToMin(const UT_Vector3T< T > &vec)
unsigned long long uint64
Definition: SYS_Types.h:117
3D Vector class.
4D Vector class.
Definition: UT_Vector4.h:166
SYS_FORCE_INLINE bool isInvalidFast() const
float fpreal32
Definition: SYS_Types.h:200
GLdouble GLdouble t
Definition: glew.h:1403
T sizeAxis(int axis) const
int minAxis() const
void translate(const UT_Vector3T< T > &delta)
Adds the given translate to each component of the bounding box.
T sizeY() const
T segmentPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &pt1, const UT_Vector3T< T > &pt2)
Definition: UT_Vector3.h:905
void addToMax(const UT_Vector3T< T > &vec)
void initBounds(const fpreal64 *v)
Initialize zero-sized bounds at the location of the point given by v.
UT_BoundingBoxT & operator=(const UT_BoundingBoxT< S > &bbox)
GLint GLenum GLint x
Definition: glcorearb.h:408
int intersectRange(const UT_Vector3T< T > &org, const UT_Vector3T< T > &dir, T &min, T &max) const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
SYS_FORCE_INLINE void expandBounds(T relative, T absolute)
double fpreal64
Definition: SYS_Types.h:201
T maxDist2(const UT_Vector3T< T > &p) const
Returns maximum distance between point and bounding box squared.
GLuint GLenum GLenum transform
Definition: glew.h:15055
UT_API bool save(UT_JSONWriter &w) const
T & operator()(unsigned m, unsigned n)
void OIIO_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
void setSerialized(const fpreal64 floats[6])
const T * data() const
SYS_FORCE_INLINE T & y()
Definition: UT_Vector3.h:508
bool operator!=(const UT_BoundingBoxT< T > &bbox) const
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void getBBoxPoints(UT_Vector3T< T >(&ptarray)[8]) const
UT_Vector3T< T > center() const
UT_API void outTo(std::ostream &os) const
UT_BoundingBoxT(const UT_Vector3T< T > &lowerbound, const UT_Vector3T< T > &upperbound)
GLsizei GLsizei GLfloat distance
Definition: glew.h:13923
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:170
const GLdouble * v
Definition: glcorearb.h:836
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE T & z()
Definition: UT_Vector3.h:510
#define UT_FASTBOX(idx)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
int intersectTube(const UT_Vector3T< T > &org, const UT_Vector3T< T > &dir, T radius, T tmin=-1E17f, T tmax=1E17f) const
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
int maxAxis() const
long long int64
Definition: SYS_Types.h:116
void enlargeBounds(const fpreal32 *v)
Enlarge the existing bounds to encompass the point given in v.
UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingBoxT< T > &v)
GLfloat GLfloat p
Definition: glew.h:16656
UT_API bool load(UT_JSONParser &p)
int computeIntersection(const UT_BoundingBoxT< T > &box)
T minDist2(const UT_BoundingBoxT< T > &box) const
Minimum disance between two bboxes squared.
T sizeMax() const
Return the size of the largest dimension.
UT_Vector3T< T > minDistToMaxOverlap(const UT_BoundingBoxT< T > &box) const
void enlargeBounds(const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
T xsize() const
GLfloat v0
Definition: glcorearb.h:815
uint64 hash() const
Compute UT_BoundingBox hash.
UT_Vector3T< T > size() const
const T * getSerialized() const
GLdouble n
Definition: glcorearb.h:2007
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
void setSerialized(const fpreal32 floats[6])
void assign(T xx=0.0f, T yy=0.0f, T zz=0.0f)
Set the values of the vector components.
Definition: UT_Vector3.h:537
T volume() const
T zcenter() const
GLuint GLfloat * val
Definition: glcorearb.h:1607
GLsizei const GLint box[]
Definition: glew.h:11654
UT_API void dumpGeo(FILE *fp) const
Dump the bounding box geometry to a draw file.
T getRadius() const
Returns the radius of a sphere that would fully enclose the box.
void enlargeBounds(const fpreal64 *v)
Enlarge the existing bounds to encompass the point given in v.
T operator()(unsigned m, unsigned n) const
SYS_FORCE_INLINE bool isValid() const
Check whether the bounding box contains at least one point.
UT_Vector3T< T > minvec() const
#define SYS_FTOLERANCE_R
Definition: SYS_Types.h:283
T sizeZ() const
bool intersects(const Box< Vec3< T > > &b, const Line3< T > &r, Vec3< T > &ip)
Definition: ImathBoxAlgo.h:728
void splitRight(UT_BoundingBoxT< T > &box, int axis, T split)
void initMaxBounds()
Initialize the box to the largest size.
SYS_FORCE_INLINE void initBounds()
T centerX() const
const GLdouble * m
Definition: glew.h:9166
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:77
SYS_FORCE_INLINE T & x()
Definition: UT_Vector3.h:506
void splitLeft(UT_BoundingBoxT< T > &box, int axis, T split)
int isInside(const UT_Vector3T< T > &pt) const
UT_BoundingBoxT(T axmin, T aymin, T azmin, T axmax, T aymax, T azmax)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:171
GLintptr offset
Definition: glcorearb.h:664
T xcenter() const
friend std::size_t hash_value(const this_type &t)
Compute UT_BoundingBox hash.
void enlargeFloats(int bits=1, T min=1e-5)
UT_BoundingBoxT(const UT_BoundingBoxT< S > &bbox)
#define SYSmin(a, b)
Definition: SYS_Math.h:1536
void initBounds(const fpreal32 *v)
Initialize zero-sized bounds at the location of the point given by v.
static bool SYSisEqual(int64 a, int64 b, int64)
int isLineInside(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &idir) const
T centerAxis(int axis) const
const T * begin() const
GLint y
Definition: glcorearb.h:102
void clipBounds(const UT_BoundingBoxT< T > &box)
Find the intersections of two bounding boxes.
void scaleOffset(const UT_Vector3T< T > &scale, const UT_Vector3T< T > &offset)
Scale then offset a bounding box.
T sizeX() const
bool isEqual(const UT_BoundingBoxT< T > &bbox, T tol=SYS_FTOLERANCE_R) const
int getOutCode(const UT_Vector3T< T > &pt) const
Finds the out code of the point relative to this box: