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
    00049                 void addInternalPoint(const vector3d<T>& p)
    00050                 {
    00051                         addInternalPoint(p.X, p.Y, p.Z);
    00052                 }
    00053
    00055
    00057                 void addInternalBox(const aabbox3d<T>& b)
    00058                 {
    00059                         addInternalPoint(b.MaxEdge);
    00060                         addInternalPoint(b.MinEdge);
    00061                 }
    00062
    00064
    00067                 void reset(T x, T y, T z)
    00068                 {
    00069                         MaxEdge.set(x,y,z);
    00070                         MinEdge = MaxEdge;
    00071                 }
    00072
    00074
    00075                 void reset(const aabbox3d<T>& initValue)
    00076                 {
    00077                         *this = initValue;
    00078                 }
    00079
    00081
    00082                 void reset(const vector3d<T>& initValue)
    00083                 {
    00084                         MaxEdge = initValue;
    00085                         MinEdge = initValue;
    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
    00107                 bool isPointInside(const vector3d<T>& p) const
    00108                 {
    00109                         return (p.X >= MinEdge.X && p.X <= MaxEdge.X &&
    00110                                 p.Y >= MinEdge.Y && p.Y <= MaxEdge.Y &&
    00111                                 p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z);
    00112                 }
    00113
    00115
    00117                 bool isPointTotalInside(const vector3d<T>& p) const
    00118                 {
    00119                         return (p.X > MinEdge.X && p.X < MaxEdge.X &&
    00120                                 p.Y > MinEdge.Y && p.Y < MaxEdge.Y &&
    00121                                 p.Z > MinEdge.Z && p.Z < MaxEdge.Z);
    00122                 }
    00123
    00125
    00128                 bool intersectsWithBox(const aabbox3d<T>& other) const
    00129                 {
    00130                         return (MinEdge <= other.MaxEdge && MaxEdge >= other.MinEdge);
    00131                 }
    00132
    00134
    00137                 bool isFullInside(const aabbox3d<T>& other) const
    00138                 {
    00139                         return MinEdge >= other.MinEdge && MaxEdge <= other.MaxEdge;
    00140                 }
    00141
    00143
    00145                 bool intersectsWithLine(const line3d<T>& line) const
    00146                 {
    00147                         return intersectsWithLine(line.getMiddle(), line.getVector().normalize(),
    00148                                         (T)(line.getLength() * 0.5));
    00149                 }
    00150
    00152
    00156                 bool intersectsWithLine(const vector3d<T>& linemiddle,
    00157                                         const vector3d<T>& linevect,
    00158                                         T halflength) const
    00159                 {
    00160                         const vector3d<T> e = getExtent() * (T)0.5;
    00161                         const vector3d<T> t = getCenter() - linemiddle;
    00162
    00163                         if ((fabs(t.X) > e.X + halflength * fabs(linevect.X)) ||
    00164                                 (fabs(t.Y) > e.Y + halflength * fabs(linevect.Y)) ||
    00165                                 (fabs(t.Z) > e.Z + halflength * fabs(linevect.Z)) )
    00166                                 return false;
    00167
    00168                         T r = e.Y * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.Y);
    00169                         if (fabs(t.Y*linevect.Z - t.Z*linevect.Y) > r )
    00170                                 return false;
    00171
    00172                         r = e.X * (T)fabs(linevect.Z) + e.Z * (T)fabs(linevect.X);
    00173                         if (fabs(t.Z*linevect.X - t.X*linevect.Z) > r )
    00174                                 return false;
    00175
    00176                         r = e.X * (T)fabs(linevect.Y) + e.Y * (T)fabs(linevect.X);
    00177                         if (fabs(t.X*linevect.Y - t.Y*linevect.X) > r)
    00178                                 return false;
    00179
    00180                         return true;
    00181                 }
    00182
    00184
    00188                 EIntersectionRelation3D classifyPlaneRelation(const plane3d<T>& plane) const
    00189                 {
    00190                         vector3d<T> nearPoint(MaxEdge);
    00191                         vector3d<T> farPoint(MinEdge);
    00192
    00193                         if (plane.Normal.X > (T)0)
    00194                         {
    00195                                 nearPoint.X = MinEdge.X;
    00196                                 farPoint.X = MaxEdge.X;
    00197                         }
    00198
    00199                         if (plane.Normal.Y > (T)0)
    00200                         {
    00201                                 nearPoint.Y = MinEdge.Y;
    00202                                 farPoint.Y = MaxEdge.Y;
    00203                         }
    00204
    00205                         if (plane.Normal.Z > (T)0)
    00206                         {
    00207                                 nearPoint.Z = MinEdge.Z;
    00208                                 farPoint.Z = MaxEdge.Z;
    00209                         }
    00210
    00211                         if (plane.Normal.dotProduct(nearPoint) + plane.D > (T)0)
    00212                                 return ISREL3D_FRONT;
    00213
    00214                         if (plane.Normal.dotProduct(farPoint) + plane.D > (T)0)
    00215                                 return ISREL3D_CLIPPED;
    00216
    00217                         return ISREL3D_BACK;
    00218                 }
    00219
    00220
    00222
    00223                 vector3d<T> getCenter() const
    00224                 {
    00225                         return (MinEdge + MaxEdge) / 2;
    00226                 }
    00227
    00228
    00230
    00231                 vector3d<T> getExtent() const
    00232                 {
    00233                         return MaxEdge - MinEdge;
    00234                 }
    00235
    00236
    00238
    00239                 void getEdges(vector3d<T> *edges) const
    00240                 {
    00241                         const core::vector3d<T> middle = getCenter();
    00242                         const core::vector3d<T> diag = middle - MaxEdge;
    00243
    00244                         /*
    00245                         Edges are stored in this way:
    00246                         Hey, am I an ascii artist, or what? :) niko.
    00247                   /3--------/7
    00248                  /  |      / |
    00249                 /   |     /  |
    00250                 1---------5  |
    00251                 |   2- - -| -6
    00252                 |  /      |  /
    00253                 |/        | /
    00254                 0---------4/
    00255                         */
    00256
    00257                         edges[0].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
    00258                         edges[1].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
    00259                         edges[2].set(middle.X + diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
    00260                         edges[3].set(middle.X + diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
    00261                         edges[4].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z + diag.Z);
    00262                         edges[5].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z + diag.Z);
    00263                         edges[6].set(middle.X - diag.X, middle.Y + diag.Y, middle.Z - diag.Z);
    00264                         edges[7].set(middle.X - diag.X, middle.Y - diag.Y, middle.Z - diag.Z);
    00265                 }
    00266
    00267
    00269
    00272                 bool isEmpty() const
    00273                 {
    00274                         return MinEdge.equals ( MaxEdge );
    00275                 }
    00276
    00277
    00279
    00280                 void repair()
    00281                 {
    00282                         T t;
    00283
    00284                         if (MinEdge.X > MaxEdge.X)
    00285                                 { t=MinEdge.X; MinEdge.X = MaxEdge.X; MaxEdge.X=t; }
    00286                         if (MinEdge.Y > MaxEdge.Y)
    00287                                 { t=MinEdge.Y; MinEdge.Y = MaxEdge.Y; MaxEdge.Y=t; }
    00288                         if (MinEdge.Z > MaxEdge.Z)
    00289                                 { t=MinEdge.Z; MinEdge.Z = MaxEdge.Z; MaxEdge.Z=t; }
    00290                 }
    00291
    00293
    00296                 aabbox3d<T> getInterpolated(const aabbox3d<T>& other, f32 d) const
    00297                 {
    00298                         f32 inv = 1.0f - d;
    00299                         return aabbox3d<T>((other.MinEdge*inv) + (MinEdge*d),
    00300                                 (other.MaxEdge*inv) + (MaxEdge*d));
    00301                 }
    00302
    00304                 T getVolume() const
    00305                 {
    00306                         const vector3d<T> e = getExtent();
    00307                         return e.X * e.Y * e.Z;
    00308                 }
    00309
    00311                 T getArea() const
    00312                 {
    00313                         const vector3d<T> e = getExtent();
    00314                         return 2*(e.X*e.Y + e.X*e.Z + e.Y*e.Z);
    00315                 }
    00316
    00318                 vector3d<T> MinEdge;
    00319
    00321                 vector3d<T> MaxEdge;
    00322 };
    00323
    00325         typedef aabbox3d<f32> aabbox3df;
    00327         typedef aabbox3d<s32> aabbox3di;
    00328
    00329 } // end namespace core
    00330 } // end namespace irr
    00331
    00332 #endif
    00333

| The Irrlicht Engine Documentation © 2003-2009 by Nikolaus Gebhardt. Generated on Sun Jan 10 09:24:03 2010 by Doxygen (1.5.6)