# OgreAxisAlignedBox.h

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright (c) 2000-2005 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #ifndef __AxisAlignedBox_H_
    00026 #define __AxisAlignedBox_H_
    00027
    00028 // Precompiler options
    00029 #include "OgrePrerequisites.h"
    00030
    00031 #include "OgreVector3.h"
    00032 #include "OgreMatrix4.h"
    00033
    00034 namespace Ogre {
    00035
    00045     class _OgreExport AxisAlignedBox
    00046     {
    00047     protected:
    00048         Vector3 mMinimum;
    00049         Vector3 mMaximum;
    00050         bool mNull;
    00051
    00052         Vector3 mCorners[8];
    00053
    00056         void updateCorners(void)
    00057         {
    00058             // The order of these items is, using right-handed co-ordinates:
    00059             // Minimum Z face, starting with Min(all), then anticlockwise
    00060             //   around face (looking onto the face)
    00061             // Maximum Z face, starting with Max(all), then anticlockwise
    00062             //   around face (looking onto the face)
    00063             mCorners[0] = mMinimum;
    00064             mCorners[1].x = mMinimum.x; mCorners[1].y = mMaximum.y; mCorners[1].z = mMinimum.z;
    00065             mCorners[2].x = mMaximum.x; mCorners[2].y = mMaximum.y; mCorners[2].z = mMinimum.z;
    00066             mCorners[3].x = mMaximum.x; mCorners[3].y = mMinimum.y; mCorners[3].z = mMinimum.z;
    00067
    00068             mCorners[4] = mMaximum;
    00069             mCorners[5].x = mMinimum.x; mCorners[5].y = mMaximum.y; mCorners[5].z = mMaximum.z;
    00070             mCorners[6].x = mMinimum.x; mCorners[6].y = mMinimum.y; mCorners[6].z = mMaximum.z;
    00071             mCorners[7].x = mMaximum.x; mCorners[7].y = mMinimum.y; mCorners[7].z = mMaximum.z;
    00072         }
    00073
    00074     public:
    00075         inline AxisAlignedBox()
    00076         {
    00077             // Default to null box
    00078             setMinimum( -0.5, -0.5, -0.5 );
    00079             setMaximum( 0.5, 0.5, 0.5 );
    00080             mNull = true;
    00081         }
    00082
    00083         inline AxisAlignedBox( const Vector3& min, const Vector3& max )
    00084         {
    00085             setExtents( min, max );
    00086         }
    00087
    00088         inline AxisAlignedBox(
    00089             Real mx, Real my, Real mz,
    00090             Real Mx, Real My, Real Mz )
    00091         {
    00092             setExtents( mx, my, mz, Mx, My, Mz );
    00093         }
    00094
    00097         inline const Vector3& getMinimum(void) const
    00098         {
    00099             return mMinimum;
    00100         }
    00101
    00104         inline const Vector3& getMaximum(void) const
    00105         {
    00106             return mMaximum;
    00107         }
    00108
    00111         inline void setMinimum( const Vector3& vec )
    00112         {
    00113             mNull = false;
    00114             mMinimum = vec;
    00115             updateCorners();
    00116         }
    00117
    00118         inline void setMinimum( Real x, Real y, Real z )
    00119         {
    00120             mNull = false;
    00121             mMinimum.x = x;
    00122             mMinimum.y = y;
    00123             mMinimum.z = z;
    00124             updateCorners();
    00125         }
    00126
    00129         inline void setMaximum( const Vector3& vec )
    00130         {
    00131             mNull = false;
    00132             mMaximum = vec;
    00133             updateCorners();
    00134         }
    00135
    00136         inline void setMaximum( Real x, Real y, Real z )
    00137         {
    00138             mNull = false;
    00139             mMaximum.x = x;
    00140             mMaximum.y = y;
    00141             mMaximum.z = z;
    00142             updateCorners();
    00143         }
    00144
    00147         inline void setExtents( const Vector3& min, const Vector3& max )
    00148         {
    00149             mNull = false;
    00150             mMinimum = min;
    00151             mMaximum = max;
    00152             updateCorners();
    00153         }
    00154
    00155         inline void setExtents(
    00156             Real mx, Real my, Real mz,
    00157             Real Mx, Real My, Real Mz )
    00158         {
    00159             mNull = false;
    00160
    00161             mMinimum.x = mx;
    00162             mMinimum.y = my;
    00163             mMinimum.z = mz;
    00164
    00165             mMaximum.x = Mx;
    00166             mMaximum.y = My;
    00167             mMaximum.z = Mz;
    00168
    00169             updateCorners();
    00170         }
    00171
    00195         inline const Vector3* getAllCorners(void) const
    00196         {
    00197             assert( !mNull && "Can't get corners of a null AAB" );
    00198             return (const Vector3*)mCorners;
    00199         }
    00200
    00201         friend std::ostream& operator<<( std::ostream& o, AxisAlignedBox aab )
    00202         {
    00203             if (aab.isNull())
    00204             {
    00205                 o << "AxisAlignedBox(null)";
    00206             }
    00207             else
    00208             {
    00209                 o << "AxisAlignedBox(min=" << aab.mMinimum << ", max=" << aab.mMaximum;
    00210                 o << ", corners=";
    00211                 for (int i = 0; i < 7; ++i)
    00212                     o << aab.mCorners[i] << ", ";
    00213                 o << aab.mCorners[7] << ")";
    00214             }
    00215             return o;
    00216         }
    00217
    00221         void merge( const AxisAlignedBox& rhs )
    00222         {
    00223             // Do nothing if rhs null
    00224             if (rhs.mNull)
    00225             {
    00226                 return;
    00227             }
    00228             // Otherwise if current null, just take rhs
    00229             else if (mNull)
    00230             {
    00231                 setExtents(rhs.mMinimum, rhs.mMaximum);
    00232             }
    00233             // Otherwise merge
    00234             else
    00235             {
    00236                 Vector3 min = mMinimum;
    00237                 Vector3 max = mMaximum;
    00238                 max.makeCeil(rhs.mMaximum);
    00239                 min.makeFloor(rhs.mMinimum);
    00240
    00241                 setExtents(min, max);
    00242             }
    00243
    00244         }
    00245
    00248         void merge( const Vector3& point )
    00249         {
    00250             if (mNull){ // if null, use this point
    00251                 setExtents(point, point);
    00252             } else {
    00253                 mMaximum.makeCeil(point);
    00254                 mMinimum.makeFloor(point);
    00255                 updateCorners();
    00256             }
    00257         }
    00258
    00268         void transform( const Matrix4& matrix )
    00269         {
    00270             // Do nothing if current null
    00271             if( mNull )
    00272                 return;
    00273
    00274             Vector3 min, max, temp;
    00275             bool first = true;
    00276             size_t i;
    00277
    00278             for( i = 0; i < 8; ++i )
    00279             {
    00280                 // Transform and check extents
    00281                 temp = matrix * mCorners[i];
    00282                 if( first || temp.x > max.x )
    00283                     max.x = temp.x;
    00284                 if( first || temp.y > max.y )
    00285                     max.y = temp.y;
    00286                 if( first || temp.z > max.z )
    00287                     max.z = temp.z;
    00288                 if( first || temp.x < min.x )
    00289                     min.x = temp.x;
    00290                 if( first || temp.y < min.y )
    00291                     min.y = temp.y;
    00292                 if( first || temp.z < min.z )
    00293                     min.z = temp.z;
    00294
    00295                 first = false;
    00296             }
    00297
    00298             setExtents( min,max );
    00299
    00300         }
    00301
    00304         inline void setNull()
    00305         {
    00306             mNull = true;
    00307         }
    00308
    00311         bool isNull(void) const
    00312         {
    00313             return mNull;
    00314         }
    00315
    00317         inline bool intersects(const AxisAlignedBox& b2) const
    00318         {
    00319             // Early-fail for nulls
    00320             if (this->isNull() || b2.isNull())
    00321                 return false;
    00322
    00323             // Use up to 6 separating planes
    00324             if (mMaximum.x < b2.mMinimum.x)
    00325                 return false;
    00326             if (mMaximum.y < b2.mMinimum.y)
    00327                 return false;
    00328             if (mMaximum.z < b2.mMinimum.z)
    00329                 return false;
    00330
    00331             if (mMinimum.x > b2.mMaximum.x)
    00332                 return false;
    00333             if (mMinimum.y > b2.mMaximum.y)
    00334                 return false;
    00335             if (mMinimum.z > b2.mMaximum.z)
    00336                 return false;
    00337
    00338             // otherwise, must be intersecting
    00339             return true;
    00340
    00341         }
    00342
    00344         inline AxisAlignedBox intersection(const AxisAlignedBox& b2) const
    00345         {
    00346             if (!this->intersects(b2))
    00347             {
    00348                 return AxisAlignedBox();
    00349             }
    00350             Vector3 intMin, intMax;
    00351
    00352             const Vector3& b2max = b2.getMaximum();
    00353             const Vector3& b2min = b2.getMinimum();
    00354
    00355             if (b2max.x > mMaximum.x && mMaximum.x > b2min.x)
    00356                 intMax.x = mMaximum.x;
    00357             else
    00358                 intMax.x = b2max.x;
    00359             if (b2max.y > mMaximum.y && mMaximum.y > b2min.y)
    00360                 intMax.y = mMaximum.y;
    00361             else
    00362                 intMax.y = b2max.y;
    00363             if (b2max.z > mMaximum.z && mMaximum.z > b2min.z)
    00364                 intMax.z = mMaximum.z;
    00365             else
    00366                 intMax.z = b2max.z;
    00367
    00368             if (b2min.x < mMinimum.x && mMinimum.x < b2max.x)
    00369                 intMin.x = mMinimum.x;
    00370             else
    00371                 intMin.x= b2min.x;
    00372             if (b2min.y < mMinimum.y && mMinimum.y < b2max.y)
    00373                 intMin.y = mMinimum.y;
    00374             else
    00375                 intMin.y= b2min.y;
    00376             if (b2min.z < mMinimum.z && mMinimum.z < b2max.z)
    00377                 intMin.z = mMinimum.z;
    00378             else
    00379                 intMin.z= b2min.z;
    00380
    00381             return AxisAlignedBox(intMin, intMax);
    00382
    00383         }
    00384
    00386         Real volume(void) const
    00387         {
    00388             if (mNull)
    00389             {
    00390                 return 0.0f;
    00391             }
    00392             else
    00393             {
    00394                 Vector3 diff = mMaximum - mMinimum;
    00395                 return diff.x * diff.y * diff.z;
    00396             }
    00397
    00398         }
    00399
    00401         inline void scale(const Vector3& s)
    00402         {
    00403             // NB assumes centered on origin
    00404             Vector3 min = mMinimum * s;
    00405             Vector3 max = mMaximum * s;
    00406             setExtents(min, max);
    00407         }
    00408
    00410         bool intersects(const Sphere& s) const
    00411         {
    00412             return Math::intersects(s, *this);
    00413         }
    00415         bool intersects(const Plane& p) const
    00416         {
    00417             return Math::intersects(p, *this);
    00418         }
    00420         bool intersects(const Vector3& v) const
    00421         {
    00422             return(v.x >= mMinimum.x  &&  v.x <= mMaximum.x  &&
    00423                 v.y >= mMinimum.y  &&  v.y <= mMaximum.y  &&
    00424                 v.z >= mMinimum.z  &&  v.z <= mMaximum.z);
    00425         }
    00427         Vector3 getCenter(void) const
    00428         {
    00429             return Vector3((mMaximum + mMinimum) * 0.5);
    00430         }
    00431
    00432
    00433     };
    00434
    00435 } // namespace Ogre
    00436
    00437 #endif

Copyright © 2000-2005 by The OGRE Team
Last modified Sun Nov 20 12:35:56 2005