00001 #ifndef __VMML__AXIS_ALIGNED_BOUNDING_BOX__H__
00002 #define __VMML__AXIS_ALIGNED_BOUNDING_BOX__H__
00003
00004 #include <vmmlib/vector3.h>
00005 #include <vmmlib/vector4.h>
00006
00007 namespace vmml
00008 {
00009
00010 template< typename T >
00011 class AxisAlignedBoundingBox
00012 {
00013 public:
00014 AxisAlignedBoundingBox();
00015 AxisAlignedBoundingBox( const Vector3< T >& pMin, const Vector3< T >& pMax );
00016 AxisAlignedBoundingBox( const Vector4< T >& sphere );
00017 AxisAlignedBoundingBox( T cx, T cy, T cz, T size );
00018
00019 inline bool isIn( const Vector3< T >& pos );
00020 inline bool isIn2d( const Vector3< T >& pos );
00021 inline bool isIn( const Vector4< T >& sphere );
00022
00023 inline void set( const Vector3< T >& pMin, const Vector3< T >& pMax );
00024 inline void set( T cx, T cy, T cz, T size );
00025 inline void setMin( const Vector3< T >& pMin );
00026 inline void setMax( const Vector3< T >& pMax );
00027 inline const Vector3< T >& getMin() const;
00028 inline const Vector3< T >& getMax() const;
00029
00030 inline void merge( const AxisAlignedBoundingBox< T >& aabb );
00031
00032 inline void setEmpty( bool empty = true );
00033 inline bool isEmpty() const;
00034 inline void setDirty( bool dirty = true );
00035 inline bool isDirty() const;
00036
00037 Vector3< T > getCenter() const;
00038
00039 protected:
00040 Vector3< T > _min;
00041 Vector3< T > _max;
00042 bool _dirty;
00043 bool _empty;
00044
00045 };
00046
00047
00048
00049 template< typename T >
00050 AxisAlignedBoundingBox< T >::AxisAlignedBoundingBox()
00051 : _dirty( false )
00052 , _empty( true )
00053 {}
00054
00055
00056
00057 template< typename T >
00058 AxisAlignedBoundingBox< T >::AxisAlignedBoundingBox( const Vector3< T >& pMin, const Vector3< T >& pMax )
00059 : _min( pMin )
00060 , _max( pMax )
00061 , _dirty( false )
00062 , _empty( false )
00063 {}
00064
00065
00066
00067 template< typename T >
00068 AxisAlignedBoundingBox< T >::AxisAlignedBoundingBox( const Vector4< T >& sphere )
00069 : _dirty( false )
00070 , _empty( false )
00071 {
00072 _max = _min = sphere.getCenter();
00073 _max += sphere.getRadius();
00074 _min -= sphere.getRadius();
00075 }
00076
00077
00078
00079 template< typename T >
00080 AxisAlignedBoundingBox< T >::AxisAlignedBoundingBox( T cx, T cy, T cz, T size )
00081 : _dirty( false )
00082 , _empty( false )
00083 {
00084 _max = _min = Vector3f( cx, cy, cz );
00085 _max += size;
00086 _min -= size;
00087 }
00088
00089
00090
00091 template< typename T >
00092 inline bool AxisAlignedBoundingBox< T >::isIn( const Vector4< T >& sphere )
00093 {
00094 if ( _empty )
00095 return false;
00096 Vector3< T > sv ( sphere.getCenter() );
00097 sv += sphere.getRadius();
00098 if ( sv.x > _max.x || sv.y > _max.y || sv.z > _max.z )
00099 return false;
00100 sv -= sphere.getRadius() * 2.0f;
00101 if ( sv.x < _min.x || sv.y < _min.y || sv.z < _min.z )
00102 return false;
00103 return true;
00104 }
00105
00106
00107
00108 template< typename T >
00109 inline bool AxisAlignedBoundingBox< T >::isIn( const Vector3< T >& pos )
00110 {
00111 if ( _empty )
00112 return false;
00113 if ( pos.x > _max.x || pos.y > _max.y || pos.z > _max.z
00114 || pos.x < _min.x || pos.y < _min.y || pos.z < _min.z )
00115 {
00116 return false;
00117 }
00118 return true;
00119 }
00120
00121
00122
00123 template< typename T >
00124 inline bool AxisAlignedBoundingBox< T >::isIn2d( const Vector3< T >& pos )
00125 {
00126 if ( _empty )
00127 return false;
00128 if ( pos.x > _max.x || pos.y > _max.y || pos.x < _min.x || pos.y < _min.y )
00129 {
00130 return false;
00131 }
00132 return true;
00133 }
00134
00135
00136
00137 template< typename T >
00138 inline void AxisAlignedBoundingBox< T >::set( const Vector3< T >& pMin,
00139 const Vector3< T >& pMax )
00140 {
00141 _min = pMin;
00142 _max = pMax;
00143 _empty = false;
00144 }
00145
00146
00147
00148 template< typename T >
00149 inline void AxisAlignedBoundingBox< T >::set( T cx, T cy, T cz, T size )
00150 {
00151 Vector3< T > center( cx, cy, cz );
00152 _min = center - size;
00153 _max = center + size;
00154 _empty = false;
00155 }
00156
00157
00158
00159 template< typename T >
00160 inline void AxisAlignedBoundingBox< T >::setMin( const Vector3< T >& pMin )
00161 {
00162 _min = pMin;
00163 }
00164
00165
00166
00167 template< typename T >
00168 inline void AxisAlignedBoundingBox< T >::setMax( const Vector3< T >& pMax )
00169 {
00170 _max = pMax;
00171 }
00172
00173
00174
00175 template< typename T >
00176 inline const Vector3< T >& AxisAlignedBoundingBox< T >::getMin() const
00177 {
00178 return _min;
00179 }
00180
00181
00182
00183 template< typename T >
00184 inline const Vector3< T >& AxisAlignedBoundingBox< T >::getMax() const
00185 {
00186 return _max;
00187 }
00188
00189
00190
00191 template< typename T >
00192 Vector3< T >
00193 AxisAlignedBoundingBox< T >::getCenter() const
00194 {
00195 return _min + ( ( _max - _min ) * 0.5f );
00196 }
00197
00198
00199
00200 template< typename T >
00201 void
00202 AxisAlignedBoundingBox< T >::merge( const AxisAlignedBoundingBox< T >& aabb )
00203 {
00204 if ( aabb._empty )
00205 return;
00206
00207 if ( _empty )
00208 {
00209
00210 _min = aabb._min;
00211 _max = aabb._max;
00212 _empty = _dirty = false;
00213 return;
00214 }
00215
00216
00217 const Vector3< T >& min = aabb.getMin();
00218 const Vector3< T >& max = aabb.getMax();
00219
00220 if ( min.x < _min.x )
00221 _min.x = min.x;
00222 if ( min.y < _min.y )
00223 _min.y = min.y;
00224 if ( min.z < _min.z )
00225 _min.z = min.z;
00226
00227 if ( max.x > _max.x )
00228 _max.x = max.x;
00229 if ( max.y > _max.y )
00230 _max.y = max.y;
00231 if ( max.z > _max.z )
00232 _max.z = max.z;
00233 }
00234
00235
00236
00237 template< typename T >
00238 inline void
00239 AxisAlignedBoundingBox< T >::setEmpty( bool empty )
00240 {
00241 _empty = empty;
00242 }
00243
00244
00245
00246 template< typename T >
00247 inline bool
00248 AxisAlignedBoundingBox< T >::isEmpty() const
00249 {
00250 return _empty;
00251 }
00252
00253
00254
00255 template< typename T >
00256 inline void
00257 AxisAlignedBoundingBox< T >::setDirty( bool dirty )
00258 {
00259 _dirty = dirty;
00260 }
00261
00262
00263
00264 template< typename T >
00265 inline bool
00266 AxisAlignedBoundingBox< T >::isDirty() const
00267 {
00268 return _dirty;
00269 }
00270
00271
00272
00273 typedef AxisAlignedBoundingBox< float > Aabbf;
00274
00275 };
00276
00277 #endif
00278