Refactored the use of epsilon in the clamping of the start/end points of the LineSegmentIntersector to better handle numerical precision issues.
This commit is contained in:
parent
698365e47f
commit
b9ecec6452
@ -53,8 +53,7 @@ class Intersector : public osg::Referenced
|
||||
Intersector(CoordinateFrame cf=MODEL):
|
||||
_coordinateFrame(cf),
|
||||
_intersectionLimit(NO_LIMIT),
|
||||
_disabledCount(0),
|
||||
_epsilon(1e-4) {}
|
||||
_disabledCount(0) {}
|
||||
|
||||
|
||||
void setCoordinateFrame(CoordinateFrame cf) { _coordinateFrame = cf; }
|
||||
@ -85,19 +84,11 @@ class Intersector : public osg::Referenced
|
||||
|
||||
inline bool reachedLimit() { return _intersectionLimit == LIMIT_ONE && containsIntersections(); }
|
||||
|
||||
/** Set Epsilon value, where supported is used in numerical comparisons to workaround number precisions issues.*/
|
||||
inline void setEpsilon(double epsilon) { _epsilon = epsilon; }
|
||||
|
||||
/** Get Epsilon value.*/
|
||||
inline double getEpsilon() const { return _epsilon; }
|
||||
|
||||
protected:
|
||||
|
||||
CoordinateFrame _coordinateFrame;
|
||||
IntersectionLimit _intersectionLimit;
|
||||
unsigned int _disabledCount;
|
||||
double _epsilon;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -244,7 +244,6 @@ Intersector* LineSegmentIntersector::clone(osgUtil::IntersectionVisitor& iv)
|
||||
osg::ref_ptr<LineSegmentIntersector> lsi = new LineSegmentIntersector(_start, _end);
|
||||
lsi->_parent = this;
|
||||
lsi->_intersectionLimit = this->_intersectionLimit;
|
||||
lsi->_epsilon = this->_epsilon;
|
||||
return lsi.release();
|
||||
}
|
||||
|
||||
@ -279,7 +278,6 @@ Intersector* LineSegmentIntersector::clone(osgUtil::IntersectionVisitor& iv)
|
||||
osg::ref_ptr<LineSegmentIntersector> lsi = new LineSegmentIntersector(_start * inverse, _end * inverse);
|
||||
lsi->_parent = this;
|
||||
lsi->_intersectionLimit = this->_intersectionLimit;
|
||||
lsi->_epsilon = this->_epsilon;
|
||||
return lsi.release();
|
||||
}
|
||||
|
||||
@ -486,18 +484,11 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
osg::Vec3d bb_min(bbInput._min);
|
||||
osg::Vec3d bb_max(bbInput._max);
|
||||
|
||||
// expand the extents of the bounding box by the epsilon to prevent numerical errors resulting in misses.
|
||||
bb_min.x() -= _epsilon;
|
||||
bb_min.y() -= _epsilon;
|
||||
bb_min.z() -= _epsilon;
|
||||
bb_max.x() += _epsilon;
|
||||
bb_max.y() += _epsilon;
|
||||
bb_max.z() += _epsilon;
|
||||
double epsilon = 1e-13;
|
||||
|
||||
// compate s and e against the xMin to xMax range of bb.
|
||||
if (s.x()<=e.x())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.x()<bb_min.x()) return false;
|
||||
if (s.x()>bb_max.x()) return false;
|
||||
@ -505,13 +496,15 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
if (s.x()<bb_min.x())
|
||||
{
|
||||
// clip s to xMin.
|
||||
s = s+(e-s)*(bb_min.x()-s.x())/(e.x()-s.x());
|
||||
double r = (bb_min.x()-s.x())/(e.x()-s.x()) - epsilon;
|
||||
if (r>0.0) s = s + (e-s)*r;
|
||||
}
|
||||
|
||||
if (e.x()>bb_max.x())
|
||||
{
|
||||
// clip e to xMax.
|
||||
e = s+(e-s)*(bb_max.x()-s.x())/(e.x()-s.x());
|
||||
double r = (bb_max.x()-s.x())/(e.x()-s.x()) + epsilon;
|
||||
if (r<1.0) e = s+(e-s)*r;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -521,21 +514,22 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
|
||||
if (e.x()<bb_min.x())
|
||||
{
|
||||
// clip s to xMin.
|
||||
e = s+(e-s)*(bb_min.x()-s.x())/(e.x()-s.x());
|
||||
// clip e to xMin.
|
||||
double r = (bb_min.x()-e.x())/(s.x()-e.x()) - epsilon;
|
||||
if (r>0.0) e = e + (s-e)*r;
|
||||
}
|
||||
|
||||
if (s.x()>bb_max.x())
|
||||
{
|
||||
// clip e to xMax.
|
||||
s = s+(e-s)*(bb_max.x()-s.x())/(e.x()-s.x());
|
||||
// clip s to xMax.
|
||||
double r = (bb_max.x()-e.x())/(s.x()-e.x()) + epsilon;
|
||||
if (r<1.0) s = e + (s-e)*r;
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the yMin to yMax range of bb.
|
||||
if (s.y()<=e.y())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.y()<bb_min.y()) return false;
|
||||
if (s.y()>bb_max.y()) return false;
|
||||
@ -543,13 +537,15 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
if (s.y()<bb_min.y())
|
||||
{
|
||||
// clip s to yMin.
|
||||
s = s+(e-s)*(bb_min.y()-s.y())/(e.y()-s.y());
|
||||
double r = (bb_min.y()-s.y())/(e.y()-s.y()) - epsilon;
|
||||
if (r>0.0) s = s + (e-s)*r;
|
||||
}
|
||||
|
||||
if (e.y()>bb_max.y())
|
||||
{
|
||||
// clip e to yMax.
|
||||
e = s+(e-s)*(bb_max.y()-s.y())/(e.y()-s.y());
|
||||
double r = (bb_max.y()-s.y())/(e.y()-s.y()) + epsilon;
|
||||
if (r<1.0) e = s+(e-s)*r;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -559,21 +555,22 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
|
||||
if (e.y()<bb_min.y())
|
||||
{
|
||||
// clip s to yMin.
|
||||
e = s+(e-s)*(bb_min.y()-s.y())/(e.y()-s.y());
|
||||
// clip e to yMin.
|
||||
double r = (bb_min.y()-e.y())/(s.y()-e.y()) - epsilon;
|
||||
if (r>0.0) e = e + (s-e)*r;
|
||||
}
|
||||
|
||||
if (s.y()>bb_max.y())
|
||||
{
|
||||
// clip e to yMax.
|
||||
s = s+(e-s)*(bb_max.y()-s.y())/(e.y()-s.y());
|
||||
// clip s to yMax.
|
||||
double r = (bb_max.y()-e.y())/(s.y()-e.y()) + epsilon;
|
||||
if (r<1.0) s = e + (s-e)*r;
|
||||
}
|
||||
}
|
||||
|
||||
// compate s and e against the zMin to zMax range of bb.
|
||||
if (s.z()<=e.z())
|
||||
{
|
||||
|
||||
// trivial reject of segment wholely outside.
|
||||
if (e.z()<bb_min.z()) return false;
|
||||
if (s.z()>bb_max.z()) return false;
|
||||
@ -581,13 +578,15 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
if (s.z()<bb_min.z())
|
||||
{
|
||||
// clip s to zMin.
|
||||
s = s+(e-s)*(bb_min.z()-s.z())/(e.z()-s.z());
|
||||
double r = (bb_min.z()-s.z())/(e.z()-s.z()) - epsilon;
|
||||
if (r>0.0) s = s + (e-s)*r;
|
||||
}
|
||||
|
||||
if (e.z()>bb_max.z())
|
||||
{
|
||||
// clip e to zMax.
|
||||
e = s+(e-s)*(bb_max.z()-s.z())/(e.z()-s.z());
|
||||
double r = (bb_max.z()-s.z())/(e.z()-s.z()) + epsilon;
|
||||
if (r<1.0) e = s+(e-s)*r;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -597,14 +596,16 @@ bool LineSegmentIntersector::intersectAndClip(osg::Vec3d& s, osg::Vec3d& e,const
|
||||
|
||||
if (e.z()<bb_min.z())
|
||||
{
|
||||
// clip s to zMin.
|
||||
e = s+(e-s)*(bb_min.z()-s.z())/(e.z()-s.z());
|
||||
// clip e to zMin.
|
||||
double r = (bb_min.z()-e.z())/(s.z()-e.z()) - epsilon;
|
||||
if (r>0.0) e = e + (s-e)*r;
|
||||
}
|
||||
|
||||
if (s.z()>bb_max.z())
|
||||
{
|
||||
// clip e to zMax.
|
||||
s = s+(e-s)*(bb_max.z()-s.z())/(e.z()-s.z());
|
||||
// clip s to zMax.
|
||||
double r = (bb_max.z()-e.z())/(s.z()-e.z()) + epsilon;
|
||||
if (r<1.0) s = e + (s-e)*r;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user