[osg][原]自定义osgGA漫游器

相机矩阵变化基础:http://blog.youkuaiyun.com/popy007/article/details/5120158

osg漫游器原理:http://blog.youkuaiyun.com/csxiaoshui/article/details/51295591

osgGA::CameraManpulator原理:http://blog.youkuaiyun.com/csxiaoshui/article/details/51303086

 

 简单的说osgGA::CameraManipulator就是用来修改相机节点姿态的。

关于osg相机的默认姿态:http://www.cnblogs.com/lyggqm/p/8073688.html

 

osg一帧的绘制中会经历 事件遍历、更新遍历、渲染这三个过程。

事件遍历处理完其他事件回调后会调用漫游器的handle()函数

更新遍历处理完其他更新回调后会调用漫游器的updateCamera()函数

 

也就是说需要自定义漫游器最重要的两个重写函数是:

//事件处理,按键,鼠标交互处理
bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
//更新当前帧的摄像机(通常由viewer调用)
//默认实现只需设置摄像机视图矩阵。
virtual void updateCamera(osg::Camera& camera);

而 updateCamera() 一般也不会重写,而是重写getInverseMatrix() 

 

    //所有漫游器都必须实现的4个纯虚函数  
    virtual void setByMatrix(const osg::Matrixd& matrix){}  //设置相机的位置姿态矩阵  
    virtual void setByInverseMatrix(const osg::Matrixd& matrix){}  //设置相机的视图矩阵  
    virtual osg::Matrixd getMatrix() const{return osg::Matrix();}  //获取相机的姿态矩阵 
    virtual osg::Matrixd getInverseMatrix() const;   //获取相机的视图矩阵 

 一般重写getInverseMatrix()。 因为这个函数返回的矩阵在updateCamera中使用:

virtual void updateCamera(osg::Camera& camera) { camera.setViewMatrix(getInverseMatrix()); }

所以,自定义函数最重要的两个重写函数是:

handle  和  getInverseMatrix

 

OSG(OpenSceneGraph)是一个开源的图形库,广泛应用于三维可视化领域。在 OSG 中,“自定义操作”通常指用户通过编写特定的行为逻辑来自定义相机、节点或其他组件的操作。 ### 自定义操作的概念 osgGAOSG GUI Abstraction Layer 的缩写)模块提供了一套用于处理用户输入事件(如鼠标点击、键盘按键等)的基础机制,并允许开发者创建自定义的操作来响应这些事件。例如: 1. **NodeTrackerManipulator**:跟踪某个场景图节点并围绕该点旋转。 2. **TrackballManipulator**:模拟轨迹球的效果,在移动鼠标时能够平滑地控制视角变化。 如果内置操作无法满足需求,则可以继承 `osgGA::GUIEventHandler` 或者 `osgGA::CameraManipulator` 来构建自己的操作。 --- #### 实现步骤 - 创建一个简单的自定义操作 以下是基于 C++ 和 OSG 构建的一个简单示例: ```cpp #include <osgViewer/Viewer> #include <osgGA/GUIEventHandler> class CustomManipulator : public osgGA::GUIEventHandler { public: CustomManipulator() {} bool handle(const osgGA::Event* event, osg::Object*, osg::NodeVisitor*) override { if (event->getEventType() == osgGA::GUIEventAdapter::KEYDOWN) { // 检查按下的键是否是我们关心的某按钮 if (event->getKey() == 'a') { std::cout << "A 键被按下" << std::endl; return true; // 表明已成功处理此事件 } } return false; // 如果未匹配到需要拦截的情况则返回false让其他处理继续尝试 } protected: ~CustomManipulator() {} }; int main(int argc, char** argv){ osgViewer::Viewer viewer; CustomManipulator customManipulatorInstance; // 添加我们的定制化事件监听 viewer.addEventHandler(&customManipulatorInstance); osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFile("cow.osg"); if (!loadedModel) return 0; viewer.setSceneData(loadedModel); return viewer.run(); } ``` 上述代码演示了如何添加一个名为“CustomManipulator”的事件处理程序,当用户按下字母“A”时打印一条消息至终端屏幕。 --- ### 总结 利用 OSG 提供的强大框架支持,我们可以轻松地为应用程序增添交互功能,从基础的方向导航到复杂的手势识别都可以由各类操纵完成。此外,结合实际项目需求不断调整和完善这些自定义类将极大提升用户体验质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值