標籤:

OSG獲取滑鼠點選事件的位置

引用自博主

OSG獲取滑鼠點選事件的位置 - CSDN博客kestiny的專欄 - CSDN博客?

blog.csdn.net

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_OBJECTpublic: 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事件時,只有兩者的點完全一致,我才認為發生了點選操作,否則則忽略此事件。

推薦閱讀:

現在滑鼠品牌里最好的是哪個?
黑科技:萬能滑鼠!
為什麼要用滑鼠?
滑鼠按原理結構分為幾種啊?
有人入手了多彩垂直滑鼠嗎??

TAG:滑鼠 |