IceAABB.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains AABB-related code. (axis-aligned bounding box)
  4. * \file IceAABB.h
  5. * \author Pierre Terdiman
  6. * \date January, 13, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. // Include Guard
  11. #ifndef __ICEAABB_H__
  12. #define __ICEAABB_H__
  13. // Forward declarations
  14. class Sphere;
  15. //! Declarations of type-independent methods (most of them implemented in the .cpp)
  16. #define AABB_COMMON_METHODS \
  17. AABB& Add(const AABB& aabb); \
  18. float MakeCube(AABB& cube) const; \
  19. void MakeSphere(Sphere& sphere) const; \
  20. const sbyte* ComputeOutline(const Point& local_eye, sdword& num) const; \
  21. float ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num) const; \
  22. bool IsInside(const AABB& box) const; \
  23. bool ComputePlanes(Plane* planes) const; \
  24. bool ComputePoints(Point* pts) const; \
  25. const Point* GetVertexNormals() const; \
  26. const udword* GetEdges() const; \
  27. const Point* GetEdgeNormals() const; \
  28. inline_ BOOL ContainsPoint(const Point& p) const \
  29. { \
  30. if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE; \
  31. if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE; \
  32. if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE; \
  33. return TRUE; \
  34. }
  35. enum AABBType
  36. {
  37. AABB_RENDER = 0, //!< AABB used for rendering. Not visible == not rendered.
  38. AABB_UPDATE = 1, //!< AABB used for dynamic updates. Not visible == not updated.
  39. AABB_FORCE_DWORD = 0x7fffffff,
  40. };
  41. #ifdef USE_MINMAX
  42. struct ICEMATHS_API ShadowAABB
  43. {
  44. Point mMin;
  45. Point mMax;
  46. };
  47. class ICEMATHS_API AABB
  48. {
  49. public:
  50. //! Constructor
  51. inline_ AABB() {}
  52. //! Destructor
  53. inline_ ~AABB() {}
  54. //! Type-independent methods
  55. AABB_COMMON_METHODS;
  56. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. /**
  58. * Setups an AABB from min & max vectors.
  59. * \param min [in] the min point
  60. * \param max [in] the max point
  61. */
  62. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. void SetMinMax(const Point& min, const Point& max) { mMin = min; mMax = max; }
  64. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. /**
  66. * Setups an AABB from center & extents vectors.
  67. * \param c [in] the center point
  68. * \param e [in] the extents vector
  69. */
  70. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. void SetCenterExtents(const Point& c, const Point& e) { mMin = c - e; mMax = c + e; }
  72. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. /**
  74. * Setups an empty AABB.
  75. */
  76. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  77. void SetEmpty() { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); mMin = -p; mMax = p;}
  78. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. /**
  80. * Setups a point AABB.
  81. */
  82. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. void SetPoint(const Point& pt) { mMin = mMax = pt; }
  84. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  85. /**
  86. * Gets the size of the AABB. The size is defined as the longest extent.
  87. * \return the size of the AABB
  88. */
  89. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. float GetSize() const { Point e; GetExtents(e); return e.Max(); }
  91. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  92. /**
  93. * Extends the AABB.
  94. * \param p [in] the next point
  95. */
  96. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. void Extend(const Point& p)
  98. {
  99. if(p.x > mMax.x) mMax.x = p.x;
  100. if(p.x < mMin.x) mMin.x = p.x;
  101. if(p.y > mMax.y) mMax.y = p.y;
  102. if(p.y < mMin.y) mMin.y = p.y;
  103. if(p.z > mMax.z) mMax.z = p.z;
  104. if(p.z < mMin.z) mMin.z = p.z;
  105. }
  106. // Data access
  107. //! Get min point of the box
  108. inline_ void GetMin(Point& min) const { min = mMin; }
  109. //! Get max point of the box
  110. inline_ void GetMax(Point& max) const { max = mMax; }
  111. //! Get component of the box's min point along a given axis
  112. inline_ float GetMin(udword axis) const { return mMin[axis]; }
  113. //! Get component of the box's max point along a given axis
  114. inline_ float GetMax(udword axis) const { return mMax[axis]; }
  115. //! Get box center
  116. inline_ void GetCenter(Point& center) const { center = (mMax + mMin)*0.5f; }
  117. //! Get box extents
  118. inline_ void GetExtents(Point& extents) const { extents = (mMax - mMin)*0.5f; }
  119. //! Get component of the box's center along a given axis
  120. inline_ float GetCenter(udword axis) const { return (mMax[axis] + mMin[axis])*0.5f; }
  121. //! Get component of the box's extents along a given axis
  122. inline_ float GetExtents(udword axis) const { return (mMax[axis] - mMin[axis])*0.5f; }
  123. //! Get box diagonal
  124. inline_ void GetDiagonal(Point& diagonal) const { diagonal = mMax - mMin; }
  125. inline_ float GetWidth() const { return mMax.x - mMin.x; }
  126. inline_ float GetHeight() const { return mMax.y - mMin.y; }
  127. inline_ float GetDepth() const { return mMax.z - mMin.z; }
  128. //! Volume
  129. inline_ float GetVolume() const { return GetWidth() * GetHeight() * GetDepth(); }
  130. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. /**
  132. * Computes the intersection between two AABBs.
  133. * \param a [in] the other AABB
  134. * \return true on intersection
  135. */
  136. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  137. inline_ BOOL Intersect(const AABB& a) const
  138. {
  139. if(mMax.x < a.mMin.x
  140. || a.mMax.x < mMin.x
  141. || mMax.y < a.mMin.y
  142. || a.mMax.y < mMin.y
  143. || mMax.z < a.mMin.z
  144. || a.mMax.z < mMin.z) return FALSE;
  145. return TRUE;
  146. }
  147. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. /**
  149. * Computes the 1D-intersection between two AABBs, on a given axis.
  150. * \param a [in] the other AABB
  151. * \param axis [in] the axis (0, 1, 2)
  152. * \return true on intersection
  153. */
  154. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  155. inline_ BOOL Intersect(const AABB& a, udword axis) const
  156. {
  157. if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis]) return FALSE;
  158. return TRUE;
  159. }
  160. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. /**
  162. * Recomputes the AABB after an arbitrary transform by a 4x4 matrix.
  163. * Original code by Charles Bloom on the GD-Algorithm list. (I slightly modified it)
  164. * \param mtx [in] the transform matrix
  165. * \param aabb [out] the transformed AABB [can be *this]
  166. */
  167. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const
  169. {
  170. // The three edges transformed: you can efficiently transform an X-only vector
  171. // by just getting the "X" column of the matrix
  172. Point vx,vy,vz;
  173. mtx.GetRow(0, vx); vx *= (mMax.x - mMin.x);
  174. mtx.GetRow(1, vy); vy *= (mMax.y - mMin.y);
  175. mtx.GetRow(2, vz); vz *= (mMax.z - mMin.z);
  176. // Transform the min point
  177. aabb.mMin = aabb.mMax = mMin * mtx;
  178. // Take the transformed min & axes and find new extents
  179. // Using CPU code in the right place is faster...
  180. if(IS_NEGATIVE_FLOAT(vx.x)) aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x;
  181. if(IS_NEGATIVE_FLOAT(vx.y)) aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y;
  182. if(IS_NEGATIVE_FLOAT(vx.z)) aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z;
  183. if(IS_NEGATIVE_FLOAT(vy.x)) aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x;
  184. if(IS_NEGATIVE_FLOAT(vy.y)) aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y;
  185. if(IS_NEGATIVE_FLOAT(vy.z)) aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z;
  186. if(IS_NEGATIVE_FLOAT(vz.x)) aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x;
  187. if(IS_NEGATIVE_FLOAT(vz.y)) aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y;
  188. if(IS_NEGATIVE_FLOAT(vz.z)) aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z;
  189. }
  190. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. /**
  192. * Checks the AABB is valid.
  193. * \return true if the box is valid
  194. */
  195. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  196. inline_ BOOL IsValid() const
  197. {
  198. // Consistency condition for (Min, Max) boxes: min < max
  199. if(mMin.x > mMax.x) return FALSE;
  200. if(mMin.y > mMax.y) return FALSE;
  201. if(mMin.z > mMax.z) return FALSE;
  202. return TRUE;
  203. }
  204. //! Operator for AABB *= float. Scales the extents, keeps same center.
  205. inline_ AABB& operator*=(float s)
  206. {
  207. Point Center; GetCenter(Center);
  208. Point Extents; GetExtents(Extents);
  209. SetCenterExtents(Center, Extents * s);
  210. return *this;
  211. }
  212. //! Operator for AABB /= float. Scales the extents, keeps same center.
  213. inline_ AABB& operator/=(float s)
  214. {
  215. Point Center; GetCenter(Center);
  216. Point Extents; GetExtents(Extents);
  217. SetCenterExtents(Center, Extents / s);
  218. return *this;
  219. }
  220. //! Operator for AABB += Point. Translates the box.
  221. inline_ AABB& operator+=(const Point& trans)
  222. {
  223. mMin+=trans;
  224. mMax+=trans;
  225. return *this;
  226. }
  227. private:
  228. Point mMin; //!< Min point
  229. Point mMax; //!< Max point
  230. };
  231. #else
  232. class ICEMATHS_API AABB
  233. {
  234. public:
  235. //! Constructor
  236. inline_ AABB() {}
  237. //! Destructor
  238. inline_ ~AABB() {}
  239. //! Type-independent methods
  240. AABB_COMMON_METHODS;
  241. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242. /**
  243. * Setups an AABB from min & max vectors.
  244. * \param min [in] the min point
  245. * \param max [in] the max point
  246. */
  247. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  248. void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; }
  249. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  250. /**
  251. * Setups an AABB from center & extents vectors.
  252. * \param c [in] the center point
  253. * \param e [in] the extents vector
  254. */
  255. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256. void SetCenterExtents(const Point& c, const Point& e) { mCenter = c; mExtents = e; }
  257. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  258. /**
  259. * Setups an empty AABB.
  260. */
  261. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  262. void SetEmpty() { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);}
  263. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  264. /**
  265. * Setups a point AABB.
  266. */
  267. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  268. void SetPoint(const Point& pt) { mCenter = pt; mExtents.Zero(); }
  269. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  270. /**
  271. * Gets the size of the AABB. The size is defined as the longest extent.
  272. * \return the size of the AABB
  273. */
  274. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. float GetSize() const { return mExtents.Max(); }
  276. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  277. /**
  278. * Extends the AABB.
  279. * \param p [in] the next point
  280. */
  281. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  282. void Extend(const Point& p)
  283. {
  284. Point Max = mCenter + mExtents;
  285. Point Min = mCenter - mExtents;
  286. if(p.x > Max.x) Max.x = p.x;
  287. if(p.x < Min.x) Min.x = p.x;
  288. if(p.y > Max.y) Max.y = p.y;
  289. if(p.y < Min.y) Min.y = p.y;
  290. if(p.z > Max.z) Max.z = p.z;
  291. if(p.z < Min.z) Min.z = p.z;
  292. SetMinMax(Min, Max);
  293. }
  294. // Data access
  295. //! Get min point of the box
  296. inline_ void GetMin(Point& min) const { min = mCenter - mExtents; }
  297. //! Get max point of the box
  298. inline_ void GetMax(Point& max) const { max = mCenter + mExtents; }
  299. //! Get component of the box's min point along a given axis
  300. inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; }
  301. //! Get component of the box's max point along a given axis
  302. inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; }
  303. //! Get box center
  304. inline_ void GetCenter(Point& center) const { center = mCenter; }
  305. //! Get box extents
  306. inline_ void GetExtents(Point& extents) const { extents = mExtents; }
  307. //! Get component of the box's center along a given axis
  308. inline_ float GetCenter(udword axis) const { return mCenter[axis]; }
  309. //! Get component of the box's extents along a given axis
  310. inline_ float GetExtents(udword axis) const { return mExtents[axis]; }
  311. //! Get box diagonal
  312. inline_ void GetDiagonal(Point& diagonal) const { diagonal = mExtents * 2.0f; }
  313. inline_ float GetWidth() const { return mExtents.x * 2.0f; }
  314. inline_ float GetHeight() const { return mExtents.y * 2.0f; }
  315. inline_ float GetDepth() const { return mExtents.z * 2.0f; }
  316. //! Volume
  317. inline_ float GetVolume() const { return mExtents.x * mExtents.y * mExtents.z * 8.0f; }
  318. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. /**
  320. * Computes the intersection between two AABBs.
  321. * \param a [in] the other AABB
  322. * \return true on intersection
  323. */
  324. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. inline_ BOOL Intersect(const AABB& a) const
  326. {
  327. float tx = mCenter.x - a.mCenter.x; float ex = a.mExtents.x + mExtents.x; if(AIR(tx) > IR(ex)) return FALSE;
  328. float ty = mCenter.y - a.mCenter.y; float ey = a.mExtents.y + mExtents.y; if(AIR(ty) > IR(ey)) return FALSE;
  329. float tz = mCenter.z - a.mCenter.z; float ez = a.mExtents.z + mExtents.z; if(AIR(tz) > IR(ez)) return FALSE;
  330. return TRUE;
  331. }
  332. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  333. /**
  334. * The standard intersection method from Gamasutra. Just here to check its speed against the one above.
  335. * \param a [in] the other AABB
  336. * \return true on intersection
  337. */
  338. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  339. inline_ bool GomezIntersect(const AABB& a)
  340. {
  341. Point T = mCenter - a.mCenter; // Vector from A to B
  342. return ((fabsf(T.x) <= (a.mExtents.x + mExtents.x))
  343. && (fabsf(T.y) <= (a.mExtents.y + mExtents.y))
  344. && (fabsf(T.z) <= (a.mExtents.z + mExtents.z)));
  345. }
  346. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  347. /**
  348. * Computes the 1D-intersection between two AABBs, on a given axis.
  349. * \param a [in] the other AABB
  350. * \param axis [in] the axis (0, 1, 2)
  351. * \return true on intersection
  352. */
  353. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  354. inline_ BOOL Intersect(const AABB& a, udword axis) const
  355. {
  356. float t = mCenter[axis] - a.mCenter[axis];
  357. float e = a.mExtents[axis] + mExtents[axis];
  358. if(AIR(t) > IR(e)) return FALSE;
  359. return TRUE;
  360. }
  361. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  362. /**
  363. * Recomputes the AABB after an arbitrary transform by a 4x4 matrix.
  364. * \param mtx [in] the transform matrix
  365. * \param aabb [out] the transformed AABB [can be *this]
  366. */
  367. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  368. inline_ void Rotate(const Matrix4x4& mtx, AABB& aabb) const
  369. {
  370. // Compute new center
  371. aabb.mCenter = mCenter * mtx;
  372. // Compute new extents. FPU code & CPU code have been interleaved for improved performance.
  373. Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x);
  374. IR(Ex.x)&=0x7fffffff; IR(Ex.y)&=0x7fffffff; IR(Ex.z)&=0x7fffffff;
  375. Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y);
  376. IR(Ey.x)&=0x7fffffff; IR(Ey.y)&=0x7fffffff; IR(Ey.z)&=0x7fffffff;
  377. Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z);
  378. IR(Ez.x)&=0x7fffffff; IR(Ez.y)&=0x7fffffff; IR(Ez.z)&=0x7fffffff;
  379. aabb.mExtents.x = Ex.x + Ey.x + Ez.x;
  380. aabb.mExtents.y = Ex.y + Ey.y + Ez.y;
  381. aabb.mExtents.z = Ex.z + Ey.z + Ez.z;
  382. }
  383. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  384. /**
  385. * Checks the AABB is valid.
  386. * \return true if the box is valid
  387. */
  388. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  389. inline_ BOOL IsValid() const
  390. {
  391. // Consistency condition for (Center, Extents) boxes: Extents >= 0
  392. if(IS_NEGATIVE_FLOAT(mExtents.x)) return FALSE;
  393. if(IS_NEGATIVE_FLOAT(mExtents.y)) return FALSE;
  394. if(IS_NEGATIVE_FLOAT(mExtents.z)) return FALSE;
  395. return TRUE;
  396. }
  397. //! Operator for AABB *= float. Scales the extents, keeps same center.
  398. inline_ AABB& operator*=(float s) { mExtents*=s; return *this; }
  399. //! Operator for AABB /= float. Scales the extents, keeps same center.
  400. inline_ AABB& operator/=(float s) { mExtents/=s; return *this; }
  401. //! Operator for AABB += Point. Translates the box.
  402. inline_ AABB& operator+=(const Point& trans)
  403. {
  404. mCenter+=trans;
  405. return *this;
  406. }
  407. private:
  408. Point mCenter; //!< AABB Center
  409. Point mExtents; //!< x, y and z extents
  410. };
  411. #endif
  412. inline_ void ComputeMinMax(const Point& p, Point& min, Point& max)
  413. {
  414. if(p.x > max.x) max.x = p.x;
  415. if(p.x < min.x) min.x = p.x;
  416. if(p.y > max.y) max.y = p.y;
  417. if(p.y < min.y) min.y = p.y;
  418. if(p.z > max.z) max.z = p.z;
  419. if(p.z < min.z) min.z = p.z;
  420. }
  421. inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts)
  422. {
  423. if(list)
  424. {
  425. Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
  426. Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT);
  427. while(nb_pts--)
  428. {
  429. // _prefetch(list+1); // off by one ?
  430. ComputeMinMax(*list++, Mini, Maxi);
  431. }
  432. aabb.SetMinMax(Mini, Maxi);
  433. }
  434. }
  435. #endif // __ICEAABB_H__