OSG获取鼠标点选事件的位置
2015-07-08 22:13
302 查看
OSG点选操作的思路是从
代码如下:pickhandle.h
此处提供了世界坐标和经纬度坐标两套信息供外部选择。
实现代码:pickhandle.cpp
我在处理PUSH和RELEASE事件时,只有两者的点完全一致,我才认为发生了点选操作,否则则忽略此事件。
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事件时,只有两者的点完全一致,我才认为发生了点选操作,否则则忽略此事件。
相关文章推荐
- dedecms整合discuz
- ASP.NET浏览器跨域
- 单例模式
- 第九十七天 how can i 坚持
- InitializingBean和init-method
- OC基础8:分类和协议
- Unity4.x升级5.0出现的32位dll问题
- c++ primer读书笔记-第十一章 泛型算法
- List对象排序的通用方法
- python基础(1)
- 快速排序法
- OC基础8:分类和协议
- Spring Bean生命周期
- 如何由新特性跳转到App首页
- cacti监控工具之自定数据收集方法
- android之3g调试1
- C++中的static关键字的总结
- 欢迎使用CSDN-markdown编辑器
- [NOIP2009][spfa]最优贸易
- StormDRPC 概念以及简单例子测试