看看整体流程
如果有osgGA::GUIEventAdapter::QUIT_APPLICATION,就可以随时关闭程序
这里对退出起作用的是结束键
退出键不一定按esc键,也可以是其他键,增加灵活性,保证随时退出
当然,最终是因为_done起作用,所以可以直接设置,直接终止。
比如,当前事件是WM_MOVE
注册的事件处理器有8个,依次处理
handleWithCheckAgainstIgnoreHandledEventsMask()主要执行GUIEventHandler::handle函数时,后者在用户定义的事件处理器中是必须被重写的
一句一句翻译
应该这么说,如果是false,则进行处理
也就是说,handle=false时,
才进行处理
如果handled为真,则设为true,也就是说, 再也不会成立,即其他handlers不再处理
不管handled是真是假,都会返回bool量,
其实,return什么都不重要,关键是和
当前handler处理完后,设置为真还是假,这决定着下一个事件处理器是否进行处理,能不能进去if语句。
如果时真,则直接return false,跳出去了
因为这是个固定模式,所以i要求尽量别重写handleWithCheckAgainstIgnoreHandledEventsMask()
因为则这个判断语句中,还有个条件
可以直接设置_ignoreHandledEventsMask为true,则可以使处理器队列不再处理这一事件,
如果传入GUIEventAdapter::EventType类型的参数,则不处理这一类事件,如果通过或运算传入多个EventType类型,则不再处理多类事件。
反之,如果处理,则位与结果为0
在事件处理器组_eventHandlers处理过事件后,场景漫游器_cameraManipulator将再次考察同一事件,TrackballManipulator等漫游器就在这个时候进行场景的平移、旋转和缩放动作。因此,不要设置鼠标键盘事件的handle函数为true,以免屏蔽掉漫游器对这些事件的处理
下面说了eventTraversal()函数中,使用事件回调和更新回调的调用时机,我觉得似乎有问题。因为事件回调确实是,但是更新回调应该是再updateTraversal(),后面第十天的内容也说了这点。
对于场景图形中的任何节点,以及Geode叶节点所包含的任何Drawable几何体,都可以是用setEventCallback和setUpdateCalback来设置它的事件回调和更新回调对象。这些回调对象必须继承自osg::NodeCallback,并重写NodeCallback::operator()函数以实现回调的具体内容。
其中,Drawable对象的事件回调必须继承自Drawable::EventCallback,并重载EventCallback::event函数的内容,用_eventVisitor访问器遍历场景的节点和几何体对象。
更新函数继承Drawable::UpdateCallback,并重载UpdateCallback::update(),用_updateVisitor负责更新遍历。
为了正确遍历场景的节点和几何体对象,并执行所有可能的事件回调和更新回调,osg使用访问器(visitor)机制来处理场景图形的访问工作。其中,_eventVisitor就是负责管理事件回调的遍历工作。这个值会自动初始化
也可以用ViewrerBase::SetEventVisitor加载我们自定义的事件访问器,前提是这个访问器继承自osgGA::EventVisitor类
在事件回调的处理函数中(operator()或者event),可以通过读取第二个传入参数,并调用EventVisitor::getEvents()函数来获取当前的事件,所有的交互和系统事件都会一次又一次地触发事件回调。
上面可以看到对于Node节点,可能有子节点,所以要继续遍历;而drawable已经是绘制节点了,无需遍历。
拉回来,
在遍历场景节点并执行其事件回调后,osg还要转至主摄像机_camera和从摄像机_slaves,再次执行它们的事件回调对象。依次使用访问器,到那时设置访问器不要向下遍历节点,(因为camera同样可以作为场景中的一个中间节点),在访问过所有摄像机之后再恢复访问器的原有值。
事件回调结束了,下一步调试更新回调