您的位置:首页 > 其它

OSG获取鼠标点选事件的位置

2015-07-08 22:13 302 查看
OSG点选操作的思路是从
osgGA::GUIEventHandler
继承,并重新实现虚函数
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
。获取到点选信息后,此处我们不进行处理,而是单一的传出去,由外部需要此点选信息的地方进行处理。对于传出信息,我选择了Qt的信号槽操作,因而,在继承
osgGA::GUIEventHandler
的同时,我们还需要继承QObject。

代码如下:pickhandle.h

class PickHandle : public QObject, public osgGA::GUIEventHandler
{
Q_OBJECT
public:
PickHandle(const osgEarth::SpatialReference* srs);
~PickHandle();

protected:
virtual bool handle(const osgGA::GUIEventAdapter& ea,
osgGA::GUIActionAdapter& aa);

private:
osg::Vec3d getPos(const osgGA::GUIEventAdapter& ea,
osgGA::GUIActionAdapter& aa, osg::Vec3d& pos);

signals:
// 经纬度信息
void signalPicked(osg::Vec3d pos);
void signalMoving(osg::Vec3d pos);

// 世界坐标信息
void signalPickedXYZ(osg::Vec3d pos);
void signalMovingXYZ(osg::Vec3d pos);

void signalRightPicked();

private:
osg::Vec3d m_vecPostion;
const osg::EllipsoidModel* m_pEllipsoid;
};


此处提供了世界坐标和经纬度坐标两套信息供外部选择。

实现代码:pickhandle.cpp

PickHandle::PickHandle(const osgEarth::SpatialReference* srs)
{
m_pEllipsoid = srs->getGeodeticSRS()->getEllipsoid();
}

PickHandle::~PickHandle()
{

}

bool PickHandle::handle(const osgGA::GUIEventAdapter& ea,
osgGA::GUIActionAdapter& aa)
{
// 存储经纬度信息
osg::Vec3d vecPos;
switch (ea.getEventType())
{
// 点击事件
case osgGA::GUIEventAdapter::PUSH:
{
osg::Vec3d pos = getPos(ea, aa, vecPos);
// 鼠标左键
if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
m_vecPostion = pos;
}
break;
}

// 鼠标移动事件
case osgGA::GUIEventAdapter::MOVE:
{
osg::Vec3d pos = getPos(ea, aa, vecPos);
emit signalMoving(vecPos);
emit signalMovingXYZ(pos);
break;
}

// 鼠标释放事件
case osgGA::GUIEventAdapter::RELEASE:
{
osg::Vec3d pos = getPos(ea, aa, vecPos);
// 鼠标左键
if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
// 如果释放的点和点击的点同一,则发送单击事件发生的位置
if (m_vecPostion == pos && m_vecPostion != osg::Vec3d(0, 0, 0))
{
emit signalPicked(vecPos);
emit signalPickedXYZ(pos);
}
}
else if (ea.getButton() == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)
{
emit signalRightPicked();
}
break;
}
}

return false;
}

osg::Vec3d PickHandle::getPos(const osgGA::GUIEventAdapter& ea,
osgGA::GUIActionAdapter& aa, osg::Vec3d& pos)
{
pos = osg::Vec3d(0, 0, 0);
osgViewer::Viewer* pViewer = dynamic_cast<osgViewer::Viewer*>(&aa);
if (pViewer == NULL)
{
return osg::Vec3d(0, 0, 0);
}
// 获取当前点
osgUtil::LineSegmentIntersector::Intersections intersection;
double x = ea.getX();
double y = ea.getY();
pViewer->computeIntersections(ea.getX(), ea.getY(), intersection);
osgUtil::LineSegmentIntersector::Intersections::iterator iter
= intersection.begin();
if (iter != intersection.end())
{
m_pEllipsoid->convertXYZToLatLongHeight(
iter->getWorldIntersectPoint().x(), iter->getWorldIntersectPoint().y(), iter->getWorldIntersectPoint().z(),
pos.y(), pos.x(), pos.z());
pos.x() = osg::RadiansToDegrees(pos.x());
pos.y() = osg::RadiansToDegrees(pos.y());
return iter->getWorldIntersectPoint();
}
return osg::Vec3d(0, 0, 0);
}


我在处理PUSH和RELEASE事件时,只有两者的点完全一致,我才认为发生了点选操作,否则则忽略此事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: