原文地址:ogre的场景管理器作者:zhouwenjie

在通常的情况下,Ogre的场景管理器会负责处理以下事情:

·在场景中创建和放置活动物体、灯光以及摄像机,并维护他们的在场景图中的周游和变换。

·载入和布置世界地图(World geometry,与活动实体不同,世界地图是巨大且可以延伸的,通常情况下是不可移动的,比如一个完整的BSP地图)。

·对场景查询(Scene Queries)的支持,比如回答“在世界的某个原型空间内,都包含了那些物体”。

·剔除不可见物体并且将可见物体放入渲染队列。

·根据当前和渲染物体的透视图,对无方向的光源(Nondirectional Light)进行组织和排序(按由近到远)。

·设置并且渲染场景中的阴影。

·渲染场景中的其他物体,如背景和天空盒

·发送组织好的内容到渲染系统执行渲染

场景管理器类型

在Ogre的论坛中经常有人问这样一个问题“我们已经有了场景管理器可以使用了,为什么还要有‘场景类型’概念呢?”这里可以简单的回答一下这个问题:因为Ogre中所使用的场景管理器事实上是以插件的形式提供的,这就代表着在同一个程序中可能存在着多个场景管理器。如果你是这样一个游戏,既有室内的密集空间,又有室外的稀疏场景。这时候你可能需要为每一种世界地图使用不同的场景管理器来进行具体的管理(不同的管理算法适用于不同的情况,后面将会具体介绍)。

每个场景管理器插件都会向Ogre系统注册一个用来产生管理器的工厂实例,并且同时注册一个代表场景管理器的创建类型的字符串ID到系统中。作为历史遗留的原因,为了兼容早期版本的使用方法,插件也同时向系统注册了一个代表它自己的掩码ID(mask identifying)。

注意:如果你是从当前版本才开始接触Ogre的使用者,你可以跳过这个段落继续阅读。但如果你有使用早期版本Ogre的经验,你就要注意这里的问题:从Ogre1.2(Dagon)版本之后(也就是本书所介绍的版本)。多场景管理器能支持场景管理器把自己的类型注册为字符串ID(比如“OctreeSceneManager”或“TerrainSceneManager”)。这样你就可以使用迭代的方法在管理器中找到自己所需要的具体实现,亦或者可以简单的使用最后一个被注册进来的管理器类型。不同于之前Ogre版本中使用枚举类型作为索引(如TR_INTERIOR或者ST_EXTERIOR_CLOSE),使用这种方式注册和索引可以让用户摆脱只能使用固定数量场景管理器类型的限制。不过当前Ogre仍然可以对以前的使用方法兼容,所以就算你仍然坚持使用以前的方法,也不会有什么问题。

你可以自己创建一个场景管理器实例,并为它提供一个名字(也可以让Ogre帮你分配)。不过通常情况下,你需要在代码中保存一个指向场景管理器的指针,因为在大多数情况下只有一个场景管理器名字可能不怎么够用。

Ogre自身提供两个场景管理器类型:OctreeSceneManager和TerrainSceneManager。OctreeSceneManager是一个通用的场景管理器。TerrainSceneManager是一个为高度场场景优化的场景管理器,我们将在之后的章节中具体的了解它们相应的细节。

对于程序的开发者而言,场景管理器的直接用途一般是用来创建场景中所使用的对象,比如:灯光、摄影机、实体、粒子系统以及公告栏这些活动物体,以及天空盒、静态几何体和世界地图(World geometry)这些非活动物体。对于场景中存在的物体,不论是否能被渲染,都会交给场景管理器进行具体的管理工作。这样做的好处就是场景管理器可以根据自己的需要对物体进行相应的优化处理(例如,可以在你场景管理器的具体实现里面对摄像机进行有针对性的优化工作)。注意,这里的“管理”指的是对场景中物体整个生命周期的管理:提供了创建、获得、销毁以及销毁本类型全部实例的方法。任何从场景管理器得到的对象必须由同一个场景管理器销毁:换句话说,不可以直接“删除”任何有场景管理器创建返回给你的指针所指对象。当你需要释放和清空整个场景的时候,必须让相应的场景管理器自己来做(也可以让Ogre的Root对象在关闭的时候自动得帮你调用相应的方法)。

场景节点

场景管理器用场景节点来定义场景图的结构。这些场景节点以层次的结构组织在场景管理器中:一个场景节点可以有一个父节点和任意数量的子节点。你可以对场景管理器中的节点进行绑定或者摘除操作;这里提供一个简单的办法来关闭场景中的某个部分:只要把不希望渲染部分的根节点从场景图中摘除下来,这个部分就不会被渲染了。场景节点必须通过创建它们的场景管理器来销毁。

小心:虽然这么做不会导致Ogre系统崩溃,不过当你删除了还有内容或者数据挂接在上面的场景节点的时候,还是需要人为来保证这个被挂接的对象不会导致内存泄漏。尽管你可以根据你自己的需要随意管理所需的节点的生命期,不过同时也许要你对这些“脆弱”的场景节点行使谨慎而严密的相关处理。

在场景管理器创建的时候,会给整个场景提供一个总的父节点:场景的根节点(Root Scene Node)——场景中唯一没有父节点的场景节点。根节点的概念对整个场景图至关重要,所以用户无权销毁它。对于场景图来说,根节点的显式作用可以用来挂接所有场景中存在的其他节点;隐式作用是场景图用它来挂接静态物体和整个世界地图。尽管你可以移动根节点,但尽量不要这么做,因为大多数时候都需要保持根节点的稳定性。

场景中新建立的节点必须作为子节点挂接在已经存在的节点上面。这就意味着,第一个放入场景的节点,必须挂到根节点上面,然后再不断挂接扩充,直至形成一个你所需要的场景树状结构图。图5-1中展示了经过几次挂接后场景图的层次结构。

场景中新建立的节点必须作为子节点挂接在已经存在的节点上面。这就意味着,第一个放入场景的节点,必须挂到根节点上面,然后再不断挂接扩充,直至形成一个你所需要的场景树状结构图。图5-1中展示了经过几次挂接后场景图的层次结构。

在你创建了一个场景节点之后,场景管理器不会往上面挂接任何内容。当你需要的时候,应该自己创建内容并向需要操作的节点挂接。不过并没有要求场景中存在的节点一定要有绑定内容在上面,你可以挂接一个空节点,并可以根据需要时随时挂接内容到它上面。单独的节点上面并没有限制帮定内容的数量。你可以把所有内容对象都帮定到一个节点上面,不过这也就意味着无法单独的移动它们(如同连体婴一般)。

就像我们之前所说,场景内容独立于场景节点。你可以把场景内容从场景节点中分离出来,这样的操作并不会引起场景内容的销毁或者删除。但还是不能把一个场景内容同时挂接到两个以及两个以上的场景节点上面,也不能让一个场景节点同时挂接到两个父节点上面,这些操作都会引起Ogre的内部异常。

在这里你必须了解:在场景图中有三个重要的空间操作(移动、旋转、缩放),它们的操作目标都是场景节点,而不是场景内容。换句话说,用户操作场景节点,场景内容跟随着所挂接节点一同移动、旋转和缩放。

场景查询

场景管理起另外一个很重要的功用就是用来进行空间场景查询(从场景中得到查询的反馈信息),其中包括:光线查询(Ray Queries)、球体查询(Sphere Queries)、边界盒查询(Bounding-Box Queries)、边界平面查询(Bounding-Plane Queries)以及相交查询(Intersection Queries)。其中光线查询返回与给定光线(空间中两点组成的虚拟线)相交的物体信息;球体查询返回给定球体(通过球中点和半径确定的空间区域)中所有包含的物体信息;边界盒查询返回给定轴向包围盒(通过两个三维向量作为对角点产生的与空间轴平行的长方体空间)中所包含的物体信息;边界平面查询返回与给定的无限延伸的平面相交物体的信息;相交查询返回与指定物体相交的所有物体信息。

这些查询的结果都是随着场景变化而变动的,所以当你要解决类似地形跟随关卡的时候,就需要在每一帧对地图执行相关的查询操作。

提示:地形跟随的概念指的是在某些场景中需要某个对象与世界地图(通常是室外场景)保持一个固定距离(通常是零)。要实现这种动作需要知道所在地形的垂直高度,简单的作法是利用一条射线(光线检测)射向地面,得到与世界片段的交点。然后通过与世界的相对高度来设置对象的高度。这是一个很普遍的技术。(举一个简单的例子:在《三角洲特种部队》中,士兵作为场景中的物体,在移动时脚一定要和起伏的地面接触,也就是要让人物和地图保持一定的距离。)

这里所提到的所有查询过程都已经进行了很好的优化(比如采用轴向包围盒的原因,就是因为它比一般的包围盒可以使用更少的计算量)。所有的查询过程都是可进行屏蔽操作的(Maskable),这意味着你可以通过这个功能过滤到你不需要的对象。据个例子来说,你需要得到一个给定球体空间内所有的物体,但是不需要里面的地形信息。你就可以在执行前通过设置屏蔽信息来过滤掉地形片段的返回。

ogre的场景管理器相关推荐

  1. Ogre 场景管理器

    转自:http://blog.sina.com.cn/s/blog_694aab1b0100rdvm.html 在通常的情况下,Ogre的场景管理器会负责处理以下事情: ·在场景中创建和放置活动物体. ...

  2. 转:OGRE场景管理器介绍

    一个场景代表在虚拟世界中显示的物品.场景可以包括静态几何体(比如地形或者室内),模型(比如树.椅子等),光和摄像机.场景有下面种类.室内场景:可能由走廊.有家具的屋子和挂着装饰品的墙组成.室外场景:可 ...

  3. Laya:场景管理器。

    在Laya中打开新场景时,使用Laya.Scene.open方法即可.但直接这样使用会有一个问题:如果在场景A中挂在了一个脚本,且在Update里执行了某个方法,当打开新场景B时,场景A里的Updat ...

  4. gaia引擎分析(二)场景管理

    只是粗略的分析原理,大虾轻喷~~ Gaia引擎中没有场景管理器(scenemanager)这种东西,但是并不是没有场景管理,而是在cGameHost类中有一课场景树进行场景组织.一棵四叉树用来进行剪裁 ...

  5. 队列管理器连接数设置_详解!基于Redis解决业务场景中延迟队列的应用实践,你不得不服啊...

    一.业务概述 我们假定设置两个队列,一个队列维护正式工单,另一个队列维护挂起工单.对于挂起操作,我们通过Redis设置key有效时间,当key失效时,客户端监听失效事件,获取工单,实现 挂起工单队列的 ...

  6. 【Unity2D好项目分享】用全是好活制作横版卷轴射击游戏④制作敌人管理器以及播数显示和音效以及场景加载器

    学习目标: 可能有人看到我前面截图的场景中并没有将设置为预设体的Enemy01-03拖入场景中,场景却能持续不断的生成敌人,因为制作了敌人管理器,确保敌人能够一直生成.今天研究一下怎么创建敌人管理器. ...

  7. 码农技术炒股之路——数据库管理器、正则表达式管理器

    我选用的数据库是Mysql.选用它是因为其可以满足我的需求,而且资料多.因为作为第三方工具,难免有一些配置问题.所以本文也会讲解一些和Mysql配置及开发相关的问题.(转载请指明出于breaksoft ...

  8. python笔记2(函数 面向对象 文件编程 上下文管理器)

    记录python听课笔记 文章目录 记录python听课笔记 一,函数 1.介绍python里的函数 2.用户自定义函数 3.变量的作用域 4.参数的传递 5.参数的默认值 6.向函数内部批量传递数据 ...

  9. oracle如何进入管理器,oracle 启动管理器

    oracle 启动管理器 emctl start dbconsole 是10g的启动console服务的命令 将OEM服务停止emctl stop dbconsole emctl start dbco ...

最新文章

  1. Leetcode剑指 Offer II 024. 反转链表
  2. idea设置scanner = new Scanner(System.in);的实时模板
  3. Entity Framework Core 执行SQL语句和存储过程
  4. win下php的memcached的安装与使用
  5. Python运算符含义汇总
  6. 浏览器对象模型(Browser Object Model)
  7. 学习成果区块链问世,中科宇创为人才能力认证提供权威账本
  8. 普元eos如何在日志文件中打印SQL语句及参数
  9. Web基础配置篇(十三): ELK集群搭建
  10. 教师资格证综合素质作文素材
  11. Java到底能干什么?有哪些实际用途?
  12. 请在微信客户端中打开链接是什么鬼 ?
  13. P4199-FFT,manacher
  14. 手披云雾开鸿蒙,描写泰山的诗句不是整首诗、注明作者
  15. 使用Arduino开发ESP32(18):使用Preferences保存数据
  16. Codeforces Round #476 (Div. 2) 题解
  17. 苹果手机通话声音小怎么调_通话音量小怎么办?教你安卓和苹果的解决教程,只需2步...
  18. 2020北京邮电大学计算机学院复试经验分享
  19. 专利申请要准备哪些资料
  20. java long型时间_long类型转换成日期

热门文章

  1. vue循环生成元素_Vue循环中多个input绑定指定v-model实例
  2. MyBatis数据持久化(十一)Mybatis3、Spring4、Struts2整合开发
  3. 机械设计基础 第6版六版 杨可桢 课后习题答案加考研重点
  4. 基于java网上童装销售系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  5. 微信小程序底部菜单、购物车实现
  6. 大数据企业应用格局:三足鼎立却又共陷迷城
  7. 脱机使用计算机是什么意思,脱机使用打印机是什么意思?
  8. 用文字总结出计算机组装步骤,电脑技术的实结
  9. sql与nosql异同点
  10. 【转载】关于音乐的流派,分类问题