00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://ogre.sourceforge.net/ 00006 00007 Copyright © 2000-2002 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 Vector3 getMinimum(void) const 00098 { 00099 return mMinimum; 00100 } 00101 00104 inline 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 00255 void transform( const Matrix4& matrix ) 00256 { 00257 // Do nothing if current null 00258 if( mNull ) 00259 return; 00260 00261 Vector3 min, max, temp; 00262 bool first = true; 00263 int i; 00264 00265 for( i = 0; i < 8; ++i ) 00266 { 00267 // Transform and check extents 00268 temp = matrix * mCorners[i]; 00269 if( first || temp.x > max.x ) 00270 max.x = temp.x; 00271 if( first || temp.y > max.y ) 00272 max.y = temp.y; 00273 if( first || temp.z > max.z ) 00274 max.z = temp.z; 00275 if( first || temp.x < min.x ) 00276 min.x = temp.x; 00277 if( first || temp.y < min.y ) 00278 min.y = temp.y; 00279 if( first || temp.z < min.z ) 00280 min.z = temp.z; 00281 00282 first = false; 00283 } 00284 00285 setExtents( min,max ); 00286 00287 } 00288 00291 inline void setNull() 00292 { 00293 mNull = true; 00294 } 00295 00298 bool isNull(void) const 00299 { 00300 return mNull; 00301 } 00302 }; 00303 00304 } // namespace Ogre 00305 00306 #endif
Copyright © 2002 by The OGRE Team