WBoundingBox.h

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
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends