diff --git a/src/osgGA/TerrainManipulator.cpp b/src/osgGA/TerrainManipulator.cpp index a6c520dc0..afe246feb 100644 --- a/src/osgGA/TerrainManipulator.cpp +++ b/src/osgGA/TerrainManipulator.cpp @@ -190,9 +190,84 @@ void TerrainManipulator::addMouseEvent(const GUIEventAdapter& ea) void TerrainManipulator::setByMatrix(const osg::Matrixd& matrix) { - osg::notify(osg::WARN)<<"Ignoring TerrainManipulator::setByMatrix()"<getBound(); + float distance = (eye-bs.center()).length() + _node->getBound().radius(); + osg::Vec3 start_segment = eye; + osg::Vec3 end_segment = eye + lookVector*distance; + + osg::notify(INFO)<<"start="< 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()) + { + notify(INFO) << "Hit terrain ok"<< std::endl; + osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); + _coordinateFrame = getCoordinateFrame( ip.x(), ip.y(), ip.z()); + + _distance = (eye-ip).length(); + + osg::Matrix rotation_matrix = osg::Matrixd::translate(0.0,0.0,-_distance)* + matrix* + osg::Matrixd::inverse(_coordinateFrame); + + rotation_matrix.get(_rotation); + + hitFound = true; + } + } + + if (!hitFound) + { + CoordinateFrame eyePointCoordFrame = getCoordinateFrame( eye.x(), eye.y(), eye.z()); + + // clear the intersect visitor ready for a new test + iv.reset(); + + osg::ref_ptr 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()) + { + osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get()); + if (!hitList.empty()) + { + notify(INFO) << "Hit terrain ok"<< std::endl; + osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); + + _coordinateFrame = getCoordinateFrame( ip.x(), ip.y(), ip.z()); + + _distance = (eye-ip).length(); + + _rotation.set(0,0,0,1); + + hitFound = true; + } + } + } + } osg::Matrixd TerrainManipulator::getMatrix() const @@ -226,7 +301,7 @@ void TerrainManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& c osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segLookVector.get()); if (!hitList.empty()) { - osg::notify(osg::NOTICE) << "Hit terrain ok"<< std::endl; + osg::notify(osg::INFO) << "Hit terrain ok"<< std::endl; osg::Vec3 ip = hitList.front().getWorldIntersectPoint(); osg::Vec3 np = hitList.front().getWorldIntersectNormal(); @@ -314,7 +389,7 @@ bool TerrainManipulator::calcMovement() osg::Matrixd::rotate(_rotation)* _coordinateFrame; - // osg::notify(osg::NOTICE)<<"\tafter "<<_coordinateFrame.getTrans()<getBound().radius(); + osg::Vec3 start_segment = _coordinateFrame.getTrans() + getUpVector(_coordinateFrame) * distance; + osg::Vec3 end_segment = start_segment - getUpVector(_coordinateFrame) * (2.0f*distance); //end_segment.set(0.0f,0.0f,0.0f); - osg::notify(osg::NOTICE)<<"start="<