mBox.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 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 _MPOINT_H_
  25. #include "math/mPoint.h"
  26. #endif
  27. //------------------------------------------------------------------------------
  28. /// Bounding Box
  29. ///
  30. /// A helper class for working with boxes. It runs at F32 precision.
  31. ///
  32. /// @see Box3D
  33. class Box3F
  34. {
  35. public:
  36. Point3F mMin; ///< Minimum extents of box
  37. Point3F mMax; ///< Maximum extents of box
  38. public:
  39. Box3F() { }
  40. /// Create a box from two points.
  41. ///
  42. /// Normally, this function will compensate for mismatched
  43. /// min/max values. If you know your values are valid, you
  44. /// can set in_overrideCheck to true and skip this.
  45. ///
  46. /// @param in_rMin Minimum extents of box.
  47. /// @param in_rMax Maximum extents of box.
  48. /// @param in_overrideCheck Pass true to skip check of extents.
  49. Box3F(const Point3F& in_rMin, const Point3F& in_rMax, const bool in_overrideCheck = false);
  50. /// Create a box from six extent values.
  51. ///
  52. /// No checking is performed as to the validity of these
  53. /// extents, unlike the other constructor.
  54. Box3F(F32 xmin, F32 ymin, F32 zmin, F32 max, F32 ymax, F32 zmax);
  55. /// Check to see if a point is contained in this box.
  56. bool isContained(const Point3F& in_rContained) const;
  57. /// Check to see if another box overlaps this box.
  58. bool isOverlapped(const Box3F& in_rOverlap) const;
  59. /// Check to see if another box is contained in this box.
  60. bool isContained(const Box3F& in_rContained) const;
  61. F32 len_x() const;
  62. F32 len_y() const;
  63. F32 len_z() const;
  64. /// Perform an intersection operation with another box
  65. /// and store the results in this box.
  66. void intersect(const Box3F& in_rIntersect);
  67. void intersect(const Point3F& in_rIntersect);
  68. /// Get the center of this box.
  69. ///
  70. /// This is the average of min and mMax.
  71. void getCenter(Point3F* center) const;
  72. /// Collide a line against the box.
  73. ///
  74. /// @param start Start of line.
  75. /// @param end End of line.
  76. /// @param t Value from 0.0-1.0, indicating position
  77. /// along line of collision.
  78. /// @param n Normal of collision.
  79. bool collideLine(const Point3F& start, const Point3F& end, F32*t, Point3F*n) const;
  80. /// Collide a line against the box.
  81. ///
  82. /// Returns true on collision.
  83. bool collideLine(const Point3F& start, const Point3F& end) const;
  84. /// Collide an oriented box against the box.
  85. ///
  86. /// Returns true if "oriented" box collides with us.
  87. /// Assumes incoming box is centered at origin of source space.
  88. ///
  89. /// @param radii The dimension of incoming box (half x,y,z length).
  90. /// @param toUs A transform that takes incoming box into our space.
  91. bool collideOrientedBox(const Point3F & radii, const MatrixF & toUs) const;
  92. /// Check that the box is valid.
  93. ///
  94. /// Currently, this just means that min < mMax.
  95. bool isValidBox() const { return (mMin.x <= mMax.x) &&
  96. (mMin.y <= mMax.y) &&
  97. (mMin.z <= mMax.z); }
  98. /// Return the closest point of the box, relative to the passed point.
  99. Point3F getClosestPoint(const Point3F& refPt) const;
  100. };
  101. inline Box3F::Box3F(const Point3F& in_rMin, const Point3F& in_rMax, const bool in_overrideCheck)
  102. : mMin(in_rMin),
  103. mMax(in_rMax)
  104. {
  105. if (in_overrideCheck == false) {
  106. mMin.setMin(in_rMax);
  107. mMax.setMax(in_rMin);
  108. }
  109. }
  110. inline Box3F::Box3F(F32 xMin, F32 yMin, F32 zMin, F32 xMax, F32 yMax, F32 zMax)
  111. : mMin(xMin,yMin,zMin),
  112. mMax(xMax,yMax,zMax)
  113. {
  114. }
  115. inline bool Box3F::isContained(const Point3F& in_rContained) const
  116. {
  117. return (in_rContained.x >= mMin.x && in_rContained.x < mMax.x) &&
  118. (in_rContained.y >= mMin.y && in_rContained.y < mMax.y) &&
  119. (in_rContained.z >= mMin.z && in_rContained.z < mMax.z);
  120. }
  121. inline bool Box3F::isOverlapped(const Box3F& in_rOverlap) const
  122. {
  123. if (in_rOverlap.mMin.x > mMax.x ||
  124. in_rOverlap.mMin.y > mMax.y ||
  125. in_rOverlap.mMin.z > mMax.z)
  126. return false;
  127. if (in_rOverlap.mMax.x < mMin.x ||
  128. in_rOverlap.mMax.y < mMin.y ||
  129. in_rOverlap.mMax.z < mMin.z)
  130. return false;
  131. return true;
  132. }
  133. inline bool Box3F::isContained(const Box3F& in_rContained) const
  134. {
  135. return (mMin.x <= in_rContained.mMin.x) &&
  136. (mMin.y <= in_rContained.mMin.y) &&
  137. (mMin.z <= in_rContained.mMin.z) &&
  138. (mMax.x >= in_rContained.mMax.x) &&
  139. (mMax.y >= in_rContained.mMax.y) &&
  140. (mMax.z >= in_rContained.mMax.z);
  141. }
  142. inline F32 Box3F::len_x() const
  143. {
  144. return mMax.x - mMin.x;
  145. }
  146. inline F32 Box3F::len_y() const
  147. {
  148. return mMax.y - mMin.y;
  149. }
  150. inline F32 Box3F::len_z() const
  151. {
  152. return mMax.z - mMin.z;
  153. }
  154. inline void Box3F::intersect(const Box3F& in_rIntersect)
  155. {
  156. mMin.setMin(in_rIntersect.mMin);
  157. mMax.setMax(in_rIntersect.mMax);
  158. }
  159. inline void Box3F::intersect(const Point3F& in_rIntersect)
  160. {
  161. mMin.setMin(in_rIntersect);
  162. mMax.setMax(in_rIntersect);
  163. }
  164. inline void Box3F::getCenter(Point3F* center) const
  165. {
  166. center->x = F32((mMin.x + mMax.x) * 0.5);
  167. center->y = F32((mMin.y + mMax.y) * 0.5);
  168. center->z = F32((mMin.z + mMax.z) * 0.5);
  169. }
  170. inline Point3F Box3F::getClosestPoint(const Point3F& refPt) const
  171. {
  172. Point3F closest;
  173. if (refPt.x <= mMin.x) closest.x = mMin.x;
  174. else if (refPt.x > mMax.x) closest.x = mMax.x;
  175. else closest.x = refPt.x;
  176. if (refPt.y <= mMin.y) closest.y = mMin.y;
  177. else if (refPt.y > mMax.y) closest.y = mMax.y;
  178. else closest.y = refPt.y;
  179. if (refPt.z <= mMin.z) closest.z = mMin.z;
  180. else if (refPt.z > mMax.z) closest.z = mMax.z;
  181. else closest.z = refPt.z;
  182. return closest;
  183. }
  184. //------------------------------------------------------------------------------
  185. /// Clone of Box3F, using 3D types.
  186. ///
  187. /// 3D types use F64.
  188. ///
  189. /// @see Box3F
  190. class Box3D
  191. {
  192. public:
  193. Point3D mMin;
  194. Point3D mMax;
  195. public:
  196. Box3D() { }
  197. Box3D(const Point3D& in_rMin, const Point3D& in_rMax, const bool in_overrideCheck = false);
  198. bool isContained(const Point3D& in_rContained) const;
  199. bool isOverlapped(const Box3D& in_rOverlap) const;
  200. F64 len_x() const;
  201. F64 len_y() const;
  202. F64 len_z() const;
  203. void intersect(const Box3D& in_rIntersect);
  204. void getCenter(Point3D* center) const;
  205. };
  206. inline Box3D::Box3D(const Point3D& in_rMin, const Point3D& in_rMax, const bool in_overrideCheck)
  207. : mMin(in_rMin),
  208. mMax(in_rMax)
  209. {
  210. if (in_overrideCheck == false) {
  211. mMin.setMin(in_rMax);
  212. mMax.setMax(in_rMin);
  213. }
  214. }
  215. inline bool Box3D::isContained(const Point3D& in_rContained) const
  216. {
  217. return (in_rContained.x >= mMin.x && in_rContained.x < mMax.x) &&
  218. (in_rContained.y >= mMin.y && in_rContained.y < mMax.y) &&
  219. (in_rContained.z >= mMin.z && in_rContained.z < mMax.z);
  220. }
  221. inline bool Box3D::isOverlapped(const Box3D& in_rOverlap) const
  222. {
  223. if (in_rOverlap.mMin.x > mMax.x ||
  224. in_rOverlap.mMin.y > mMax.y ||
  225. in_rOverlap.mMin.z > mMax.z)
  226. return false;
  227. if (in_rOverlap.mMax.x < mMin.x ||
  228. in_rOverlap.mMax.y < mMin.y ||
  229. in_rOverlap.mMax.z < mMin.z)
  230. return false;
  231. return true;
  232. }
  233. inline F64 Box3D::len_x() const
  234. {
  235. return mMax.x - mMin.x;
  236. }
  237. inline F64 Box3D::len_y() const
  238. {
  239. return mMax.y - mMin.y;
  240. }
  241. inline F64 Box3D::len_z() const
  242. {
  243. return mMax.z - mMin.z;
  244. }
  245. inline void Box3D::intersect(const Box3D& in_rIntersect)
  246. {
  247. mMin.setMin(in_rIntersect.mMin);
  248. mMax.setMax(in_rIntersect.mMax);
  249. }
  250. inline void Box3D::getCenter(Point3D* center) const
  251. {
  252. center->x = (mMin.x + mMax.x) * 0.5;
  253. center->y = (mMin.y + mMax.y) * 0.5;
  254. center->z = (mMin.z + mMax.z) * 0.5;
  255. }
  256. #endif // _DBOX_H_