00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_DIMENSION_AABB_H__
00009 #define __SP_DIMENSION_AABB_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spDimensionVector3D.hpp"
00014 #include "Base/spDimensionLine3D.hpp"
00015 #include "Base/spDimensionQuadrangle3D.hpp"
00016
00017
00018 namespace sp
00019 {
00020 namespace dim
00021 {
00022
00023
00024 template <typename T> class plane3d;
00025
00026
00027 #define DefineConstOperator(op) \
00028 aabbox3d<T> operator op (const aabbox3d<T> &other) const \
00029 { \
00030 return aabbox3d<T>(Min op other.Min, Max op other.Max); \
00031 }
00032
00033 #define DefineOperator(op) \
00034 aabbox3d<T>& operator op (const aabbox3d<T> &other) \
00035 { \
00036 Min op other.Min; \
00037 Max op other.Max; \
00038 return *this; \
00039 }
00040
00041
00043 template <typename T> class aabbox3d
00044 {
00045
00046 public:
00047
00048 aabbox3d()
00049 {
00050 }
00051 aabbox3d(const vector3d<T> &MinEdge, const vector3d<T> &MaxEdge) :
00052 Min(MinEdge),
00053 Max(MaxEdge)
00054 {
00055 }
00056 aabbox3d(const line3d<T> &Line) :
00057 Min(Line.Start ),
00058 Max(Line.End )
00059 {
00060 }
00061 aabbox3d(const aabbox3d<T> &Other) :
00062 Min(Other.Min),
00063 Max(Other.Max)
00064 {
00065 }
00066 ~aabbox3d()
00067 {
00068 }
00069
00070
00071
00072 DefineConstOperator(*)
00073 DefineConstOperator(/)
00074 DefineConstOperator(+)
00075 DefineConstOperator(-)
00076
00077 DefineOperator(*=)
00078 DefineOperator(/=)
00079 DefineOperator(+=)
00080 DefineOperator(-=)
00081
00082
00083
00085 inline vector3d<T> getCenter() const
00086 {
00087 return (Min + Max) / 2;
00088 }
00089
00091 inline vector3d<T> getSize() const
00092 {
00093 return Max - Min;
00094 }
00095
00097 inline T getVolume() const
00098 {
00099 return getSize().getVolume();
00100 }
00101
00103 inline bool checkBoxBoxIntersection(const aabbox3d<T> &other) const
00104 {
00105 return Min <= other.Max && Max >= other.Min;
00106 }
00107
00109 inline bool isBoxInside(const aabbox3d<T> &other) const
00110 {
00111 return Min >= other.Min && Max <= other.Max;
00112 }
00113
00115 inline bool isPointInside(const vector3d<T> &Point) const
00116 {
00117 return (
00118 Point.X >= Min.X && Point.Y >= Min.Y && Point.Z >= Min.Z &&
00119 Point.X <= Max.X && Point.Y <= Max.Y && Point.Z <= Max.Z
00120 );
00121 }
00122
00124 inline bool empty(f32 Tolerance = math::ROUNDING_ERROR) const
00125 {
00126 return Min.equal(Max, Tolerance);
00127 }
00128
00130 inline bool valid() const
00131 {
00132 return
00133 Max.X >= Min.X &&
00134 Max.Y >= Min.Y &&
00135 Max.Z >= Min.Z;
00136 }
00137
00139 inline aabbox3d<T>& repair()
00140 {
00141 if (Min.X > Max.X) math::Swap(Min.X, Max.X);
00142 if (Min.Y > Max.Y) math::Swap(Min.Y, Max.Y);
00143 if (Min.Z > Max.Z) math::Swap(Min.Z, Max.Z);
00144 return *this;
00145 }
00146
00148 inline void insertPoint(const vector3d<T> &Point)
00149 {
00150 if (Point.X > Max.X) Max.X = Point.X;
00151 if (Point.Y > Max.Y) Max.Y = Point.Y;
00152 if (Point.Z > Max.Z) Max.Z = Point.Z;
00153
00154 if (Point.X < Min.X) Min.X = Point.X;
00155 if (Point.Y < Min.Y) Min.Y = Point.Y;
00156 if (Point.Z < Min.Z) Min.Z = Point.Z;
00157 }
00158
00160 inline void insertBox(const aabbox3d<T> &Other)
00161 {
00162 insertPoint(Other.Min);
00163 insertPoint(Other.Max);
00164 }
00165
00167 inline T getBoxVolume() const
00168 {
00169 return
00170 (Max.X - Min.X).getAbs() *
00171 (Max.Y - Min.Y).getAbs() *
00172 (Max.Z - Min.Z).getAbs();
00173 }
00174
00176 inline aabbox3d<T> getScaled(const vector3d<T> &Size) const
00177 {
00178 return aabbox3d<T>(Min * Size, Max * Size);
00179 }
00180
00187 inline vector3d<T> getMaxRadius() const
00188 {
00189 const vector3d<T> AbsMin(Min.getAbs());
00190 const vector3d<T> AbsMax(Max.getAbs());
00191 return vector3d<T>(
00192 math::Max(AbsMin.X, AbsMax.X),
00193 math::Max(AbsMin.Y, AbsMax.Y),
00194 math::Max(AbsMin.Z, AbsMax.Z)
00195 );
00196 }
00197
00198 plane3d<T> getLeftPlane() const;
00199 plane3d<T> getRightPlane() const;
00200 plane3d<T> getTopPlane() const;
00201 plane3d<T> getBottomPlane() const;
00202 plane3d<T> getFrontPlane() const;
00203 plane3d<T> getBackPlane() const;
00204
00205 plane3d<T> getPlane(u32 Index) const
00206 {
00207 switch (Index)
00208 {
00209 case 0: return getLeftPlane();
00210 case 1: return getRightPlane();
00211 case 2: return getTopPlane();
00212 case 3: return getBottomPlane();
00213 case 4: return getFrontPlane();
00214 case 5: return getBackPlane();
00215 }
00216 return plane3d<T>();
00217 }
00218
00219 inline quadrangle3d<T> getLeftQuad() const
00220 {
00221 return quadrangle3d<T>(
00222 vector3d<T>(Min.X, Min.Y, Max.Z),
00223 vector3d<T>(Min.X, Max.Y, Max.Z),
00224 vector3d<T>(Min.X, Max.Y, Min.Z),
00225 vector3d<T>(Min.X, Min.Y, Min.Z)
00226 );
00227 }
00228 inline quadrangle3d<T> getRightQuad() const
00229 {
00230 return quadrangle3d<T>(
00231 vector3d<T>(Max.X, Min.Y, Min.Z),
00232 vector3d<T>(Max.X, Max.Y, Min.Z),
00233 vector3d<T>(Max.X, Max.Y, Max.Z),
00234 vector3d<T>(Max.X, Min.Y, Max.Z)
00235 );
00236 }
00237 inline quadrangle3d<T> getTopQuad() const
00238 {
00239 return quadrangle3d<T>(
00240 vector3d<T>(Min.X, Max.Y, Min.Z),
00241 vector3d<T>(Min.X, Max.Y, Max.Z),
00242 vector3d<T>(Max.X, Max.Y, Max.Z),
00243 vector3d<T>(Max.X, Max.Y, Min.Z)
00244 );
00245 }
00246 inline quadrangle3d<T> getBottomQuad() const
00247 {
00248 return quadrangle3d<T>(
00249 vector3d<T>(Min.X, Min.Y, Max.Z),
00250 vector3d<T>(Min.X, Min.Y, Min.Z),
00251 vector3d<T>(Max.X, Min.Y, Min.Z),
00252 vector3d<T>(Max.X, Min.Y, Max.Z)
00253 );
00254 }
00255 inline quadrangle3d<T> getFrontQuad() const
00256 {
00257 return quadrangle3d<T>(
00258 vector3d<T>(Min.X, Min.Y, Min.Z),
00259 vector3d<T>(Min.X, Max.Y, Min.Z),
00260 vector3d<T>(Max.X, Max.Y, Min.Z),
00261 vector3d<T>(Max.X, Min.Y, Min.Z)
00262 );
00263 }
00264 inline quadrangle3d<T> getBackQuad() const
00265 {
00266 return quadrangle3d<T>(
00267 vector3d<T>(Max.X, Min.Y, Max.Z),
00268 vector3d<T>(Max.X, Max.Y, Max.Z),
00269 vector3d<T>(Min.X, Max.Y, Max.Z),
00270 vector3d<T>(Min.X, Min.Y, Max.Z)
00271 );
00272 }
00273
00279 vector3d<T> getCorner(u32 Index) const
00280 {
00281 switch (Index)
00282 {
00283 case 0: return vector3d<T>(Min.X, Min.Y, Min.Z);
00284 case 1: return vector3d<T>(Max.X, Min.Y, Min.Z);
00285 case 2: return vector3d<T>(Min.X, Max.Y, Min.Z);
00286 case 3: return vector3d<T>(Max.X, Max.Y, Min.Z);
00287 case 4: return vector3d<T>(Min.X, Min.Y, Max.Z);
00288 case 5: return vector3d<T>(Max.X, Min.Y, Max.Z);
00289 case 6: return vector3d<T>(Min.X, Max.Y, Max.Z);
00290 case 7: return vector3d<T>(Max.X, Max.Y, Max.Z);
00291 }
00292 return T(0);
00293 }
00294
00295 line3d<T> getEdge(u32 Index) const
00296 {
00297 switch (Index)
00298 {
00299 case 0: return line3d<T>(vector3d<T>(Min.X, Min.Y, Min.Z), vector3d<T>(Max.X, Min.Y, Min.Z));
00300 case 1: return line3d<T>(vector3d<T>(Min.X, Max.Y, Min.Z), vector3d<T>(Max.X, Max.Y, Min.Z));
00301 case 2: return line3d<T>(vector3d<T>(Min.X, Max.Y, Max.Z), vector3d<T>(Max.X, Max.Y, Max.Z));
00302 case 3: return line3d<T>(vector3d<T>(Min.X, Min.Y, Max.Z), vector3d<T>(Max.X, Min.Y, Max.Z));
00303
00304 case 4: return line3d<T>(vector3d<T>(Min.X, Min.Y, Min.Z), vector3d<T>(Min.X, Max.Y, Min.Z));
00305 case 5: return line3d<T>(vector3d<T>(Max.X, Min.Y, Min.Z), vector3d<T>(Max.X, Max.Y, Min.Z));
00306 case 6: return line3d<T>(vector3d<T>(Max.X, Min.Y, Max.Z), vector3d<T>(Max.X, Max.Y, Max.Z));
00307 case 7: return line3d<T>(vector3d<T>(Min.X, Min.Y, Max.Z), vector3d<T>(Min.X, Max.Y, Max.Z));
00308
00309 case 8: return line3d<T>(vector3d<T>(Min.X, Min.Y, Min.Z), vector3d<T>(Min.X, Min.Y, Max.Z));
00310 case 9: return line3d<T>(vector3d<T>(Max.X, Min.Y, Min.Z), vector3d<T>(Max.X, Min.Y, Max.Z));
00311 case 10: return line3d<T>(vector3d<T>(Max.X, Max.Y, Min.Z), vector3d<T>(Max.X, Max.Y, Max.Z));
00312 case 11: return line3d<T>(vector3d<T>(Min.X, Max.Y, Min.Z), vector3d<T>(Min.X, Max.Y, Max.Z));
00313 }
00314 return line3d<T>();
00315 }
00316
00318 vector3d<T> getClosestPoint(const plane3d<T> &Plane) const;
00319
00320
00321
00322 vector3d<T> Min;
00323 vector3d<T> Max;
00324
00325
00326
00327 static const aabbox3d<T> OMEGA;
00328 static const aabbox3d<T> IDENTITY;
00329 static const aabbox3d<T> CUBE;
00330
00331 };
00332
00333 template <typename T> const aabbox3d<T> aabbox3d<T>::OMEGA(math::OMEGA, -math::OMEGA);
00334 template <typename T> const aabbox3d<T> aabbox3d<T>::IDENTITY(T(-1), T(1));
00335 template <typename T> const aabbox3d<T> aabbox3d<T>::CUBE(T(-0.5), T(0.5));
00336
00337 typedef aabbox3d<s32> aabbox3di;
00338 typedef aabbox3d<f32> aabbox3df;
00339
00340
00341 #undef DefineConstOperator
00342 #undef DefineOperator
00343
00344
00345 }
00346
00347 }
00348
00349
00350 #endif
00351
00352
00353
00354