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