| Irrlicht 3D Engine |

aabbox3d.h
Go to the documentation of this file.

    00001 // Copyright (C) 2002-2012 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.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 } // end namespace core
    00329 } // end namespace irr
    00330
    00331 #endif
    00332