From 2a54ff3e4a22dc00e7c95f59d37f296f91ecfae1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 3 Apr 2008 18:36:50 +0000 Subject: [PATCH] Introduced CMake build option for compiling double or float versions of osg::BoundingSphere and osg::BoundingBox. Introduced code in BoundgingSphere, BoundingBox, ProxyNode and LOD to utilise the above settings. Added Matrix::value_type, Plane::value_type, BoundingSphere::value_type and BoundingBox::value_type command line options that report where the types of floats or doubles. --- CMakeLists.txt | 15 +++- applications/osgversion/osgversion.cpp | 36 ++++++++- include/osg/BoundingBox | 76 +++++++++++-------- include/osg/BoundingSphere | 59 +++++++++----- include/osg/LOD | 15 ++-- include/osg/ProxyNode | 13 ++-- include/osg/Vec4d | 25 ++++++ src/osg/BoundingSphere.cpp | 57 +++++++++++--- src/osgGA/NodeTrackerManipulator.cpp | 2 +- src/osgGA/TerrainManipulator.cpp | 2 +- src/osgPlugins/Inventor/ConvertToInventor.cpp | 3 +- 11 files changed, 225 insertions(+), 78 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0cb20baa..7bd1527e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,18 +177,29 @@ ENDIF(WIN32) #luigi#ENDIF(UNIX) ######################################################################################################## -OPTION(OSG_USE_FLOAT_MATRIX "Set to ON to build OpenSceneGraph with float matrix instead of double." OFF) +OPTION(OSG_USE_FLOAT_MATRIX "Set to ON to build OpenSceneGraph with float Matrix instead of double." OFF) MARK_AS_ADVANCED(OSG_USE_FLOAT_MATRIX) IF(OSG_USE_FLOAT_MATRIX) ADD_DEFINITIONS(-DOSG_USE_FLOAT_MATRIX) ENDIF(OSG_USE_FLOAT_MATRIX) -OPTION(OSG_USE_FLOAT_PLANE "Set to ON to build OpenSceneGraph with float matrix instead of double." OFF) +OPTION(OSG_USE_FLOAT_PLANE "Set to ON to build OpenSceneGraph with float Plane instead of double." OFF) MARK_AS_ADVANCED(OSG_USE_FLOAT_PLANE) IF(OSG_USE_FLOAT_PLANE) ADD_DEFINITIONS(-DOSG_USE_FLOAT_PLANE) ENDIF(OSG_USE_FLOAT_PLANE) +OPTION(OSG_USE_FLOAT_BOUNDINGSPHERE "Set to ON to build OpenSceneGraph with float BoundingSphere instead of double." ON) +MARK_AS_ADVANCED(OSG_USE_FLOAT_BOUNDINGSPHERE) +IF(NOT OSG_USE_FLOAT_BOUNDINGSPHERE) + ADD_DEFINITIONS(-DOSG_USE_DOUBLE_BOUNDINGSPHERE) +ENDIF(NOT OSG_USE_FLOAT_BOUNDINGSPHERE) + +OPTION(OSG_USE_FLOAT_BOUNDINGBOX "Set to ON to build OpenSceneGraph with float BoundingBox instead of double." ON) +MARK_AS_ADVANCED(OSG_USE_FLOAT_BOUNDINGBOX) +IF(NOT OSG_USE_FLOAT_BOUNDINGBOX) + ADD_DEFINITIONS(-DOSG_USE_DOUBLE_BOUNDINGBOX) +ENDIF(NOT OSG_USE_FLOAT_BOUNDINGBOX) ################################################################################ # 3rd Party Dependency Stuff diff --git a/applications/osgversion/osgversion.cpp b/applications/osgversion/osgversion.cpp index 9bd16df5f..d0f833f5e 100644 --- a/applications/osgversion/osgversion.cpp +++ b/applications/osgversion/osgversion.cpp @@ -1,6 +1,13 @@ #include #include #include + +#include +#include +#include +#include + + #include #include @@ -719,6 +726,10 @@ int main( int argc, char **argv) arguments.getApplicationUsage()->addCommandLineOption("--so-number ","Print out shared object version number only"); arguments.getApplicationUsage()->addCommandLineOption("--openthreads-version-number","Print out version number for OpenThreads only"); arguments.getApplicationUsage()->addCommandLineOption("--openthreads-soversion-number","Print out shared object version number for OpenThreads only"); + arguments.getApplicationUsage()->addCommandLineOption("Matrix::value_type","Print the value of Matrix::value_type"); + arguments.getApplicationUsage()->addCommandLineOption("Plane::value_type","Print the value of Plane::value_type"); + arguments.getApplicationUsage()->addCommandLineOption("BoundingSphere::value_type","Print the value of BoundingSphere::value_type"); + arguments.getApplicationUsage()->addCommandLineOption("BoundingBox::value_type","Print the value of BoundingBox::value_type"); arguments.getApplicationUsage()->addCommandLineOption("-r or --read ","Read the ChangeLog to generate an estimated contributors list."); if (arguments.read("--version-number")) @@ -776,13 +787,36 @@ int main( int argc, char **argv) std::cout< #include +#include #include namespace osg { @@ -30,23 +31,32 @@ class OSG_EXPORT BoundingBox { public: +#ifdef OSG_USE_DOUBLE_BOUNDINGBOX + typedef Vec3d vec_type; + typedef doulbe value_type; +#else + typedef Vec3f vec_type; + typedef float value_type; +#endif + + /** Minimum extent. (Smallest X, Y, and Z values of all coordinates.) */ - Vec3 _min; + vec_type _min; /** Maximum extent. (Greatest X, Y, and Z values of all coordinates.) */ - Vec3 _max; + vec_type _max; /** Creates an uninitialized bounding box. */ inline BoundingBox() : _min(FLT_MAX,FLT_MAX,FLT_MAX), _max(-FLT_MAX,-FLT_MAX,-FLT_MAX) {} /** Creates a bounding box initialized to the given extents. */ - inline BoundingBox(float xmin,float ymin,float zmin, - float xmax,float ymax,float zmax) : - _min(xmin,ymin,zmin), - _max(xmax,ymax,zmax) {} + inline BoundingBox(value_type xmin, value_type ymin, value_type zmin, + value_type xmax, value_type ymax, value_type zmax) : + _min(xmin,ymin,zmin), + _max(xmax,ymax,zmax) {} /** Creates a bounding box initialized to the given extents. */ - inline BoundingBox(const Vec3& min,const Vec3& max) : + inline BoundingBox(const vec_type& min,const vec_type& max) : _min(min), _max(max) {} @@ -64,56 +74,56 @@ class OSG_EXPORT BoundingBox } /** Sets the bounding box extents. */ - inline void set (float xmin,float ymin,float zmin, - float xmax,float ymax,float zmax) + inline void set (value_type xmin, value_type ymin, value_type zmin, + value_type xmax, value_type ymax, value_type zmax) { _min.set(xmin,ymin,zmin); _max.set(xmax,ymax,zmax); } /** Sets the bounding box extents. */ - inline void set(const Vec3& min,const Vec3& max) + inline void set(const vec_type& min,const vec_type& max) { _min = min; _max = max; } - inline float& xMin() { return _min.x(); } - inline float xMin() const { return _min.x(); } + inline value_type& xMin() { return _min.x(); } + inline value_type xMin() const { return _min.x(); } - inline float& yMin() { return _min.y(); } - inline float yMin() const { return _min.y(); } + inline value_type& yMin() { return _min.y(); } + inline value_type yMin() const { return _min.y(); } - inline float& zMin() { return _min.z(); } - inline float zMin() const { return _min.z(); } + inline value_type& zMin() { return _min.z(); } + inline value_type zMin() const { return _min.z(); } - inline float& xMax() { return _max.x(); } - inline float xMax() const { return _max.x(); } + inline value_type& xMax() { return _max.x(); } + inline value_type xMax() const { return _max.x(); } - inline float& yMax() { return _max.y(); } - inline float yMax() const { return _max.y(); } + inline value_type& yMax() { return _max.y(); } + inline value_type yMax() const { return _max.y(); } - inline float& zMax() { return _max.z(); } - inline float zMax() const { return _max.z(); } + inline value_type& zMax() { return _max.z(); } + inline value_type zMax() const { return _max.z(); } /** Calculates and returns the bounding box center. */ - inline const Vec3 center() const + inline const vec_type center() const { - return (_min+_max)*0.5f; + return (_min+_max)*0.5; } /** Calculates and returns the bounding box radius. */ - inline float radius() const + inline value_type radius() const { - return sqrtf(radius2()); + return sqrt(radius2()); } /** Calculates and returns the squared length of the bounding box radius. * Note, radius2() is faster to calculate than radius(). */ - inline float radius2() const + inline value_type radius2() const { - return 0.25f*((_max-_min).length2()); + return 0.25*((_max-_min).length2()); } /** Returns a specific corner of the bounding box. @@ -121,14 +131,14 @@ class OSG_EXPORT BoundingBox * Each bit selects an axis, X, Y, or Z from least- to * most-significant. Unset bits select the minimum value * for that axis, and set bits select the maximum. */ - inline const Vec3 corner(unsigned int pos) const + inline const vec_type corner(unsigned int pos) const { - return Vec3(pos&1?_max.x():_min.x(),pos&2?_max.y():_min.y(),pos&4?_max.z():_min.z()); + return vec_type(pos&1?_max.x():_min.x(),pos&2?_max.y():_min.y(),pos&4?_max.z():_min.z()); } /** Expands the bounding box to include the given coordinate. * If the box is uninitialized, set its min and max extents to v. */ - inline void expandBy(const Vec3& v) + inline void expandBy(const vec_type& v) { if(v.x()<_min.x()) _min.x() = v.x(); if(v.x()>_max.x()) _max.x() = v.x(); @@ -143,7 +153,7 @@ class OSG_EXPORT BoundingBox /** Expands the bounding box to include the given coordinate. * If the box is uninitialized, set its min and max extents to * Vec3(x,y,z). */ - inline void expandBy(float x,float y,float z) + inline void expandBy(value_type x,value_type y,value_type z) { if(x<_min.x()) _min.x() = x; if(x>_max.x()) _max.x() = x; @@ -180,7 +190,7 @@ class OSG_EXPORT BoundingBox } /** Returns true if this bounding box contains the specified coordinate. */ - inline bool contains(const Vec3& v) const + inline bool contains(const vec_type& v) const { return valid() && (v.x()>=_min.x() && v.x()<=_max.x()) && diff --git a/include/osg/BoundingSphere b/include/osg/BoundingSphere index ce31fecf7..b2d5723aa 100644 --- a/include/osg/BoundingSphere +++ b/include/osg/BoundingSphere @@ -15,7 +15,8 @@ #define OSG_BOUNDINGSPHERE 1 #include -#include +#include +#include namespace osg { @@ -30,64 +31,83 @@ class BoundingBox; class OSG_EXPORT BoundingSphere { public: + +#ifdef OSG_USE_DOUBLE_BOUNDINGSPHERE + typedef Vec3d vec_type; + typedef double value_type; +#else + typedef Vec3f vec_type; + typedef float value_type; +#endif - Vec3 _center; - float _radius; + vec_type _center; + value_type _radius; /** Construct a default bounding sphere with radius to -1.0f, representing an invalid/unset bounding sphere.*/ - BoundingSphere() : _center(0.0f,0.0f,0.0f),_radius(-1.0f) {} + BoundingSphere() : _center(0.0,0.0,0.0),_radius(-1.0) {} /** Creates a bounding sphere initialized to the given extents. */ - BoundingSphere(const Vec3& center,float radius) : _center(center),_radius(radius) {} + BoundingSphere(const vec_type& center,value_type radius) : _center(center),_radius(radius) {} /** Creates a bounding sphere initialized to the given extents. */ BoundingSphere(const BoundingSphere& bs) : _center(bs._center),_radius(bs._radius) {} /** Creates a bounding sphere initialized to the given extents. */ - BoundingSphere(const BoundingBox& bb) : _center(0.0f,0.0f,0.0f),_radius(-1.0f) { expandBy(bb); } + BoundingSphere(const BoundingBox& bb) : _center(0.0,0.0,0.0),_radius(-1.0) { expandBy(bb); } /** Clear the bounding sphere. Reset to default values. */ inline void init() { - _center.set(0.0f,0.0f,0.0f); - _radius = -1.0f; + _center.set(0.0,0.0,0.0); + _radius = -1.0; } /** Returns true of the bounding sphere extents are valid, false * otherwise. */ - inline bool valid() const { return _radius>=0.0f; } + inline bool valid() const { return _radius>=0.0; } - /** Set the bounding sphere to the given center/radius. */ - inline void set(const Vec3& center,float radius) + /** Set the bounding sphere to the given center/radius using floats. */ + inline void set(const vec_type& center,value_type radius) { _center = center; _radius = radius; } /** Returns the center of the bounding sphere. */ - inline Vec3& center() { return _center; } + inline vec_type& center() { return _center; } + /** Returns the const center of the bounding sphere. */ - inline const Vec3& center() const { return _center; } + inline const vec_type& center() const { return _center; } /** Returns the radius of the bounding sphere. */ - inline float& radius() { return _radius; } + inline value_type& radius() { return _radius; } /** Returns the const radius of the bounding sphere. */ - inline float radius() const { return _radius; } + inline value_type radius() const { return _radius; } /** Returns the squared length of the radius. Note, For performance * reasons, the calling method is responsible for checking to make * sure the sphere is valid. */ - inline float radius2() const { return _radius*_radius; } + inline value_type radius2() const { return _radius*_radius; } /** Expands the sphere to encompass the given point. Repositions the * sphere center to minimize the radius increase. If the sphere is * uninitialized, set its center to v and radius to zero. */ - void expandBy(const Vec3& v); + void expandBy(const Vec3f& v); /** Expands the sphere to encompass the given point. Does not * reposition the sphere center. If the sphere is * uninitialized, set its center to v and radius to zero. */ - void expandRadiusBy(const Vec3& v); + void expandRadiusBy(const Vec3f& v); + + /** Expands the sphere to encompass the given point. Repositions the + * sphere center to minimize the radius increase. If the sphere is + * uninitialized, set its center to v and radius to zero. */ + void expandBy(const Vec3d& v); + + /** Expands the sphere to encompass the given point. Does not + * reposition the sphere center. If the sphere is + * uninitialized, set its center to v and radius to zero. */ + void expandRadiusBy(const Vec3d& v); /** Expands the sphere to encompass the given sphere. Repositions the * sphere center to minimize the radius increase. If the sphere is @@ -108,11 +128,12 @@ class OSG_EXPORT BoundingSphere void expandRadiusBy(const BoundingBox& bb); /** Returns true if v is within the sphere. */ - inline bool contains(const Vec3& v) const + inline bool contains(const vec_type& v) const { return valid() && ((v-_center).length2()<=radius2()); } + /** Returns true if there is a non-empty intersection with the given * bounding sphere. */ inline bool intersects( const BoundingSphere& bs ) const diff --git a/include/osg/LOD b/include/osg/LOD index 6f652b329..732de9819 100644 --- a/include/osg/LOD +++ b/include/osg/LOD @@ -43,6 +43,9 @@ class OSG_EXPORT LOD : public Group META_Node(osg, LOD); + typedef osg::BoundingSphere::vec_type vec_type; + typedef osg::BoundingSphere::value_type value_type; + virtual void traverse(NodeVisitor& nv); virtual bool addChild(Node *child); @@ -69,18 +72,18 @@ class OSG_EXPORT LOD : public Group /** Sets the object-space point which defines the center of the osg::LOD. center is affected by any transforms in the hierarchy above the osg::LOD.*/ - inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } + inline void setCenter(const vec_type& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } /** return the LOD center point. */ - inline const Vec3& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } + inline const vec_type& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } /** Set the object-space reference radius of the volume enclosed by the LOD. * Used to determine the bounding sphere of the LOD in the absence of any children.*/ - inline void setRadius(float radius) { _radius = radius; } + inline void setRadius(value_type radius) { _radius = radius; } /** Get the object-space radius of the volume enclosed by the LOD.*/ - inline float getRadius() const { return _radius; } + inline value_type getRadius() const { return _radius; } @@ -124,8 +127,8 @@ class OSG_EXPORT LOD : public Group virtual ~LOD() {} CenterMode _centerMode; - Vec3 _userDefinedCenter; - float _radius; + vec_type _userDefinedCenter; + value_type _radius; RangeMode _rangeMode; RangeList _rangeList; diff --git a/include/osg/ProxyNode b/include/osg/ProxyNode index 920f3e57d..9db9fb095 100644 --- a/include/osg/ProxyNode +++ b/include/osg/ProxyNode @@ -31,6 +31,9 @@ class OSG_EXPORT ProxyNode : public Group META_Node(osg, ProxyNode); + typedef osg::BoundingSphere::vec_type vec_type; + typedef osg::BoundingSphere::value_type value_type; + virtual void traverse(NodeVisitor& nv); virtual bool addChild(Node *child); @@ -81,15 +84,15 @@ class OSG_EXPORT ProxyNode : public Group inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } /** return the ProxyNode center point. */ - inline const Vec3& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } + inline const vec_type& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } /** Set the object-space reference radius of the volume enclosed by the ProxyNode. * Used to determine the bounding sphere of the ProxyNode in the absence of any children.*/ - inline void setRadius(float radius) { _radius = radius; } + inline void setRadius(value_type radius) { _radius = radius; } /** Get the object-space radius of the volume enclosed by the ProxyNode.*/ - inline float getRadius() const { return _radius; } + inline value_type getRadius() const { return _radius; } virtual BoundingSphere computeBound() const; @@ -105,8 +108,8 @@ class OSG_EXPORT ProxyNode : public Group LoadingExternalReferenceMode _loadingExtReference; CenterMode _centerMode; - Vec3 _userDefinedCenter; - float _radius; + vec_type _userDefinedCenter; + value_type _radius; }; diff --git a/include/osg/Vec4d b/include/osg/Vec4d index a89cb6e87..9d18bfdfa 100644 --- a/include/osg/Vec4d +++ b/include/osg/Vec4d @@ -248,12 +248,37 @@ inline Vec4d::value_type operator * (const Vec3d& lhs,const Vec4d& rhs) return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+rhs[3]; } +/** Compute the dot product of a (Vec3,1.0) and a Vec4d. */ +inline Vec4d::value_type operator * (const Vec3f& lhs,const Vec4d& rhs) +{ + return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+rhs[3]; +} + +/** Compute the dot product of a (Vec3,1.0) and a Vec4d. */ +inline Vec4d::value_type operator * (const Vec3d& lhs,const Vec4f& rhs) +{ + return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+rhs[3]; +} + + /** Compute the dot product of a Vec4d and a (Vec3,1.0). */ inline Vec4d::value_type operator * (const Vec4d& lhs,const Vec3d& rhs) { return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+lhs[3]; } +/** Compute the dot product of a Vec4d and a (Vec3,1.0). */ +inline Vec4d::value_type operator * (const Vec4d& lhs,const Vec3f& rhs) +{ + return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+lhs[3]; +} + +/** Compute the dot product of a Vec4d and a (Vec3,1.0). */ +inline Vec4d::value_type operator * (const Vec4f& lhs,const Vec3d& rhs) +{ + return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+lhs[3]; +} + } // end of namespace osg #endif diff --git a/src/osg/BoundingSphere.cpp b/src/osg/BoundingSphere.cpp index 8ec8b8c87..e87001d5a 100644 --- a/src/osg/BoundingSphere.cpp +++ b/src/osg/BoundingSphere.cpp @@ -15,15 +15,15 @@ using namespace osg; -void BoundingSphere::expandBy(const Vec3& v) +void BoundingSphere::expandBy(const Vec3f& v) { if (valid()) { - Vec3 dv = v-_center; - float r = dv.length(); + vec_type dv = v-_center; + value_type r = dv.length(); if (r>_radius) { - float dr = (r-_radius)*0.5f; + value_type dr = (r-_radius)*0.5; _center += dv*(dr/r); _radius += dr; } // else do nothing as vertex is within sphere. @@ -31,27 +31,66 @@ void BoundingSphere::expandBy(const Vec3& v) else { _center = v; - _radius = 0.0f; + _radius = 0.0; } } -void BoundingSphere::expandRadiusBy(const Vec3& v) +void BoundingSphere::expandRadiusBy(const Vec3f& v) { if (valid()) { - float r = (v-_center).length(); + value_type r = (v-_center).length(); if (r>_radius) _radius = r; // else do nothing as vertex is within sphere. } else { _center = v; - _radius = 0.0f; + _radius = 0.0; } } + +void BoundingSphere::expandBy(const Vec3d& v) +{ + if (valid()) + { + vec_type dv = v-_center; + value_type r = dv.length(); + if (r>_radius) + { + value_type dr = (r-_radius)*0.5; + _center += dv*(dr/r); + _radius += dr; + } // else do nothing as vertex is within sphere. + } + else + { + _center = v; + _radius = 0.0; + } +} + + +void BoundingSphere::expandRadiusBy(const Vec3d& v) +{ + if (valid()) + { + value_type r = (v-_center).length(); + if (r>_radius) _radius = r; + // else do nothing as vertex is within sphere. + } + else + { + _center = v; + _radius = 0.0; + } +} + + + void BoundingSphere::expandBy(const BoundingSphere& sh) { @@ -107,7 +146,7 @@ void BoundingSphere::expandRadiusBy(const BoundingSphere& sh) { if (valid()) { - float r = (sh._center-_center).length()+sh._radius; + value_type r = (sh._center-_center).length()+sh._radius; if (r>_radius) _radius = r; // else do nothing as vertex is within sphere. } diff --git a/src/osgGA/NodeTrackerManipulator.cpp b/src/osgGA/NodeTrackerManipulator.cpp index 1fd927c0a..64a99727d 100644 --- a/src/osgGA/NodeTrackerManipulator.cpp +++ b/src/osgGA/NodeTrackerManipulator.cpp @@ -105,7 +105,7 @@ void NodeTrackerManipulator::setNode(osg::Node* node) const osg::BoundingSphere& boundingSphere=_node->getBound(); const float minimumDistanceScale = 0.001f; _minimumDistance = osg::clampBetween( - boundingSphere._radius * minimumDistanceScale, + float(boundingSphere._radius) * minimumDistanceScale, 0.00001f,1.0f); osg::notify(osg::INFO)<<"Setting Tracker manipulator _minimumDistance to "<<_minimumDistance<getBound(); const float minimumDistanceScale = 0.001f; _minimumDistance = osg::clampBetween( - boundingSphere._radius * minimumDistanceScale, + float(boundingSphere._radius) * minimumDistanceScale, 0.00001f,1.0f); osg::notify(osg::INFO)<<"Setting terrain manipulator _minimumDistance to "<<_minimumDistance<range.set1Value(i, node.getMaxRange(i)); // set center - lod->center.setValue(node.getCenter().ptr()); + osg::Vec3f center(node.getCenter()); + lod->center.setValue(center.ptr()); ivLOD = lod;