mBox.h

Engine/source/math/mBox.h

More...

Classes:

class

Clone of Box3F, using 3D types.

class

Axis-aligned bounding box (AABB).

class

Bounding Box.

Public Defines

define
EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
 (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;
define
EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
else  (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;
define
EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
else  (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;

Detailed Description

Public Defines

EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
 (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;
EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
else  (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;
EXTEND_AXIS(AXIS)  (p.AXIS < minExtents.AXIS)       \
   minExtents.AXIS = p.AXIS;        \
else  (p.AXIS > maxExtents.AXIS)  \
   maxExtents.AXIS = p.AXIS;
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _MBOX_H_
 25#define _MBOX_H_
 26
 27#ifndef _MBOXBASE_H_
 28#include "math/mBoxBase.h"
 29#endif
 30
 31#ifndef _MPOINT3_H_
 32#include "math/mPoint3.h"
 33#endif
 34
 35#ifndef _MPOINT2_H_
 36#include "math/mPoint2.h"
 37#endif
 38
 39
 40class MatrixF;
 41class SphereF;
 42
 43
 44
 45/// Axis-aligned bounding box (AABB).
 46///
 47/// A helper class for working with boxes. It runs at F32 precision.
 48///
 49/// @see Box3D
 50class Box3F : public BoxBase
 51{
 52   public:
 53
 54      Point3F minExtents; ///< Minimum extents of box
 55      Point3F maxExtents; ///< Maximum extents of box
 56
 57      Box3F() { }
 58
 59      /// Create a box from two points.
 60      ///
 61      /// Normally, this function will compensate for mismatched
 62      /// min/max values. If you know your values are valid, you
 63      /// can set in_overrideCheck to true and skip this.
 64      ///
 65      /// @param   in_rMin          Minimum extents of box.
 66      /// @param   in_rMax          Maximum extents of box.
 67      /// @param   in_overrideCheck  Pass true to skip check of extents.
 68      Box3F( const Point3F& in_rMin, const Point3F& in_rMax, const bool in_overrideCheck = false );
 69
 70      /// Create a box from six extent values.
 71      ///
 72      /// No checking is performed as to the validity of these
 73      /// extents, unlike the other constructor.
 74      Box3F( const F32 &xMin, const F32 &yMin, const F32 &zMin, 
 75             const F32 &xMax, const F32 &yMax, const F32 &zMax );
 76
 77      Box3F(F32 cubeSize);
 78
 79      void set( const Point3F& in_rMin, const Point3F& in_rMax );
 80
 81      void set( const F32 &xMin, const F32 &yMin, const F32 &zMin, 
 82                const F32 &xMax, const F32 &yMax, const F32 &zMax );
 83
 84      /// Create box around origin given lengths
 85      void set( const Point3F& in_Length );   
 86
 87      /// Recenter the box
 88      void setCenter( const Point3F& center );
 89
 90      /// Check to see if a point is contained in this box.
 91      bool isContained( const Point3F& in_rContained ) const;
 92      
 93      /// Check if the Point2F is within the box xy extents.
 94      bool isContained( const Point2F &pt ) const;
 95
 96      /// Check to see if another box overlaps this box.
 97      bool isOverlapped( const Box3F&  in_rOverlap ) const;
 98
 99      /// Check if the given sphere overlaps with the box.
100      bool isOverlapped( const SphereF& sphere ) const;
101
102      /// Check to see if another box is contained in this box.
103      bool isContained( const Box3F& in_rContained ) const;
104
105      /// Returns the length of the x extent.
106      F32 len_x() const { return maxExtents.x - minExtents.x; }
107
108      /// Returns the length of the y extent.
109      F32 len_y() const  { return maxExtents.y - minExtents.y; }
110
111      /// Returns the length of the z extent.
112      F32 len_z() const  { return maxExtents.z - minExtents.z; }
113
114      /// Returns the minimum box extent.
115      F32 len_min() const { return getMin( len_x(), getMin( len_y(), len_z() ) ); }
116
117      /// Returns the maximum box extent.
118      F32 len_max() const { return getMax( len_x(), getMax( len_y(), len_z() ) ); }
119
120      /// Returns the diagonal box length.
121      F32 len() const { return ( maxExtents - minExtents ).len(); }
122
123      /// Returns the length of extent by axis index.
124      ///
125      /// @param axis The axis index of 0, 1, or 2.
126      ///
127      F32 len( S32 axis ) const { return maxExtents[axis] - minExtents[axis]; }
128
129      /// Returns true if any of the extent axes
130      /// are less than or equal to zero.
131      bool isEmpty() const { return len_x() <= 0.0f || len_y() <= 0.0f || len_z() <= 0.0f; }
132
133      /// Perform an intersection operation with another box
134      /// and store the results in this box.
135      void intersect( const Box3F &in_rIntersect );
136      void intersect( const Point3F &in_rIntersect );
137
138      /// Return the overlap between this box and @a otherBox.
139      Box3F getOverlap( const Box3F& otherBox ) const;
140
141      /// Return the volume of the box.
142      F32 getVolume() const;
143
144      /// Get the center of this box.
145      ///
146      /// This is the average of min and max.
147      void getCenter( Point3F *center ) const;
148      Point3F getCenter() const;
149
150      /// Returns the max minus the min extents.
151      Point3F getExtents() const { return maxExtents - minExtents; }
152
153      /// Collide a line against the box.
154      ///
155      /// @param   start   Start of line.
156      /// @param   end     End of line.
157      /// @param   t       Value from 0.0-1.0, indicating position
158      ///                  along line of collision.
159      /// @param   n       Normal of collision.
160      bool collideLine( const Point3F &start, const Point3F &end, F32 *t, Point3F *n ) const;
161
162      /// Collide a line against the box.
163      ///
164      /// Returns true on collision.
165      bool collideLine( const Point3F &start, const Point3F &end ) const;
166
167      /// Collide an oriented box against the box.
168      ///
169      /// Returns true if "oriented" box collides with us.
170      /// Assumes incoming box is centered at origin of source space.
171      ///
172      /// @param   radii   The dimension of incoming box (half x,y,z length).
173      /// @param   toUs    A transform that takes incoming box into our space.
174      bool collideOrientedBox( const Point3F &radii, const MatrixF &toUs ) const;
175
176      /// Check that the min extents of the box is
177      /// less than or equal to the max extents.
178      bool isValidBox() const { return (minExtents.x <= maxExtents.x) &&
179                                       (minExtents.y <= maxExtents.y) &&
180                                       (minExtents.z <= maxExtents.z); }
181
182      /// Return the closest point of the box, relative to the passed point.
183      Point3F getClosestPoint( const Point3F &refPt ) const;
184
185      /// Return distance of closest point on box to refPt.
186      F32 getDistanceToPoint( const Point3F &refPt ) const;
187
188      /// Return the squared distance to  closest point on box to refPt.
189      F32 getSqDistanceToPoint( const Point3F &refPt ) const;
190
191      /// Return one of the corner vertices of the box.
192      Point3F computeVertex( U32 corner ) const;
193
194      /// Get the length of the longest diagonal in the box.
195      F32 getGreatestDiagonalLength() const;
196
197      /// Return the bounding sphere that contains this AABB.
198      SphereF getBoundingSphere() const;
199
200      /// Extend the box to include point.
201      /// @see Invalid
202      void extend( const Point3F &p );
203
204      /// Scale the box by a Point3F or F32
205      void scale( const Point3F &amt );
206      void scale( F32 amt );
207      
208      /// Equality operator.
209      bool operator==( const Box3F &b ) const;
210      
211      /// Inequality operator.
212      bool operator!=( const Box3F &b ) const;
213
214      /// Create an AABB that fits around the given point cloud, i.e.
215      /// find the minimum and maximum extents of the given point set.
216      static Box3F aroundPoints( const Point3F* points, U32 numPoints );
217
218   public:
219
220      /// An inverted bounds where the minimum point is positive
221      /// and the maximum point is negative.  Should be used with
222      /// extend() to construct a minimum volume box.
223      /// @see extend
224      static const Box3F Invalid;
225
226      /// A box that covers the entire floating point range.
227      static const Box3F Max;
228
229      /// A null box of zero size.
230      static const Box3F Zero;
231};
232
233inline Box3F::Box3F(const Point3F& in_rMin, const Point3F& in_rMax, const bool in_overrideCheck)
234 : minExtents(in_rMin),
235   maxExtents(in_rMax)
236{
237   if (in_overrideCheck == false) {
238      minExtents.setMin(in_rMax);
239      maxExtents.setMax(in_rMin);
240   }
241}
242
243inline Box3F::Box3F( const F32 &xMin, const F32 &yMin, const F32 &zMin, 
244                    const F32 &xMax, const F32 &yMax, const F32 &zMax )
245   : minExtents(xMin,yMin,zMin),
246     maxExtents(xMax,yMax,zMax)
247{
248}
249
250inline Box3F::Box3F(F32 cubeSize)
251   : minExtents(-0.5f * cubeSize, -0.5f * cubeSize, -0.5f * cubeSize),
252     maxExtents(0.5f * cubeSize, 0.5f * cubeSize, 0.5f * cubeSize)
253{
254}
255
256inline void Box3F::set(const Point3F& in_rMin, const Point3F& in_rMax)
257{
258   minExtents.set(in_rMin);
259   maxExtents.set(in_rMax);
260}
261
262inline void Box3F::set( const F32 &xMin, const F32 &yMin, const F32 &zMin, 
263                        const F32 &xMax, const F32 &yMax, const F32 &zMax  )
264{
265   minExtents.set( xMin, yMin, zMin );
266   maxExtents.set( xMax, yMax, zMax );
267}
268
269inline void Box3F::set(const Point3F& in_Length)
270{
271   minExtents.set(-in_Length.x * 0.5f, -in_Length.y * 0.5f, -in_Length.z * 0.5f);
272   maxExtents.set( in_Length.x * 0.5f,  in_Length.y * 0.5f,  in_Length.z * 0.5f);
273}
274
275inline void Box3F::setCenter(const Point3F& center)
276{
277   F32 halflenx = len_x() * 0.5f;
278   F32 halfleny = len_y() * 0.5f;
279   F32 halflenz = len_z() * 0.5f;
280
281   minExtents.set(center.x-halflenx, center.y-halfleny, center.z-halflenz);
282   maxExtents.set(center.x+halflenx, center.y+halfleny, center.z+halflenz);
283}
284
285inline bool Box3F::isContained(const Point3F& in_rContained) const
286{
287   return (in_rContained.x >= minExtents.x && in_rContained.x < maxExtents.x) &&
288          (in_rContained.y >= minExtents.y && in_rContained.y < maxExtents.y) &&
289          (in_rContained.z >= minExtents.z && in_rContained.z < maxExtents.z);
290}
291
292inline bool Box3F::isContained( const Point2F &pt ) const
293{
294   return ( pt.x >= minExtents.x && pt.x < maxExtents.x ) &&
295          ( pt.y >= minExtents.y && pt.y < maxExtents.y );      
296}
297
298inline bool Box3F::isOverlapped(const Box3F& in_rOverlap) const
299{
300   if (in_rOverlap.minExtents.x > maxExtents.x ||
301       in_rOverlap.minExtents.y > maxExtents.y ||
302       in_rOverlap.minExtents.z > maxExtents.z)
303      return false;
304   if (in_rOverlap.maxExtents.x < minExtents.x ||
305       in_rOverlap.maxExtents.y < minExtents.y ||
306       in_rOverlap.maxExtents.z < minExtents.z)
307      return false;
308   return true;
309}
310
311inline bool Box3F::isContained(const Box3F& in_rContained) const
312{
313   return (minExtents.x <= in_rContained.minExtents.x) &&
314          (minExtents.y <= in_rContained.minExtents.y) &&
315          (minExtents.z <= in_rContained.minExtents.z) &&
316          (maxExtents.x >= in_rContained.maxExtents.x) &&
317          (maxExtents.y >= in_rContained.maxExtents.y) &&
318          (maxExtents.z >= in_rContained.maxExtents.z);
319}
320
321inline void Box3F::intersect(const Box3F& in_rIntersect)
322{
323   minExtents.setMin(in_rIntersect.minExtents);
324   maxExtents.setMax(in_rIntersect.maxExtents);
325}
326
327inline void Box3F::intersect(const Point3F& in_rIntersect)
328{
329   minExtents.setMin(in_rIntersect);
330   maxExtents.setMax(in_rIntersect);
331}
332
333inline Box3F Box3F::getOverlap( const Box3F& otherBox ) const
334{
335   Box3F overlap;
336
337   for( U32 i = 0; i < 3; ++ i )
338   {
339      if( minExtents[ i ] > otherBox.maxExtents[ i ] || otherBox.minExtents[ i ] > maxExtents[ i ] )
340      {
341         overlap.minExtents[ i ] = 0.f;
342         overlap.maxExtents[ i ] = 0.f;
343      }
344      else
345      {
346         overlap.minExtents[ i ] = getMax( minExtents[ i ], otherBox.minExtents[ i ] );
347         overlap.maxExtents[ i ] = getMin( maxExtents[ i ], otherBox.maxExtents[ i ] );
348      }
349   }
350
351   return overlap;
352}
353
354inline F32 Box3F::getVolume() const
355{
356   return ( maxExtents.x - minExtents.x ) * ( maxExtents.y - minExtents.y ) * ( maxExtents.z - minExtents.z );
357}
358
359inline void Box3F::getCenter(Point3F* center) const
360{
361   center->x = (minExtents.x + maxExtents.x) * 0.5f;
362   center->y = (minExtents.y + maxExtents.y) * 0.5f;
363   center->z = (minExtents.z + maxExtents.z) * 0.5f;
364}
365
366inline Point3F Box3F::getCenter() const
367{
368   Point3F center;
369   center.x = (minExtents.x + maxExtents.x) * 0.5f;
370   center.y = (minExtents.y + maxExtents.y) * 0.5f;
371   center.z = (minExtents.z + maxExtents.z) * 0.5f;
372   return center;
373}
374
375inline Point3F Box3F::getClosestPoint(const Point3F& refPt) const
376{
377   Point3F closest;
378   if      (refPt.x <= minExtents.x) closest.x = minExtents.x;
379   else if (refPt.x >  maxExtents.x) closest.x = maxExtents.x;
380   else                       closest.x = refPt.x;
381
382   if      (refPt.y <= minExtents.y) closest.y = minExtents.y;
383   else if (refPt.y >  maxExtents.y) closest.y = maxExtents.y;
384   else                       closest.y = refPt.y;
385
386   if      (refPt.z <= minExtents.z) closest.z = minExtents.z;
387   else if (refPt.z >  maxExtents.z) closest.z = maxExtents.z;
388   else                       closest.z = refPt.z;
389
390   return closest;
391}
392
393inline F32 Box3F::getDistanceToPoint(const Point3F& refPt) const
394{
395   return mSqrt( getSqDistanceToPoint( refPt ) );
396}
397
398inline F32 Box3F::getSqDistanceToPoint( const Point3F &refPt ) const
399{
400   F32 sqDist = 0.0f;
401
402   for ( U32 i=0; i < 3; i++ )
403   {
404      const F32 v = refPt[i];
405      if ( v < minExtents[i] )
406         sqDist += mSquared( minExtents[i] - v );
407      else if ( v > maxExtents[i] )
408         sqDist += mSquared( v - maxExtents[i] );
409   }
410
411   return sqDist;
412}
413
414inline void Box3F::extend(const Point3F & p)
415{
416#define EXTEND_AXIS(AXIS)    \
417if (p.AXIS < minExtents.AXIS)       \
418   minExtents.AXIS = p.AXIS;        \
419if (p.AXIS > maxExtents.AXIS)  \
420   maxExtents.AXIS = p.AXIS;
421
422   EXTEND_AXIS(x)
423   EXTEND_AXIS(y)
424   EXTEND_AXIS(z)
425
426#undef EXTEND_AXIS
427}
428
429inline void Box3F::scale( const Point3F &amt )
430{
431   minExtents *= amt;
432   maxExtents *= amt;
433}
434
435inline void Box3F::scale( F32 amt )
436{
437   minExtents *= amt;
438   maxExtents *= amt;
439}
440
441inline bool Box3F::operator==( const Box3F &b ) const
442{
443   return minExtents.equal( b.minExtents ) && maxExtents.equal( b.maxExtents );
444}
445
446inline bool Box3F::operator!=( const Box3F &b ) const
447{
448   return !minExtents.equal( b.minExtents ) || !maxExtents.equal( b.maxExtents );   
449}
450
451//------------------------------------------------------------------------------
452/// Clone of Box3F, using 3D types.
453///
454/// 3D types use F64.
455///
456/// @see Box3F
457class Box3D
458{
459  public:
460   Point3D minExtents;
461   Point3D maxExtents;
462
463  public:
464   Box3D() { }
465   Box3D(const Point3D& in_rMin, const Point3D& in_rMax, const bool in_overrideCheck = false);
466
467   bool isContained(const Point3D& in_rContained) const;
468   bool isOverlapped(const Box3D&  in_rOverlap) const;
469
470   F64 len_x() const;
471   F64 len_y() const;
472   F64 len_z() const;
473
474   void intersect(const Box3D& in_rIntersect);
475   void getCenter(Point3D* center) const;
476
477   void extend(const Point3D & p);
478};
479
480inline Box3D::Box3D(const Point3D& in_rMin, const Point3D& in_rMax, const bool in_overrideCheck)
481 : minExtents(in_rMin),
482   maxExtents(in_rMax)
483{
484   if (in_overrideCheck == false) {
485      minExtents.setMin(in_rMax);
486      maxExtents.setMax(in_rMin);
487   }
488}
489
490inline bool Box3D::isContained(const Point3D& in_rContained) const
491{
492   return (in_rContained.x >= minExtents.x && in_rContained.x < maxExtents.x) &&
493          (in_rContained.y >= minExtents.y && in_rContained.y < maxExtents.y) &&
494          (in_rContained.z >= minExtents.z && in_rContained.z < maxExtents.z);
495}
496
497inline bool Box3D::isOverlapped(const Box3D& in_rOverlap) const
498{
499   if (in_rOverlap.minExtents.x > maxExtents.x ||
500       in_rOverlap.minExtents.y > maxExtents.y ||
501       in_rOverlap.minExtents.z > maxExtents.z)
502      return false;
503   if (in_rOverlap.maxExtents.x < minExtents.x ||
504       in_rOverlap.maxExtents.y < minExtents.y ||
505       in_rOverlap.maxExtents.z < minExtents.z)
506      return false;
507   return true;
508}
509
510inline F64 Box3D::len_x() const
511{
512   return maxExtents.x - minExtents.x;
513}
514
515inline F64 Box3D::len_y() const
516{
517   return maxExtents.y - minExtents.y;
518}
519
520inline F64 Box3D::len_z() const
521{
522   return maxExtents.z - minExtents.z;
523}
524
525inline void Box3D::intersect(const Box3D& in_rIntersect)
526{
527   minExtents.setMin(in_rIntersect.minExtents);
528   maxExtents.setMax(in_rIntersect.maxExtents);
529}
530
531inline void Box3D::getCenter(Point3D* center) const
532{
533   center->x = (minExtents.x + maxExtents.x) * 0.5;
534   center->y = (minExtents.y + maxExtents.y) * 0.5;
535   center->z = (minExtents.z + maxExtents.z) * 0.5;
536}
537
538inline void Box3D::extend(const Point3D & p)
539{
540#define EXTEND_AXIS(AXIS)    \
541if (p.AXIS < minExtents.AXIS)       \
542   minExtents.AXIS = p.AXIS;        \
543else if (p.AXIS > maxExtents.AXIS)  \
544   maxExtents.AXIS = p.AXIS;
545
546   EXTEND_AXIS(x)
547   EXTEND_AXIS(y)
548   EXTEND_AXIS(z)
549
550#undef EXTEND_AXIS
551}
552
553
554/// Bounding Box
555///
556/// A helper class for working with boxes. It runs at F32 precision.
557///
558/// @see Box3D
559class Box3I
560{
561public:
562   Point3I minExtents; ///< Minimum extents of box
563   Point3I maxExtents; ///< Maximum extents of box
564
565public:
566   Box3I() { }
567
568   /// Create a box from two points.
569   ///
570   /// Normally, this function will compensate for mismatched
571   /// min/max values. If you know your values are valid, you
572   /// can set in_overrideCheck to true and skip this.
573   ///
574   /// @param   in_rMin          Minimum extents of box.
575   /// @param   in_rMax          Maximum extents of box.
576   /// @param   in_overrideCheck  Pass true to skip check of extents.
577   Box3I(const Point3I& in_rMin, const Point3I& in_rMax, const bool in_overrideCheck = false);
578
579   /// Create a box from six extent values.
580   ///
581   /// No checking is performed as to the validity of these
582   /// extents, unlike the other constructor.
583   Box3I(S32 xmin, S32 ymin, S32 zmin, S32 max, S32 ymax, S32 zmax);
584
585   /// Check to see if a point is contained in this box.
586   bool isContained(const Point3I& in_rContained) const;
587
588   /// Check to see if another box overlaps this box.
589   bool isOverlapped(const Box3I&  in_rOverlap) const;
590
591   /// Check to see if another box is contained in this box.
592   bool isContained(const Box3I& in_rContained) const;
593
594   S32 len_x() const;
595   S32 len_y() const;
596   S32 len_z() const;
597
598   /// Perform an intersection operation with another box
599   /// and store the results in this box.
600   void intersect(const Box3I& in_rIntersect);
601
602   /// Get the center of this box.
603   ///
604   /// This is the average of min and max.
605   void getCenter(Point3I* center) const;
606
607   /// Check that the box is valid.
608   ///
609   /// Currently, this just means that min < max.
610   bool isValidBox() const 
611   { 
612      return (minExtents.x <= maxExtents.x) &&
613         (minExtents.y <= maxExtents.y) &&
614         (minExtents.z <= maxExtents.z); 
615   }
616
617   void extend(const Point3I & p);
618};
619
620inline Box3I::Box3I(const Point3I& in_rMin, const Point3I& in_rMax, const bool in_overrideCheck)
621: minExtents(in_rMin),
622maxExtents(in_rMax)
623{
624   if (in_overrideCheck == false) 
625   {
626      minExtents.setMin(in_rMax);
627      maxExtents.setMax(in_rMin);
628   }
629}
630
631inline Box3I::Box3I(S32 xMin, S32 yMin, S32 zMin, S32 xMax, S32 yMax, S32 zMax)
632: minExtents(xMin,yMin,zMin),
633maxExtents(xMax,yMax,zMax)
634{
635}
636
637inline bool Box3I::isContained(const Point3I& in_rContained) const
638{
639   return (in_rContained.x >= minExtents.x && in_rContained.x < maxExtents.x) &&
640      (in_rContained.y >= minExtents.y && in_rContained.y < maxExtents.y) &&
641      (in_rContained.z >= minExtents.z && in_rContained.z < maxExtents.z);
642}
643
644inline bool Box3I::isOverlapped(const Box3I& in_rOverlap) const
645{
646   if (in_rOverlap.minExtents.x > maxExtents.x ||
647      in_rOverlap.minExtents.y > maxExtents.y ||
648      in_rOverlap.minExtents.z > maxExtents.z)
649      return false;
650   if (in_rOverlap.maxExtents.x < minExtents.x ||
651      in_rOverlap.maxExtents.y < minExtents.y ||
652      in_rOverlap.maxExtents.z < minExtents.z)
653      return false;
654   return true;
655}
656
657inline bool Box3I::isContained(const Box3I& in_rContained) const
658{
659   return (minExtents.x <= in_rContained.minExtents.x) &&
660      (minExtents.y <= in_rContained.minExtents.y) &&
661      (minExtents.z <= in_rContained.minExtents.z) &&
662      (maxExtents.x >= in_rContained.maxExtents.x) &&
663      (maxExtents.y >= in_rContained.maxExtents.y) &&
664      (maxExtents.z >= in_rContained.maxExtents.z);
665}
666
667inline S32 Box3I::len_x() const
668{
669   return maxExtents.x - minExtents.x;
670}
671
672inline S32 Box3I::len_y() const
673{
674   return maxExtents.y - minExtents.y;
675}
676
677inline S32 Box3I::len_z() const
678{
679   return maxExtents.z - minExtents.z;
680}
681
682inline void Box3I::intersect(const Box3I& in_rIntersect)
683{
684   minExtents.setMin(in_rIntersect.minExtents);
685   maxExtents.setMax(in_rIntersect.maxExtents);
686}
687
688inline void Box3I::getCenter(Point3I* center) const
689{
690   center->x = (minExtents.x + maxExtents.x) >> 1;
691   center->y = (minExtents.y + maxExtents.y) >> 1;
692   center->z = (minExtents.z + maxExtents.z) >> 1;
693}
694
695inline void Box3I::extend(const Point3I & p)
696{
697#define EXTEND_AXIS(AXIS)    \
698if (p.AXIS < minExtents.AXIS)       \
699   minExtents.AXIS = p.AXIS;        \
700else if (p.AXIS > maxExtents.AXIS)  \
701   maxExtents.AXIS = p.AXIS;
702
703   EXTEND_AXIS(x)
704   EXTEND_AXIS(y)
705   EXTEND_AXIS(z)
706
707#undef EXTEND_AXIS
708}
709
710
711#endif // _DBOX_H_
712