我正在使用具有OSGWidget的QT应用程序 . 如何在osg查看器中获取拾取对象的坐标并将其传输到对话窗口中的QT textEdit . 你能给出一些建议,如何从查看器中提取所选对象的osg :: Vec3d,将其转换为字符串并显示出来吗?例如 . 我有这样的场景:
当我点击添加按钮时,它会打开一个对话框窗口,其中我有一个textEdit对象 . 在此editText中传输coords . 怎么可能这样呢?忘记添加此多维数据集是从广告文件导入的 . 可能它可以在任何地方提供帮助 .
为了检索对象's coordinates from your scene, you' ll需要向查看器添加新的事件处理程序 . 我们称之为 PickHandler .
PickHandler
这是一个可以帮助您入门的基本代码 . 您需要添加“包含”并对其进行修改以满足您的需求 . (请注意,我还没有测试过 . 我是通过“内存”编写的,但如果有任何错误,应该很容易修复) .
PickHandler.h
class PickHandler: public QObject, public osgGA::GUIEventHandler { Q_OBJECT public: PickHandler(); virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ); signals: void query( osg::Vec3f ); protected: virtual ~PickHandler() { } bool pick( const double x, const double y, osgViewer::Viewer* viewer ); private: bool getPickedPoint( const double x, const double y, float buffer, osgViewer::Viewer* viewer, osg::Vec3f& point ); };
PickHandler.cpp
PickHandler::PickHandler() : osgGA::GUIEventHandler() { } bool PickHandler::handle( const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa ) { osgViewer::View* viewer = dynamic_cast<osgViewer::Viewer*>( &aa ); if( !viewer ) { return false; } switch( ea.getEventType() ) { default: break; case osgGA::GUIEventAdapter::RELEASE: { if( pick(ea.getXnormalized(), ea.getYnormalized(), viewer ) ) { return true; } break; } } return false; } bool PickHandler::pick( const double x, const double y, osgViewer::Viewer* viewer ) { if( !viewer->getSceneData() ) { return false; } osg::Vec3f point; float buffer = 0.005f; if( getPickedPoint( x, y, buffer, viewer, point ) ) { emit query( point ); } return false; } bool PickHandler::getPickedPoint( const double x, const double y, float buffer, osgViewer::Viewer* viewer, osg::Vec3f& point ) { osg::ref_ptr<osgUtil::PolytopeIntersector> intersector( 0 ); try { intersector = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, x - buffer, y - buffer, x + buffer, y + buffer ) ; } catch( const std::bad_alloc& ) { return false; } // DimZero = check only for points intersector->setDimensionMask( osgUtil:: PolytopeIntersector::DimZero ); // intersector->setIntersectionLimit( osgUtil::Intersector::LIMIT_NEAREST ); osgUtil::IntersectionVisitor iv( intersector ); viewer->getCamera()->accept( iv ); if( intersector->containsIntersections() ) { osgUtil::PolytopeIntersector::Intersection intersection = *( intersector->getIntersections().begin() ) ; const osg::Vec3f& P = intersection.intersectionPoints[ 0 ]; if( P.isNaN() ) { return false; } point.set( P[ 0 ], P[ 1 ], P[ 2 ] ); return true; } return false; }
我正在使用 PolytopeIntersector ,因为我没有_1074209的示例数据;只有很多分数并且使用 LineIntersector (最快)几乎不可能获得成功 . Polytope 将构建一个与您指定区域中的任何内容相交的截头体积(在构造 Polytope 时使用参数) .
PolytopeIntersector
LineIntersector
Polytope
此外,您可能需要使用发送到pick功能的参数,例如缓冲区大小 . 我使用 ea.getXNormalized() 并在 pick() 中使用 osgUtil::Intersector::PROJECTION 值 .
ea.getXNormalized()
pick()
osgUtil::Intersector::PROJECTION
如果你使用_比如 osgUtil::Intersector::WINDOW 值,你在视图中没有"strange"转换,很可能 PROJECTION 值就是你需要的 .
osgUtil::Intersector::WINDOW
PROJECTION
最后,这段代码相当陈旧 . 对于较新的 osg 版本,可能会有一些版本被视为已弃用 . 我'm not sure as I haven' t更新了我的选择器代码 .
osg
现在,使用此代码,当找到itersection时,它将检索FIRST并通过emit发送点值 . 你只需将这个 Launcher 连接到你的SLOT并接收cliked point coords .
最后,为了将某些东西转换为字符串,您可以使用Qt String函数 QString::number(...) .
QString::number(...)
例如:
const QString x = QString::number( point[0], 'd', 6 );
将使用带有6位小数的定点格式对点的x-coord进行字符串化 .
1 回答
为了检索对象's coordinates from your scene, you' ll需要向查看器添加新的事件处理程序 . 我们称之为
PickHandler
.这是一个可以帮助您入门的基本代码 . 您需要添加“包含”并对其进行修改以满足您的需求 . (请注意,我还没有测试过 . 我是通过“内存”编写的,但如果有任何错误,应该很容易修复) .
PickHandler.h
PickHandler.cpp
我正在使用
PolytopeIntersector
,因为我没有_1074209的示例数据;只有很多分数并且使用LineIntersector
(最快)几乎不可能获得成功 .Polytope
将构建一个与您指定区域中的任何内容相交的截头体积(在构造Polytope
时使用参数) .此外,您可能需要使用发送到pick功能的参数,例如缓冲区大小 . 我使用
ea.getXNormalized()
并在pick()
中使用osgUtil::Intersector::PROJECTION
值 .如果你使用_比如
osgUtil::Intersector::WINDOW
值,你在视图中没有"strange"转换,很可能PROJECTION
值就是你需要的 .最后,这段代码相当陈旧 . 对于较新的
osg
版本,可能会有一些版本被视为已弃用 . 我'm not sure as I haven' t更新了我的选择器代码 .现在,使用此代码,当找到itersection时,它将检索FIRST并通过emit发送点值 . 你只需将这个 Launcher 连接到你的SLOT并接收cliked point coords .
最后,为了将某些东西转换为字符串,您可以使用Qt String函数
QString::number(...)
.例如:
将使用带有6位小数的定点格式对点的x-coord进行字符串化 .