OpenWalnut 1.3.1
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WBOUNDINGBOX_H 00026 #define WBOUNDINGBOX_H 00027 00028 #include <ostream> 00029 #include <iomanip> // for setprecision 00030 #include <cmath> // std::sqrt 00031 00032 #include <osg/BoundingBox> 00033 00034 #include "exceptions/WInvalidBoundingBox.h" 00035 //#include "math/linearAlgebra/WLinearAlgebra.h" 00036 00037 /** 00038 * Represents a \e axis \e parallel bounding box and provides some useful operations with them. 00039 * 00040 * \note Reason for subclassing: We don't want \c _min and \c _max member variables to be public. 00041 * \note Reason for not having a \e private osg::BoundingBox member is, we don't have to wrap many 00042 * member functions and can make use of the using directive. A downside on this is, we cannot 00043 * automatical cast to osg::BoundingBox even if we provide a cast operator! Hence when we need this 00044 * we will provide a toOsgBB() member function. 00045 */ 00046 template< class VT > 00047 class WBoundingBoxImpl : private osg::BoundingBoxImpl< VT > 00048 { 00049 public: 00050 /** 00051 * Vertex type for min and max positions of this box. 00052 */ 00053 typedef typename osg::BoundingBoxImpl< VT >::vec_type vec_type; 00054 00055 /** 00056 * Value type of the vertex type for example double, float, etc. 00057 */ 00058 typedef typename osg::BoundingBoxImpl< VT >::value_type value_type; 00059 00060 /** 00061 * Default constructor. 00062 */ 00063 WBoundingBoxImpl(); 00064 00065 /** 00066 * Wrapps the component wise bounding box constructor from osg::BoundingBox. 00067 * 00068 * \param xmin Minimal x coordinate 00069 * \param ymin Minimal y coordinate 00070 * \param zmin Minimal z coordinate 00071 * \param xmax Maximal x coordinate 00072 * \param ymax Maximal y coordinate 00073 * \param zmax Maximal z coordinate 00074 */ 00075 WBoundingBoxImpl( value_type xmin, value_type ymin, value_type zmin, value_type xmax, value_type ymax, value_type zmax ); 00076 00077 /** 00078 * Constructs a bounding box by min and max positions. 00079 * 00080 * \param min Position containing minx miny and minz coordinates. 00081 * \param max Position containing maxx maxy and maxz coordinates. 00082 */ 00083 WBoundingBoxImpl( const vec_type& min, const vec_type& max ); 00084 00085 /** 00086 * Destructs this instance. 00087 */ 00088 virtual ~WBoundingBoxImpl(); 00089 00090 /** 00091 * Resets this box to an initial state where max is FLT_MIN and min FLT_MAX. 00092 * 00093 * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::init() 00094 */ 00095 void reset(); 00096 00097 using osg::BoundingBoxImpl< VT >::valid; 00098 using osg::BoundingBoxImpl< VT >::set; 00099 using osg::BoundingBoxImpl< VT >::xMin; 00100 using osg::BoundingBoxImpl< VT >::yMin; 00101 using osg::BoundingBoxImpl< VT >::zMin; 00102 using osg::BoundingBoxImpl< VT >::xMax; 00103 using osg::BoundingBoxImpl< VT >::yMax; 00104 using osg::BoundingBoxImpl< VT >::zMax; 00105 using osg::BoundingBoxImpl< VT >::center; 00106 using osg::BoundingBoxImpl< VT >::radius; 00107 00108 /** 00109 * Calculates and returns the squared length of the bounding box radius. 00110 * 00111 * \note This is a wrapper call to osg::BoundingBoxImpl< VT >::radius2() 00112 * 00113 * \return squared bbox radius 00114 */ 00115 value_type radiusSquare() const; 00116 00117 using osg::BoundingBoxImpl< VT >::corner; 00118 00119 /** 00120 * Explicit type conversion function to use a WBoundingBox as osg::BoundingBox. 00121 * 00122 * \return A copy of this bounding box as osg::BoundingBox. 00123 */ 00124 osg::BoundingBox toOSGBB() const; 00125 00126 using osg::BoundingBoxImpl< VT >::expandBy; 00127 00128 /** 00129 * Expands this bounding box to include the given bounding box. 00130 * 00131 * \param bb The other bounding box. 00132 */ 00133 void expandBy( const WBoundingBoxImpl< VT > &bb ); 00134 00135 /** 00136 * Checks for intersection of this bounding box with the specified bounding box. 00137 * 00138 * \param bb The other bouding box to tetst with. 00139 * 00140 * \return True if they intersect, false otherwise. 00141 */ 00142 bool intersects( const WBoundingBoxImpl< VT > &bb ) const; 00143 00144 /** 00145 * Computes the minimal distance of tow axis parallel bounding boxes. 00146 * 00147 * \param bb The other bounding box. 00148 * 00149 * \return Zero if they intersect, otherwise their minimal distance. 00150 */ 00151 value_type minDistance( const WBoundingBoxImpl< VT > &bb ) const; 00152 00153 using osg::BoundingBoxImpl< VT >::contains; 00154 00155 /** 00156 * Gives the front lower left aka minimum corner. 00157 * 00158 * \return Minimum corner. 00159 */ 00160 const vec_type& getMin() const; 00161 00162 /** 00163 * Gives the back upper right aka maximum corner. 00164 * 00165 * \return Maximum corner. 00166 */ 00167 const vec_type& getMax() const; 00168 00169 protected: 00170 private: 00171 }; 00172 00173 template< class VT > 00174 inline WBoundingBoxImpl< VT >::WBoundingBoxImpl() 00175 : osg::BoundingBoxImpl< VT >() 00176 { 00177 } 00178 00179 template< class VT > 00180 inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( value_type xmin, value_type ymin, value_type zmin, value_type xmax, value_type ymax, value_type zmax ) // NOLINT line length 00181 : osg::BoundingBoxImpl< VT >( xmin, ymin, zmin, xmax, ymax, zmax ) 00182 { 00183 } 00184 00185 template< class VT > 00186 inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( const vec_type& min, const vec_type& max ) 00187 : osg::BoundingBoxImpl< VT >( min, max ) 00188 { 00189 } 00190 00191 template< class VT > 00192 inline WBoundingBoxImpl< VT >::~WBoundingBoxImpl() 00193 { 00194 } 00195 00196 template< class VT > 00197 inline void WBoundingBoxImpl< VT >::reset() 00198 { 00199 this->init(); 00200 } 00201 00202 template< class VT > 00203 inline typename WBoundingBoxImpl< VT >::value_type WBoundingBoxImpl< VT >::radiusSquare() const 00204 { 00205 return this->raidus2(); 00206 } 00207 00208 template< class VT > 00209 inline osg::BoundingBox WBoundingBoxImpl< VT >::toOSGBB() const 00210 { 00211 return osg::BoundingBox( osg::BoundingBoxImpl< VT >::_min, osg::BoundingBoxImpl< VT >::_max ); 00212 } 00213 00214 template< class VT > 00215 inline void WBoundingBoxImpl< VT >::expandBy( const WBoundingBoxImpl< VT > &bb ) 00216 { 00217 osg::BoundingBoxImpl< VT >::expandBy( bb ); 00218 } 00219 00220 template< class VT > 00221 inline bool WBoundingBoxImpl< VT >::intersects( const WBoundingBoxImpl< VT > &bb ) const 00222 { 00223 return osg::BoundingBoxImpl< VT >::intersects( bb ); 00224 } 00225 00226 /** 00227 * Anonymous namespace, just to be DRY in minDistance. 00228 */ 00229 namespace 00230 { 00231 /** 00232 * Checks if the two given intervals intersect and computes the distance between them. 00233 * 00234 * \param a0 lower bound of the first interval 00235 * \param a1 upper bound of the first interval 00236 * \param b0 lower bound of the second interval 00237 * \param b1 upper bound if the second interval 00238 * 00239 * \return The distance between those intervals if they don't overlap, zero otherwise 00240 */ 00241 inline double intervalDistance( double a0, double a1, double b0, double b1 ) 00242 { 00243 if( a1 < b0 ) 00244 { 00245 return b0 - a1; 00246 } 00247 else if( b1 < a0 ) 00248 { 00249 return a0 - b1; 00250 } 00251 return 0.0; 00252 } 00253 } 00254 00255 template< class VT > 00256 inline typename WBoundingBoxImpl< VT >::value_type WBoundingBoxImpl< VT >::minDistance( const WBoundingBoxImpl< VT > &bb ) const 00257 { 00258 // test if they are valid 00259 if( !valid() || !bb.valid() ) 00260 { 00261 throw WInvalidBoundingBox( "One of the both bounding boxes inside minDistance computation is not valid." ); 00262 } 00263 00264 double dx = intervalDistance( xMin(), xMax(), bb.xMin(), bb.xMax() ); 00265 double dy = intervalDistance( yMin(), yMax(), bb.yMin(), bb.yMax() ); 00266 double dz = intervalDistance( zMin(), zMax(), bb.zMin(), bb.zMax() ); 00267 if( dx == 0.0 && dy == 0.0 && dz == 0.0 ) 00268 { 00269 return 0.0; 00270 } 00271 return std::sqrt( dx * dx + dy * dy + dz * dz ); 00272 } 00273 00274 /** 00275 * Output operator for the WBoundingBoxImpl class. 00276 * 00277 * \param out Output stream operator 00278 * \param bb The box which should be streamed out 00279 * 00280 * \return reference to the output stream 00281 */ 00282 template< class VT > 00283 inline std::ostream& operator<<( std::ostream& out, const WBoundingBoxImpl< VT >& bb ) 00284 { 00285 out << std::scientific << std::setprecision( 16 ); 00286 out << "AABB( min: " << bb.xMin() << ", " << bb.yMin() << ", " << bb.zMin(); 00287 out << " max: " << bb.xMax() << ", " << bb.yMax() << ", " << bb.zMax() << " )"; 00288 return out; 00289 } 00290 00291 template< class VT > 00292 inline const typename WBoundingBoxImpl< VT >::vec_type& WBoundingBoxImpl< VT >::getMin() const 00293 { 00294 return osg::BoundingBoxImpl< VT >::_min; 00295 } 00296 00297 template< class VT > 00298 inline const typename WBoundingBoxImpl< VT >::vec_type& WBoundingBoxImpl< VT >::getMax() const 00299 { 00300 return osg::BoundingBoxImpl< VT >::_max; 00301 } 00302 00303 typedef WBoundingBoxImpl< osg::Vec3 > WBoundingBox; 00304 00305 #endif // WBOUNDINGBOX_H