mBox.h 21 KB

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