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

那我们就开始处理这些事件中得到的所有的交互事件,首先我们要判断这些事件是否包含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 inti=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 inti=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类生物---呼吸分解之事件循环三的更多相关文章
- 探索未知种族之osg类生物---呼吸分解之事件循环一
		事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateC ... 
- 探索未知种族之osg类生物---呼吸分解之事件循环二
		VPM矩阵 1.V 表示摄像机的观察矩阵(View Matrix),它的作用是把对象从世界坐标系变换到摄像机坐标系.因此,对于世界坐标系下的坐标值 worldCoord(x0, y0, z0),如果希 ... 
- 探索未知种族之osg类生物---呼吸分解之更新循环三
		补充 当然细心的你会发现,_scene->updateSceneGraph(*_updateVisitor)中还有一个imagePager::UpdateSceneGraph()还没有进行讲解, ... 
- 探索未知种族之osg类生物---呼吸分解之更新循环一
		上节总结 前几天我们大体上介绍完成了osg的事件循环的介绍,总结一下osg的时间循环主要就是得到平台(windows)的所有消息,并遍历所有的node的eventCallback,并对他们进行处理.接 ... 
- 探索未知种族之osg类生物---呼吸分解之更新循环二
		_scene->updateSceneGraph(*_updateVisitor); 我们用了前面4节才刚刚算是完成对DatabasePager::DatabaseThread::run()函数 ... 
- 探索未知种族之osg类生物---呼吸分解之渲染遍历二
		那么今天我们就正式进入osg整个呼吸动作之中最复杂的一个动作,ViewerBase::renderingTraversals(),我们先介绍renderingTraversals的开头的简单的几步操作 ... 
- 探索未知种族之osg类生物---呼吸分解之advance
		回顾 我们用了两节的内容才堪堪讲解完ViewerBase::frame()函数中调用的realize()---Viewer:: realize()函数.我们简单的总结就是Viewer:: realiz ... 
- 探索未知种族之osg类生物---呼吸分解之渲染遍历一
		总结 前面我们基本上已经完成对ViewerBase::frame()函数的探究,只剩下renderingTraversals()渲染遍历的探究,虽然就剩下了一个函数,但是这却是最重要的,不可少的一个步 ... 
- 《探索未知种族之osg类生物》目录
		精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ... 
随机推荐
- spring boot 项目配置字符编码
- JSTL标签不起作用的解决办法
			JSP页面中的EL标签直接成字符串输出(如:${user.id}),说明el标签没有被识别,造成的原因有: 1.jdk+jstl的组合不匹配 2.web.xml版本不匹配 但我们解决以上这个问题时,先 ... 
- 最小生成树二·Kruscal算法
			描述 随着小Hi拥有城市数目的增加,在之间所使用的Prim算法已经无法继续使用了——但是幸运的是,经过计算机的分析,小Hi已经筛选出了一些比较适合建造道路的路线,这个数量并没有特别的大. 所以问题变成 ... 
- 税控服务器   TC5002UpdatePackage 安装更新
			Linux版税控服务器单税号版本税控应用: TC5002UpdatePackage2008160711.zip 单税号服务器(型号:TCG-01S1) Linux版税控服务器20个 ... 
- Centos7永久修改hostname
			hostnamectl set-hostname hdp-01 centos7中除了修改hosts文件和network文件后,还需修改etc/hostname文件,具体步骤如下 第一步:修改/etc/ ... 
- metasploitable使用
			DVWA默认的用户有5个,用户名密码如下(一个足以): admin/password gordonb/abc123 1337/charley pablo/letmein smithy/password 
- veil-catapult
			veil-catapult进行payload投放,直接使payload在内存中执行. kaliIP:192.168.1.119 目标IP:192.168.1.121 1.powershell powe ... 
- Java 面向切面 AOP
			参考: :http://www.blogjava.net/supercrsky/articles/174368.html AOP: Aspect Oriented Programming 即面向切面编 ... 
- AdminLTE 侧边栏收缩时触发的事件
			点击此处,会触发 expanded.pushMenu 或 collapsed.pushMenu 事件 如果需要在事件触发时编写相关逻辑,可用如下方式 $("body").on(&q ... 
- Lattice Constants and Crystal Structures of some Semiconductors
			Lattice Constants and Crystal Structures of some Semiconductors and Other Materials Element or Compo ... 
