#include"StdAfx.h"
#include"RovingManipulator.h"
#include"FindNodeVisitor.h"
#include<osg/Notify>
#include<osg/io_utils>
#include<osgUtil/LineSegmentIntersector>
CRovingManipulator::CRovingManipulator(void)
{
m_rotationMode = ELEVATION_AZIM;
m_distance = 1.0;
m_thrown = false;
m_RovingMode = LECoreCommon::THREED_ROVING;
m_bZoomed = false;
m_dDefaultCameraFovy = 90.0;
m_dCameraFovy = 90.0;
}
CRovingManipulator::~CRovingManipulator(void)
{
}
void CRovingManipulator::setRotationMode(RotationMode mode)
{
m_rotationMode = mode;
// need to correct rotation.
}
void CRovingManipulator::setCameraRovingMode(LECoreCommon::EnumRovingMode erm)
{
m_RovingMode = erm;
}
void CRovingManipulator::setNode(osg::Node* node)
{
m_node = node;
if (())
{
const osg::BoundingSphere& boundingSphere = m_node->getBound();
const float minimumDistanceScale = 0.001f;
_minimumDistance = osg::clampBetween(
float(boundingSphere._radius) * minimumDistanceScale,
0.00001f,1.0f);
osg::notify(osg::INFO)<<"Setting roving manipulator _minimumDistance to "<<_minimumDistance<<std::endl; }
if (getAutoComputeHomePosition()) computeHomePosition();
}
const osg::Node* CRovingManipulator::getNode() const
{
return ();
}
osg::Node* CRovingManipulator::getNode()
{
return ();
}
bool CRovingManipulator::intersect(const osg::Vec3d& start, const osg::Vec3d& end, osg::Vec3d& intersection) const
{
osgUtil::IntersectionVisitor ());
iv.setTraversalMask(_intersectTraversalMask);
m_node->accept(iv);
// 如果包含交点,取得交点
if (lsi->containsIntersections())
{
intersection = lsi->getIntersections().begin()->getWorldIntersectPoint();
return true;
}
return false;
}
void CRovingManipulator::home(const osgGA::GUIEventAdapter& , osgGA::GUIActionAdapter& us)
{
/
/if (getAutoComputeHomePosition()) computeHomePosition();
_homeEye = osg::Vec3d(0.0f, -30000000.0f, 0.0f);
_homeCenter = osg::Vec3d(0.0f, 0.0f, 0.0f);
_homeUp = osg::Vec3d(0.0f, 0.0f, 1.0f);
computePosition(_homeEye, _homeCenter, _homeUp);
}
void CRovingManipulator::init(const osgGA::GUIEventAdapter& ,osgGA::GUIActionAdapter& )
{
flushMouseEventStack();
}
void CRovingManipulator::getUsage(osg::ApplicationUsage& usage) const
{
usage.addKeyboardMouseBinding("Roving: Space","Reset the viewing position to home");
usage.addKeyboardMouseBinding("Roving: +","When in stereo, increase the fusion distance"); usage.addKeyboardMouseBinding("Roving: -","When in stereo, reduce the fusion distance"); }
bool CRovingManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) {
EventType())
{
// 帧事件
case(osgGA::GUIEventAdapter::FRAME):
if (m_thrown)
{
if (calcMovement()) us.requestRedraw();
}
return false;
default:
break;
}
if (ea.getHandled()) return false;
EventType())
{
// 按下鼠标按键
case(osgGA::GUIEventAdapter::PUSH):
{
flushMouseEventStack();
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
m_thrown = false;
// 释放鼠标按键
case(osgGA::GUIEventAdapter::RELEASE):
{
/
/ 如果是单个键释放
if (ea.getButtonMask()==0)
{
// 如果鼠标移动
if (isMouseMoving())
{
// 如果计算出移动量
if (calcMovement())
{
m_thrown = false;
}
}
// 否则鼠标没移动
else
{
flushMouseEventStack(); // 刷新鼠标事件堆栈
addMouseEvent(ea); // 添加鼠标事件
if (calcMovement()) us.requestRedraw(); // 如果计算出移动量,要求重绘 us.requestContinuousUpdate(false); // 不要求继续更新
m_thrown = false;
}
}
// 否则多个键释放
else
{
flushMouseEventStack();
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
m_thrown = false;
}
return true;
}
// 鼠标拖动
case(osgGA::GUIEventAdapter::DRAG):
{
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
m_thrown = false;
return true;
}
// 鼠标移动,不处理
case(osgGA::GUIEventAdapter::MOVE):
{
return false;
}
// 按下键盘
case(osgGA::GUIEventAdapter::KEYDOWN):
// 如果按下空格键,回到初始位置
if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Space)
{
flushMouseEventStack();
m_thrown = false;
home(ea,us);
return true;
}
return false;
}
}
bool CRovingManipulator::isMouseMoving()
{
if (m_()==NULL || m_()==NULL) return false;
static const float velocity = 0.1f;
float dx = m_ga_t0->getXnormalized()-m_ga_t1->getXnormalized();
float dy = m_ga_t0->getYnormalized()-m_ga_t1->getYnormalized();
float len = sqrtf(dx*dx+dy*dy);
float dt = m_ga_t0->getTime()-m_ga_t1->getTime();
return (len>dt*velocity);
}
void CRovingManipulator::flushMouseEventStack()
{
m_ga_t1 = NULL;
m_ga_t0 = NULL;
}
void CRovingManipulator::addMouseEvent(const osgGA::GUIEventAdapter& ea)
{
m_ga_t1 = m_ga_t0;
m_ga_t0 = &ea;
}
void CRovingManipulator::setByMatrix(const osg::Matrixd& matrix)
{
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(osg::INFO)<<"eye point "<<eye<<std::endl;
osg::notify(osg::INFO)<<"lookVector "<<lookVector<<std::endl;
if (!m_node)
{
m_center = eye + lookVector;
m_distance = lookVector.length();
m_rotation = Rotate();
return;
}
// need to reintersect with the terrain
const osg::BoundingSphere& bs = m_node->getBound();
float distance = (()).length() + m_node->getBound().radius();
osg::Vec3d start_segment = eye;
osg::Vec3d end_segment = eye + lookVector*distance;
osg::Vec3d ip;
bool hitFound = false;
if (intersect(start_segment, end_segment, ip))
{
notify(osg::INFO) << "Hit terrain ok A"<< std::endl;
m_center = ip;
m_distance = (eye-ip).length();
osg::Matrixd rotation_matrix = osg::Matrixd::translate(0.0,0.0,-m_distance)* matrix*
osg::Matrixd::translate(-m_center);
m_rotation = Rotate();
if (!hitFound)
{
osg::CoordinateFrame eyePointCoordFrame = getCoordinateFrame( eye );
if (intersect(eye+getUpVector(eyePointCoordFrame)*distance,
eye-getUpVector(eyePointCoordFrame)*distance,
ip))
{
m_center = ip;
m_distance = (eye-ip).length();
m_rotation.set(0,0,0,1);
hitFound = true;
}
}
osg::CoordinateFrame coordinateFrame = getCoordinateFrame(m_center);
m_previousUp = getUpVector(coordinateFrame);
clampOrientation();
}
osg::Matrixd CRovingManipulator::getMatrix() const
{
return osg::Matrixd::translate(0.0,0.0,m_distance)*osg::Matrixd::rotate(m_rotation)*osg::Matrixd::translate (m_center);
}
osg::Matrixd CRovingManipulator::getInverseMatrix() const
{
return osg::Matrixd::translate(-m_center)*osg::Matrixd::rotate(m_rotation.inverse())*osg::Matrixd::
translate(0.0,0.0,-m_distance);
}
void CRovingManipulator::computePosition(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up) {
if (!m_node) return;
/
/ compute rotation matrix
osg::Vec3d lv(center-eye);
m_distance = lv.length();
m_center = center;
osg::notify(osg::INFO) << "In compute"<< std::endl;
if (m_node.valid())
{
bool hitFound = false;
double distance = lv.length();
double maxDistance = distance+2*(eye-m_node->getBound().center()).length();
osg::Vec3d farPosition = eye+lv*(maxDistance/distance);
osg::Vec3d endPoint = center;
float upfor(int i=0; !hitFound && i<2; ++i, endPoint = farPosition)
{
// compute the intersection with the scene.
osg::Vec3d ip;
if (intersect(eye, endPoint, ip))
{
m_center = ip;
m_distance = (ip-eye).length();
hitFound = true;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论