那我们就开始处理这些事件中得到的所有的交互事件,首先我们要判断这些事件是否包含osg的退出事件,那什么情况下会触发这个退出事件呢?如果您运行过osg中example中的小例子的,聪明的你一定就会发现当按下esc时就会退出osg。所以osg中默认的退出事件就是由esc触发的。当然我们也可以通过ViewerBase::setQuitEventSetsDone 设置是否允许按下某个键之后直接退出这种做法, 同时还可以使用另一个函数 ViewerBase::setKeyEventSetsDone 来设置自定义的退出键。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
_eventVisitor->setFrameStamp(getFrameStamp());
        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
 
        for(osgGA::EventQueue::Events::iterator itr = events.begin();
            itr != events.end();
            ++itr)
        {
            osgGA::GUIEventAdapter* event = (*itr)->asGUIEventAdapter();
            if (!event) continue;
 
            _eventVisitor->reset();
            _eventVisitor->addEvent( event );
 
            getSceneData()->accept(*_eventVisitor);
 
            // Do EventTraversal for slaves with their own subgraph
            for(unsigned int i=0; i<getNumSlaves(); ++i)
            {
                osg::View::Slave& slave = getSlave(i);
                osg::Camera* camera = slave._camera.get();
                if(camera && !slave._useMastersSceneData)
                {
                    camera->accept(*_eventVisitor);
                }
            }
 
 
            // call any camera event callbacks, but only traverse that callback, don't traverse its subgraph
            // leave that to the scene update traversal.
            osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
            _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
 
            if (_camera.valid() && _camera->getEventCallback()) _camera->accept(*_eventVisitor);
 
            for(unsigned int i=0; i<getNumSlaves(); ++i)
            {
                osg::View::Slave& slave = getSlave(i);
                osg::Camera* camera = slave._camera.get();
                if (camera && slave._useMastersSceneData && camera->getEventCallback())
                {
                    camera->accept(*_eventVisitor);
                }
            }
 
            _eventVisitor->setTraversalMode(tm);
 
        }

我们还是先来看一下其中一些新认识的成员。_eventVisitor:, 为了正确地遍历场景的节点和几何体对象,并执行所有可能的事件回调和更新回调, OSG 使用访问器(Visitor)机制来处理场景图形的访问工作。这其中,_eventVisitor 就是负 责管理事件回调的遍历工作的。在事件循环中主要是的访问器主要是通过setEventCallback来设置Drawable对象中的事件回调的。在事件回调的处理函数中(operator()或者 event),我们可以通过读取第二个传入参数, 并调用 EventVisitor::getEvents 函数来获取当前发生的事件。所有的交互和系统事件都会一次 又一次地触发事件回调,因此编写这个回调的内容时请一定要慎重,不然会大幅度地降低系 统的性能。

那我们回到osgViewer::eventTraversal函数中,首先我们需要设置当前的处于那一帧中,并进行统计,下一步就是我们要遍历所有事件队列中的事件,并放到eventVisitor中。,OSG 还要转至主摄像机_camera 和从摄像机组 _slaves,再次执行它们的事件回调对象,依然使用访问器,但是设置访问器不要向下遍历节点(因为 Camera 同样可以作为场景 的一个中间节点),在访问过所有摄像机之后再恢复访问器的原有值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for(osgGA::EventQueue::Events::iterator itr = events.begin();
        itr != events.end();
        ++itr)
    {
        osgGA::Event* event = itr->get();
        for(EventHandlers::iterator hitr = _eventHandlers.begin();
            hitr != _eventHandlers.end();
            ++hitr)
        {
            (*hitr)->handle( event, 0, _eventVisitor.get());
        }
 
    }
 
    for(osgGA::EventQueue::Events::iterator itr = events.begin();
        itr != events.end();
        ++itr)
    {
        osgGA::Event* event = itr->get();
        if (event && _cameraManipulator.valid())
        {
            _cameraManipulator->handle( event, 0, _eventVisitor.get());
        }
    }

然后在遍历场景节点并执行其事件回调之后,在遍历所有的相机操作中的handler函数。这样就基本完成了事件循环的遍历。最后,计算事件遍历的结束时间,将相关的时刻信息保存到记录器中。

原文链接  http://www.3wwang.cn/blog/article.ftl?id=20

探索未知种族之osg类生物---呼吸分解之事件循环三的更多相关文章

  1. 探索未知种族之osg类生物---呼吸分解之事件循环一

    事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateC ...

  2. 探索未知种族之osg类生物---呼吸分解之事件循环二

    VPM矩阵 1.V 表示摄像机的观察矩阵(View Matrix),它的作用是把对象从世界坐标系变换到摄像机坐标系.因此,对于世界坐标系下的坐标值 worldCoord(x0, y0, z0),如果希 ...

  3. 探索未知种族之osg类生物---呼吸分解之更新循环三

    补充 当然细心的你会发现,_scene->updateSceneGraph(*_updateVisitor)中还有一个imagePager::UpdateSceneGraph()还没有进行讲解, ...

  4. 探索未知种族之osg类生物---呼吸分解之更新循环一

    上节总结 前几天我们大体上介绍完成了osg的事件循环的介绍,总结一下osg的时间循环主要就是得到平台(windows)的所有消息,并遍历所有的node的eventCallback,并对他们进行处理.接 ...

  5. 探索未知种族之osg类生物---呼吸分解之更新循环二

    _scene->updateSceneGraph(*_updateVisitor); 我们用了前面4节才刚刚算是完成对DatabasePager::DatabaseThread::run()函数 ...

  6. 探索未知种族之osg类生物---呼吸分解之渲染遍历二

    那么今天我们就正式进入osg整个呼吸动作之中最复杂的一个动作,ViewerBase::renderingTraversals(),我们先介绍renderingTraversals的开头的简单的几步操作 ...

  7. 探索未知种族之osg类生物---呼吸分解之advance

    回顾 我们用了两节的内容才堪堪讲解完ViewerBase::frame()函数中调用的realize()---Viewer:: realize()函数.我们简单的总结就是Viewer:: realiz ...

  8. 探索未知种族之osg类生物---呼吸分解之渲染遍历一

    总结 前面我们基本上已经完成对ViewerBase::frame()函数的探究,只剩下renderingTraversals()渲染遍历的探究,虽然就剩下了一个函数,但是这却是最重要的,不可少的一个步 ...

  9. 《探索未知种族之osg类生物》目录

    精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...

随机推荐

  1. Illegal access: this web application instance has been stopped already. could not load **

    启动tomcat的时候会报这样的错误: Illegal access: this web application instance has been stopped already.  could n ...

  2. vue-router,vuex

    vue设置路由为了服务器渲染今天换另一种方式首先在文件夹中router建立router和routes两个js文件,router用来设置路由,routes用来建立路由代码如下: router: impo ...

  3. Sql中EXISTS与IN的使用及效率

    in 和exists 对于以上两种查询条件,in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询. 一直以来认为exists 比in 效率高 ...

  4. Requests库的文档高级用法

    高级用法 本篇文档涵盖了 Requests 的一些高级特性. 会话对象 会话对象让你能够跨请求保持某些参数.它也会在同一个 Session 实例发出的所有请求之间保持 cookie, 期间使用 url ...

  5. ubuntu下mysql源码编译安装

    建议:cpu4核以上,内存4G以上 1. 安装环境:Ubuntu Server 14.10MySQL-5.6.23.tar.gz 2. 安装必备的工具sudo apt-get install make ...

  6. 04_web基础(二)之web构建

    03.04.05.06web项目创建 07.第一个Servlet程序 1.拷贝tomcat 中的 servlet-api.jar 在lib包下面 2.新建一个HelloWordServlet类并实现 ...

  7. Gimbal Lock

    [Gimbal Lock] 万向锁源于欧拉角的是有序处理的.U3D中的序列为: y->x->z.当旋转y时,local坐标系与世界坐标系重合,所以y等于永远按惯性坐标旋转.当x旋转+/-9 ...

  8. 使用git或TortoiseGit推送项目至gitlab

    一.Wins安装Git+Trtoisegit工具实现版本克隆与推送 Git:         https://git-scm.com/ Tortoisegit: https://tortoisegit ...

  9. C# 写App.config配置文件的方法

    private static void AccessAppSettings() { //获取Configuration对象 Configuration config = ConfigurationMa ...

  10. GIT 命令集

    Git图形化界面 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下. Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remot ...