Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:37 2006