IceAABB.h
Go to the documentation of this file.
00001 
00002 
00008 
00009 
00011 // Include Guard
00012 #ifndef __ICEAABB_H__
00013 #define __ICEAABB_H__
00014 
00015         // Forward declarations
00016         class Sphere;
00017 
00019 #define AABB_COMMON_METHODS                                                                                                                                                                                                                     \
00020                         AABB&                   Add(const AABB& aabb);                                                                                                                                                                  \
00021                         float                   MakeCube(AABB& cube)                                                                                                                                                    const;  \
00022                         void                    MakeSphere(Sphere& sphere)                                                                                                                                              const;  \
00023                         const sbyte*    ComputeOutline(const Point& local_eye, sdword& num)                                                                                             const;  \
00024                         float                   ComputeBoxArea(const Point& eye, const Matrix4x4& mat, float width, float height, sdword& num)  const;  \
00025                         bool                    IsInside(const AABB& box)                                                                                                                                               const;  \
00026                         bool                    ComputePlanes(Plane* planes)                                                                                                                                    const;  \
00027                         bool                    ComputePoints(Point* pts)                                                                                                                                               const;  \
00028                         const Point*    GetVertexNormals()                                                                                                                                                              const;  \
00029                         const udword*   GetEdges()                                                                                                                                                                              const;  \
00030                         const Point*    GetEdgeNormals()                                                                                                                                                                const;  \
00031         inline_ BOOL                    ContainsPoint(const Point& p)                                                                                                                                   const   \
00032                                                         {                                                                                                                                                                                                               \
00033                                                                 if(p.x > GetMax(0) || p.x < GetMin(0)) return FALSE;                                                                                            \
00034                                                                 if(p.y > GetMax(1) || p.y < GetMin(1)) return FALSE;                                                                                            \
00035                                                                 if(p.z > GetMax(2) || p.z < GetMin(2)) return FALSE;                                                                                            \
00036                                                                 return TRUE;                                                                                                                                                                            \
00037                                                         }
00038 
00039         enum AABBType
00040         {
00041                 AABB_RENDER                     = 0,    
00042                 AABB_UPDATE                     = 1,    
00043 
00044                 AABB_FORCE_DWORD        = 0x7fffffff,
00045         };
00046 
00047 #ifdef USE_MINMAX
00048 
00049         struct ICEMATHS_API ShadowAABB
00050         {
00051                 Point   mMin;
00052                 Point   mMax;
00053         };
00054 
00055         class ICEMATHS_API AABB
00056         {
00057                 public:
00059                 inline_                                         AABB()  {}
00061                 inline_                                         ~AABB() {}
00062 
00064                                                                         AABB_COMMON_METHODS;
00065 
00067 
00072 
00073                                                 void            SetMinMax(const Point& min, const Point& max)           { mMin = min;           mMax = max;                                                                     }
00074 
00076 
00081 
00082                                                 void            SetCenterExtents(const Point& c, const Point& e)        { mMin = c - e;         mMax = c + e;                                                           }
00083 
00085 
00088 
00089                                                 void            SetEmpty()                                                                                      { Point p(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);     mMin = -p; mMax = p;}
00090 
00092 
00095 
00096                                                 void            SetPoint(const Point& pt)                                                       { mMin = mMax = pt;                                                                                             }
00097 
00099 
00103 
00104                                                 float           GetSize()                                                               const           { Point e; GetExtents(e);       return e.Max(); }
00105 
00107 
00111 
00112                                                 void            Extend(const Point& p)
00113                                                                         {
00114                                                                                 if(p.x > mMax.x)        mMax.x = p.x;
00115                                                                                 if(p.x < mMin.x)        mMin.x = p.x;
00116 
00117                                                                                 if(p.y > mMax.y)        mMax.y = p.y;
00118                                                                                 if(p.y < mMin.y)        mMin.y = p.y;
00119 
00120                                                                                 if(p.z > mMax.z)        mMax.z = p.z;
00121                                                                                 if(p.z < mMin.z)        mMin.z = p.z;
00122                                                                         }
00123                 // Data access
00124 
00126                 inline_                 void            GetMin(Point& min)                                              const           { min = mMin;                                                           }
00128                 inline_                 void            GetMax(Point& max)                                              const           { max = mMax;                                                           }
00129 
00131                 inline_                 float           GetMin(udword axis)                                             const           { return mMin[axis];                                            }
00133                 inline_                 float           GetMax(udword axis)                                             const           { return mMax[axis];                                            }
00134 
00136                 inline_                 void            GetCenter(Point& center)                                const           { center = (mMax + mMin)*0.5f;                          }
00138                 inline_                 void            GetExtents(Point& extents)                              const           { extents = (mMax - mMin)*0.5f;                         }
00139 
00141                 inline_                 float           GetCenter(udword axis)                                  const           { return (mMax[axis] + mMin[axis])*0.5f;        }
00143                 inline_                 float           GetExtents(udword axis)                                 const           { return (mMax[axis] - mMin[axis])*0.5f;        }
00144 
00146                 inline_                 void            GetDiagonal(Point& diagonal)                    const           { diagonal = mMax - mMin;                                       }
00147                 inline_                 float           GetWidth()                                                              const           { return mMax.x - mMin.x;                                       }
00148                 inline_                 float           GetHeight()                                                             const           { return mMax.y - mMin.y;                                       }
00149                 inline_                 float           GetDepth()                                                              const           { return mMax.z - mMin.z;                                       }
00150 
00152                 inline_                 float           GetVolume()                                                             const           { return GetWidth() * GetHeight() * GetDepth();         }
00153 
00155 
00160 
00161                 inline_                 BOOL            Intersect(const AABB& a)                                const
00162                                                                         {
00163                                                                                 if(mMax.x < a.mMin.x
00164                                                                                 || a.mMax.x < mMin.x
00165                                                                                 || mMax.y < a.mMin.y
00166                                                                                 || a.mMax.y < mMin.y
00167                                                                                 || mMax.z < a.mMin.z
00168                                                                                 || a.mMax.z < mMin.z)   return FALSE;
00169 
00170                                                                                 return TRUE;
00171                                                                         }
00172 
00174 
00180 
00181                 inline_                 BOOL            Intersect(const AABB& a, udword axis)   const
00182                                                                         {
00183                                                                                 if(mMax[axis] < a.mMin[axis] || a.mMax[axis] < mMin[axis])      return FALSE;
00184                                                                                 return TRUE;
00185                                                                         }
00186 
00188 
00194 
00195                 inline_                 void            Rotate(const Matrix4x4& mtx, AABB& aabb)        const
00196                                                                         {
00197                                                                                 // The three edges transformed: you can efficiently transform an X-only vector
00198                                                                                 // by just getting the "X" column of the matrix
00199                                                                                 Point vx,vy,vz;
00200                                                                                 mtx.GetRow(0, vx);      vx *= (mMax.x - mMin.x);
00201                                                                                 mtx.GetRow(1, vy);      vy *= (mMax.y - mMin.y);
00202                                                                                 mtx.GetRow(2, vz);      vz *= (mMax.z - mMin.z);
00203 
00204                                                                                 // Transform the min point
00205                                                                                 aabb.mMin = aabb.mMax = mMin * mtx;
00206 
00207                                                                                 // Take the transformed min & axes and find new extents
00208                                                                                 // Using CPU code in the right place is faster...
00209                                                                                 if(IS_NEGATIVE_FLOAT(vx.x))     aabb.mMin.x += vx.x; else aabb.mMax.x += vx.x;
00210                                                                                 if(IS_NEGATIVE_FLOAT(vx.y))     aabb.mMin.y += vx.y; else aabb.mMax.y += vx.y;
00211                                                                                 if(IS_NEGATIVE_FLOAT(vx.z))     aabb.mMin.z += vx.z; else aabb.mMax.z += vx.z;
00212                                                                                 if(IS_NEGATIVE_FLOAT(vy.x))     aabb.mMin.x += vy.x; else aabb.mMax.x += vy.x;
00213                                                                                 if(IS_NEGATIVE_FLOAT(vy.y))     aabb.mMin.y += vy.y; else aabb.mMax.y += vy.y;
00214                                                                                 if(IS_NEGATIVE_FLOAT(vy.z))     aabb.mMin.z += vy.z; else aabb.mMax.z += vy.z;
00215                                                                                 if(IS_NEGATIVE_FLOAT(vz.x))     aabb.mMin.x += vz.x; else aabb.mMax.x += vz.x;
00216                                                                                 if(IS_NEGATIVE_FLOAT(vz.y))     aabb.mMin.y += vz.y; else aabb.mMax.y += vz.y;
00217                                                                                 if(IS_NEGATIVE_FLOAT(vz.z))     aabb.mMin.z += vz.z; else aabb.mMax.z += vz.z;
00218                                                                         }
00219 
00221 
00225 
00226                 inline_                 BOOL            IsValid()       const
00227                                                                         {
00228                                                                                 // Consistency condition for (Min, Max) boxes: min < max
00229                                                                                 if(mMin.x > mMax.x)     return FALSE;
00230                                                                                 if(mMin.y > mMax.y)     return FALSE;
00231                                                                                 if(mMin.z > mMax.z)     return FALSE;
00232                                                                                 return TRUE;
00233                                                                         }
00234 
00236                 inline_                 AABB&           operator*=(float s)
00237                                                                         {
00238                                                                                 Point Center;   GetCenter(Center);
00239                                                                                 Point Extents;  GetExtents(Extents);
00240                                                                                 SetCenterExtents(Center, Extents * s);
00241                                                                                 return *this;
00242                                                                         }
00243 
00245                 inline_                 AABB&           operator/=(float s)
00246                                                                         {
00247                                                                                 Point Center;   GetCenter(Center);
00248                                                                                 Point Extents;  GetExtents(Extents);
00249                                                                                 SetCenterExtents(Center, Extents / s);
00250                                                                                 return *this;
00251                                                                         }
00252 
00254                 inline_                 AABB&           operator+=(const Point& trans)
00255                                                                         {
00256                                                                                 mMin+=trans;
00257                                                                                 mMax+=trans;
00258                                                                                 return *this;
00259                                                                         }
00260                 private:
00261                                                 Point           mMin;                   
00262                                                 Point           mMax;                   
00263         };
00264 
00265 #else
00266 
00267         class ICEMATHS_API AABB
00268         {
00269                 public:
00271                 inline_                                         AABB()  {}
00273                 inline_                                         ~AABB() {}
00274 
00276                                                                         AABB_COMMON_METHODS;
00277 
00279 
00284 
00285                                                 void            SetMinMax(const Point& min, const Point& max)           { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f;              }
00286 
00288 
00293 
00294                                                 void            SetCenterExtents(const Point& c, const Point& e)        { mCenter = c;   mExtents = e;                                                                  }
00295 
00297 
00300 
00301                                                 void            SetEmpty()                                                                                      { mCenter.Zero(); mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);}
00302 
00304 
00307 
00308                                                 void            SetPoint(const Point& pt)                                                       { mCenter = pt; mExtents.Zero();                                                                }
00309 
00311 
00315 
00316                                                 float           GetSize()                                                               const           { return mExtents.Max();                                        }
00317 
00319 
00323 
00324                                                 void            Extend(const Point& p)
00325                                                                         {
00326                                                                                 Point Max = mCenter + mExtents;
00327                                                                                 Point Min = mCenter - mExtents;
00328 
00329                                                                                 if(p.x > Max.x) Max.x = p.x;
00330                                                                                 if(p.x < Min.x) Min.x = p.x;
00331 
00332                                                                                 if(p.y > Max.y) Max.y = p.y;
00333                                                                                 if(p.y < Min.y) Min.y = p.y;
00334 
00335                                                                                 if(p.z > Max.z) Max.z = p.z;
00336                                                                                 if(p.z < Min.z) Min.z = p.z;
00337 
00338                                                                                 SetMinMax(Min, Max);
00339                                                                         }
00340                 // Data access
00341 
00343                 inline_                 void            GetMin(Point& min)                                              const           { min = mCenter - mExtents;                                     }
00345                 inline_                 void            GetMax(Point& max)                                              const           { max = mCenter + mExtents;                                     }
00346 
00348                 inline_                 float           GetMin(udword axis)                                             const           { return mCenter[axis] - mExtents[axis];        }
00350                 inline_                 float           GetMax(udword axis)                                             const           { return mCenter[axis] + mExtents[axis];        }
00351 
00353                 inline_                 void            GetCenter(Point& center)                                const           { center = mCenter;                                                     }
00355                 inline_                 void            GetExtents(Point& extents)                              const           { extents = mExtents;                                           }
00356 
00358                 inline_                 float           GetCenter(udword axis)                                  const           { return mCenter[axis];                                         }
00360                 inline_                 float           GetExtents(udword axis)                                 const           { return mExtents[axis];                                        }
00361 
00363                 inline_                 void            GetDiagonal(Point& diagonal)                    const           { diagonal = mExtents * 2.0f;                           }
00364                 inline_                 float           GetWidth()                                                              const           { return mExtents.x * 2.0f;                                     }
00365                 inline_                 float           GetHeight()                                                             const           { return mExtents.y * 2.0f;                                     }
00366                 inline_                 float           GetDepth()                                                              const           { return mExtents.z * 2.0f;                                     }
00367 
00369                 inline_                 float           GetVolume()                                                             const           { return mExtents.x * mExtents.y * mExtents.z * 8.0f;   }
00370 
00372 
00377 
00378                 inline_                 BOOL            Intersect(const AABB& a)                                const
00379                                                                         {
00380                                                                                 float tx = mCenter.x - a.mCenter.x;     float ex = a.mExtents.x + mExtents.x;   if(AIR(tx) > IR(ex))    return FALSE;
00381                                                                                 float ty = mCenter.y - a.mCenter.y;     float ey = a.mExtents.y + mExtents.y;   if(AIR(ty) > IR(ey))    return FALSE;
00382                                                                                 float tz = mCenter.z - a.mCenter.z;     float ez = a.mExtents.z + mExtents.z;   if(AIR(tz) > IR(ez))    return FALSE;
00383                                                                                 return TRUE;
00384                                                                         }
00385 
00387 
00392 
00393                 inline_                 bool            GomezIntersect(const AABB& a)
00394                                                                         {
00395                                                                                 Point   T = mCenter - a.mCenter;        // Vector from A to B
00396                                                                                 return  ((fabsf(T.x) <= (a.mExtents.x + mExtents.x))
00397                                                                                                 && (fabsf(T.y) <= (a.mExtents.y + mExtents.y))
00398                                                                                                 && (fabsf(T.z) <= (a.mExtents.z + mExtents.z)));
00399                                                                         }
00400 
00402 
00408 
00409                 inline_                 BOOL            Intersect(const AABB& a, udword axis)   const
00410                                                                         {
00411                                                                                 float t = mCenter[axis] - a.mCenter[axis];
00412                                                                                 float e = a.mExtents[axis] + mExtents[axis];
00413                                                                                 if(AIR(t) > IR(e))      return FALSE;
00414                                                                                 return TRUE;
00415                                                                         }
00416 
00418 
00423 
00424                 inline_                 void            Rotate(const Matrix4x4& mtx, AABB& aabb)        const
00425                                                                         {
00426                                                                                 // Compute new center
00427                                                                                 aabb.mCenter = mCenter * mtx;
00428 
00429                                                                                 // Compute new extents. FPU code & CPU code have been interleaved for improved performance.
00430                                                                                 Point Ex(mtx.m[0][0] * mExtents.x, mtx.m[0][1] * mExtents.x, mtx.m[0][2] * mExtents.x);
00431                                                                                 IR(Ex.x)&=0x7fffffff;   IR(Ex.y)&=0x7fffffff;   IR(Ex.z)&=0x7fffffff;
00432 
00433                                                                                 Point Ey(mtx.m[1][0] * mExtents.y, mtx.m[1][1] * mExtents.y, mtx.m[1][2] * mExtents.y);
00434                                                                                 IR(Ey.x)&=0x7fffffff;   IR(Ey.y)&=0x7fffffff;   IR(Ey.z)&=0x7fffffff;
00435 
00436                                                                                 Point Ez(mtx.m[2][0] * mExtents.z, mtx.m[2][1] * mExtents.z, mtx.m[2][2] * mExtents.z);
00437                                                                                 IR(Ez.x)&=0x7fffffff;   IR(Ez.y)&=0x7fffffff;   IR(Ez.z)&=0x7fffffff;
00438 
00439                                                                                 aabb.mExtents.x = Ex.x + Ey.x + Ez.x;
00440                                                                                 aabb.mExtents.y = Ex.y + Ey.y + Ez.y;
00441                                                                                 aabb.mExtents.z = Ex.z + Ey.z + Ez.z;
00442                                                                         }
00443 
00445 
00449 
00450                 inline_                 BOOL            IsValid()       const
00451                                                                         {
00452                                                                                 // Consistency condition for (Center, Extents) boxes: Extents >= 0
00453                                                                                 if(IS_NEGATIVE_FLOAT(mExtents.x))       return FALSE;
00454                                                                                 if(IS_NEGATIVE_FLOAT(mExtents.y))       return FALSE;
00455                                                                                 if(IS_NEGATIVE_FLOAT(mExtents.z))       return FALSE;
00456                                                                                 return TRUE;
00457                                                                         }
00458 
00460                 inline_                 AABB&           operator*=(float s)             { mExtents*=s;  return *this;   }
00461 
00463                 inline_                 AABB&           operator/=(float s)             { mExtents/=s;  return *this;   }
00464 
00466                 inline_                 AABB&           operator+=(const Point& trans)
00467                                                                         {
00468                                                                                 mCenter+=trans;
00469                                                                                 return *this;
00470                                                                         }
00471                 private:
00472                                                 Point           mCenter;                        
00473                                                 Point           mExtents;                       
00474         };
00475 
00476 #endif
00477 
00478         inline_ void ComputeMinMax(const Point& p, Point& min, Point& max)
00479         {
00480                 if(p.x > max.x) max.x = p.x;
00481                 if(p.x < min.x) min.x = p.x;
00482 
00483                 if(p.y > max.y) max.y = p.y;
00484                 if(p.y < min.y) min.y = p.y;
00485 
00486                 if(p.z > max.z) max.z = p.z;
00487                 if(p.z < min.z) min.z = p.z;
00488         }
00489 
00490         inline_ void ComputeAABB(AABB& aabb, const Point* list, udword nb_pts)
00491         {
00492                 if(list)
00493                 {
00494                         Point Maxi(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT);
00495                         Point Mini(MAX_FLOAT, MAX_FLOAT, MAX_FLOAT);
00496                         while(nb_pts--)
00497                         {
00498 //                              _prefetch(list+1);      // off by one ?
00499                                 ComputeMinMax(*list++, Mini, Maxi);
00500                         }
00501                         aabb.SetMinMax(Mini, Maxi);
00502                 }
00503         }
00504 
00505 #endif  // __ICEAABB_H__


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Sun Apr 2 2017 03:43:54