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