Changeset 9268

Show
Ignore:
Timestamp:
11/26/08 17:39:52 (3 years ago)
Author:
robert
Message:

From Tim Moore, "Double precision versions of BoundingBox? and BoundingSphere? are useful for doing computations in world coordinates, especially when working with a geocentric scene. By default, these classes are built using floats, so templated versions fill a need. I've used the double precision templates to fix some problems with ViewDependentShadow?, which will follow shortly.
"

Location:
OpenSceneGraph/trunk
Files:
2 removed
3 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/BoundingBox

    r8477 r9268  
    2323namespace osg { 
    2424 
    25 class BoundingSphere; 
     25template<typename VT> 
     26class BoundingSphereImpl; 
    2627 
    2728/** General purpose axis-aligned bounding box class for enclosing objects/vertices. 
     
    2930  * culling etc. 
    3031*/ 
    31 class OSG_EXPORT BoundingBox 
     32template<typename VT> 
     33class BoundingBoxImpl 
    3234{ 
    3335    public: 
    34      
    35 #ifdef OSG_USE_FLOAT_BOUNDINGBOX 
    36         typedef Vec3f vec_type; 
    37         typedef float value_type; 
    38 #else 
    39         typedef Vec3d vec_type; 
    40         typedef double value_type; 
    41 #endif 
    42  
     36        typedef VT vec_type; 
     37        typedef typename VT::value_type value_type; 
    4338     
    4439        /** Minimum extent. (Smallest X, Y, and Z values of all coordinates.) */ 
     
    4843 
    4944        /** Creates an uninitialized bounding box. */ 
    50         inline BoundingBox() : _min(FLT_MAX,FLT_MAX,FLT_MAX), 
    51                         _max(-FLT_MAX,-FLT_MAX,-FLT_MAX) {} 
     45        inline BoundingBoxImpl() : 
     46            _min(FLT_MAX, 
     47                 FLT_MAX, 
     48                 FLT_MAX), 
     49            _max(-FLT_MAX, 
     50                 -FLT_MAX, 
     51                 -FLT_MAX) 
     52        {} 
    5253     
    5354        /** Creates a bounding box initialized to the given extents. */ 
    54         inline BoundingBox(value_type xmin, value_type ymin, value_type zmin, 
     55        inline BoundingBoxImpl(value_type xmin, value_type ymin, value_type zmin, 
    5556                           value_type xmax, value_type ymax, value_type zmax) : 
    5657                           _min(xmin,ymin,zmin), 
     
    5859 
    5960        /** Creates a bounding box initialized to the given extents. */ 
    60         inline BoundingBox(const vec_type& min,const vec_type& max) :  
     61        inline BoundingBoxImpl(const vec_type& min,const vec_type& max) :  
    6162                    _min(min), 
    6263                    _max(max) {} 
     
    6566        inline void init() 
    6667        { 
    67             _min.set(FLT_MAX,FLT_MAX,FLT_MAX); 
    68             _max.set(-FLT_MAX,-FLT_MAX,-FLT_MAX); 
     68            _min.set(FLT_MAX, 
     69                     FLT_MAX, 
     70                     FLT_MAX); 
     71            _max.set(-FLT_MAX, 
     72                     -FLT_MAX, 
     73                     -FLT_MAX); 
    6974        } 
    7075         
     
    169174        /** Expands this bounding box to include the given bounding box. 
    170175          * If this box is uninitialized, set it equal to bb. */ 
    171         void expandBy(const BoundingBox& bb); 
     176        void expandBy(const BoundingBoxImpl& bb); 
    172177 
    173178        /** Expands this bounding box to include the given sphere. 
    174179          * If this box is uninitialized, set it to include sh. */ 
    175         void expandBy(const BoundingSphere& sh); 
     180        void expandBy(const BoundingSphereImpl<VT>& sh); 
    176181         
    177182 
    178183        /** Returns the intersection of this bounding box and the specified bounding box. */ 
    179         BoundingBox intersect(const BoundingBox& bb) const 
    180         {    return osg::BoundingBox(osg::maximum(xMin(),bb.xMin()),osg::maximum(yMin(),bb.yMin()),osg::maximum(zMin(),bb.zMin()), 
     184        BoundingBoxImpl intersect(const BoundingBoxImpl& bb) const 
     185        {    return BoundingBoxImpl(osg::maximum(xMin(),bb.xMin()),osg::maximum(yMin(),bb.yMin()),osg::maximum(zMin(),bb.zMin()), 
    181186                                     osg::minimum(xMax(),bb.xMax()),osg::minimum(yMax(),bb.yMax()),osg::minimum(zMax(),bb.zMax())); 
    182187 
     
    184189 
    185190        /** Return true if this bounding box intersects the specified bounding box. */ 
    186         bool intersects(const BoundingBox& bb) const 
     191        bool intersects(const BoundingBoxImpl& bb) const 
    187192        {    return osg::maximum(xMin(),bb.xMin()) <= osg::minimum(xMax(),bb.xMax()) && 
    188193                    osg::maximum(yMin(),bb.yMin()) <= osg::minimum(yMax(),bb.yMax()) && 
     
    201206}; 
    202207 
     208template<typename VT> 
     209void BoundingBoxImpl<VT>::expandBy(const BoundingBoxImpl<VT>& bb) 
     210{ 
     211    if (!bb.valid()) return; 
     212 
     213    if(bb._min.x()<_min.x()) _min.x() = bb._min.x(); 
     214    if(bb._max.x()>_max.x()) _max.x() = bb._max.x(); 
     215 
     216    if(bb._min.y()<_min.y()) _min.y() = bb._min.y(); 
     217    if(bb._max.y()>_max.y()) _max.y() = bb._max.y(); 
     218 
     219    if(bb._min.z()<_min.z()) _min.z() = bb._min.z(); 
     220    if(bb._max.z()>_max.z()) _max.z() = bb._max.z(); 
    203221} 
    204222 
     223template<typename VT> 
     224void BoundingBoxImpl<VT>::expandBy(const BoundingSphereImpl<VT>& sh) 
     225{ 
     226    if (!sh.valid()) return; 
     227 
     228    if(sh._center.x()-sh._radius<_min.x()) _min.x() = sh._center.x()-sh._radius; 
     229    if(sh._center.x()+sh._radius>_max.x()) _max.x() = sh._center.x()+sh._radius; 
     230 
     231    if(sh._center.y()-sh._radius<_min.y()) _min.y() = sh._center.y()-sh._radius; 
     232    if(sh._center.y()+sh._radius>_max.y()) _max.y() = sh._center.y()+sh._radius; 
     233 
     234    if(sh._center.z()-sh._radius<_min.z()) _min.z() = sh._center.z()-sh._radius; 
     235    if(sh._center.z()+sh._radius>_max.z()) _max.z() = sh._center.z()+sh._radius; 
     236} 
     237 
     238typedef BoundingBoxImpl<Vec3f> BoundingBoxf; 
     239typedef BoundingBoxImpl<Vec3d> BoundingBoxd; 
     240 
     241#ifdef OSG_USE_FLOAT_BOUNDINGBOX 
     242typedef BoundingBoxf BoundingBox; 
     243#else 
     244typedef BoundingBoxd BoundingBox; 
    205245#endif 
     246 
     247} 
     248 
     249#endif 
  • OpenSceneGraph/trunk/include/osg/BoundingSphere

    r8477 r9268  
    2222namespace osg { 
    2323 
    24 class BoundingBox; 
     24template<typename VT> 
     25class BoundingBoxImpl; 
    2526 
    2627/** General purpose bounding sphere class for enclosing nodes/objects/vertices. 
     
    3031  * greater volume. 
    3132*/ 
    32 class OSG_EXPORT BoundingSphere 
     33template<typename VT> 
     34class BoundingSphereImpl 
    3335{ 
    3436    public: 
    35  
    36 #ifdef OSG_USE_FLOAT_BOUNDINGSPHERE 
    37         typedef Vec3f vec_type; 
    38         typedef float value_type; 
    39 #else 
    40         typedef Vec3d vec_type; 
    41         typedef double value_type; 
    42 #endif 
    43          
     37        typedef VT vec_type; 
     38        typedef typename vec_type::value_type value_type;         
     39 
    4440        vec_type    _center; 
    4541        value_type  _radius; 
    4642 
    4743        /** Construct a default bounding sphere with radius to -1.0f, representing an invalid/unset bounding sphere.*/  
    48         BoundingSphere() : _center(0.0,0.0,0.0),_radius(-1.0) {} 
     44        BoundingSphereImpl() : _center(0.0,0.0,0.0),_radius(-1.0) {} 
    4945     
    5046        /** Creates a bounding sphere initialized to the given extents. */ 
    51         BoundingSphere(const vec_type& center,value_type radius) : _center(center),_radius(radius) {} 
     47        BoundingSphereImpl(const vec_type& center,value_type radius) : _center(center),_radius(radius) {} 
    5248 
    5349        /** Creates a bounding sphere initialized to the given extents. */ 
    54         BoundingSphere(const BoundingSphere& bs) : _center(bs._center),_radius(bs._radius) {} 
     50        BoundingSphereImpl(const BoundingSphereImpl& bs) : _center(bs._center),_radius(bs._radius) {} 
    5551 
    5652        /** Creates a bounding sphere initialized to the given extents. */ 
    57         BoundingSphere(const BoundingBox& bb) : _center(0.0,0.0,0.0),_radius(-1.0) { expandBy(bb); } 
     53        BoundingSphereImpl(const BoundingBoxImpl<VT>& bb) : _center(0.0,0.0,0.0),_radius(-1.0) { expandBy(bb); } 
    5854 
    5955        /** Clear the bounding sphere. Reset to default values. */ 
     
    9490          * sphere center to minimize the radius increase. If the sphere is 
    9591          * uninitialized, set its center to v and radius to zero. */ 
    96         void expandBy(const Vec3f& v); 
     92        template<typename vector_type> 
     93        void expandBy(const vector_type& v); 
    9794 
    9895        /** Expands the sphere to encompass the given point. Does not 
    9996          * reposition the sphere center. If the sphere is 
    10097          * uninitialized, set its center to v and radius to zero. */ 
    101         void expandRadiusBy(const Vec3f& v); 
    102  
    103         /** Expands the sphere to encompass the given point. Repositions the 
    104           * sphere center to minimize the radius increase. If the sphere is 
    105           * uninitialized, set its center to v and radius to zero. */ 
    106         void expandBy(const Vec3d& v); 
    107  
    108         /** Expands the sphere to encompass the given point. Does not 
    109           * reposition the sphere center. If the sphere is 
    110           * uninitialized, set its center to v and radius to zero. */ 
    111         void expandRadiusBy(const Vec3d& v); 
     98        template<typename vector_type> 
     99        void expandRadiusBy(const vector_type& v); 
    112100 
    113101        /** Expands the sphere to encompass the given sphere. Repositions the 
    114102          * sphere center to minimize the radius increase. If the sphere is 
    115103          * uninitialized, set its center and radius to match sh. */ 
    116         void expandBy(const BoundingSphere& sh); 
     104        void expandBy(const BoundingSphereImpl& sh); 
    117105 
    118106        /** Expands the sphere to encompass the given sphere. Does not 
    119107          * repositions the sphere center. If the sphere is 
    120108          * uninitialized, set its center and radius to match sh. */ 
    121         void expandRadiusBy(const BoundingSphere& sh); 
     109        void expandRadiusBy(const BoundingSphereImpl& sh); 
    122110 
    123111        /** Expands the sphere to encompass the given box. Repositions the 
    124112          * sphere center to minimize the radius increase. */ 
    125         void expandBy(const BoundingBox& bb); 
     113        void expandBy(const BoundingBoxImpl<VT>& bb); 
    126114 
    127115        /** Expands the sphere to encompass the given box. Does not 
    128116          * repositions the sphere center. */ 
    129         void expandRadiusBy(const BoundingBox& bb); 
     117        void expandRadiusBy(const BoundingBoxImpl<VT>& bb); 
    130118 
    131119        /** Returns true if v is within the sphere. */ 
     
    138126        /** Returns true if there is a non-empty intersection with the given 
    139127          * bounding sphere. */ 
    140         inline bool intersects( const BoundingSphere& bs ) const 
     128        inline bool intersects( const BoundingSphereImpl& bs ) const 
    141129        { 
    142130            return valid() && bs.valid() && 
    143131                   ((_center - bs._center).length2() <= (_radius + bs._radius)*(_radius + bs._radius)); 
    144132        } 
    145  
     133         
    146134}; 
    147135 
    148 } 
    149  
     136 
     137template<typename VT> 
     138 template<typename vector_type> 
     139void BoundingSphereImpl<VT>::expandBy(const vector_type& v) 
     140{ 
     141    if (valid()) 
     142    { 
     143        vec_type dv = v-_center; 
     144        value_type r = dv.length(); 
     145        if (r>_radius) 
     146        { 
     147            value_type dr = (r-_radius)*0.5; 
     148            _center += dv*(dr/r); 
     149            _radius += dr; 
     150        } // else do nothing as vertex is within sphere. 
     151    } 
     152    else 
     153    { 
     154        _center = v; 
     155        _radius = 0.0; 
     156    } 
     157} 
     158 
     159template<typename VT> 
     160 template<typename vector_type> 
     161void BoundingSphereImpl<VT>::expandRadiusBy(const vector_type& v) 
     162{ 
     163    if (valid()) 
     164    { 
     165        value_type r = (v-_center).length(); 
     166        if (r>_radius) _radius = r; 
     167        // else do nothing as vertex is within sphere. 
     168    } 
     169    else 
     170    { 
     171        _center = v; 
     172        _radius = 0.0; 
     173    } 
     174} 
     175 
     176template<typename VT> 
     177void BoundingSphereImpl<VT>::expandBy(const BoundingSphereImpl& sh) 
     178{ 
     179    // ignore operation if incomming BoundingSphere is invalid. 
     180    if (!sh.valid()) return; 
     181 
     182    // This sphere is not set so use the inbound sphere 
     183    if (!valid()) 
     184    { 
     185        _center = sh._center; 
     186        _radius = sh._radius; 
     187 
     188        return; 
     189    } 
     190     
     191     
     192    // Calculate d == The distance between the sphere centers    
     193    double d = ( _center - sh.center() ).length(); 
     194 
     195    // New sphere is already inside this one 
     196    if ( d + sh.radius() <= _radius )   
     197    { 
     198        return; 
     199    } 
     200 
     201    //  New sphere completely contains this one  
     202    if ( d + _radius <= sh.radius() )   
     203    { 
     204        _center = sh._center; 
     205        _radius = sh._radius; 
     206        return; 
     207    } 
     208 
     209     
     210    // Build a new sphere that completely contains the other two: 
     211    // 
     212    // The center point lies halfway along the line between the furthest 
     213    // points on the edges of the two spheres. 
     214    // 
     215    // Computing those two points is ugly - so we'll use similar triangles 
     216    double new_radius = (_radius + d + sh.radius() ) * 0.5; 
     217    double ratio = ( new_radius - _radius ) / d ; 
     218 
     219    _center[0] += ( sh.center()[0] - _center[0] ) * ratio; 
     220    _center[1] += ( sh.center()[1] - _center[1] ) * ratio; 
     221    _center[2] += ( sh.center()[2] - _center[2] ) * ratio; 
     222 
     223    _radius = new_radius; 
     224 
     225} 
     226 
     227template<typename VT> 
     228void BoundingSphereImpl<VT>::expandRadiusBy(const BoundingSphereImpl& sh) 
     229{ 
     230    if (sh.valid()) 
     231    { 
     232        if (valid()) 
     233        { 
     234            value_type r = (sh._center-_center).length()+sh._radius; 
     235            if (r>_radius) _radius = r; 
     236            // else do nothing as vertex is within sphere. 
     237        } 
     238        else 
     239        { 
     240            _center = sh._center; 
     241            _radius = sh._radius; 
     242        } 
     243    } 
     244} 
     245 
     246template<typename VT>         
     247void BoundingSphereImpl<VT>::expandBy(const BoundingBoxImpl<VT>& bb) 
     248{ 
     249    if (bb.valid()) 
     250    { 
     251        if (valid()) 
     252        { 
     253            BoundingBoxImpl<vec_type> newbb(bb); 
     254 
     255            for(unsigned int c=0;c<8;++c) 
     256            { 
     257                vec_type v = bb.corner(c)-_center; // get the direction vector from corner 
     258                v.normalize(); // normalise it. 
     259                v *= -_radius; // move the vector in the opposite direction distance radius. 
     260                v += _center; // move to absolute position. 
     261                newbb.expandBy(v); // add it into the new bounding box. 
     262            } 
     263             
     264            _center = newbb.center(); 
     265            _radius = newbb.radius(); 
     266             
     267        } 
     268        else 
     269        { 
     270            _center = bb.center(); 
     271            _radius = bb.radius(); 
     272        } 
     273    } 
     274} 
     275 
     276template<typename VT> 
     277void BoundingSphereImpl<VT>::expandRadiusBy(const BoundingBoxImpl<VT>& bb) 
     278{ 
     279    if (bb.valid()) 
     280    { 
     281        if (valid()) 
     282        { 
     283            for(unsigned int c=0;c<8;++c) 
     284            { 
     285                expandRadiusBy(bb.corner(c)); 
     286            } 
     287        } 
     288        else 
     289        { 
     290            _center = bb.center(); 
     291            _radius = bb.radius(); 
     292        } 
     293    } 
     294} 
     295 
     296typedef BoundingSphereImpl<Vec3f> BoundingSpheref; 
     297typedef BoundingSphereImpl<Vec3d> BoundingSphered; 
     298 
     299#ifdef OSG_USE_FLOAT_BOUNDINGSPHERE 
     300        typedef BoundingSpheref BoundingSphere; 
     301#else 
     302        typedef BoundingSphered BoundingSphere;         
    150303#endif 
     304} 
     305 
     306#endif 
  • OpenSceneGraph/trunk/src/osg/CMakeLists.txt

    r9218 r9268  
    198198    BlendEquation.cpp 
    199199    BlendFunc.cpp 
    200     BoundingBox.cpp 
    201     BoundingSphere.cpp 
    202200    BufferObject.cpp 
    203201    Camera.cpp