00001
00002
00003
00004
00005 #ifndef __IRR_AABBOX_3D_H_INCLUDED__
00006 #define __IRR_AABBOX_3D_H_INCLUDED__
00007
00008 #include "irrMath.h"
00009 #include "plane3d.h"
00010 #include "line3d.h"
00011
00012 namespace irr
00013 {
00014 namespace core
00015 {
00016
00018
00020 template <class T>
00021 class aabbox3d
00022 {
00023 public:
00024
00026 aabbox3d(): MinEdge(-1,-1,-1), MaxEdge(1,1,1) {}
00028 aabbox3d(const vector3d<T>& min, const vector3d<T>& max): MinEdge(min), MaxEdge(max) {}
00030 aabbox3d(const vector3d<T>& init): MinEdge(init), MaxEdge(init) {}
00032 aabbox3d(T minx, T miny, T minz, T maxx, T maxy, T maxz): MinEdge(minx, miny, minz), MaxEdge(maxx, maxy, maxz) {}
00033
00034
00036
00038 inline bool operator==(const aabbox3d<T>& other) const { return (MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
00040
00042 inline bool operator!=(const aabbox3d<T>& other) const { return !(MinEdge == other.MinEdge && other.MaxEdge == MaxEdge);}
00043
00044
00045
00047
00050 void reset(T x, T y, T z)
00051 {
00052 MaxEdge.set(x,y,z);
00053 MinEdge = MaxEdge;
00054 }
00055
00057
00058 void reset(const aabbox3d<T>& initValue)
00059 {
00060 *this = initValue;
00061 }
00062
00064
00065 void reset(const vector3d<T>& initValue)
00066 {
00067 MaxEdge = initValue;
00068 MinEdge = initValue;
00069 }
00070
00072
00074 void addInternalPoint(const vector3d<T>& p)
00075 {
00076 addInternalPoint(p.X, p.Y, p.Z);
00077 }
00078
00080
00082 void addInternalBox(const aabbox3d<T>& b)
00083 {
00084 addInternalPoint(b.MaxEdge);
00085 addInternalPoint(b.MinEdge);
00086 }
00087
00089
00093 void addInternalPoint(T x, T y, T z)
00094 {
00095 if (x>MaxEdge.X) MaxEdge.X = x;
00096 if (y>MaxEdge.Y) MaxEdge.Y = y;
00097 if (z>MaxEdge.Z) MaxEdge.Z = z;
00098
00099 if (x<MinEdge.X) MinEdge.X = x;
00100 if (y<MinEdge.Y) MinEdge.Y = y;
00101 if (z<MinEdge.Z) MinEdge.Z = z;
00102 }
00103
00105
00106 vector3d<T> getCenter() const
00107 {
00108 return (MinEdge + MaxEdge) / 2;
00109 }
00110
00112
00113 vector3d<T> getExtent() const
00114 {
00115 return MaxEdge - MinEdge;
00116 }
00117
00119
00121 bool isEmpty() const
00122 {
00123 return MinEdge.equals ( MaxEdge );
00124 }
00125
00127 T getVolume() const
00128 {
00129 const vector3d<T> e = getExtent();
00130 return e.X * e.Y * e.Z;
00131 }
00132
00134 T getArea() const
00135 {
00136 const vector3d<T> e = getExtent();
00137 return 2*(e.X*e.Y + e.X*e.Z + e.Y*e.Z);
00138 }
00139
00141
00142 void getEdges(vector3d<T> *edges) const
00143 {
00144 const core::vector3d<T> middle = getCenter();
00145 const core::vector3d<T> diag = middle - MaxEdge;
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
00161 edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
00162 edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
00163 edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
00164 edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
00165 edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
00166 edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
00167 edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
00168 }
00169
00171
00172 void repair()
00173 {
00174 T t;
00175
00176 if (MinEdge.X > MaxEdge.X)
00177 { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; }
00178 if (MinEdge.Y > MaxEdge.Y)
00179 { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; }
00180 if (MinEdge.Z > MaxEdge.Z)
00181 { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; }
00182 }
00183
00185
00190 aabbox3d<T> getInterpolated(const aabbox3d<T>& other, f32 d) const
00191 {
00192 f32 inv = 1.0f - d;
00193 return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d),
00194 (other.MaxEdge*inv) + (MaxEdge*d));
00195 }
00196
00198
00201 bool isPointInside(const vector3d<T>& p) const
00202 {
00203 return (p.X >= MinEdge.X && p.X <= MaxEdge.X &&
00204 p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y &&
00205 p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z);
00206 }
00207
00209
00212 bool isPointTotalInside(const vector3d<T>& p) const
00213 {
00214 return (p.X > MinEdge.X && p.X < MaxEdge.X &&
00215 p.Y > MinEdge.Y && p.Y < MaxEdge.Y &&
00216 p.Z > MinEdge.Z && p.Z < MaxEdge.Z);
00217 }
00218
00220
00223 bool isFullInside(const aabbox3d<T>& other) const
00224 {
00225 return (MinEdge.X >= other.MinEdge.X && MinEdge.Y >= other.MinEdge.Y && MinEdge.Z >= other.MinEdge.Z &&
00226 MaxEdge.X <= other.MaxEdge.X && MaxEdge.Y <= other.MaxEdge.Y && MaxEdge.Z <= other.MaxEdge.Z);
00227 }
00228
00230
00233 bool intersectsWithBox(const aabbox3d<T>& other) const
00234 {
00235 return (MinEdge.X <= other.MaxEdge.X && MinEdge.Y <= other.MaxEdge.Y && MinEdge.Z <= other.MaxEdge.Z &&
00236 MaxEdge.X >= other.MinEdge.X && MaxEdge.Y >= other.MinEdge.Y && MaxEdge.Z >= other.MinEdge.Z);
00237 }
00238
00240
00242 bool intersectsWithLine(const line3d<T>& line) const
00243 {
00244 return intersectsWithLine(line.getMiddle(), line.getVector().normalize(),
00245 (T)(line.getLength() * 0.5));
00246 }
00247
00249
00253 bool intersectsWithLine(const vector3d<T>& linemiddle,
00254 const vector3d<T>& linevect, T halflength) const
00255 {
00256 const vector3d<T> e = getExtent() * (T)0.5;
00257 const vector3d<T> t = getCenter() - linemiddle;
00258
00259 if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) ||
00260 (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) ||
00261 (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) )
00262 return false;
00263
00264 T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y);
00265 if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r )
00266 return false;
00267
00268 r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X);
00269 if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r )
00270 return false;
00271
00272 r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X);
00273 if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r)
00274 return false;
00275
00276 return true;
00277 }
00278
00280
00284 EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const
00285 {
00286 vector3d<T> nearPoint(MaxEdge);
00287 vector3d<T> farPoint(MinEdge);
00288
00289 if (plane.Normal.X > (T)0)
00290 {
00291 nearPoint.X = MinEdge.X;
00292 farPoint.X = MaxEdge.X;
00293 }
00294
00295 if (plane.Normal.Y > (T)0)
00296 {
00297 nearPoint.Y = MinEdge.Y;
00298 farPoint.Y = MaxEdge.Y;
00299 }
00300
00301 if (plane.Normal.Z > (T)0)
00302 {
00303 nearPoint.Z = MinEdge.Z;
00304 farPoint.Z = MaxEdge.Z;
00305 }
00306
00307 if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0)
00308 return ISREL3D_FRONT;
00309
00310 if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0)
00311 return ISREL3D_CLIPPED;
00312
00313 return ISREL3D_BACK;
00314 }
00315
00317 vector3d<T> MinEdge;
00318
00320 vector3d<T> MaxEdge;
00321 };
00322
00324 typedef aabbox3d<f32> aabbox3df;
00326 typedef aabbox3d<s32> aabbox3di;
00327
00328 }
00329 }
00330
00331 #endif
00332