Converted TerrainManipulator to use osgUtil::InterectionVisitor rather than the

old IntersectVisitor
This commit is contained in:
Robert Osfield 2008-07-04 19:16:19 +00:00
parent db57d2504e
commit e70e3a6d5d
3 changed files with 81 additions and 92 deletions

View File

@ -85,6 +85,8 @@ class OSGGA_EXPORT TerrainManipulator : public MatrixManipulator
virtual ~TerrainManipulator();
bool intersect(const osg::Vec3d& start, const osg::Vec3d& end, osg::Vec3d& intersection);
/** Reset the internal GUIEvent stack.*/
void flushMouseEventStack();
/** Add the current mouse GUIEvent to internal stack.*/

View File

@ -13,6 +13,7 @@
#include <osg/KdTree>
#include <osg/Geode>
#include <osg/io_utils>
using namespace osg;
@ -29,6 +30,7 @@ bool KdTree::build(osg::Geometry* geometry)
bool KdTree::intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections)
{
osg::notify(osg::NOTICE)<<"KdTree::intersect("<<start<<","<<end<<")"<<std::endl;
return false;
}

View File

@ -16,6 +16,7 @@
#include <osg/Notify>
#include <osg/io_utils>
#include <osgUtil/IntersectVisitor>
#include <osgUtil/LineSegmentIntersector>
using namespace osg;
using namespace osgGA;
@ -219,11 +220,52 @@ void TerrainManipulator::addMouseEvent(const GUIEventAdapter& ea)
_ga_t0 = &ea;
}
bool TerrainManipulator::intersect(const osg::Vec3d& start, const osg::Vec3d& end, osg::Vec3d& intersection)
{
#if 0
// need to reintersect with the terrain
osgUtil::IntersectVisitor iv;
iv.setTraversalMask(_intersectTraversalMask);
osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
segLookVector->set(start,end);
iv.addLineSegment(segLookVector.get());
_node->accept(iv);
if (iv.hits())
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
if (!hitList.empty())
{
intersection = hitList.front().getWorldIntersectPoint();
return true;
}
}
return false;
#else
osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start,end);
osgUtil::IntersectionVisitor iv(lsi.get());
iv.setTraversalMask(_intersectTraversalMask);
_node->accept(iv);
if (lsi->containsIntersections())
{
intersection = lsi->getIntersections().begin()->getWorldIntersectPoint();
return true;
}
return false;
#endif
}
void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix)
{
osg::Vec3 lookVector(- matrix(2,0),-matrix(2,1),-matrix(2,2));
osg::Vec3 eye(matrix(3,0),matrix(3,1),matrix(3,2));
osg::Vec3d lookVector(- matrix(2,0),-matrix(2,1),-matrix(2,2));
osg::Vec3d eye(matrix(3,0),matrix(3,1),matrix(3,2));
osg::notify(INFO)<<"eye point "<<eye<<std::endl;
osg::notify(INFO)<<"lookVector "<<lookVector<<std::endl;
@ -238,32 +280,16 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix)
// need to reintersect with the terrain
osgUtil::IntersectVisitor iv;
iv.setTraversalMask(_intersectTraversalMask);
const osg::BoundingSphere& bs = _node->getBound();
float distance = (eye-bs.center()).length() + _node->getBound().radius();
osg::Vec3d start_segment = eye;
osg::Vec3d end_segment = eye + lookVector*distance;
//CoordinateFrame coordinateFrame = getCoordinateFrame(_center.x(), _center.y(), _center.z());
//osg::notify(INFO)<<"start="<<start_segment<<"\tend="<<end_segment<<"\tupVector="<<getUpVector(coordinateFrame)<<std::endl;
osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
segLookVector->set(start_segment,end_segment);
iv.addLineSegment(segLookVector.get());
_node->accept(iv);
osg::Vec3d ip;
bool hitFound = false;
if (iv.hits())
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
if (!hitList.empty())
if (intersect(start_segment, end_segment, ip))
{
notify(INFO) << "Hit terrain ok A"<< std::endl;
osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
_center = ip;
_distance = (eye-ip).length();
@ -276,31 +302,15 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix)
hitFound = true;
}
}
if (!hitFound)
{
CoordinateFrame eyePointCoordFrame = getCoordinateFrame( eye );
// clear the intersect visitor ready for a new test
iv.reset();
osg::ref_ptr<osg::LineSegment> segDowVector = new osg::LineSegment;
segLookVector->set(eye+getUpVector(eyePointCoordFrame)*distance,
eye-getUpVector(eyePointCoordFrame)*distance);
iv.addLineSegment(segLookVector.get());
_node->accept(iv);
hitFound = false;
if (iv.hits())
if (intersect(eye+getUpVector(eyePointCoordFrame)*distance,
eye-getUpVector(eyePointCoordFrame)*distance,
ip))
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
if (!hitList.empty())
{
notify(INFO) << "Hit terrain ok B"<< std::endl;
osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
_center = ip;
_distance = (eye-ip).length();
@ -310,7 +320,7 @@ void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix)
hitFound = true;
}
}
}
CoordinateFrame coordinateFrame = getCoordinateFrame(_center);
_previousUp = getUpVector(coordinateFrame);
@ -352,23 +362,10 @@ void TerrainManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d&
++i, endPoint = farPosition)
{
// compute the intersection with the scene.
osgUtil::IntersectVisitor iv;
iv.setTraversalMask(_intersectTraversalMask);
osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
segLookVector->set(eye,endPoint );
iv.addLineSegment(segLookVector.get());
_node->accept(iv);
if (iv.hits())
osg::Vec3d ip;
if (intersect(eye, endPoint, ip))
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
if (!hitList.empty())
{
osg::notify(osg::INFO) << "Hit terrain ok C"<< std::endl;
osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
_center = ip;
_distance = (ip-eye).length();
@ -376,7 +373,6 @@ void TerrainManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d&
}
}
}
}
// note LookAt = inv(CF)*inv(RM)*inv(T) which is equivalent to:
// inv(R) = CF*LookAt.
@ -493,6 +489,8 @@ bool TerrainManipulator::calcMovement()
// need to recompute the intersection point along the look vector.
bool hitFound = false;
if (_node.valid())
{
@ -500,34 +498,21 @@ bool TerrainManipulator::calcMovement()
CoordinateFrame coordinateFrame = getCoordinateFrame(_center);
// need to reintersect with the terrain
osgUtil::IntersectVisitor iv;
iv.setTraversalMask(_intersectTraversalMask);
double distance = _node->getBound().radius()*0.1f;
osg::Vec3d start_segment = _center + getUpVector(coordinateFrame) * distance;
osg::Vec3d end_segment = start_segment - getUpVector(coordinateFrame) * (2.0f*distance);
osg::notify(INFO)<<"start="<<start_segment<<"\tend="<<end_segment<<"\tupVector="<<getUpVector(coordinateFrame)<<std::endl;
osg::ref_ptr<osg::LineSegment> segLookVector = new osg::LineSegment;
segLookVector->set(start_segment,end_segment);
iv.addLineSegment(segLookVector.get());
_node->accept(iv);
bool hitFound = false;
if (iv.hits())
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get());
if (!hitList.empty())
osg::Vec3d ip;
if (intersect(start_segment,end_segment, ip))
{
notify(INFO) << "Hit terrain ok"<< std::endl;
osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
_center = ip;
hitFound = true;
}
}
if (!hitFound)
{