LCOV - code coverage report
Current view: top level - vmmlib - aabb.hpp (source / functions) Hit Total Coverage
Test: vmmlib Lines: 49 54 90.7 %
Date: 2015-11-02 15:45:14 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2006-2014, Visualization and Multimedia Lab,
       3             :  *                          University of Zurich <http://vmml.ifi.uzh.ch>,
       4             :  *                          Eyescale Software GmbH,
       5             :  *                          Blue Brain Project, EPFL
       6             :  *
       7             :  * This file is part of VMMLib <https://github.com/VMML/vmmlib/>
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions are met:
      11             :  *
      12             :  * Redistributions of source code must retain the above copyright notice, this
      13             :  * list of conditions and the following disclaimer.  Redistributions in binary
      14             :  * form must reproduce the above copyright notice, this list of conditions and
      15             :  * the following disclaimer in the documentation and/or other materials provided
      16             :  * with the distribution.  Neither the name of the Visualization and Multimedia
      17             :  * Lab, University of Zurich nor the names of its contributors may be used to
      18             :  * endorse or promote products derived from this software without specific prior
      19             :  * written permission.
      20             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
      21             :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
      24             :  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : #ifndef __VMML__AXIS_ALIGNED_BOUNDING_BOX__HPP__
      33             : #define __VMML__AXIS_ALIGNED_BOUNDING_BOX__HPP__
      34             : 
      35             : #include <vmmlib/vector.hpp>
      36             : #include <limits>
      37             : 
      38             : namespace vmml
      39             : {
      40             : /**
      41             :  * An axis-aligned bounding box.
      42             :  *
      43             :  * An empty bounding box has undefined, implementation-specific values. Read
      44             :  * operations (getMin(), getMax(), getDimension(), isIn(), etc.) have undefined
      45             :  * semantics on an empty bounding box. set() and merge() operations will define
      46             :  * the bounding box correctly.
      47             :  */
      48             : template< typename T > class AABB
      49             : {
      50             : public:
      51             :     /** Create an empty bounding box. */
      52             :     AABB();
      53             :     AABB( const vector< 3, T >& pMin,
      54             :                             const vector< 3, T >& pMax );
      55             :     AABB( const vector< 4, T >& sphere );
      56             :     AABB( T cx, T cy, T cz, T size );
      57             : 
      58             :     bool isIn( const vector< 3, T >& pos );
      59             :     bool isIn2d( const vector< 3, T >& pos ); // only x and y components are checked
      60             :     bool isIn( const vector< 4, T >& sphere );
      61             : 
      62             :     void set( const vector< 3, T >& pMin, const vector< 3, T >& pMax );
      63             :     void set( T cx, T cy, T cz, T size );
      64             :     void setMin( const vector< 3, T >& pMin );
      65             :     void setMax( const vector< 3, T >& pMax );
      66             : 
      67             :     const vector< 3, T >& getMin() const;
      68             :     const vector< 3, T >& getMax() const;
      69             :     vector< 3, T >& getMin();
      70             :     vector< 3, T >& getMax();
      71             : 
      72             :     void merge( const AABB< T >& aabb );
      73             :     void merge( const vector< 3, T >& point );
      74             : 
      75             :     void setEmpty();
      76             :     bool isEmpty() const;
      77             : 
      78             :     AABB operator*( const T value ) const;
      79             :     AABB operator/( const T value ) const;
      80             :     AABB operator+( const T value ) const;
      81             :     AABB operator-( const T value ) const;
      82             : 
      83             :     void operator*=( const T value );
      84             :     void operator/=( const T value );
      85             :     void operator+=( const T value );
      86             :     void operator-=( const T value );
      87             : 
      88             :     template< class U >
      89             :     bool operator==( const AABB< U >& other ) const;
      90             :     template< class U >
      91             :     bool operator!=( const AABB< U >& other ) const;
      92             : 
      93             :     vector< 3, T > getCenter() const;
      94             :     vector< 3, T > getDimension() const;
      95             : 
      96             :     static AABB< T > makeUnitBox();
      97             : 
      98             : protected:
      99             :     vector< 3, T > _min;
     100             :     vector< 3, T > _max;
     101             : };
     102             : 
     103             : #ifndef VMMLIB_NO_TYPEDEFS
     104             : typedef AABB< float >  AABBf;
     105             : typedef AABB< double > AABBd;
     106             : #endif
     107             : 
     108             : template< typename T >
     109           0 : inline std::ostream& operator << ( std::ostream& os,
     110             :                                    const AABB< T >& aabb )
     111             : {
     112           0 :     return os << aabb.getMin() << " - " << aabb.getMax();
     113             : }
     114             : 
     115             : template< typename T > AABB< T >::AABB()
     116             :     : _min( std::numeric_limits< T >::max( ))
     117             :     , _max( std::numeric_limits< T >::min( ))
     118             : {}
     119             : 
     120           1 : template<> inline AABB< float >::AABB()
     121           1 :     : _min( std::numeric_limits< float >::max( ))
     122           1 :     , _max( -std::numeric_limits< float >::max( ))
     123           1 : {}
     124             : 
     125             : template<> inline AABB< double >::AABB()
     126             :     : _min( std::numeric_limits< double >::max( ))
     127             :     , _max( -std::numeric_limits< double >::max( ))
     128             : {}
     129             : 
     130             : template< typename T >
     131           1 : AABB< T >::AABB( const vector< 3, T >& pMin,
     132             :                  const vector< 3, T >& pMax)
     133             :     : _min( pMin )
     134           1 :     , _max( pMax )
     135           1 : {}
     136             : 
     137             : template< typename T >
     138             : AABB< T >::AABB( const vector< 4, T >& sphere )
     139             : {
     140             :     _max = _min = sphere.getCenter();
     141             :     _max += sphere.getRadius();
     142             :     _min -= sphere.getRadius();
     143             : }
     144             : 
     145             : template< typename T >
     146             : AABB< T >::AABB( T cx, T cy, T cz, T size )
     147             : {
     148             :     _max = _min = vector< 3, T >( cx, cy, cz );
     149             :     _max += size;
     150             :     _min -= size;
     151             : }
     152             : 
     153             : template< typename T >
     154             : inline bool AABB< T >::isIn( const vector< 4, T >& sphere )
     155             : {
     156             :     vector< 3, T > sv ( sphere.getCenter() );
     157             :     sv += sphere.getRadius();
     158             :     if ( sv.x() > _max.x() || sv.y() > _max.y() || sv.z() > _max.z() )
     159             :         return false;
     160             :     sv -= sphere.getRadius() * 2.0f;
     161             :     if ( sv.x() < _min.x() || sv.y() < _min.y() || sv.z() < _min.z() )
     162             :         return false;
     163             :     return true;
     164             : }
     165             : 
     166             : template< typename T >
     167             : inline bool AABB< T >::isIn( const vector< 3, T >& pos )
     168             : {
     169             :     if ( pos.x() > _max.x() || pos.y() > _max.y() || pos.z() > _max.z() ||
     170             :          pos.x() < _min.x() || pos.y() < _min.y() || pos.z() < _min.z( ))
     171             :     {
     172             :         return false;
     173             :     }
     174             :     return true;
     175             : }
     176             : 
     177             : template< typename T >
     178             : inline bool AABB< T >::isIn2d( const vector< 3, T >& pos )
     179             : {
     180             :     if ( pos.x() > _max.x() || pos.y() > _max.y() || pos.x() < _min.x() ||
     181             :          pos.y() < _min.y( ))
     182             :     {
     183             :         return false;
     184             :     }
     185             :     return true;
     186             : }
     187             : 
     188             : template< typename T >
     189             : inline void AABB< T >::set( const vector< 3, T >& pMin,
     190             :                             const vector< 3, T >& pMax )
     191             : {
     192             :     _min = pMin;
     193             :     _max = pMax;
     194             : }
     195             : 
     196             : template< typename T >
     197             : inline void AABB< T >::set( T cx, T cy, T cz, T size )
     198             : {
     199             :     vector< 3, T > center( cx, cy, cz );
     200             :     _min = center - size;
     201             :     _max = center + size;
     202             : }
     203             : 
     204             : template< typename T >
     205             : inline void AABB< T >::setMin( const vector< 3, T >& pMin )
     206             : {
     207             :     _min = pMin;
     208             : }
     209             : 
     210             : template< typename T >
     211             : inline void AABB< T >::setMax( const vector< 3, T >& pMax )
     212             : {
     213             :     _max = pMax;
     214             : }
     215             : 
     216             : template< typename T >
     217           2 : inline const vector< 3, T >& AABB< T >::getMin() const
     218             : {
     219           2 :     return _min;
     220             : }
     221             : 
     222             : template< typename T >
     223           2 : inline const vector< 3, T >& AABB< T >::getMax() const
     224             : {
     225           2 :     return _max;
     226             : }
     227             : 
     228           2 : template< typename T > inline vector< 3, T >& AABB< T >::getMin()
     229             : {
     230           2 :     return _min;
     231             : }
     232             : 
     233           2 : template< typename T > inline vector< 3, T >& AABB< T >::getMax()
     234             : {
     235           2 :     return _max;
     236             : }
     237             : 
     238             : template< typename T > AABB< T >
     239             : AABB< T >::operator*( const T value ) const
     240             : {
     241             :     AABB result = *this;
     242             :     result *= value;
     243             :     return result;
     244             : }
     245             : 
     246             : template< typename T > AABB< T >
     247             : AABB< T >::operator/( const T value ) const
     248             : {
     249             :     AABB result = *this;
     250             :     result /= value;
     251             :     return result;
     252             : }
     253             : 
     254             : template< typename T > AABB< T >
     255             : AABB< T >::operator+( const T value ) const
     256             : {
     257             :     AABB result = *this;
     258             :     result += value;
     259             :     return result;
     260             : }
     261             : 
     262             : template< typename T > AABB< T >
     263             : AABB< T >::operator-( const T value ) const
     264             : {
     265             :     AABB result = *this;
     266             :     result -= value;
     267             :     return result;
     268             : }
     269             : 
     270             : template< typename T >
     271             : void AABB< T >::operator*=( const T value )
     272             : {
     273             :     _min *= value;
     274             :     _max *= value;
     275             : }
     276             : 
     277             : template< typename T >
     278             : void AABB< T >::operator/=( const T value )
     279             : {
     280             :     _min /= value;
     281             :     _max /= value;
     282             : }
     283             : 
     284             : template< typename T >
     285             : void AABB< T >::operator+=( const T value )
     286             : {
     287             :     _min += value;
     288             :     _max += value;
     289             : }
     290             : 
     291             : template< typename T >
     292             : void AABB< T >::operator-=( const T value )
     293             : {
     294             :     _min -= value;
     295             :     _max -= value;
     296             : }
     297             : 
     298             : template< typename T > template< class U > bool
     299           1 : AABB< T >::operator==( const AABB< U >& other )
     300             :     const
     301             : {
     302           1 :     return _min == other._min && _max == other._max;
     303             : }
     304             : 
     305             : template< typename T > template< class U > bool
     306             : AABB< T >::operator!=( const AABB< U >& other )
     307             :     const
     308             : {
     309             :     return _min != other._min || _max != other._max;
     310             : }
     311             : 
     312             : template< typename T >
     313             : vector< 3, T > AABB< T >::getCenter() const
     314             : {
     315             :     return _min + ( ( _max - _min ) * 0.5f );
     316             : }
     317             : 
     318             : template< typename T >
     319           2 : vector< 3, T > AABB< T >::getDimension() const
     320             : {
     321           2 :     return _max - _min;
     322             : }
     323             : 
     324             : template< typename T >
     325           1 : void AABB< T >::merge( const AABB<T>& aabb )
     326             : {
     327           1 :     const vector< 3, T >& min = aabb.getMin();
     328           1 :     const vector< 3, T >& max = aabb.getMax();
     329             : 
     330           1 :     if ( min.x() < _min.x() )
     331           1 :         _min.x() = min.x();
     332           1 :     if ( min.y() < _min.y() )
     333           1 :         _min.y() = min.y();
     334           1 :     if ( min.z() < _min.z() )
     335           1 :         _min.z() = min.z();
     336             : 
     337           1 :     if ( max.x() > _max.x() )
     338           0 :         _max.x() = max.x();
     339           1 :     if ( max.y() > _max.y() )
     340           0 :         _max.y() = max.y();
     341           1 :     if ( max.z() > _max.z() )
     342           0 :         _max.z() = max.z();
     343           1 : }
     344             : 
     345             : template< typename T >
     346           2 : void AABB< T >::merge( const vector< 3, T >& point )
     347             : {
     348           2 :     if ( point.x() < _min.x() )
     349           1 :         _min.x() = point.x();
     350           2 :     if ( point.y() < _min.y() )
     351           1 :         _min.y() = point.y();
     352           2 :     if ( point.z() < _min.z() )
     353           1 :         _min.z() = point.z();
     354             : 
     355           2 :     if ( point.x() > _max.x() )
     356           2 :         _max.x() = point.x();
     357           2 :     if ( point.y() > _max.y() )
     358           2 :         _max.y() = point.y();
     359           2 :     if ( point.z() > _max.z() )
     360           2 :         _max.z() = point.z();
     361           2 : }
     362             : 
     363             : template< typename T >inline
     364             : void AABB< T >::setEmpty()
     365             : {
     366             :     _min = std::numeric_limits< T >::max();
     367             :     _max = -std::numeric_limits< T >::max();
     368             : }
     369             : 
     370             : 
     371           4 : template< typename T > inline bool AABB< T >::isEmpty() const
     372             : {
     373          12 :     return ( _min.x() >=  _max.x() || _min.y() >=  _max.y() ||
     374          12 :              _min.z() >=  _max.x( ));
     375             : }
     376             : 
     377             : template< typename T >
     378             : AABB< T > AABB< T >::makeUnitBox()
     379             : {
     380             :     return AABB( vector< 3, T >::ZERO, vector< 3, T >::ONE );
     381             : }
     382             : 
     383             : }; //namespace vmml
     384             : 
     385             : #endif

Generated by: LCOV version 1.11