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