OSG如何重写鼠标事件,实现自定义的 漫游移动、旋转、平移视角操作

摘要:使用OSG自己的窗口,带有移动旋转平移场景的基础操作功能,但是这显然无法满足各种各样用户的需求,比如:OSG自带的旋转太过于灵活,就让人操作起来不顺手,体验感很差,又没法设置它的灵敏精度,让人很是无语。基于此,我就想用OSG的方式,自己实现一套漫游操作。在网上找了一圈下来,很多人都说了点皮毛,东一点、西一点,没有一个完整的讲清楚怎么去实现自定义的漫游操作功能。求人不如求己,由于有OpenGL储备知识的加持,让我写起来得心应手。

一、先贴上一些大神写的方法,也供大家参考参考,看看是不是他们的更清楚

osg自定义操作器实现视图缩放_osg 透视投影缩小之后进行平移-CSDN博客OSG下鼠标点击实现对模型的移动,旋转(漫游器) - 代码先锋网osg自定义操作器实现视图缩放_osg 透视投影缩小之后进行平移-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要利用键盘操作器(`osgGA::GUIEventHandler`)来对从 `NodeVisitor` 遍历得到的节点进行旋转平移操作,您可以使用 OpenSceneGraph (OSG) 提供的事件处理机制。以下是一个示例代码片段,展示了如何实现这样的操作: ```cpp #include <osg/NodeVisitor> #include <osg/MatrixTransform> #include <osgGA/GUIEventHandler> #include <osgViewer/Viewer> // 自定义的 NodeVisitor 子类 class MyVisitor : public osg::NodeVisitor { public: MyVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} // 重写 apply 方法,在遍历每个节点时执行操作 virtual void apply(osg::Node& node) { // 在这里添加旋转平移的代码 osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(&node); if (transform) { // 旋转节点 transform->setMatrix(osg::Matrix::rotate(rotationAngle_, osg::Vec3(0, 0, 1))); // 平移节点 transform->setMatrix(transform->getMatrix() * osg::Matrix::translate(translationOffset_)); } // 继续遍历子节点 traverse(node); } void setRotationAngle(float angle) { rotationAngle_ = angle; } void setTranslationOffset(const osg::Vec3& offset) { translationOffset_ = offset; } private: float rotationAngle_ = 0.0f; osg::Vec3 translationOffset_; }; // 自定义的 GUIEventHandler 子类 class MyEventHandler : public osgGA::GUIEventHandler { public: MyEventHandler(MyVisitor* visitor) : visitor_(visitor) {} // 重写 handle 方法,在接收到按键事件时执行操作 virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) { switch (ea.getKey()) { case osgGA::GUIEventAdapter::KEY_Left: visitor_->setRotationAngle(-0.1f); break; case osgGA::GUIEventAdapter::KEY_Right: visitor_->setRotationAngle(0.1f); break; case osgGA::GUIEventAdapter::KEY_Up: visitor_->setTranslationOffset(osg::Vec3(0, 0.1f, 0)); break; case osgGA::GUIEventAdapter::KEY_Down: visitor_->setTranslationOffset(osg::Vec3(0, -0.1f, 0)); break; } return true; } return false; } private: MyVisitor* visitor_; }; int main() { // 创建场景图(省略加载场景文件的步骤) // 创建 MyVisitor 对象并应用于场景节点 MyVisitor visitor; scene->accept(visitor); // 创建查看器并设置场景数据 osgViewer::Viewer viewer; viewer.setSceneData(scene); // 创建事件处理器并绑定到查看器 MyEventHandler eventHandler(&visitor); viewer.addEventHandler(&eventHandler); // 运行场景图的渲染循环 viewer.run(); return 0; } ``` 在上面的示例中,我们创建了一个名为 `MyVisitor` 的自定义 `NodeVisitor` 子类,在 `apply` 方法中实现旋转平移操作。我们还创建了一个名为 `MyEventHandler` 的自定义 `GUIEventHandler` 子类,用于处理键盘事件。 在 `main` 函数中,我们创建了 `MyVisitor` 对象并将其应用于场景节点。然后,我们创建了一个 `osgViewer::Viewer` 对象,并将场景数据设置为场景图。接下来,我们创建了一个 `MyEventHandler` 对象,并将其绑定到查看器上。 最后,我们运行场景图的渲染循环。当用户按下左、右、上、下方向键时,`MyEventHandler` 类的 `handle` 方法会被调用,根据按键事件设置旋转角度和平移偏移量。然后,在每次遍历节点时,`MyVisitor` 类会根据这些设置执行相应的旋转平移操作。 请注意,上述示例中的旋转平移操作仅作为演示。您可以根据实际需求修改旋转角度和平移偏移量的设置。同时,您可能需要添加其他按键事件和相应的操作。 希望对您有所帮助!如果有任何进一步的问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大侠后花园

如果觉得文章不错请给点支持吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值