From 5e6153b4285b2cb53ab3a6bbaaa453d1ad3f830d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 6 Nov 2001 10:34:51 +0000 Subject: [PATCH] Added methods to support isNaN,isInfinte and valid to osg::Vec* and osg::Math, and added a guard to IntersectVisitor which uses these new methods to prevent invalid segments being added. --- include/osg/BoundingBox | 34 +++++++++++++++++++++++++++++++- include/osg/BoundingSphere | 9 +++++++++ include/osg/LineSegment | 2 ++ include/osg/Math | 19 ++++++++++++++++++ include/osg/Vec2 | 4 ++++ include/osg/Vec3 | 13 +++++++++--- include/osg/Vec4 | 4 ++++ src/osgUtil/IntersectVisitor.cpp | 8 ++++++++ 8 files changed, 89 insertions(+), 4 deletions(-) diff --git a/include/osg/BoundingBox b/include/osg/BoundingBox index ad8ffd274..b8bcfd637 100644 --- a/include/osg/BoundingBox +++ b/include/osg/BoundingBox @@ -29,9 +29,20 @@ class SG_EXPORT BoundingBox Vec3 _max; /** construct to invalid values to represent an unset bounding box.*/ - BoundingBox() : _min(FLT_MAX,FLT_MAX,FLT_MAX), + inline BoundingBox() : _min(FLT_MAX,FLT_MAX,FLT_MAX), _max(-FLT_MAX,-FLT_MAX,-FLT_MAX) {} + /** construct to with specified min and max values.*/ + inline BoundingBox(float xmin,float ymin,float zmin, + float xmax,float ymax,float zmax) : + _min(xmin,ymin,zmin), + _max(xmax,ymax,zmax) {} + + /** construct to with specified min and max values.*/ + inline BoundingBox(const Vec3& min,const Vec3& max) : + _min(min), + _max(max) {} + /** initialize to invalid values to represent an unset bounding box.*/ inline void init() { @@ -46,6 +57,21 @@ class SG_EXPORT BoundingBox return _max.x()>=_min.x(); } + inline void set (float xmin,float ymin,float zmin, + float xmax,float ymax,float zmax) + { + _min.set(xmin,ymin,zmin); + _max.set(xmax,ymax,zmax); + } + + /** construct to with specified min and max values.*/ + inline void set(const Vec3& min,const Vec3& max) + { + _min = min; + _max = max; + } + + inline float& xMin() { return _min.x(); } inline const float xMin() const { return _min.x(); } @@ -64,6 +90,12 @@ class SG_EXPORT BoundingBox inline float& zMax() { return _max.z(); } inline const float zMax() const { return _max.z(); } + inline Vec3& min() { return _min; } + inline const Vec3& min() const { return _min; } + + inline Vec3& max() { return _max; } + inline const Vec3& max() const { return _max; } + /** Calculate and return the center of the bounding box.*/ inline const Vec3 center() const { diff --git a/include/osg/BoundingSphere b/include/osg/BoundingSphere index e3f3ea8dd..c486b83e3 100644 --- a/include/osg/BoundingSphere +++ b/include/osg/BoundingSphere @@ -26,6 +26,9 @@ class SG_EXPORT BoundingSphere /** construct to invalid values to represent an unset bounding sphere.*/ BoundingSphere() : _center(0.0f,0.0f,0.0f),_radius(-1.0f) {} + /** construct to specified bounding sphere.*/ + BoundingSphere(const Vec3& center,float radius) : _center(center),_radius(radius) {} + /** initialize to invalid values to represent an unset bounding sphere.*/ inline void init() { @@ -37,6 +40,12 @@ class SG_EXPORT BoundingSphere false if the bounding sphere is effectively unset.*/ inline const bool isValid() const { return _radius>=0.0f; } + /** set bounding sphere.*/ + inline void set(const Vec3& center,float radius) + { + _center = center; + _radius = radius; + } /** return the center of the bounding sphere.*/ inline Vec3& center() { return _center; } diff --git a/include/osg/LineSegment b/include/osg/LineSegment index 98aea346e..36dab58e3 100644 --- a/include/osg/LineSegment +++ b/include/osg/LineSegment @@ -31,6 +31,8 @@ class SG_EXPORT LineSegment : public Referenced inline Vec3& end() { return _e; } inline const Vec3& end() const { return _e; } + inline const bool valid() const { return _s.valid() && _e.valid() && _s!=_e; } + /** return true if segment intersects BoundingBox.*/ const bool intersect(const BoundingBox& bb) const; diff --git a/include/osg/Math b/include/osg/Math index c568148a8..52b7cd195 100644 --- a/include/osg/Math +++ b/include/osg/Math @@ -10,6 +10,7 @@ // #define USE_DEGREES_INTERNALLY #if defined(WIN32) || defined (macintosh) + #include #define M_E 2.7182818284590452354 #define M_LOG2E 1.4426950408889634074 #define M_LOG10E 0.43429448190325182765 @@ -61,6 +62,12 @@ #define sqrtf sqrt #endif +#if defined(WIN32) + // needed for _isnan & _finite used below. + #include +#endif + + namespace osg { #ifdef USE_DEGREES_INTERNALLY @@ -74,6 +81,18 @@ inline double inRadians(double angle) { return angle; } inline double DegreesToRadians(double angle) { return angle*M_PI/180.0; } inline double RadiansToDegrees(double angle) { return angle*180.0/M_PI; } +#ifdef WIN32 +inline bool isNaN(float v) { return ::_isnan(v); } +inline bool isNaN(double v) { return ::isnan(v); } +inline bool isInfinite(float v) { return !::_finite(v); } +inline bool isInfinite(double v) { return !::_finite(v); } +#else +inline bool isNaN(float v) { return ::isnan(v); } +inline bool isNaN(double v) { return ::isnan(v); } +inline bool isInfinite(float v) { return ::isinf(v); } +inline bool isInfinite(double v) { return ::isinf(v); } +#endif + }; #endif // __OSG_MATH diff --git a/include/osg/Vec2 b/include/osg/Vec2 index adf1c9638..ed1b3d2d0 100644 --- a/include/osg/Vec2 +++ b/include/osg/Vec2 @@ -57,6 +57,10 @@ class Vec2 inline const float x() const { return _v[0]; } inline const float y() const { return _v[1]; } + inline const bool valid() const { return !isNaN() && !isInfinite(); } + inline const bool isNaN() const { return osg::isNaN(_v[0]) || osg::isNaN(_v[1]); } + inline const bool isInfinite() const { return osg::isInfinite(_v[0]) || osg::isInfinite(_v[1]); } + /// dot product inline const float operator * (const Vec2& rhs) const { diff --git a/include/osg/Vec3 b/include/osg/Vec3 index c08f053ce..25ed53da4 100644 --- a/include/osg/Vec3 +++ b/include/osg/Vec3 @@ -63,6 +63,10 @@ class Vec3 inline const float y() const { return _v[1]; } inline const float z() const { return _v[2]; } + inline const bool valid() const { return !isNaN() && !isInfinite(); } + inline const bool isNaN() const { return osg::isNaN(_v[0]) || osg::isNaN(_v[1]) || osg::isNaN(_v[2]); } + inline const bool isInfinite() const { return osg::isInfinite(_v[0]) || osg::isInfinite(_v[1]) || osg::isInfinite(_v[2]); } + /// dot product inline float operator * (const Vec3& rhs) const { @@ -161,9 +165,12 @@ class Vec3 inline const float normalize() { float norm = Vec3::length(); - _v[0] /= norm; - _v[1] /= norm; - _v[2] /= norm; + if (norm>0.0f) + { + _v[0] /= norm; + _v[1] /= norm; + _v[2] /= norm; + } return( norm ); } diff --git a/include/osg/Vec4 b/include/osg/Vec4 index 3c2445442..f609a87d0 100644 --- a/include/osg/Vec4 +++ b/include/osg/Vec4 @@ -72,6 +72,10 @@ class Vec4 inline float z() const { return _v[2]; } inline float w() const { return _v[3]; } + inline const bool valid() const { return !isNaN() && !isInfinite(); } + inline const bool isNaN() const { return osg::isNaN(_v[0]) || osg::isNaN(_v[1]) || osg::isNaN(_v[2]) || osg::isNaN(_v[3]); } + inline const bool isInfinite() const { return osg::isInfinite(_v[0]) || osg::isInfinite(_v[1]) || osg::isInfinite(_v[2]) || osg::isInfinite(_v[3]); } + /// dot product inline float operator * (const Vec4& rhs) const { diff --git a/src/osgUtil/IntersectVisitor.cpp b/src/osgUtil/IntersectVisitor.cpp index 7b1530e2a..644713ff1 100644 --- a/src/osgUtil/IntersectVisitor.cpp +++ b/src/osgUtil/IntersectVisitor.cpp @@ -217,6 +217,14 @@ bool IntersectVisitor::hits() void IntersectVisitor::addLineSegment(LineSegment* seg) { + if (!seg) return; + + if (!seg->valid()) + { + notify(WARN)<<"Warning: invalid line segment passed to IntersectVisitor::addLineSegment(..), segment ignored.."<