OSG 的事件处理系统是其交互功能的核心,用于处理用户输入(键盘、鼠标等)和系统事件。以下是 OSG 事件处理的全面介绍:
1. 事件处理基本架构
OSG 的事件处理基于观察者模式,主要包含以下组件:
-
事件队列(EventQueue):存储接收到的原始输入事件
-
事件处理器(GUIEventHandler):处理事件的接口
-
操作器(Manipulator):预定义的高级交互行为(如轨迹球操作器)
2. 核心类介绍
2.1 osgGA::GUIEventHandler
所有事件处理器的基类,主要方法:
virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
2.2 osgGA::EventQueue
负责收集和分发事件,通常由视图器(Viewer)内部管理。
2.3 osgGA::GUIEventAdapter
封装了各种事件类型和参数,如:
-
事件类型(EventType):KEYDOWN、KEYUP、PUSH、RELEASE等
-
键盘码(KeySymbol)
-
鼠标位置(X,Y)
-
鼠标按钮(MouseButtonMask)
3. 事件处理流程
-
操作系统输入 → 2. OSG EventQueue → 3. GUIEventHandler → 4. 场景响应
4. 实现自定义事件处理器
示例代码:
class MyEventHandler : public osgGA::GUIEventHandler {
public:
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override {
switch(ea.getEventType()) {
case osgGA::GUIEventAdapter::KEYDOWN:
if(ea.getKey() == 'a') {
// 处理A键按下
return true; // 事件已处理
}
break;
case osgGA::GUIEventAdapter::PUSH:
if(ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
// 处理鼠标左键点击
return true;
}
break;
}
return false; // 事件未处理,传递给其他处理器
}
};
// 添加到视图器
viewer.addEventHandler(new MyEventHandler());
5. 常用预定义操作器
-
TrackballManipulator:轨迹球操作器(默认)
-
FlightManipulator:飞行操作器
-
DriveManipulator:驾驶操作器
-
TerrainManipulator:地形适配操作器
使用示例:
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
6. 高级主题
6.1 多视图事件处理
通过设置View
的EventQueue
可以实现多视图独立事件处理。
6.2 事件处理优先级
通过setAllowThrow()
等方法可以控制操作器的行为特性。
6.3 自定义操作器
继承osgGA::MatrixManipulator
可以实现完全自定义的交互方式。
7. 调试技巧
-
使用
osgViewer::ViewerEventHandlers
添加默认调试处理器 -
查看事件参数:
osg::notify(osg::INFO) << "Event: " << ea.getX() << "," << ea.getY();
8. 性能考虑
-
避免在事件处理器中进行复杂计算
-
需要频繁更新的操作考虑使用回调(Callback)机制
-
使用
setHandled(true)
标记已处理事件,防止重复处理