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
486 UTformatBuffer(char *buf, size_t bufsize, const UT_BoundingBoxT<T> &v);
487 
488 
489 //////////////////////////////////////////////////////////////////////////////
490 //
491 // Inline Implementations
492 //
493 
494 template <typename T>
495 inline bool
497 {
498  return vals[0][0] <= vals[0][1] &&
499  vals[1][0] <= vals[1][1] &&
500  vals[2][0] <= vals[2][1];
501 }
502 
503 template <typename T>
504 inline void
506 {
507  // Initialize with min and max reversed, so that it's empty
508  const T maxv = 0.5*std::numeric_limits<T>::max();
509  const T minv = -maxv;
510  vals[0][0] = maxv;
511  vals[0][1] = minv;
512  vals[1][0] = maxv;
513  vals[1][1] = minv;
514  vals[2][0] = maxv;
515  vals[2][1] = minv;
516 }
517 
518 template <typename T>
519 inline void
521 {
522  vals[0][0] = pt.x();
523  vals[0][1] = pt.x();
524  vals[1][0] = pt.y();
525  vals[1][1] = pt.y();
526  vals[2][0] = pt.z();
527  vals[2][1] = pt.z();
528 }
529 
530 template <typename T>
531 inline void
533 {
534  vals[0][0] = x;
535  vals[0][1] = x;
536  vals[1][0] = y;
537  vals[1][1] = y;
538  vals[2][0] = z;
539  vals[2][1] = z;
540 }
541 
542 template <typename T>
543 inline void
545 {
546  vals[0][0] = SYSmin(vals[0][0], pt.x());
547  vals[0][1] = SYSmax(vals[0][1], pt.x());
548  vals[1][0] = SYSmin(vals[1][0], pt.y());
549  vals[1][1] = SYSmax(vals[1][1], pt.y());
550  vals[2][0] = SYSmin(vals[2][0], pt.z());
551  vals[2][1] = SYSmax(vals[2][1], pt.z());
552 }
553 
554 template <typename T>
555 inline void
557 {
558  vals[0][0] = SYSmin(vals[0][0], x);
559  vals[0][1] = SYSmax(vals[0][1], x);
560  vals[1][0] = SYSmin(vals[1][0], y);
561  vals[1][1] = SYSmax(vals[1][1], y);
562  vals[2][0] = SYSmin(vals[2][0], z);
563  vals[2][1] = SYSmax(vals[2][1], z);
564 }
565 
566 template <typename T>
567 inline void
569 {
570  vals[0][0] = SYSmin(vals[0][0], box(0, 0));
571  vals[0][1] = SYSmax(vals[0][1], box(0, 1));
572  vals[1][0] = SYSmin(vals[1][0], box(1, 0));
573  vals[1][1] = SYSmax(vals[1][1], box(1, 1));
574  vals[2][0] = SYSmin(vals[2][0], box(2, 0));
575  vals[2][1] = SYSmax(vals[2][1], box(2, 1));
576 }
577 
578 template <typename T>
579 inline void
580 UT_BoundingBoxT<T>::expandBounds(T relative, T absolute)
581 {
582  T d;
583 
584  // Don't factor out percent for improved numerical stability when
585  // dealing with large boxes.
586  d = absolute + vals[0][1]*relative - vals[0][0]*relative;
587  vals[0][0] -= d; vals[0][1] += d;
588  d = absolute + vals[1][1]*relative - vals[1][0]*relative;
589  vals[1][0] -= d; vals[1][1] += d;
590  d = absolute + vals[2][1]*relative - vals[2][0]*relative;
591  vals[2][0] -= d; vals[2][1] += d;
592 }
593 
594 template <typename T>
595 inline void
596 UT_BoundingBoxT<T>::expandBounds(T dltx, T dlty, T dltz)
597 {
598  vals[0][0] -= dltx; vals[0][1] += dltx;
599  vals[1][0] -= dlty; vals[1][1] += dlty;
600  vals[2][0] -= dltz; vals[2][1] += dltz;
601 }
602 
603 template <typename T>
604 inline int
606 {
607  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
608  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
609  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
610  return 1;
611 }
612 
613 template <typename T>
614 inline int
616 {
617  if (vals[0][0] > pt.x() || vals[0][1] < pt.x()) return 0;
618  if (vals[1][0] > pt.y() || vals[1][1] < pt.y()) return 0;
619  if (vals[2][0] > pt.z() || vals[2][1] < pt.z()) return 0;
620  return 1;
621 }
622 
623 template <typename T>
624 inline int
626 {
627  if (vals[0][0] > x || vals[0][1] < x) return 0;
628  if (vals[1][0] > y || vals[1][1] < y) return 0;
629  if (vals[2][0] > z || vals[2][1] < z) return 0;
630  return 1;
631 }
632 
633 template <typename T>
634 inline int
636 {
637  if (vals[0][0] < box.vals[0][0] || vals[0][1] > box.vals[0][1]) return 0;
638  if (vals[1][0] < box.vals[1][0] || vals[1][1] > box.vals[1][1]) return 0;
639  if (vals[2][0] < box.vals[2][0] || vals[2][1] > box.vals[2][1]) return 0;
640  return 1;
641 }
642 
643 template <typename T>
644 inline int
646 {
647  if (vals[0][0] > box.vals[0][1] || vals[0][1] < box.vals[0][0]) return 0;
648  if (vals[1][0] > box.vals[1][1] || vals[1][1] < box.vals[1][0]) return 0;
649  if (vals[2][0] > box.vals[2][1] || vals[2][1] < box.vals[2][0]) return 0;
650  return 1;
651 }
652 
653 template <typename T>
654 inline int
656 {
657  if (!intersects(box))
658  return 0;
659 
660  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
661  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
662  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
663  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
664  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
665  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
666  return 1;
667 }
668 
669 #define UT_TESTMAX tmax = t1 < tmax ? t1 : tmax;
670 #define UT_TESTMIN tmin = t1 > tmin ? t1 : tmin;
671 
672 #define UT_FASTBOX(idx) \
673  positive = (idir(idx) > 0.0); \
674  t1 = (vals[idx][ positive] - v0(idx))*idir(idx); UT_TESTMAX \
675  t1 = (vals[idx][!positive] - v0(idx))*idir(idx); UT_TESTMIN \
676  /**/
677 
678 template <typename T>
679 inline int
681  const UT_Vector3T<T> &v0, const UT_Vector3T<T> &idir) const
682 {
683  T tmin, tmax;
684  int positive;
685  T t1;
686 
687  tmin = 0;
688  tmax = 1;
689 
690  UT_FASTBOX(0)
691  UT_FASTBOX(1)
692  UT_FASTBOX(2)
693 
694  return tmin <= tmax;
695 }
696 
697 #undef UT_FASTBOX
698 #undef UT_TESTMIN
699 #undef UT_TESTMAX
700 
701 template <typename T>
702 inline T
704  const UT_Vector3T<T> &v0,
705  const UT_Vector3T<T> &dir) const
706 {
707  T dist;
708 
709  // Approximate the box with a sphere, then find the distance from the
710  // line to the sphere.
711  dist = segmentPointDist2(center(), v0, v0+dir);
712  dist = SYSmax(SYSsqrt(dist) - getRadius(), 0.0);
713  return dist*dist;
714 }
715 
716 template <typename T>
717 inline void
719 {
720  vals[0][0] = vals[1][0] = vals[2][0] = -0.5*std::numeric_limits<T>::max();
721  vals[0][1] = vals[1][1] = vals[2][1] = 0.5*std::numeric_limits<T>::max();
722 }
723 
724 template <typename T>
725 inline void
727  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
728 {
729  vals[0][0] = min.x(); vals[0][1] = max.x();
730  vals[1][0] = min.y(); vals[1][1] = max.y();
731  vals[2][0] = min.z(); vals[2][1] = max.z();
732 }
733 
734 template <typename T>
735 inline void
737 {
738  vals[0][0] = vals[0][1] = pt.x();
739  vals[1][0] = vals[1][1] = pt.y();
740  vals[2][0] = vals[2][1] = pt.z();
741 }
742 
743 template <typename T>
744 inline void
746 {
747  vals[0][0] = box(0, 0);
748  vals[0][1] = box(0, 1);
749  vals[1][0] = box(1, 0);
750  vals[1][1] = box(1, 1);
751  vals[2][0] = box(2, 0);
752  vals[2][1] = box(2, 1);
753 }
754 
755 template <typename T>
756 inline void
758  const UT_Vector3T<T> &min, const UT_Vector3T<T> &max)
759 {
760  vals[0][0] = SYSmin(vals[0][0], min.x());
761  vals[0][1] = SYSmax(vals[0][1], max.x());
762  vals[1][0] = SYSmin(vals[1][0], min.y());
763  vals[1][1] = SYSmax(vals[1][1], max.y());
764  vals[2][0] = SYSmin(vals[2][0], min.z());
765  vals[2][1] = SYSmax(vals[2][1], max.z());
766 }
767 
768 template <typename T>
769 inline void
771 {
772  vals[0][0] = SYSmin(vals[0][0], pt.x());
773  vals[0][1] = SYSmax(vals[0][1], pt.x());
774  vals[1][0] = SYSmin(vals[1][0], pt.y());
775  vals[1][1] = SYSmax(vals[1][1], pt.y());
776  vals[2][0] = SYSmin(vals[2][0], pt.z());
777  vals[2][1] = SYSmax(vals[2][1], pt.z());
778 }
779 
780 // Extract the exponent of val and create a floating point value that is
781 // the minimum mantissa value for that exponent. If bits is larger than 0,
782 // we'll use that mantissa bit.
783 template <typename T>
784 template <typename Y>
785 inline Y
787 {
788  typedef SYS_FPRealUnionT<Y> FPRealUnion;
789  typedef typename FPRealUnion::uint_type UInt;
790 
791  static const int exponent_bits = FPRealUnion::EXPONENT_BITS;
792  static const int mantissa_bits = FPRealUnion::MANTISSA_BITS;
793  FPRealUnion tmp;
794 
795  tmp.fval = val;
796  tmp.uval >>= mantissa_bits;
797  tmp.uval &= ((UInt(1) << exponent_bits) - UInt(1)); // extract exponent
798  tmp.uval -= mantissa_bits - bits;
799  tmp.uval <<= mantissa_bits;
800  return tmp.fval;
801 }
802 
803 template <typename T>
804 inline void
806 {
807  T val;
808  int i;
809 
810  UT_ASSERT(bits >= 0 && bits < 128);
811  for (i = 0; i < 3; i++)
812  {
813  val = SYSmax(getMinMantissa(vals[i][0], bits),
814  getMinMantissa(vals[i][1], bits), min);
815 
816  UT_ASSERT(val > 0);
817  vals[i][0] -= val;
818  vals[i][1] += val;
819  }
820 }
821 
822 template <>
823 inline void
825 {
826  UT_ASSERT(!"enlargeFloats is no-op for int64");
827 }
828 
829 
830 template <typename T>
831 inline void
833 {
834  vals[0][0] = SYSmax(vals[0][0], box(0, 0));
835  vals[0][1] = SYSmin(vals[0][1], box(0, 1));
836  vals[1][0] = SYSmax(vals[1][0], box(1, 0));
837  vals[1][1] = SYSmin(vals[1][1], box(1, 1));
838  vals[2][0] = SYSmax(vals[2][0], box(2, 0));
839  vals[2][1] = SYSmin(vals[2][1], box(2, 1));
840 }
841 
842 template <typename T>
843 template <typename MATRIX>
844 inline void
846 {
847  UT_BoundingBoxT<T> newbox;
848  transform(mat, newbox);
849  *this = newbox;
850 }
851 
852 template <typename T>
853 template <typename MATRIX>
854 inline void
856  const MATRIX &mat, UT_BoundingBoxT<T> &newbox) const
857 {
858  newbox.initBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][0]) * mat);
859  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][0], vals[2][1]) * mat);
860  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][0]) * mat);
861  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][0], vals[1][1], vals[2][1]) * mat);
862  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][0]) * mat);
863  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][0], vals[2][1]) * mat);
864  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][0]) * mat);
865  newbox.enlargeBounds(UT_Vector3T<T>(vals[0][1], vals[1][1], vals[2][1]) * mat);
866 }
867 
868 template <typename T>
869 inline void
871 {
872  vals[0][0] += delta.x();
873  vals[0][1] += delta.x();
874  vals[1][0] += delta.y();
875  vals[1][1] += delta.y();
876  vals[2][0] += delta.z();
877  vals[2][1] += delta.z();
878 }
879 
880 #define UT_TESTMAX(face) if (t < tmax) { \
881  if (t < tmin) return 0; \
882  tmax = t; \
883  foundmax = face; \
884  }
885 #define UT_TESTMIN(face) if (t > tmin) { \
886  if (t > tmax) return 0; \
887  tmin = t; \
888  foundmin = face; \
889  }
890 #define UT_FASTBOX(face) \
891  ray = 1.0 / d(face); \
892  positive = (ray > 0.0); \
893  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX(face) \
894  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN(face) \
895  /**/
896 
897 template <typename T>
898 int
900  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
901  T maxdist, T *distance, UT_Vector3T<T> *nml) const
902 {
903  T t, tmin, tmax;
904  T ray;
905  int positive, foundmin, foundmax;
906 
907  foundmin = -1;
908  foundmax = -1;
909  tmin = 0;
910  tmax = maxdist;
911 
912  UT_FASTBOX(0)
913  UT_FASTBOX(1)
914  UT_FASTBOX(2)
915 
916  if (foundmin != -1)
917  {
918  // We intersect the minimum.
919  if(nml)
920  {
921  if(foundmin == 0) nml->assign(1.0, 0.0, 0.0);
922  else if(foundmin == 1) nml->assign(0.0, 1.0, 0.0);
923  else nml->assign(0.0, 0.0, 1.0);
924  }
925 
926  if(distance) *distance = tmin;
927  return 1;
928  }
929  else if (foundmax != -1)
930  {
931  // We did not intersect any minimum planes, therefore are
932  // inside provided we intersected a maximum plane and weren't
933  // trivially rejected.
934  if(nml)
935  {
936  if(foundmax == 0) nml->assign(1.0, 0.0, 0.0);
937  else if(foundmax == 1) nml->assign(0.0, 1.0, 0.0);
938  else nml->assign(0.0, 0.0, 1.0);
939  }
940 
941  if(distance) *distance = tmax;
942  return 1;
943  }
944  return 0;
945 }
946 
947 #undef UT_FASTBOX
948 #undef UT_TESTMIN
949 #undef UT_TESTMAX
950 
951 #define UT_TESTMAX if(t < tmax) { if(t < tmin) return 0; tmax = t; }
952 #define UT_TESTMIN if(t > tmin) { if(t > tmax) return 0; tmin = t; }
953 
954 #define UT_FASTBOX(face) \
955  ray = 1.0 / d(face); \
956  positive = (ray > 0.0); \
957  t = (vals[face][ positive] - o(face))*ray; UT_TESTMAX \
958  t = (vals[face][1-positive] - o(face))*ray; UT_TESTMIN \
959  /**/
960 
961 template <typename T>
962 inline int
964  const UT_Vector3T<T> &o, const UT_Vector3T<T> &d,
965  T &tmin, T &tmax) const
966 {
967  T t;
968  T ray;
969  int positive;
970 
971  tmin = -std::numeric_limits<T>::max();
972  tmax = +std::numeric_limits<T>::max();
973 
974  UT_FASTBOX(0)
975  UT_FASTBOX(1)
976  UT_FASTBOX(2)
977 
978  return 1;
979 }
980 
981 #undef UT_FASTBOX
982 #undef UT_TESTMIN
983 #undef UT_TESTMAX
984 
985 template <typename T>
986 inline int
988  const UT_Vector3T<T> &org, const UT_Vector3T<T> &dir,
989  T radius, T mint, T maxt) const
990 {
991  UT_BoundingBoxT<T> tmp;
992  T tmin, tmax;
993 
994  tmp = *this;
995 
996  tmp.expandBounds(radius, radius, radius);
997  if (!tmp.intersectRange(org, dir, tmin, tmax))
998  {
999  // No hit at all.
1000  return 0;
1001  }
1002 
1003  // Check if it is within our tube.
1004  if (tmax < mint)
1005  return 0;
1006  if (tmin > maxt)
1007  return 0;
1008 
1009  return 1;
1010 }
1011 
1012 template <typename T>
1013 inline T
1015 {
1016  T t = vals[0][1] - vals[0][0];
1017  T d = vals[1][1] - vals[1][0];
1018 
1019  if (t < d) t = d;
1020  d = vals[2][1] - vals[2][0];
1021  if (t < d) t = d;
1022  return t;
1023 }
1024 
1025 template <typename T>
1026 inline T
1028 {
1029  T t = vals[0][1] - vals[0][0];
1030  T d = vals[1][1] - vals[1][0];
1031 
1032  axis = 0;
1033  if (t < d) { t = d; axis = 1; }
1034  d = vals[2][1] - vals[2][0];
1035  if (t < d) { t = d; axis = 2; }
1036  return t;
1037 }
1038 
1039 template <typename T>
1040 inline T
1041 UT_BoundingBoxT<T>::computeDelta(T bmin, T bmax, T val)
1042 {
1043  return (val > bmax) ? val - bmax : SYSmin(val - bmin, T(0));
1044 }
1045 
1046 template <typename T>
1047 inline UT_Vector3T<T>
1049 {
1050  UT_Vector3T<T> delta;
1051 
1052  delta.x() = computeDelta(vals[0][0], vals[0][1], p.x());
1053  delta.y() = computeDelta(vals[1][0], vals[1][1], p.y());
1054  delta.z() = computeDelta(vals[2][0], vals[2][1], p.z());
1055 
1056  return delta;
1057 }
1058 
1059 template <typename T>
1060 inline T
1061 UT_BoundingBoxT<T>::computeDelta(T amin, T amax, T bmin, T bmax)
1062 {
1063  T d1, d2;
1064 
1065  d1 = SYSmax(bmin - amax, T(0));
1066  d2 = SYSmax(amin - bmax, T(0));
1067  return d1 > d2 ? d1 : -d2;
1068 }
1069 
1070 template <typename T>
1071 inline UT_Vector3T<T>
1073 {
1074  UT_Vector3T<T> delta;
1075 
1076  delta.x() = computeDelta(
1077  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1078  delta.y() = computeDelta(
1079  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1080  delta.z() = computeDelta(
1081  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1082 
1083  return delta;
1084 }
1085 
1086 template <typename T>
1087 inline T
1088 UT_BoundingBoxT<T>::computeMaxDelta(T bmin, T bmax, T val)
1089 {
1090  if (SYSabs(val - bmin) > SYSabs(val - bmax))
1091  return val - bmin;
1092  else
1093  return val - bmax;
1094 }
1095 
1096 template <typename T>
1097 inline UT_Vector3T<T>
1099 {
1100  UT_Vector3T<T> delta;
1101 
1102  delta.x() = computeMaxDelta(vals[0][0], vals[0][1], p.x());
1103  delta.y() = computeMaxDelta(vals[1][0], vals[1][1], p.y());
1104  delta.z() = computeMaxDelta(vals[2][0], vals[2][1], p.z());
1105 
1106  return delta;
1107 }
1108 
1109 template <typename T>
1110 inline T
1111 UT_BoundingBoxT<T>::computeOverlapDelta(T amin, T amax, T bmin, T bmax)
1112 {
1113  T d1, d2;
1114 
1115  d1 = bmax - amax;
1116  d2 = bmin - amin;
1117 
1118  // Opposite signs imply that one box is already enclosed in the other
1119  return ((d1 < 0) != (d2 < 0)) ? 0 : (SYSabs(d1) < SYSabs(d2) ? d1 : d2);
1120 }
1121 
1122 template <typename T>
1123 inline UT_Vector3T<T>
1125 {
1126  UT_Vector3T<T> delta;
1127 
1128  delta.x() = computeOverlapDelta(
1129  vals[0][0], vals[0][1], box.vals[0][0], box.vals[0][1]);
1130  delta.y() = computeOverlapDelta(
1131  vals[1][0], vals[1][1], box.vals[1][0], box.vals[1][1]);
1132  delta.z() = computeOverlapDelta(
1133  vals[2][0], vals[2][1], box.vals[2][0], box.vals[2][1]);
1134 
1135  return delta;
1136 }
1137 
1138 template <typename T>
1139 inline int
1141 {
1142  int code = 0;
1143 
1144  if (pt.x() < vals[0][0]) code |= 1;
1145  else if (pt.x() > vals[0][1]) code |= 2;
1146  if (pt.y() < vals[1][0]) code |= 4;
1147  else if (pt.y() > vals[1][1]) code |= 8;
1148  if (pt.z() < vals[2][0]) code |= 16;
1149  else if (pt.z() > vals[2][1]) code |= 32;
1150 
1151  return code;
1152 }
1153 
1154 template <typename T>
1155 inline T
1157 {
1158  T xlen, ylen, zlen;
1159 
1160  xlen = sizeX(); ylen = sizeY(); zlen = sizeZ();
1161  return 2*(xlen*ylen+ylen*zlen+zlen*xlen);
1162 }
1163 
1164 template <typename T>
1165 inline void
1167 {
1168  vals[0][0] += vec[0];
1169  vals[1][0] += vec[1];
1170  vals[2][0] += vec[2];
1171 }
1172 
1173 template <typename T>
1174 inline void
1176 {
1177  vals[0][1] += vec[0];
1178  vals[1][1] += vec[1];
1179  vals[2][1] += vec[2];
1180 }
1181 
1182 template <typename T>
1183 inline void
1185  const UT_Vector3T<T> &offset)
1186 {
1187  vals[0][0] *= scale[0]; vals[0][1] *= scale[0];
1188  vals[1][0] *= scale[1]; vals[1][1] *= scale[1];
1189  vals[2][0] *= scale[2]; vals[2][1] *= scale[2];
1190  vals[0][0] += offset[0]; vals[0][1] += offset[0];
1191  vals[1][0] += offset[1]; vals[1][1] += offset[1];
1192  vals[2][0] += offset[2]; vals[2][1] += offset[2];
1193 }
1194 
1195 template <typename T>
1196 inline int
1198 {
1199  return sizeX() > sizeY() ? (sizeX() > sizeZ() ? 0 : 2) :
1200  sizeY() > sizeZ() ? 1 : 2;
1201 }
1202 
1203 template <typename T>
1204 inline int
1206 {
1207  return sizeX() < sizeY() ? (sizeX() < sizeZ() ? 0 : 2) :
1208  sizeY() < sizeZ() ? 1 : 2;
1209 }
1210 
1211 template <typename T>
1212 inline void
1214 {
1215  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1216  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1217  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1218  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1219  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1220  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1221  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1222  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1223 }
1224 
1225 template <typename T>
1226 inline void
1228 {
1229  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0], 1.0);
1230  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1], 1.0);
1231  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0], 1.0);
1232  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1], 1.0);
1233  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0], 1.0);
1234  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1], 1.0);
1235  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0], 1.0);
1236  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1], 1.0);
1237 }
1238 
1239 template <typename T>
1240 template <typename MATRIX>
1241 inline int
1243  UT_Vector3T<T> (&ptarray)[8],
1244  const MATRIX &transform_matrix) const
1245 {
1246  ptarray[0].assign(vals[0][0], vals[1][0], vals[2][0]);
1247  ptarray[1].assign(vals[0][0], vals[1][0], vals[2][1]);
1248  ptarray[2].assign(vals[0][0], vals[1][1], vals[2][0]);
1249  ptarray[3].assign(vals[0][0], vals[1][1], vals[2][1]);
1250  ptarray[4].assign(vals[0][1], vals[1][0], vals[2][0]);
1251  ptarray[5].assign(vals[0][1], vals[1][0], vals[2][1]);
1252  ptarray[6].assign(vals[0][1], vals[1][1], vals[2][0]);
1253  ptarray[7].assign(vals[0][1], vals[1][1], vals[2][1]);
1254 
1255  if ( transform_matrix.isIdentity() )
1256  return 0;
1257 
1258  ptarray[0] *= transform_matrix;
1259  ptarray[1] *= transform_matrix;
1260  ptarray[2] *= transform_matrix;
1261  ptarray[3] *= transform_matrix;
1262  ptarray[4] *= transform_matrix;
1263  ptarray[5] *= transform_matrix;
1264  ptarray[6] *= transform_matrix;
1265  ptarray[7] *= transform_matrix;
1266 
1267  return 1;
1268 }
1269 
1270 
1271 #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:1952
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:495
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:669
UT_Vector3T< T > maxvec() const
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
#define SYSabs(a)
Definition: SYS_Math.h:1954
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:39
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:176
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:493
T sizeY() const
T segmentPointDist2(const UT_Vector3T< T > &pos, const UT_Vector3T< T > &pt1, const UT_Vector3T< T > &pt2)
Definition: UT_Vector3.h:1132
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
UT_API size_t UTformatBuffer(char *buf, size_t bufsize, const UT_BoundingBoxT< T > &v)
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:497
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:164
#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 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:696
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:289
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:649
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:165
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:667
#define SYSmin(a, b)
Definition: SYS_Math.h:1953
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:665
int getOutCode(const UT_Vector3T< T > &pt) const
Finds the out code of the point relative to this box: