BoundingBox.pkg 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. $#include "BoundingBox.h"
  2. /// Three-dimensional axis-aligned bounding box.
  3. class BoundingBox
  4. {
  5. public:
  6. /// Construct with zero size.
  7. BoundingBox() :
  8. min_(Vector3::ZERO),
  9. max_(Vector3::ZERO),
  10. defined_(false)
  11. {
  12. }
  13. /// Copy-construct from another bounding box.
  14. BoundingBox(const BoundingBox& box) :
  15. min_(box.min_),
  16. max_(box.max_),
  17. defined_(box.defined_)
  18. {
  19. }
  20. /// Construct from a rect, with the Z dimension left zero.
  21. BoundingBox(const Rect& rect) :
  22. min_(Vector3(rect.min_, 0.0f)),
  23. max_(Vector3(rect.max_, 0.0f)),
  24. defined_(true)
  25. {
  26. }
  27. /// Construct from minimum and maximum vectors.
  28. BoundingBox(const Vector3& min, const Vector3& max) :
  29. min_(min),
  30. max_(max),
  31. defined_(true)
  32. {
  33. }
  34. /// Construct from minimum and maximum floats (all dimensions same.)
  35. BoundingBox(float min, float max) :
  36. min_(Vector3(min, min, min)),
  37. max_(Vector3(max, max, max)),
  38. defined_(true)
  39. {
  40. }
  41. /// Construct from an array of vertices.
  42. BoundingBox(const Vector3* vertices, unsigned count) :
  43. defined_(false)
  44. {
  45. Define(vertices, count);
  46. }
  47. /// Construct from a frustum.
  48. BoundingBox(const Frustum& frustum) :
  49. defined_(false)
  50. {
  51. Define(frustum);
  52. }
  53. /// Construct from a polyhedron.
  54. BoundingBox(const Polyhedron& poly) :
  55. defined_(false)
  56. {
  57. Define(poly);
  58. }
  59. /// Construct from a sphere.
  60. BoundingBox(const Sphere& sphere) :
  61. defined_(false)
  62. {
  63. Define(sphere);
  64. }
  65. /// Test for equality with another bounding box.
  66. bool operator == (const BoundingBox& rhs) const { return (min_ == rhs.min_ && max_ == rhs.max_); }
  67. /// Define from another bounding box.
  68. void Define(const BoundingBox& box)
  69. {
  70. Define(box.min_, box.max_);
  71. }
  72. /// Define from a Rect.
  73. void Define(const Rect& rect)
  74. {
  75. Define(Vector3(rect.min_, 0.0f), Vector3(rect.max_, 0.0f));
  76. }
  77. /// Define from minimum and maximum vectors.
  78. void Define(const Vector3& min, const Vector3& max)
  79. {
  80. min_ = min;
  81. max_ = max;
  82. defined_ = true;
  83. }
  84. /// Define from minimum and maximum floats (all dimensions same.)
  85. void Define(float min, float max)
  86. {
  87. min_ = Vector3(min, min, min);
  88. max_ = Vector3(max, max, max);
  89. defined_ = true;
  90. }
  91. /// Define from a point.
  92. void Define(const Vector3& point)
  93. {
  94. min_ = max_ = point;
  95. defined_ = true;
  96. }
  97. /// Merge a point.
  98. void Merge(const Vector3& point)
  99. {
  100. if (!defined_)
  101. {
  102. min_ = max_ = point;
  103. defined_ = true;
  104. return;
  105. }
  106. if (point.x_ < min_.x_)
  107. min_.x_ = point.x_;
  108. if (point.y_ < min_.y_)
  109. min_.y_ = point.y_;
  110. if (point.z_ < min_.z_)
  111. min_.z_ = point.z_;
  112. if (point.x_ > max_.x_)
  113. max_.x_ = point.x_;
  114. if (point.y_ > max_.y_)
  115. max_.y_ = point.y_;
  116. if (point.z_ > max_.z_)
  117. max_.z_ = point.z_;
  118. }
  119. /// Merge another bounding box.
  120. void Merge(const BoundingBox& box)
  121. {
  122. if (!defined_)
  123. {
  124. min_ = box.min_;
  125. max_ = box.max_;
  126. defined_ = true;
  127. return;
  128. }
  129. if (box.min_.x_ < min_.x_)
  130. min_.x_ = box.min_.x_;
  131. if (box.min_.y_ < min_.y_)
  132. min_.y_ = box.min_.y_;
  133. if (box.min_.z_ < min_.z_)
  134. min_.z_ = box.min_.z_;
  135. if (box.max_.x_ > max_.x_)
  136. max_.x_ = box.max_.x_;
  137. if (box.max_.y_ > max_.y_)
  138. max_.y_ = box.max_.y_;
  139. if (box.max_.z_ > max_.z_)
  140. max_.z_ = box.max_.z_;
  141. }
  142. /// Define from an array of vertices.
  143. void Define(const Vector3* vertices, unsigned count);
  144. /// Define from a frustum.
  145. void Define(const Frustum& frustum);
  146. /// Define from a polyhedron.
  147. void Define(const Polyhedron& poly);
  148. /// Define from a sphere.
  149. void Define(const Sphere& sphere);
  150. /// Merge an array of vertices.
  151. void Merge(const Vector3* vertices, unsigned count);
  152. /// Merge a frustum.
  153. void Merge(const Frustum& frustum);
  154. /// Merge a polyhedron.
  155. void Merge(const Polyhedron& poly);
  156. /// Merge a sphere.
  157. void Merge(const Sphere& sphere);
  158. /// Clip with another bounding box.
  159. void Clip(const BoundingBox& box);
  160. /// Transform with a 3x3 matrix.
  161. void Transform(const Matrix3& transform);
  162. /// Transform with a 3x4 matrix.
  163. void Transform(const Matrix3x4& transform);
  164. /// Clear to undefined state.
  165. void Clear()
  166. {
  167. min_ = Vector3::ZERO;
  168. max_ = Vector3::ZERO;
  169. defined_ = false;
  170. }
  171. /// Return center.
  172. Vector3 Center() const { return (max_ + min_) * 0.5f; }
  173. /// Return size.
  174. Vector3 Size() const { return max_ - min_; }
  175. /// Return half-size.
  176. Vector3 HalfSize() const { return (max_ - min_) * 0.5f; }
  177. /// Return transformed by a 3x3 matrix.
  178. BoundingBox Transformed(const Matrix3& transform) const;
  179. /// Return transformed by a 3x4 matrix.
  180. BoundingBox Transformed(const Matrix3x4& transform) const;
  181. /// Return projected by a 4x4 projection matrix.
  182. Rect Projected(const Matrix4& projection) const;
  183. /// Test if a point is inside.
  184. Intersection IsInside(const Vector3& point) const
  185. {
  186. if (point.x_ < min_.x_ || point.x_ > max_.x_ || point.y_ < min_.y_ || point.y_ > max_.y_ ||
  187. point.z_ < min_.z_ || point.z_ > max_.z_)
  188. return OUTSIDE;
  189. else
  190. return INSIDE;
  191. }
  192. /// Test if another bounding box is inside, outside or intersects.
  193. Intersection IsInside(const BoundingBox& box) const
  194. {
  195. if (box.max_.x_ < min_.x_ || box.min_.x_ > max_.x_ || box.max_.y_ < min_.y_ || box.min_.y_ > max_.y_ ||
  196. box.max_.z_ < min_.z_ || box.min_.z_ > max_.z_)
  197. return OUTSIDE;
  198. else if (box.min_.x_ < min_.x_ || box.max_.x_ > max_.x_ || box.min_.y_ < min_.y_ || box.max_.y_ > max_.y_ ||
  199. box.min_.z_ < min_.z_ || box.max_.z_ > max_.z_)
  200. return INTERSECTS;
  201. else
  202. return INSIDE;
  203. }
  204. /// Test if another bounding box is (partially) inside or outside.
  205. Intersection IsInsideFast(const BoundingBox& box) const
  206. {
  207. if (box.max_.x_ < min_.x_ || box.min_.x_ > max_.x_ || box.max_.y_ < min_.y_ || box.min_.y_ > max_.y_ ||
  208. box.max_.z_ < min_.z_ || box.min_.z_ > max_.z_)
  209. return OUTSIDE;
  210. else
  211. return INSIDE;
  212. }
  213. /// Test if a sphere is inside, outside or intersects.
  214. Intersection IsInside(const Sphere& sphere) const;
  215. /// Test if a sphere is (partially) inside or outside.
  216. Intersection IsInsideFast(const Sphere& sphere) const;
  217. /// Return as string.
  218. String ToString() const;
  219. /// Minimum vector.
  220. Vector3 min_ @ min;
  221. /// Maximum vector.
  222. Vector3 max_ @ max;
  223. };