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.
This commit is contained in:
Robert Osfield 2001-11-06 10:34:51 +00:00
parent b45aa55555
commit 5e6153b428
8 changed files with 89 additions and 4 deletions

View File

@ -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
{

View File

@ -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; }

View File

@ -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;

View File

@ -10,6 +10,7 @@
// #define USE_DEGREES_INTERNALLY
#if defined(WIN32) || defined (macintosh)
#include <float.h>
#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 <float.h>
#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

View File

@ -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
{

View File

@ -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 );
}

View File

@ -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
{

View File

@ -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.."<<endl;
return;
}
// first check to see if segment has already been added.
for(LineSegmentHitListMap::iterator itr = _segHitList.begin();
itr != _segHitList.end();