Home | Namespaces | Hierarchy | Alphabetical List | Class list | Files | Namespace Members | Class members | File members | Tutorials

aabbox3d.h

Go to the documentation of this file.
00001 // Copyright (C) 2002-2009 Nikolaus Gebhardt
00002 // This file is part of the "Irrlicht Engine".
00003 // For conditions of distribution and use, see copyright notice in irrlicht.h
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                 // operators
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                 // functions
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                         Edges are stored in this way:
00149                         Hey, am I an ascii artist, or what? :) niko.
00150                    /3--------/7
00151                   / |       / |
00152                  /  |      /  |
00153                 1---------5   |
00154                 |  /2- - -|- -6
00155                 | /       |  /
00156                 |/        | /
00157                 0---------4/
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 >= other.MinEdge && MaxEdge <= other.MaxEdge;
00226                 }
00227 
00229 
00232                 bool intersectsWithBox(const aabbox3d<T>& other) const
00233                 {
00234                         return (MinEdge <= other.MaxEdge && MaxEdge >= other.MinEdge);
00235                 }
00236 
00238 
00240                 bool intersectsWithLine(const line3d<T>& line) const
00241                 {
00242                         return intersectsWithLine(line.getMiddle(), line.getVector().normalize(),
00243                                         (T)(line.getLength() * 0.5));
00244                 }
00245 
00247 
00251                 bool intersectsWithLine(const vector3d<T>& linemiddle,
00252                                         const vector3d<T>& linevect, T halflength) const
00253                 {
00254                         const vector3d<T> e = getExtent() * (T)0.5;
00255                         const vector3d<T> t = getCenter() - linemiddle;
00256 
00257                         if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) ||
00258                                 (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) ||
00259                                 (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) )
00260                                 return false;
00261 
00262                         T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y);
00263                         if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r )
00264                                 return false;
00265 
00266                         r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X);
00267                         if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r )
00268                                 return false;
00269 
00270                         r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X);
00271                         if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r)
00272                                 return false;
00273 
00274                         return true;
00275                 }
00276 
00278 
00282                 EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const
00283                 {
00284                         vector3d<T> nearPoint(MaxEdge);
00285                         vector3d<T> farPoint(MinEdge);
00286 
00287                         if (plane.Normal.X > (T)0)
00288                         {
00289                                 nearPoint.X = MinEdge.X;
00290                                 farPoint.X = MaxEdge.X;
00291                         }
00292 
00293                         if (plane.Normal.Y > (T)0)
00294                         {
00295                                 nearPoint.Y = MinEdge.Y;
00296                                 farPoint.Y = MaxEdge.Y;
00297                         }
00298 
00299                         if (plane.Normal.Z > (T)0)
00300                         {
00301                                 nearPoint.Z = MinEdge.Z;
00302                                 farPoint.Z = MaxEdge.Z;
00303                         }
00304 
00305                         if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0)
00306                                 return ISREL3D_FRONT;
00307 
00308                         if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0)
00309                                 return ISREL3D_CLIPPED;
00310 
00311                         return ISREL3D_BACK;
00312                 }
00313 
00315                 vector3d<T> MinEdge;
00316 
00318                 vector3d<T> MaxEdge;
00319 };
00320 
00322         typedef aabbox3d<f32> aabbox3df;
00324         typedef aabbox3d<s32> aabbox3di;
00325 
00326 } // end namespace core
00327 } // end namespace irr
00328 
00329 #endif
00330 

The Irrlicht Engine
The Irrlicht Engine Documentation © 2003-2010 by Nikolaus Gebhardt. Generated on Sun Jan 31 16:45:16 2010 by Doxygen (1.6.2)