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().
300  void splitLeft(UT_BoundingBoxT<T> &box, int axis, T split)
301  {
302  box = *this;
303  box.vals[axis][0] = split;
304  vals[axis][1] = split;
305  }
306  void splitRight(UT_BoundingBoxT<T> &box, int axis, T split)
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.
355  T minDist2(const UT_BoundingBoxT<T> &box) const
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.
419  int computeIntersection(const UT_BoundingBoxT<T> &box);
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  /// Returns whether the triangle defined by the supplied points intersects
434  /// the bounding box.
436  const UT_Vector3T<T> &v1,
437  const UT_Vector3T<T> &v2) const;
438 
439  /// Dump the bounding box to stderr. The msg is printed before the bounds
440  UT_API void dump(const char *msg=0) const;
441  /// Dump the bounding box geometry to a draw file
442  UT_API void dumpGeo(FILE *fp) const;
443 
444  /// @{
445  /// Methods to serialize to a JSON stream. The vector is stored as an
446  /// array of 6 reals (xmin, xmax, ymin, ymax, zmin, zmax)
447  UT_API bool save(UT_JSONWriter &w) const;
448  UT_API bool save(UT_JSONValue &v) const;
449  UT_API bool load(UT_JSONParser &p);
450  /// @}
451 
452 
453 protected:
454  friend
455  std::ostream &operator<<(std::ostream &os, const UT_BoundingBoxT<T> &box)
456  {
457  box.outTo(os);
458  return os;
459  }
460 
461  UT_API void outTo(std::ostream &os) const;
462  // Ugly helper function to allow instantation with int64.
463  static bool SYSisEqual(int64 a, int64 b, int64) { return a==b; }
464 
465 private:
466 
467  static T computeDelta(T bmin, T bmax, T val);
468  static T computeDelta(T amin, T amax, T bmin, T bmax);
469 
470  template <typename Y> static Y getMinMantissa(Y val, int bits);
471 
472  static T computeMaxDelta(T bmin, T bmax, T val);
473 
474  static T computeOverlapDelta(T amin, T amax, T bmin, T bmax);
475 
476 };
477 
483 
484 template <typename T>
485 UT_API size_t format(char *buf, size_t bufsize, const UT_BoundingBoxT<T> &v);
486 
487 
488 //////////////////////////////////////////////////////////////////////////////
489 //
490 // Inline Implementations
491 //
492 
493 template <typename T>
494 inline bool
496 {
497  return vals[0][0] <= vals[0][1] &&
498  vals[1][0] <= vals[1][1] &&
499  vals[2][0] <= vals[2][1];
500 }
501 
502 template <typename T>
503 inline void
505 {
506  // Initialize with min and max reversed, so that it's empty
507  const T maxv = 0.5*std::numeric_limits<T>::max();
508  const T minv = -maxv;
509  vals[0][0] = maxv;
510  vals[0][1] = minv;
511  vals[1][0] = maxv;
512  vals[1][1] = minv;
513  vals[2][0] = maxv;
514  vals[2][1] = minv;
515 }
516 
517 template <typename T>
518 inline void
520 {
521  vals[0][0] = pt.x();
522  vals[0][1] = pt.x();
523  vals[1][0] = pt.y();
524  vals[1][1] = pt.y();
525  vals[2][0] = pt.z();
526  vals[2][1] = pt.z();
527 }
528 
529 template <typename T>
530 inline void
532 {
533  vals[0][0] = x;
534  vals[0][1] = x;
535  vals[1][0] = y;
536  vals[1][1] = y;
537  vals[2][0] = z;
538  vals[2][1] = z;
539 }
540 
541 template <typename T>
542 inline void
544 {
545  vals[0][0] = SYSmin(vals[0][0], pt.x());
546  vals[0][1] = SYSmax(vals[0][1], pt.x());
547  vals[1][0] = SYSmin(vals[1][0], pt.y());
548  vals[1][1] = SYSmax(vals[1][1], pt.y());
549  vals[2][0] = SYSmin(vals[2][0], pt.z());
550  vals[2][1] = SYSmax(vals[2][1], pt.z());
551 }
552 
553 template <typename T>
554 inline void
556 {
557  vals[0][0] = SYSmin(vals[0][0], x);
558  vals[0][1] = SYSmax(vals[0][1], x);
559  vals[1][0] = SYSmin(vals[1][0], y);
560  vals[1][1] = SYSmax(vals[1][1], y);
561  vals[2][0] = SYSmin(vals[2][0], z);
562  vals[2][1] = SYSmax(vals[2][1], z);
563 }
564 
565 template <typename T>
566 inline void
568 {
569  vals[0][0] = SYSmin(vals[0][0], box(0, 0));
570  vals[0][1] = SYSmax(vals[0][1], box(0, 1));
571  vals[1][0] = SYSmin(vals[1][0], box(1, 0));
572  vals[1][1] = SYSmax(vals[1][1], box(1, 1));
573  vals[2][0] = SYSmin(vals[2][0], box(2, 0));
574  vals[2][1] = SYSmax(vals[2][1], box(2, 1));
575 }
576 
577 template <typename T>
578 inline void
579 UT_BoundingBoxT<T>::expandBounds(T relative, T absolute)
580 {
581  T d;
582 
583  // Don't factor out percent for improved numerical stability when
584  // dealing with large boxes.
585  d = absolute + vals[0][1]*relative - vals[0][0]*relative;
586  vals[0][0] -= d; vals[0][1] += d;
587  d = absolute + vals[1][1]*relative - vals[1][0]*relative;
588  vals[1][0] -= d; vals[1][1] += d;
589  d = absolute + vals[2][1]*relative - vals[2][0]*relative;
590  vals[2][0] -= d; vals[2][1] += d;
591 }
592 
593 template <typename T>
594 inline void
595 UT_BoundingBoxT<T>::expandBounds(T dltx, T dlty, T dltz)
596 {
597  vals[0][0] -= dltx; vals[0][1] += dltx;
598  vals[1][0] -= dlty; vals[1][1] += dlty;
599  vals[2][0] -= dltz; vals[2][1] += dltz;
600 }
601 
602 template <typename T>
603 inline int
605 {
606  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
607  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
608  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
609  return 1;
610 }
611 
612 template <typename T>
613 inline int
615 {
616  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
617  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
618  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
619  return 1;
620 }
621 
622 template <typename T>
623 inline int
625 {
626  if (vals[0][0] > x || vals[0][1] < x) return 0;
627  if (vals[1][0] > y || vals[1][1] < y) return 0;
628  if (vals[2][0] > z || vals[2][1] < z) return 0;
629  return 1;
630 }
631 
632 template <typename T>
633 inline int
635 {
636  if (vals[0][0] < box.vals[0][0] || vals[0][1] > box.vals[0][1]) return 0;
637  if (vals[1][0] < box.vals[1][0] || vals[1][1] > box.vals[1][1]) return 0;
638  if (vals[2][0] < box.vals[2][0] || vals[2][1] > box.vals[2][1]) return 0;
639  return 1;
640 }
641 
642 template <typename T>
643 inline int
645 {
646  if (vals[0][0] > box.vals[0][1] || vals[0][1] < box.vals[0][0]) return 0;
647  if (vals[1][0] > box.vals[1][1] || vals[1][1] < box.vals[1][0]) return 0;
648  if (vals[2][0] > box.vals[2][1] || vals[2][1] < box.vals[2][0]) return 0;
649  return 1;
650 }
651 
652 template <typename T>
653 inline int
655 {
656  if (!intersects(box))
657  return 0;
658 
659  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
660  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
661  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
662  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
663  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
664  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
665  return 1;
666 }
667 
668 #define UT_TESTMAX tmax = t1 < tmax ? t1 : tmax;
669 #define UT_TESTMIN tmin = t1 > tmin ? t1 : tmin;
670 
671 #define UT_FASTBOX(idx) \
672  positive = (idir(idx) > 0.0); \
673  t1 = (vals[idx][ positive] - v0(idx))*idir(idx); UT_TESTMAX \
674  t1 = (vals[idx][!positive] - v0(idx))*idir(idx); UT_TESTMIN \
675  /**/
676 
677 template <typename T>
678 inline int
680  const UT_Vector3T<T> &v0, const UT_Vector3T<T> &idir) const
681 {
682  T tmin, tmax;
683  int positive;
684  T t1;
685 
686  tmin = 0;
687  tmax = 1;
688 
689  UT_FASTBOX(0)
690  UT_FASTBOX(1)
691  UT_FASTBOX(2)
692 
693  return tmin <= tmax;
694 }
695 
696 #undef UT_FASTBOX
697 #undef UT_TESTMIN
698 #undef UT_TESTMAX
699 
700 template <typename T>
701 inline T
703  const UT_Vector3T<T> &v0,
704  const UT_Vector3T<T> &dir) const
705 {
706  T dist;
707 
708  // Approximate the box with a sphere, then find the distance from the
709  // line to the sphere.
710  dist = segmentPointDist2(center(), v0, v0+dir);
711  dist = SYSmax(SYSsqrt(dist) - getRadius(), 0.0);
712  return dist*dist;
713 }
714 
715 template <typename T>
716 inline void
718 {
719  vals[0][0] = vals[1][0] = vals[2][0] = -0.5*std::numeric_limits<T>::max();
720  vals[0][1] = vals[1][1] = vals[2][1] = 0.5*std::numeric_limits<T>::max();
721 }
722 
723 template <typename T>
724 inline void
726  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
727 {
728  vals[0][0] = min.x(); vals[0][1] = max.x();
729  vals[1][0] = min.y(); vals[1][1] = max.y();
730  vals[2][0] = min.z(); vals[2][1] = max.z();
731 }
732 
733 template <typename T>
734 inline void
736 {
737  vals[0][0] = vals[0][1] = pt.x();
738  vals[1][0] = vals[1][1] = pt.y();
739  vals[2][0] = vals[2][1] = pt.z();
740 }
741 
742 template <typename T>
743 inline void
745 {
746  vals[0][0] = box(0, 0);
747  vals[0][1] = box(0, 1);
748  vals[1][0] = box(1, 0);
749  vals[1][1] = box(1, 1);
750  vals[2][0] = box(2, 0);
751  vals[2][1] = box(2, 1);
752 }
753 
754 template <typename T>
755 inline void
757  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
758 {
759  vals[0][0] = SYSmin(vals[0][0], min.x());
760  vals[0][1] = SYSmax(vals[0][1], max.x());
761  vals[1][0] = SYSmin(vals[1][0], min.y());
762  vals[1][1] = SYSmax(vals[1][1], max.y());
763  vals[2][0] = SYSmin(vals[2][0], min.z());
764  vals[2][1] = SYSmax(vals[2][1], max.z());
765 }
766 
767 template <typename T>
768 inline void
770 {
771  vals[0][0] = SYSmin(vals[0][0], pt.x());
772  vals[0][1] = SYSmax(vals[0][1], pt.x());
773  vals[1][0] = SYSmin(vals[1][0], pt.y());
774  vals[1][1] = SYSmax(vals[1][1], pt.y());
775  vals[2][0] = SYSmin(vals[2][0], pt.z());
776  vals[2][1] = SYSmax(vals[2][1], pt.z());
777 }
778 
779 // Extract the exponent of val and create a floating point value that is
780 // the minimum mantissa value for that exponent. If bits is larger than 0,
781 // we'll use that mantissa bit.
782 template <typename T>
783 template <typename Y>
784 inline Y
786 {
787  typedef SYS_FPRealUnionT<Y> FPRealUnion;
788  typedef typename FPRealUnion::uint_type UInt;
789 
790  static const int exponent_bits = FPRealUnion::EXPONENT_BITS;
791  static const int mantissa_bits = FPRealUnion::MANTISSA_BITS;
792  FPRealUnion tmp;
793 
794  tmp.fval = val;
795  tmp.uval >>= mantissa_bits;
796  tmp.uval &= ((UInt(1) << exponent_bits) - UInt(1)); // extract exponent
797  tmp.uval -= mantissa_bits - bits;
798  tmp.uval <<= mantissa_bits;
799  return tmp.fval;
800 }
801 
802 template <typename T>
803 inline void
805 {
806  T val;
807  int i;
808 
809  UT_ASSERT(bits >= 0 && bits < 128);
810  for (i = 0; i < 3; i++)
811  {
812  val = SYSmax(getMinMantissa(vals[i][0], bits),
813  getMinMantissa(vals[i][1], bits), min);
814 
815  UT_ASSERT(val > 0);
816  vals[i][0] -= val;
817  vals[i][1] += val;
818  }
819 }
820 
821 template <>
822 inline void
824 {
825  UT_ASSERT(!"enlargeFloats is no-op for int64");
826 }
827 
828 
829 template <typename T>
830 inline void
832 {
833  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
834  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
835  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
836  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
837  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
838  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
839 }
840 
841 template <typename T>
842 template <typename MATRIX>
843 inline void
845 {
846  UT_BoundingBoxT<T> newbox;
847  transform(mat, newbox);
848  *this = newbox;
849 }
850 
851 template <typename T>
852 template <typename MATRIX>
853 inline void
855  const MATRIX &mat, UT_BoundingBoxT<T> &newbox) const
856 {
857  newbox.initBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][0]) * mat);
858  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][1]) * mat);
859  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][0]) * mat);
860  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][1]) * mat);
861  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][0]) * mat);
862  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][1]) * mat);
863  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][0]) * mat);
864  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][1]) * mat);
865 }
866 
867 template <typename T>
868 inline void
870 {
871  vals[0][0] += delta.x();
872  vals[0][1] += delta.x();
873  vals[1][0] += delta.y();
874  vals[1][1] += delta.y();
875  vals[2][0] += delta.z();
876  vals[2][1] += delta.z();
877 }
878 
879 #define UT_TESTMAX(face) if (t < tmax) { \
880  if (t < tmin) return 0; \
881  tmax = t; \
882  foundmax = face; \
883  }
884 #define UT_TESTMIN(face) if (t > tmin) { \
885  if (t > tmax) return 0; \
886  tmin = t; \
887  foundmin = face; \
888  }
889 #define UT_FASTBOX(face) \
890  ray = 1.0 / d(face); \
891  positive = (ray > 0.0); \
892  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX(face) \
893  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN(face) \
894  /**/
895 
896 template <typename T>
897 int
899  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
900  T maxdist, T *distance, UT_Vector3T<T> *nml) const
901 {
902  T t, tmin, tmax;
903  T ray;
904  int positive, foundmin, foundmax;
905 
906  foundmin = -1;
907  foundmax = -1;
908  tmin = 0;
909  tmax = maxdist;
910 
911  UT_FASTBOX(0)
912  UT_FASTBOX(1)
913  UT_FASTBOX(2)
914 
915  if (foundmin != -1)
916  {
917  // We intersect the minimum.
918  if(nml)
919  {
920  if(foundmin == 0) nml->assign(1.0, 0.0, 0.0);
921  else if(foundmin == 1) nml->assign(0.0, 1.0, 0.0);
922  else nml->assign(0.0, 0.0, 1.0);
923  }
924 
925  if(distance) *distance = tmin;
926  return 1;
927  }
928  else if (foundmax != -1)
929  {
930  // We did not intersect any minimum planes, therefore are
931  // inside provided we intersected a maximum plane and weren't
932  // trivially rejected.
933  if(nml)
934  {
935  if(foundmax == 0) nml->assign(1.0, 0.0, 0.0);
936  else if(foundmax == 1) nml->assign(0.0, 1.0, 0.0);
937  else nml->assign(0.0, 0.0, 1.0);
938  }
939 
940  if(distance) *distance = tmax;
941  return 1;
942  }
943  return 0;
944 }
945 
946 #undef UT_FASTBOX
947 #undef UT_TESTMIN
948 #undef UT_TESTMAX
949 
950 #define UT_TESTMAX if(t < tmax) { if(t < tmin) return 0; tmax = t; }
951 #define UT_TESTMIN if(t > tmin) { if(t > tmax) return 0; tmin = t; }
952 
953 #define UT_FASTBOX(face) \
954  ray = 1.0 / d(face); \
955  positive = (ray > 0.0); \
956  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX \
957  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN \
958  /**/
959 
960 template <typename T>
961 inline int
963  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
964  T &tmin, T &tmax) const
965 {
966  T t;
967  T ray;
968  int positive;
969 
970  tmin = -std::numeric_limits<T>::max();
971  tmax = +std::numeric_limits<T>::max();
972 
973  UT_FASTBOX(0)
974  UT_FASTBOX(1)
975  UT_FASTBOX(2)
976 
977  return 1;
978 }
979 
980 #undef UT_FASTBOX
981 #undef UT_TESTMIN
982 #undef UT_TESTMAX
983 
984 template <typename T>
985 inline int
987  const UT_Vector3T<T> &org, const UT_Vector3T<T> &dir,
988  T radius, T mint, T maxt) const
989 {
990  UT_BoundingBoxT<T> tmp;
991  T tmin, tmax;
992 
993  tmp = *this;
994 
995  tmp.expandBounds(radius, radius, radius);
996  if (!tmp.intersectRange(org, dir, tmin, tmax))
997  {
998  // No hit at all.
999  return 0;
1000  }
1001 
1002  // Check if it is within our tube.
1003  if (tmax < mint)
1004  return 0;
1005  if (tmin > maxt)
1006  return 0;
1007 
1008  return 1;
1009 }
1010 
1011 template <typename T>
1012 inline T
1014 {
1015  T t = vals[0][1] - vals[0][0];
1016  T d = vals[1][1] - vals[1][0];
1017 
1018  if (t < d) t = d;
1019  d = vals[2][1] - vals[2][0];
1020  if (t < d) t = d;
1021  return t;
1022 }
1023 
1024 template <typename T>
1025 inline T
1027 {
1028  T t = vals[0][1] - vals[0][0];
1029  T d = vals[1][1] - vals[1][0];
1030 
1031  axis = 0;
1032  if (t < d) { t = d; axis = 1; }
1033  d = vals[2][1] - vals[2][0];
1034  if (t < d) { t = d; axis = 2; }
1035  return t;
1036 }
1037 
1038 template <typename T>
1039 inline T
1040 UT_BoundingBoxT<T>::computeDelta(T bmin, T bmax, T val)
1041 {
1042  return (val > bmax) ? val - bmax : SYSmin(val - bmin, T(0));
1043 }
1044 
1045 template <typename T>
1046 inline UT_Vector3T<T>
1048 {
1049  UT_Vector3T<T> delta;
1050 
1051  delta.x() = computeDelta(vals[0][0], vals[0][1], p.x());
1052  delta.y() = computeDelta(vals[1][0], vals[1][1], p.y());
1053  delta.z() = computeDelta(vals[2][0], vals[2][1], p.z());
1054 
1055  return delta;
1056 }
1057 
1058 template <typename T>
1059 inline T
1060 UT_BoundingBoxT<T>::computeDelta(T amin, T amax, T bmin, T bmax)
1061 {
1062  T d1, d2;
1063 
1064  d1 = SYSmax(bmin - amax, T(0));
1065  d2 = SYSmax(amin - bmax, T(0));
1066  return d1 > d2 ? d1 : -d2;
1067 }
1068 
1069 template <typename T>
1070 inline UT_Vector3T<T>
1072 {
1073  UT_Vector3T<T> delta;
1074 
1075  delta.x() = computeDelta(
1076  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1077  delta.y() = computeDelta(
1078  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1079  delta.z() = computeDelta(
1080  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1081 
1082  return delta;
1083 }
1084 
1085 template <typename T>
1086 inline T
1087 UT_BoundingBoxT<T>::computeMaxDelta(T bmin, T bmax, T val)
1088 {
1089  if (SYSabs(val - bmin) > SYSabs(val - bmax))
1090  return val - bmin;
1091  else
1092  return val - bmax;
1093 }
1094 
1095 template <typename T>
1096 inline UT_Vector3T<T>
1098 {
1099  UT_Vector3T<T> delta;
1100 
1101  delta.x() = computeMaxDelta(vals[0][0], vals[0][1], p.x());
1102  delta.y() = computeMaxDelta(vals[1][0], vals[1][1], p.y());
1103  delta.z() = computeMaxDelta(vals[2][0], vals[2][1], p.z());
1104 
1105  return delta;
1106 }
1107 
1108 template <typename T>
1109 inline T
1110 UT_BoundingBoxT<T>::computeOverlapDelta(T amin, T amax, T bmin, T bmax)
1111 {
1112  T d1, d2;
1113 
1114  d1 = bmax - amax;
1115  d2 = bmin - amin;
1116 
1117  // Opposite signs imply that one box is already enclosed in the other
1118  return ((d1 < 0) != (d2 < 0)) ? 0 : (SYSabs(d1) < SYSabs(d2) ? d1 : d2);
1119 }
1120 
1121 template <typename T>
1122 inline UT_Vector3T<T>
1124 {
1125  UT_Vector3T<T> delta;
1126 
1127  delta.x() = computeOverlapDelta(
1128  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1129  delta.y() = computeOverlapDelta(
1130  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1131  delta.z() = computeOverlapDelta(
1132  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1133 
1134  return delta;
1135 }
1136 
1137 template <typename T>
1138 inline int
1140 {
1141  int code = 0;
1142 
1143  if (pt.x() < vals[0][0]) code |= 1;
1144  else if (pt.x() > vals[0][1]) code |= 2;
1145  if (pt.y() < vals[1][0]) code |= 4;
1146  else if (pt.y() > vals[1][1]) code |= 8;
1147  if (pt.z() < vals[2][0]) code |= 16;
1148  else if (pt.z() > vals[2][1]) code |= 32;
1149 
1150  return code;
1151 }
1152 
1153 template <typename T>
1154 inline T
1156 {
1157  T xlen, ylen, zlen;
1158 
1159  xlen = sizeX(); ylen = sizeY(); zlen = sizeZ();
1160  return 2*(xlen*ylen+ylen*zlen+zlen*xlen);
1161 }
1162 
1163 template <typename T>
1164 inline void
1166 {
1167  vals[0][0] += vec[0];
1168  vals[1][0] += vec[1];
1169  vals[2][0] += vec[2];
1170 }
1171 
1172 template <typename T>
1173 inline void
1175 {
1176  vals[0][1] += vec[0];
1177  vals[1][1] += vec[1];
1178  vals[2][1] += vec[2];
1179 }
1180 
1181 template <typename T>
1182 inline void
1184  const UT_Vector3T<T> &offset)
1185 {
1186  vals[0][0] *= scale[0]; vals[0][1] *= scale[0];
1187  vals[1][0] *= scale[1]; vals[1][1] *= scale[1];
1188  vals[2][0] *= scale[2]; vals[2][1] *= scale[2];
1189  vals[0][0] += offset[0]; vals[0][1] += offset[0];
1190  vals[1][0] += offset[1]; vals[1][1] += offset[1];
1191  vals[2][0] += offset[2]; vals[2][1] += offset[2];
1192 }
1193 
1194 template <typename T>
1195 inline int
1197 {
1198  return sizeX() > sizeY() ? (sizeX() > sizeZ() ? 0 : 2) :
1199  sizeY() > sizeZ() ? 1 : 2;
1200 }
1201 
1202 template <typename T>
1203 inline int
1205 {
1206  return sizeX() < sizeY() ? (sizeX() < sizeZ() ? 0 : 2) :
1207  sizeY() < sizeZ() ? 1 : 2;
1208 }
1209 
1210 template <typename T>
1211 inline void
1213 {
1214  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1215  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1216  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1217  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1218  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1219  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1220  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1221  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1222 }
1223 
1224 template <typename T>
1225 inline void
1227 {
1228  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0], 1.0);
1229  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1], 1.0);
1230  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0], 1.0);
1231  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1], 1.0);
1232  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0], 1.0);
1233  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1], 1.0);
1234  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0], 1.0);
1235  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1], 1.0);
1236 }
1237 
1238 template <typename T>
1239 template <typename MATRIX>
1240 inline int
1242  UT_Vector3T<T> (&ptarray)[8],
1243  const MATRIX &transform_matrix) const
1244 {
1245  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1246  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1247  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1248  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1249  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1250  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1251  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1252  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1253 
1254  if ( transform_matrix.isIdentity() )
1255  return 0;
1256 
1257  ptarray[0] *= transform_matrix;
1258  ptarray[1] *= transform_matrix;
1259  ptarray[2] *= transform_matrix;
1260  ptarray[3] *= transform_matrix;
1261  ptarray[4] *= transform_matrix;
1262  ptarray[5] *= transform_matrix;
1263  ptarray[6] *= transform_matrix;
1264  ptarray[7] *= transform_matrix;
1265 
1266  return 1;
1267 }
1268 
1269 
1270 #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:1570
GA_API const UT_StringHolder dist
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
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:1818
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.
T minDist2(const UT_Vector3T< T > &p) const
Y
Definition: ImathEuler.h:184
SYS_FORCE_INLINE void makeInvalid()
Axis-aligned bounding box (AABB).
Definition: GEO_Detail.h:41
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)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector4.h:493
const GLdouble * v
Definition: glcorearb.h:837
const T * end() const
T centerY() const
T approxLineDist2(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &dir) const
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:848
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector3.h:667
UT_Vector3T< T > maxvec() const
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
#define SYSabs(a)
Definition: SYS_Math.h:1572
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:87
#define UT_API
Definition: UT_API.h:14
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void setBounds(T x_min, T y_min, T z_min, T x_max, T y_max, T z_max)
T ycenter() const
GLint y
Definition: glcorearb.h:103
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
T ysize() const
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
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:174
SYS_FORCE_INLINE bool isInvalidFast() const
float fpreal32
Definition: SYS_Types.h:200
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.
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector4.h:491
T sizeY() const
T segmentPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &pt1, const UT_Vector3T< T > &pt2)
Definition: UT_Vector3.h:1130
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)
int intersectRange(const UT_Vector3T< T > &org, const UT_Vector3T< T > &dir, T &min, T &max) const
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.
UT_API bool save(UT_JSONWriter &w) const
GA_API const UT_StringHolder scale
T & operator()(unsigned m, unsigned n)
GLdouble n
Definition: glcorearb.h:2008
void setSerialized(const fpreal64 floats[6])
const T * data() const
GLintptr offset
Definition: glcorearb.h:665
bool operator!=(const UT_BoundingBoxT< T > &bbox) const
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)
constexpr SYS_FORCE_INLINE T & z() noexcept
Definition: UT_Vector4.h:495
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define UT_FASTBOX(idx)
int intersectTube(const UT_Vector3T< T > &org, const UT_Vector3T< T > &dir, T radius, T tmin=-1E17f, T tmax=1E17f) const
UT_API bool triangleIntersects(const UT_Vector3T< T > &v0, const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2) const
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)
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.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
UT_Vector3T< T > minDistToMaxOverlap(const UT_BoundingBoxT< T > &box) const
void enlargeBounds(const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
GA_API const UT_StringHolder transform
GLint GLenum GLint x
Definition: glcorearb.h:409
T xsize() const
uint64 hash() const
Compute UT_BoundingBox hash.
UT_Vector3T< T > size() const
GLdouble t
Definition: glad.h:2397
const T * getSerialized() const
GLfloat v0
Definition: glcorearb.h:816
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:694
T volume() const
T zcenter() const
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
void splitRight(UT_BoundingBoxT< T > &box, int axis, T split)
GLfloat GLfloat v1
Definition: glcorearb.h:817
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void initMaxBounds()
Initialize the box to the largest size.
SYS_FORCE_INLINE void initBounds()
T centerX() const
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
void splitLeft(UT_BoundingBoxT< T > &box, int axis, T split)
IMATH_HOSTDEVICE IMATH_CONSTEXPR14 bool intersects(const Box< Vec3< T >> &b, const Line3< T > &r, Vec3< T > &ip) IMATH_NOEXCEPT
Definition: ImathBoxAlgo.h:642
int isInside(const UT_Vector3T< T > &pt) const
UT_BoundingBoxT(T axmin, T aymin, T azmin, T axmax, T aymax, T azmax)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
T xcenter() const
friend std::size_t hash_value(const this_type &t)
Compute UT_BoundingBox hash.
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
void enlargeFloats(int bits=1, T min=1e-5)
SIM_API const UT_StringHolder distance
UT_BoundingBoxT(const UT_BoundingBoxT< S > &bbox)
constexpr SYS_FORCE_INLINE T & y() noexcept
Definition: UT_Vector3.h:665
#define SYSmin(a, b)
Definition: SYS_Math.h:1571
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
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
constexpr SYS_FORCE_INLINE T & x() noexcept
Definition: UT_Vector3.h:663
int getOutCode(const UT_Vector3T< T > &pt) const
Finds the out code of the point relative to this box: