第五章 Ogre场景管理器
在这里我可以大胆的断言,目前在地球上,所有的图形引擎都在使用场景图(Scene Graph)的概念来组织管理它里面可渲染的物体(我甚至怀疑外星人也在用这个)。 场景图在图形引擎中的地位是毋庸置疑的,它不仅提供了对用户在空间中查找和搜索物体提供了高速的优化,并且针对程序库(对我们而言就是Ogre)的渲染需要,提供了相应的搜索、排序以及剔除功能。在某些时候也被用来进行碰撞检测。在一些具体的设计里面,场景图甚至可以被所有子系统使用,比如声音和物理系统都可能依赖场景图来实现相应的功能。
在管理场景中的对象以及几何体的管理功能方面,Ogre中的场景图与其他的引擎实现的功能没有什么本质的区别。不过Ogre并没有使用“一个”场景图,通过引擎所使用的插件机制,Ogre通常会使用一些外部“插入”的场景图算法来使用。Ogre中提供的SceneManager类只不过是场景图的接口,你可以通过它来调用Ogre本身提供的几个不同的场景图算法,也可以在网上找到一些Ogre场景算法的其他实现,其中包括商用的内存分页场景管理器(Paging Scene Manager——http://tuan.kuranes.free.fr/Ogre.html),以及商用收费/非商用免费的场景管理器,比如oFusion(http://ofusion.inocentric.com)。
如果你在之前已经对一些完整的游戏引擎有一些了解,比如Torque、虚幻(Unreal)或者CryENGINE这些商业游戏引擎,亦或者使用过某些图形渲染库,比如Irrlicht3D、TrueVision3D或者Blitz3D。可能在你潜意识里,就会已经认为场景图里面一定应该有一个复杂的继承体系来实现所需相应的功能,所有物体都应该继承于一个“场景节点”基类。不过如果真的这样做了的话(确实大部分其他的引擎,这样做了),你就会发当你要在场景图中扩展处理其他类型的数据时(比如声音或者物理内容),这种设计的笨拙和固化就会暴露出来。
就像在这本书前面第三章中所讲的,Ogre从核心设计之初就已经将场景结构(场景图)和场景内容完全分离,把场景图的结构和它所使用的数据节点作为平等的继承体系来使用。这种灵活且强大的设计理念,使得多种场景图的管理方式(比如BSP、八叉树或者KD-Tree)可以灵活的替换,而不会影响具体的场景内容的实现。换句话说,Ogre在场景图的领域,打破了传统,有了崭新的突破。
Ogre在场景图中还有另外一项即将实现的设计(计划在1.6X之后的版本实现):可以在同一时间内在程序中同时使用多个场景管理器。我在这里大胆的预言,这种特性将在以后的几年内将会成为热门的话题。不过不论在你的程序中是否准备同时使用多个场景管理器,你都会遇到“入口(Portalling)”问题。可以简单的理解“入口”就是两个场景区间的分界线(比如当你从一个关卡的室内场景中看到了室外场景中的一部分,那么这个窗子就成为了所谓的“入口”)。不论在什么时候,管理“入口”都是一件复杂且麻烦得让人头痛的问题。不过对于Ogre而言,对“入口” 管理的责任已经交给了每个单独的场景管理器自身,引擎的使用者已经幸运的摆脱了这个问题。只有当你希望设计自己独有的场景管理器的时候才真正的涉及到“入口”管理,不过这是图形学中更高级的话题,这本书的目的不是讨论这个。如果你真的需要,可以网上看一看相关的文章。
场景管理器
在通常的情况下,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:在场景图中挂接6个场景节点过程中的不同状态,从空场景(a)一直到过程结束(f)
在你创建了一个场景节点之后,场景管理器不会往上面挂接任何内容。当你需要的时候,应该自己创建内容并向需要操作的节点挂接。不过并没有要求场景中存在的节点一定要有绑定内容在上面,你可以挂接一个空节点,并可以根据需要时随时挂接内容到它上面。单独的节点上面并没有限制帮定内容的数量。你可以把所有内容对象都帮定到一个节点上面,不过这也就意味着无法单独的移动它们(如同连体婴一般)。
就像我们之前所说,场景内容独立于场景节点。你可以把场景内容从场景节点中分离出来,这样的操作并不会引起场景内容的销毁或者删除。但还是不能把一个场景内容同时挂接到两个以及两个以上的场景节点上面,也不能让一个场景节点同时挂接到两个父节点上面,这些操作都会引起Ogre的内部异常。
在这里你必须了解:在场景图中有三个重要的空间操作(移动、旋转、缩放),它们的操作目标都是场景节点,而不是场景内容。换句话说,用户操作场景节点,场景内容跟随着所挂接节点一同移动、旋转和缩放。
场景查询
场景管理起另外一个很重要的功用就是用来进行空间场景查询(从场景中得到查询的反馈信息),其中包括:光线查询(Ray Queries)、球体查询(Sphere Queries)、边界盒查询(Bounding-Box Queries)、边界平面查询(Bounding-Plane Queries)以及相交查询(Intersection Queries)。其中光线查询返回与给定光线(空间中两点组成的虚拟线)相交的物体信息;球体查询返回给定球体(通过球中点和半径确定的空间区域)中所有包含的物体信息;边界盒查询返回给定轴向包围盒(通过两个三维向量作为对角点产生的与空间轴平行的长方体空间)中所包含的物体信息;边界平面查询返回与给定的无限延伸的平面相交物体的信息;相交查询返回与指定物体相交的所有物体信息。
这些查询的结果都是随着场景变化而变动的,所以当你要解决类似地形跟随关卡的时候,就需要在每一帧对地图执行相关的查询操作。
提示:地形跟随的概念指的是在某些场景中需要某个对象与世界地图(通常是室外场景)保持一个固定距离(通常是零)。要实现这种动作需要知道所在地形的垂直高度,简单的作法是利用一条射线(光线检测)射向地面,得到与世界片段的交点。然后通过与世界的相对高度来设置对象的高度。这是一个很普遍的技术。(举一个简单的例子:在《三角洲特种部队》中,士兵作为场景中的物体,在移动时脚一定要和起伏的地面接触,也就是要让人物和地图保持一定的距离。)
这里所提到的所有查询过程都已经进行了很好的优化(比如采用轴向包围盒的原因,就是因为它比一般的包围盒可以使用更少的计算量)。所有的查询过程都是可进行屏蔽操作的(Maskable),这意味着你可以通过这个功能过滤到你不需要的对象。据个例子来说,你需要得到一个给定球体空间内所有的物体,但是不需要里面的地形信息。你就可以在执行前通过设置屏蔽信息来过滤掉地形片段的返回。
空间关系和3D变换
对很多刚开始接触3D应用程序开发的人来说,很难搞清楚场景节点和场景内容的关系,甚至对场景节点之间的关系也很模糊。为了帮助大家更好的理解这些概念,在这里让我们来看一些3D实际操作的例子。
空间变换(Spatial Transforms)
如果能回忆起以前学过的3D数学知识(比如线性代数),你就会想起来,任何3D空间的位置、方向以及缩放都能被表现为一个4*4矩阵的形式。换句话说,空间的任何关系都可以被定义为“一组给定的坐标集合”。
因此,空间变换运算总是会参考所给定的坐标系统。而最常使用的坐标系统空间(同时也是Ogre程序所能提供的)即是世界空间(World)、父节点空间(Parent)以及本地空间(Local)。
那什么是世界空间呢?世界就是物体(模型)所存在的地方。当我们把一个模型放进世界里面去,那么它就有了一个世界坐标,这个世界坐标是用来标记世界中不同的模型所处的位置的。在世界空间里,世界的中心就是原点(0, 0, 0)。而在Ogre中,这个点也当于场景根节点的位置,所以世界空间在Ogre中也可以理解为“相对于场景根节点”。世界空间也意味着是使用全局的X,Y,Z坐标。
父节点空间变换是相对于一个节点的父节点,也就是把父节点的坐标作为变换空间的矩阵原点。本地空间变换是相对于对象绑定的节点本身。大多数情况下,物体的移动是在父空间里面进行,旋转和缩放是在本体空间里面做,这也是Ogre中所默认的操作方式。
然而,你可能不是很擅长处理三维空间中的矩阵变换,这时候需要用更简单清晰的方法来操纵场景图之中的物体。幸运的是,Ogre里面提供了简单的移动、旋转和缩放的方法,Ogre亲自来帮你处理那些丑陋而复杂的矩阵变换实现。不过你仍然希望了解当前物体位置、旋转以及缩放的矩阵的话,Ogre也能很好的提供给你,甚至可以选择从三种空间中参考任意一个坐标系来提供相应的矩阵。
物体空间(Object Space)
如果你创建了一个物体(不论是通过3D模型工具产生还是手动构造),物体的顶点都会被放置在世界空间中。我们在这里举个例子:我们在这里是用3DS Max工具来进行模型的制作,在编辑场景的原点(0,0,0)建立一个边长为1的立方体,这样他的顶点都在类似(0.5,0.5,0.5)的范围内。参考图5-2,当Ogre载入了这个物体之后,所有顶点的位置仍然何在3DS Max编辑空间内相同。
注意:在某些时候,可能“物体空间”的意义会等同于“本地空间”;不过在本书的这个章节里,物体空间的概念专指“相对于物体本身的坐标系”。

图5-2:单位立方体相对于物体空间的顶点位置
当物体被挂接到场景节点上的时候,这个场景节点上的世界空间转换矩阵就会应用到这个物体上面的所有顶点上,从而把物体转换到世界空间的绝对位置,这也是确定物体在3D空间位置、缩放以及方向的原理。事实上这些转换并不是直接施加在物体顶点上面的,所以这些操作也不会影响物体上面所顶点到所挂接场景节点位置的距离。

图5-3: 不管场景节点如何移动,立方体相对于场景节点的位置不会改变
在上图的(a)中,场景节点(立方体中心的实心黑圈)在世界坐标的原点(0,0,0)处。而在(b)部分,我们把原点移动到点(10,10,10),同时展示了立方体在世界空间新的顶点位置。
如果你刚刚接触3D图形,并且同时也从Softimage|XSI,Maya,3DSMax或者Blender这些3D工具创建过场景内容,可能会对上面的叙述感到有些混乱,可也能会让你误认为3D工具中所提及的坐标和Ogre中所讲的不一样。但事实并不是这样:一般来说导出的模型的坐标位置会遵守“世界标准单位”(除非3D建模工具和导出插件设定了自己的“度量衡”),这种单位和3D世界中的相同。换句话说,一个在3D工具中设置在点(1,1,1)的顶点,在导出到Ogre系统中,这个顶点相对于它挂接的场景节点的位置仍然是(1,1,1)。举个具体一点的例子,如果你是用Blender工具中制造的怪物头模型,把它放置在工具中点(0,2,0)位置上,那么当他挂接到Ogre场景之后,在它的物体空间中(也就是相对于它所挂接的场景节点)的位置仍然是(0,2,0)。
本地空间
所谓变换(Translation),一般来说指的是某种物体和“别的东西”之间的关系。(在3D节点的场景中,“别的东西”包括父节点或世界原点等等)。但实际上,你也可以通过变换来改变物体和它自身的关系(也就是我们所说的本地空间变换)。例如,你可以让一个物体沿着自身的Z轴正方向旋转一定的角度。
对于物体的旋转和缩放来说,“本地空间”的概念就是绕着自己的轴旋转;相对于自己的中心点进行缩放。图5-4和图5-5中分别展示了本地空间的旋转和缩放。

图5-4: 在本地空间中,一个节点沿着自己的轴旋转。图中的箭头表示旋转的方向

图5-5:在本地空间,一个节点在自己的中心位置进行缩放。图(b)的实心球缩小为原来的体积的1/2,半径变为0.5
虽然在转换的过程中,我们要依赖场景节点进行旋转或者缩放,不过实际上,并没有对场景节点做任何操作,因为节点既不能被看到也不能被渲染出来,所以真正被操作的是节点所挂接物体上面的每个顶点,参考图5-5所示。对场景节点的影响只是让其中的变换矩阵转化成新的状态。比如,偏移(yaw)、倾斜(pitch)以及滚动(roll)的操作都可以改变场景节点自身的旋转矩阵的状态(或者也可以通过四元数或者方向来改变)。
父节点空间(Parent Space)
父节点空间变换就是相对于父节点的变换。图5-6 演示了在父节点空间中进行的变换。

图 5-6:(a)为变换前的父节点与子节点,(b)为变换后子节点变为父节点空间的(-1,-1,-1)
如上图5-6(a)所示,在世界空间内存在父节点(较大实心球)在点(5,5,0)位置上,其子节点(较小实心球)处在其父节点空间(2,-1,0)位置上。在父节点没有旋转的情况下,父空间轴向平行于世界坐标系轴向,这时子节点在世界坐标系的位置,可以简单通过本身在父空间的位置和父节点在世界坐标系位置向累加得到。在图5-6(a)中为世界坐标系点(7,4,0)上。在图5-6(b)中,我们把子节移动到父节点空间坐标系(-1,-1,-1)位置,相应的它所在世界空间的位置也改变到点(6,3,-1)上。
警告:在这里需要搞清楚坐标变换和直接设置位置的区别。变换可以在任何空间体系中使用(不论是世界空间、本体空间还是父节点空间),然而设置一个节点的位置总是在其父空间坐标系里面。另外,坐标变换是累加的:总是在上一次变换的基础上进行变换。而设置位置总是绝对的。
图 5-7展示了一个节点的子节点围绕它旋转效果。在图5-7(b)中父节点已经绕Z轴旋转了45度,首先需要要注意的是,在旋转之后,对其子节点的操作都会受到影响。子节点在父节点空间的移动、旋转以及缩放的参照坐标轴都已经改变,如果这时候把子节点(在父空间)移动向量 (1,0,0),产生的结果是沿着新的父节点空间 “专用” 的X轴移动1个单位,而不是沿着世界坐标系的“公用”的X轴移动。

图 5-7:旋转一个场景节点同时它的子节点也跟着旋转。(b)中,父节点绕着自身Z轴倾斜(父节点在本地空间旋转)
另外一个需要注意的是新的变换对子节点的影响。因为子节点会随着父节点的移动、旋转以及缩放而变换到新的位置。并且同样因为对一个节点的变换会同时作用到它的子节点,并且依次向下传递。所以当一个节点旋转的时候,其所有子节点依次旋转同样的角度,并且这些子节点的子节点也会变换。进而导致这个分支的所有节点都会发生改变。
世界空间(World Space)
虽然世界空间是最简单的空间系统,但从节点层次中提取具体节点位置的时候,世界空间仍然起着极其重要的作用。为了防止对节点进行过多的计算,Ogre在进行每次变换操作的时候将都会将世界空间坐标放入向关节点的缓存。(这极大限度的提高了整个体系的渲染速度。)
世界空间永远平行于全局坐标轴,并且总是使用这些轴向来表示世界空间坐标系。
世界空间对渲染和观察投影(View Projection)操作有非常重要的作用,除非像在世界空间内布置物体这种特殊的操作除外,用户很少直接使用世界空间来进行工作。大部分的场景内节点的操作(比如以动物体),通常是在其他空间内完成。
场景中的活动物体(Movable Scene Object)
活动物体(Movable Object)由场景管理器创建,并且绑定到场景节点上,最后再由场景管理器销毁。因为这些内容独立于场景图,所以可以根据需要随时从场景节点上分离或者挂接,也可以在一个节点上挂接多个活动物体。不过需要注意的是同一时间内一个活动物体只能被挂接到一个场景节点上。
其中可以被渲染的活动动物,比如只包含几何和纹理的模型,在它们里面并不包含或处理具体的场景图信息。而另外不可渲染的活动物体(比如进入场景中的灯光或者摄影机等),虽然并不包含任何几何体或者纹理数据,但是它们仍然有能力简单的绘制自己(例如你可以在需要的时候让一个摄影机在场景中可见)。
以资源为基础的物体(Resource-Based Objects)
在Ogre中有相当多的场景内容是根据磁盘的信息来创建的,在这里把它们称为以资源为基础(也可称为磁盘基础)的活动物体,其中最常见的莫过于模型本身以及相应的骨骼数据。虽然我们可以在场景管理器中直接通过磁盘路径来创建这些模型实体,不过事实上场景管理器并没有负责实际载入工作,它只是帮你调用相应的资源管理器来读入数据,因为这些资源仍然被Ogre的相应的资源管理器(将在第7章了解更多的细节)进行管理。
在一般的时候,你可以直接通过场景管理器来构建模型实体,场景管理器会帮助你把这个过程分解成为详细的步骤,比如通过资源管理器分别载入模型、骨骼以及材质等,并把它们组合起来交给你处理。不过如果有需要,你也可以通过手动的方式来分别载入比如骨骼这种模型相关的信息。(因为骨骼模型其实可以和不同的模型数据搭配,所以有时候可能需要手工载入骨骼来处理相关问题。)
在成功创建了模型实体之后,它并没有被挂接到任何场景节点之上。为了让它进入渲染队列,你还需要进行相应的挂接工作。另外还需要注意的是,当挂接之后,模型被创建到所挂接节点的本地空间,而不是世界空间。
提示:虽然可能这不是什么至关紧要的问题,但是我还是想要在这里顺便提及一下。当你的美工(也许就是你本人),制作3D模型的时候,通常会使用3D模型工具的场景来作为管理模型的基础,而这些场景数据在导出模型时都会被原封不动的导出到Ogre的模型文件中。但是因为很多3D模型工具所使用的坐标系统是Z轴向上,这就与Ogre空间中Y轴向上的坐标系统产生一些小茅盾。为了解决这个问题,大多数Ogre的导出插件都提供了“旋转90度”的设置。
以四边形为基础的物体(Quad-Based Objects)
在活动物体中有很多的以四边形(Quad)为基础的实体,其中包括了粒子系统(Particle System)、公告栏(Billboards)、跟踪轨迹(Ribbon Trail)、表层(Overlay)和天空盒(Skybox,以及相关的天空面Skyplane和穹顶Skydemo)。它们由四边形面片构造,并且没有相关的模型资源。而他们所拥有的资源是包括定义纹理本身和生命周期(粒子系统以及跟踪轨迹会用到)的脚本,通常而言这些四边形为基础的物体都会把带有纹理的一面一直朝向着摄影机方向。在这一章节中我们着重介绍天空盒、天空面以及穹顶;而关于粒子系统和跟踪轨迹的具体细节我们将在之后的第十章进行具体的讨论;表层相关的信息要到第十二章才会有所涉及。
虽然天空面、天空盒和穹顶之间的区别是很让人感兴趣的,不过在这之前我们首先要了解它们的共同之处。其中最大的共同点是它们总是和摄像机保持着固定距离;其次,它们要么是在所有场景物体渲染之前渲染(这也是默认的情况),要么是在所有场景物体渲染之后渲染;虽然他们高高在上,但仍然和所有场景中其他物体是用相同的材质进行渲染,因此天空的纹理和其他的活动纹理并没有本质区别(下一章会着重讲解这些材质相关细节);最后它们都可以通过场景管理器开放或者关闭,也可以重新设置它和摄像机的距离。
天空面(Skyplane)
简单而言,天空面就是一个用来模拟现实世界中天空的一个平面。和Ogre中所有其他的平面一样,通过法线和距离来定在场景中的放置位置。通常而言,它只是一个平面;不过如果你需要,也可以把它当成“弯曲的”平面。场景管理器可以把天空面分解成多个片断,并能控制它的弧度,甚至你也可以亲自通过控制每个顶点来改变天空面的样子。当天空面弯曲的时候,可能很类似穹顶所产生的效果,不过还是需要运用一些云雾的效果来掩饰其中的不足。
穹顶(Skydome)
和使用了一个平面的“天空面”不同,穹顶技术使用了五个平面来构造天空,它是一个拥有一个顶和四个侧面构成的的半盒。换句话说它是一个没有底的盒子,意味着你必须要用世界地图(World geometry)来挡住盒子的底部,也就是类似地平线的效果。不过半盒下部分的纹理因为曲率过大而导致失真,所以地平线的高度应该调整到足够挡住这些问题的地方。系统通过调整纹理的坐标来产生弧度效果,这种弧度是可以被手动调整的。当这个值设置的较低的时候会让天空产生“平坦”的效果(这种状态适合在室外场景中看到“宽广的天空”的效果);较高的设置会产生“陡峭”的弧度(适合在室内场景的关卡中所透过窗口所看到的天空,虽然很小但是可以在任何时候看到全貌)。
天空半盒的每一个面都和摄像机总是保持固定的距离,这个距离可以交给具体应用来配置。不过这里需要注意的是:当你把这个距离设置得太近,可能会看到因天空渲染得太近,导致把场景地图中的一些区域给覆盖了。
与天空面类似,你可以任意的给天空半盒制定所需的纹理,比如你可以通过活动纹理来产生浮云一样的效果。如果想更好的控制这些就需要了解纹理坐标变换的一些高级特性(在本书的下一章节中会详细介绍这些)。
天空盒(Skybox)
首先要注意的是,天空盒并不是简单的在穹顶技术上增加了一个底部平面。而是不同前面所介绍的技术,天空盒并没有“弯曲”纹理坐标的能力,而是使用了标准的UV坐标映射的方法来处理相应纹理,进而只有天空盒才能使用立方体纹理(Cubic Texture)技术来实现天空的细节。与普通的纹理不同,立方体纹理可以“平铺”到整个空间中。
使用天空盒的目的也与穹顶和天空面不同,经常被用于展示摄像机六个方向所有能看到的天空面,而不只是头顶的一部分。另外,如果可能的话,天空盒还能潜在的利用到硬件对立方体纹理的加速功能。
渲染对象(Rendering Objects)
因为英文翻译到中文的关系,有些语义会变得模糊,所以首先要说明一下,这里阐述的渲染对象(Rendering Objects)和之前看到的可渲染物体(Renderable Object)概念不同。渲染对象指的是用来帮助场景图进行渲染功能的对象,而不是被渲染到屏幕的物体。在场景中两个最主要的渲染对象是摄象机和灯光。其中摄像机用来帮助你“拍摄”场景中的物体,而活动的灯光使你的场景显得更立体和真实。
摄象机(Camera)
对于场景中的摄像机来说,最主要的工作就是定义产生一个视截体用来处理渲染工作。更细致一点地说,它是一个包含“眼睛”所能看到所有内容的“盒子”(我们可以简单认为眼睛存在于视截体四条边所汇聚的点上面)。请参看图5-8。

图 5-8: 视平截头体的图形描述
在上面的图5-8中,你可以认为那个奇怪的眼睛就是“你”在场景中所拥有的。其中的近截面定义使用了两个参数:其与眼睛的距离和所拥有的视野(也就是你眼睛所能看到的范围);远截面不仅通过两个参数来定义了它的尺寸,同时还拥有和眼镜(摄像机)距离的参数。通过这两个“截面”进而产生了六个面组成的视截体。
Ogre利用这六面来剔除场景中不可见的物体,换句话说,图形硬件使用它裁减掉“盒子外”一定粒度下的几何图形(多边形的级别)。
同时摄像机也是场景中的活动物体,所以它也可以有移动、旋转以及改变位置的操作(视截体也一同被操作)。另外,作为特殊属性,摄像机可以在没有挂接到场景节点的情况下可以直接放置在场景中,也可以不依赖节点进行自身的旋转移动等操作。这其实是一种比较常用的做法,当摄像机被创建之后就已经开始正常的工作了,场景把它配置在世界空间坐标的(0,0,0)位置上,你可以把它移动到任何你希望的位置上去。
提示:这里并没有说摄像机不能挂接到场景节点上进行工作。不过需要注意的是,在把摄像机放置在节点上操作的时候,需要关闭其“锁定偏移轴(use fixed yaw axis)”设置,否则摄像机将会维持固定的“向上”状态,导致无法进行滚动(Roll)操作。当你对挂载摄像机的节点进行场景操作的时候,如果觉得有些不对劲,比如有一个或者更多的轴向被锁定,那么八九不离十就是上面所说的问题了。
灯光(Light)
很多时候,灯光都会被绑定到某些场景节点上,用来产生特殊的效果,在这里我们可考虑下面的一些情况:
?汽车模型的前灯
?手掌中散发出来的火焰
?黑暗走廊中飘荡的火球
上面每个例子里描述的灯光都需要绑定到一个场景中的对象,换句话说,它们都需要挂接在同一个场景节点上。
可以认为任何能够照亮场景的东西都是灯光。灯光既可以是活动的也可以是固定的。在场景中灯光拥有其类型、位置以及强度的属性。不过,灯光只能被用于场景中物体的局部辐射光照算法(Local Object Illumination)使用。
信息:所谓全局辐射度模型(Global Illumination),就是在计算光照的时候考虑所有光源,其中不仅包括光源本身,也包括从其他物体上反射过来的光线。使用全局辐射度模型的算法包括光线跟踪(Raytracing)和光能传递(Radiosity)。由于这种算法都有很高的计算强度,在本书写作的时候,硬件还鲜有能力进行真正的实时渲染,所以目前版本的Ogre也没有支持任何真正的全局辐射度算法。不过相对而言,还有一些准全局辐射度算法模型的存在(更精确的说,是半影模型“Soft Shadow Model”),其中包括环境光吸收算法(Ambient Occlusion,简称AO)以及计算次表面散射算法(Percomputed Radiance Transfer,简称PTR)已经被“通过”为3D硬件的解决方案。Ogre提供了对其中AO渲染算法的支持。
在局部光照的模型中,对物体的光照计算只考虑光源和物体本身。详细一点地讲,就是通过物体表面法线以及材质属性来计算光照最终在摄像机中的表现,最终计算出的颜色值提供给显示器输出。虽然理论上Ogre本身可以支持任意数量的光源,不过在下一章节中会看到,在实际执行的过程中,还是会有一些具体的限制(比如硬件)。其中有一个限制是: 3D硬件在渲染的过程中,每个渲染通路(Pass)只能使用一定数目的灯光(通常情况下是八个),所以如果你希望使用更多的灯光,那么就要使用更多的渲染通路。最终导致渲染效率的下降。另外一个限制是:真的有必要计算所有灯光么?在实际的场景中,可能有一些灯光微弱且距离很远,这时候可能只会对物体产生微弱的影响。Ogre提供了对灯光由近及远的排序,所以在大多数情况下你只要处理一个渲染通路所提供的灯光数量就足够了。
Ogre中包含了三种灯光模型(与普通3D硬件相同):点光源(Point),聚光灯光源(Spot),有向光源(Directional)。虽然它们都是可移动的,不过移动对它们的意义却各不相同;其中对有向光源的位置改变并没有实际意义,事实上有向光模型并没有位置属性,你只能通过四元数来操纵它的方向,进而改变光线的方向。点光源和聚光灯光源都对会对距离的增加进行衰减,你可以应用不同类型的衰减系数(包括常量,线性和二次)来具体影响它们。这两种光源还有其影响范围属性,超过这个范围的物体不会得到光照。所有的光源都有自身的颜色属性,被用于最终的颜色计算。
点光源(Point Lights)
点光源是在3D场景中比较常用的一种光源。它可以从空间中的一个点向周围辐射光线,点光非常适合模拟一个辐射的灯光,例如,一个壁灯或者台灯,也可以是场景中任何可以移动的需要向周围辐射灯光的对象。
聚光灯光源(Spot Lights)
聚光灯光源与点光非常相似,但是带有了方向特性。一个聚光灯光源光有一个锥形作用范围,你可以指定一个附加的衰减率作外锥所特有的叠加衰减系数,看图5-9。

图5-9:聚光灯光源的光锥特效
聚光灯光源就像它的名字一样,非常适合模拟聚光灯,也可以模拟出摩托车前灯的照射效果。
有向光(Directional Lights)
有向光完全不同于前面提到的两种光。通过“有向”这个词,可以想象到这种光源有方向特性。因为在该概念中,它是从场景外非常遥远的地方发射过来的光线,所以它并没有位置属性。我们可以拿真实世界中的太阳光来说明:太阳从很远的地方以一定角度照射地球上的所有物体。跟太阳一样,因为太遥远了,进而没有明显的距离衰减。因此它也不需要衰减参数,任何与衰减有关的参数都被有向光忽略。当然,有向光最适合模拟场景中的太阳光。
世界地图(World Geometry)
你可以认为世界地图中包含除了活动物体(Movable Object)之外所有的东西,比如高度场地图,网格地图,以及在地图上面的建筑和自然景观(树木以及植被),室内的门和窗户。而比如怪物和场景中活动的门不属于地图本身,它们是活动物体。可以这么理解,世界地图是角色们表演的“舞台”,是演员们存在和表演的场所。
通常来说,可以通过离线的制作工具来生成世界地图,比如一些3D建模工具Softimage|XSI、3D Studio Max、Maya以及Blender,或者高度场地图制作工具Terragen(http://www.planetside.co.uk/terragen/)。最终产生的地图通常是由网格模型为基础构成的,其中包括诸如一些简单的室内场景、建筑结构(比如桥梁)、植物(比如树木或者灌木丛)等等。虽然地形和整个室外场景也是可以用网格模型来构成,不过为了提高性能,它们被“分割”成一些较小的部分,当它们被系统载入的时候才会“缝合”在一起以供显示。
注意:当创建以网格模型为基础的场景或者关卡的时候,你有必要把它们拆分成许多小的部分。否则的话,就算整个网格模型只有一小部分需要显示,Ogre也会渲染整个模型的全部,这样对整个渲染效率的影响就不言自明了。一般来说,大部分的场景管理器(比如分页场景管理器“Paging Scene Manager”)都会提供自己的场景地图分割工具,虽然高度场地图本身并不支持在构建的时候进行分块,但是这些工作会交给系统在载入的时候自动进行。
Ogre的场景管理器提供了两种不同(却类似)的场景读取方式:直接从磁盘文件载入数据以及从任意的数据流载入数据。其中使用数据流的方式允许你在程序中把网格模型包装构造成通用或者私有的地图格式,并直接发送到场景管理器中。但是大多数情况还是使用从磁盘中读取地图的方法,在这种方法里世界地图文件通常是能直接打开和载入的磁盘上的独立文件。
通用的空间分割策略
场景管理器会根据设计和优化的需要,把场景中的几何体分解成一些集合来进行操纵和管理。这些几何体集合的划分方式被称空间分割(Spatial Partitioning),其分割的依据包括每个自空间有多少个几何体才能达到稳定、内含多少个可活动的物体、期待的密度和如何布置它们。对于Ogre来说,对场景地图的分割会建立在物体粒度上而不是多边形本身。这是因为Ogre 3D引擎是一个依靠硬件加速的工具,而当前的3D图形硬件中能更好的处理几何体批次,所以针对物体的分割方式可以得到比针对多边形的分割方式更好的效率。(分割多变形的技术更适合那些软件3D光栅化的工作,不过那是在没有图形硬件对3D变换和光照提供加速的时候)。
四叉树(Quadtree)和八叉树(Octree)的空间分割策略
四叉树是一种历史悠久的2D分割策略,不过在某些3D场景中也可以很好的使用,比如那些垂直高度变化很小的室外场景或者地形中。而八叉树是一种比较适合小型室外场景等分割方式,并且在允许摄像机随意位置的室内场景中工作的一样良好(比如摄像机可以在天棚上面或者地板之下)。
在图5-10中,分别提供了一个八叉树的垂直分割和四叉树分割过程展示,其中包含了三层的空间分割。

图 5-10 :八叉树(a)和四叉树(b)空间分割方试图
图 5-10(a)中你能够看到把空间逐层分割到八个(所以叫做八叉树)子空间的每一步。同样的,你也可以在图5-10(b)中看到四叉树算法把空间逐层分割成四个相同子空间的过程。这两种方式都是递归的分割独立的空间。
八叉树和四叉树更擅长处理在把多变形打包成几何体进行分割的工作,而这并不是二叉空间分割树(BSP)所擅长的。如果希望更多的了解四叉树和八叉树的信息,可以去网上找一些相关的资料来参阅。本书就不在这里多费口舌了。
二叉空间分割树(Binary-Space Partitioning)
BSP(binary-space partitioning)是一个非常有效的场景组织方式,但是对于现在的应用程序而言,更倾向于使用BSP做空间快速碰撞检测而不是几何体分割。虽然Ogre提供了一个简单得BSP支持(事实上也就是《雷神之锤III竞技场》所使用的地图格式),不过因为《雷神之锤III》因为历史的原因,更倾向于把几何数据划分成很多小的数据块而不是打包成大的数据批次,这使得现代的图形硬件并不能很好的进行处理。也便因此,已经没有开发人员继续维护这种BSP格式的简单实现。虽然现在仍然提供这种BSP地图场景管理器插件,但是它的作用也仅限于载入那些使用《雷神之锤III》关卡编辑器制作的地图所用。
静态几何体(Static Geometry)
看起来似乎静态几何体是活动物体(Moveable Object)的反义词,但事实上也不全是:通常来说静态几何体会由很多不再活动的活动物体来构成。
在这里需要要再次提到这个问题,现代的GPU更适合渲染少量巨大物体,而不是很多小几何片断。
注意:因为这个原因,当在现在图形硬件上来测试3D应用程序性能时,光衡量渲染三角面数量的能力通常是没有意义的事情:比如当一百万个三角面捆绑成一个簇里能达到每秒300帧的渲染速度,在结构组织改变的时候,把这些三角形分布在一千个簇中(平均每簇一千个三角面),就可能会降低到30帧每秒这样的结果。所以在现代3D应用程序中可渲染三角面的数量已经不是衡量应用程序的唯一标准。
所以通常而言,越多的三角面集中在一个簇中渲染,对提升你的应用程序效率越有利(当然,也不能盲目,很多时候还要考虑诸如图形硬件带宽吞吐量等诸多因素的影响。)
可能在这里你会觉得把复杂的场景作为静态物体来处理可能是一个不错的注意,但事实也并非如此,在下面列出静态物体的几个缺点:
·一般而言,巨大的静态物体需要在使用前被构建,通常这是一个缓慢的过程,所以不能在每一帧都执行。
· 静态几何体将按着放入物体的材质来进行分类,并且把材质相同的集合体放置到同一个渲染设置当中(换句话说,也就是放到同一个簇中)。但这并不表示只要把一组几何体打包成一个静态物体就能神奇的把它们捆绑到一个渲染设置中:不同材质的物体仍然会被拆分成不同的簇中被渲染。所以这时候你需要在两种需求中进行折衷:是在一次调用中渲染最多的三角形还是最少的调用的次数(也就意味着决定在静态物体中放置多少不同的材质)。
·在静态几何体中“静态”的含义是:一旦物体被放入静态几何体中,你就不能在单独移动它了。任何对静态几何体的世界变换都会应用到所有里面包含的物体上。这就好像放入咖啡中的方糖,你可以扔进去,但是再也捞不到它了。
·通常来说静态几何体会比同样大小的活动物体占用更多的内存;这是因为对于活动物体来说,可以多个实体共享一个网格模型。而静态几何体会为每一个实体创建一个网格模型数据的拷贝。不过在这本书写作的时候,GPU的几何处理也正在发生变革,可能在这本书出版之后,硬件会支持更加优化静态几何体的处理方式。
·就算在你的视野里(视截体)中看到了整个静态几何体的一小部分,甚至包括在你身后的整个数据都会传到图形硬件中渲染。假如你把场景中所有的植被都放到一个静态物体中,即使你只看到一颗小草,那么整个森林都会被渲染。
此外,在场景对静态几何体材质和模型的LoD(细节等级)处理中,会遵照整个静态场景最远的物体距离来设定整组物体的等级。这导致当距离改变的时候,整个静态物体的LoD都会有相同的改变。不过除了上面说的问题之外也有好的一面,场景管理器会通过空间分割算法把静态几何体分组,进而把那些没有在显示空间的静态几何体直接屏蔽到渲染队列之外。对于静态几何体的处理就和所有软件工程中所出现的问题一样,你必须为提高程序的性能而进行一系列设计上的折衷。
通过例子了解场景管理器
前面的文字主要的讨论了为什么要使用场景管理器,在之后的文字中我们将要通过一系列的例子来学习具体使用过程以及相应的编码。
以下的例子都取自Ogre本身的演示程序,你可以在网上免费下载到完整版本。而之后我会尽量把关键的片断列出来,并详细讲解里面的重点内容。
基础工作
在真正的通过场景管理器操纵整个场景之前,我们需要完成一些基础工作。首先要建立一个场景管理器的实例,然后至少还要构建一个摄像机,并执行“放置一个实体到场景中”的操作。
建立一个场景管理器和摄像机
在Ogre的演示程序中,创建场景管理器和摄像机的工作是教给作为演示程序框架的基类(在文件ExampleApplication.h中的ExampleApplication类)来实现,具体的过程可以在方法chooseSceneManager()和createCamera()中找到(代码5-1)。
相关推荐
Ansys Lumerical 启动时出现 Error: Could not connect to Ansys license server specified at 1055@ 的另一种解决办法
昨天在关闭了中之后 就能正常打开 FDTD 了,结果今天想开启出现了同样的报错:我猜测昨天能启动的原因在于关闭之后要重启电脑,并且在重启之后我第一时间打开 lumerical 测试因此端口没有被占用,今天是在电脑启动之后一段时间才打开所以又遇到了端口占用的问题。
OGRE场景管理
<br />Ogre 场景管理<br /><br />每个3D引擎都会用scene graph 来组织它的可渲染对象。scene graph 总是会为了更快地搜索与查询做<br />优化,提供给用户查找目标对象附近特定对象的功能,允许查找,排序,剔除多边形,以实现更高效的渲染。偶尔,scene graph也用于碰撞检测。有时,一个单独的scene graph可被用于程序中的所有子系统,包括<br />音效与物理。<br />Ogre使用插件机制来实现场景管理功能。ScenceManager只是接口,他可以有
IDEA集成selenium自动化测试(Java+Selenuim+testNG+Maven)
文章目录写在前面01 | 新建Maven项目02 | idea集成Selenium03 | 写在前面 因为软件测试的需求和博主比较经常使用Java,于是,想在Idea中集成selenuim,用Java编写测试代码,因此有了这篇文章来记录一下过程。 资源指路: java使用selenium实现模拟浏览器操作API大全 模拟登录 TestNG入门教程 感谢上面博客的大佬。 01 | 新建Maven项目 不使用骨架创建,直接点击左侧Maven,然后一路next即可。 02 | idea集成Sele
OGRE资源的四种状态
未定义 游戏程序启动时所有资源的默认状态,资源未被索引,所以OGRE不知道它们的存在。已声明 资源已被索引,OGRE已经知道这些资源的存在,但它们还没被初始化。 (平时我们读取了资源配置文件之后,资源就进入了这种状态。)未载入 资源已被初始化——被初始化的资源都生成了一个分别对它们的引用(这些引用会占用小部分内存),但资源还没被载入到内存。 p.s
[QDS]从零开始,写第一个Qt Design Studio到程序调用的项目
最近在使用Qt Design Studio进行开发,但是简中网上要不就是只搜得到Qt Designer(Qt Creator内部库),要不就只搜得到一点营销号不知道从哪里搬来的账号,鉴于Qt Design Studio是一个这么强大的软件,自然是需要来进行一下小小的实践的。所以开了这篇文章,方便没有使用过Qt Design Studio 和 QML的开发者也可以快速上手QDS(Qt Design Studio)。在本文中,你将学会如何使用QDS开发一个简单的QML程序,与你的C++后端代码进行交流。
comsol移动网格_comsol模拟移动的纳秒脉冲激光烧蚀材料,温度场分布,结果总不理想,求助大佬!!...
本人comsol新手一枚,希望大家多多指点研究课题:纳秒脉冲激光刻蚀材料表面想用comsol模拟刻蚀过程中的温度场分布,脉宽为300ns,重复频率100kHz,光斑移动速度为5000mm/s,光斑直径50um,激光功率10W,材料种类为:有机涂层,属性如下目前,采用的是一个移动的高斯面光源x脉冲函数,脉冲函数我用的是一个周期性方波:周期性拓展后,画出来的脉冲图,不知道为什么在0~1s的区间内只有1...
空间数据结构(四叉树/八叉树/BVH树/BSP树/k-d树)
一个自定义区域一般是一个凸多边形,然后可通过一些编辑器手动设置好其各顶点位置,最终手工划分出一块凸多边形区域。3D凸多面体一般很少用,即使在要求划分区域属于同一XOZ面不同高度的3D世界里,考虑到性能,可能更适合用凸多边形+高度来划分区域。此外一提,能不用凹多边形就不用。因为许多程序算法都可以应用在凸多边形上,而相对应用于凹多边形上可能行不通或者得用更低效的算法为了达到自定义区域之间的无缝衔接,游戏程序还往往采用图(或者树)结构来存储这些自定义区域,表示它们之间的联系。
自建邮局服务器| 批量邮件群发系统PowerMTA+oem(mumara,mailwizz, interspire)
世界顶级自建邮局服务器PowerMTA+oem(mumara,mailwizz, interspire) PowerMTA4.5(最好用的 群发邮件软件)是用于大批量多ip开发的邮件传递邮寄。可按每小时发送数近百万条电子邮件,发送IP地址和域可以详细配置,加上目前流行前端oem,mumara,mailwizz, interspire等,可定时发送,定时重复发送,实现全自动化 邮件群发 方案。 官网(powermta4.5下载) https://www.sparkpost.com/powermta/ 使用Po
空间数据结构(四叉树,八叉树,BVH树,BSP树,K-d树)
听说过没学过的空间型数据结构
Computer Networks 和 Computer & Security投稿经验
论文投稿
Unity微信小游戏资源管理实战:YooAsset的Tag与Group策略精讲
本文深入解析了在Unity微信小游戏开发中,如何利用YooAsset的Tag与Group策略进行精细化资源管理。通过实战案例,详细阐述了如何通过Tag实现核心资源的必下与额外资源的按需加载,并借助Collector的合理打包策略,实现热更新包体最小化,从而有效解决加载慢、更新流量大的痛点,最终提升玩家体验。
空间数据结构(四叉树、八叉树、BVH树、BSP树、k-d树)
转载地址:https://www.cnblogs.com/KillerAery/p/10878367.html 1. 前言: 在游戏程序中,利用空间数据结构加速计算往往是非常重要的优化思想,空间数据结构可以应用于场景管理、渲染、物理、游戏逻辑等方面。 因此,博主将游戏程序中常用的几个空间数据结构整理出这篇笔记,也会持续更新下去,有错误或有未及之处望指出。 2. 四叉树/八叉树 (Quadtree/Octree) 四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构。 它将已知范围的空间等分成四个相等
游戏大厂状态同步与帧同步技术全解析——让虚拟世界万物协同的“时间齿轮”
本文深入解析了大厂游戏开发中的两种核心同步技术:状态同步和帧同步。状态同步适合大型MMO和FPS游戏,由服务端计算并广播世界状态;帧同步则通过统一操作输入实现MOBA和RTS游戏的绝对公平。文章详细比较了两者的差异、适用场景和底层实现原理,并揭秘了《王者荣耀》《PUBG》等热门游戏的同步机制。同时探讨了本地预测、延迟补偿、防作弊等关键技术,以及未来AI和云游戏带来的同步新挑战,为开发者提供了全面的技术参考和实践指南。
Ogre 场景管理器
转自:http://blog.sina.com.cn/s/blog_694aab1b0100rdvm.html 在通常的情况下,Ogre的场景管理器会负责处理以下事情: ·在场景中创建和放置活动物体、灯光以及摄像机,并维护他们的在场景图中的周游和变换。 ·载入和布置世界地图(World geometry,与活动实体不同,世界地图是巨大且可以延伸的,通...
win10 跳过U8环境检测的IE WebControls.rar
win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。
精雕软件(JDpaint) 5.5 绿色版
精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版
ogre的场景管理器
原文地址:ogre的场景管理器作者:zhouwenjie在通常的情况下,Ogre的场景管理器会负责处理以下事情: ·在场景中创建和放置活动物体、灯光以及摄像机,并维护他们的在场景图中的周游和变换。 ·载入和布置世界地图(World geometry,与活动实体不同,世界地图是巨大且可以延伸的,通常情况下是不可移动的,比如一个完整的BSP地图)。 ·对场景查询(Scene Queries)的支持
Statistics and Machine Learning Toolbox
Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具
OGRE场景管理器
场景管理器不是单例,您想创建多少就创建多少。创建方法1、new SceneManager()2、Root的createSceneManager方法 一般都使用方法2为什么使用createSceneManager函数?原因是Ogre的插件系统,比如你使用了OctreeSceneManager插件的话,OctreeSceneManager会将自身注册为ST_GENERIC类
文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况
主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。
OGRE - 场景管理器
1月20日OGRE教程 - 场景管理器上次,我们讲了初始化OGRE,写完以后对自己很不满意,觉得写出来的东西没有什么实质内容,大家学不了什么东西.这次就讲点实际的吧. 首先讲解一点图形学知识. 基本变换 所谓变换,就是指物体的平移,旋转,缩放这几个最基本的操作. 而在3D的世界,这几个操作都是源于矩阵的乘法.(大家会不会问:平移怎么会是乘法呢?明明是加法啊?这个后
(3) OGRE的基石:场景管理器、场景节点、实体
提示1、确定你已经按照前一教程配置好了第一个应用程序的环境2、所有的代码,你应该自己去敲键盘,尝试多种情况并运行查看效果简介在这篇教程里,我会向您介绍OGRE最基础的构架:场景管理器,场景节点和实体从这里开始将前一教程的工程拷贝一份,我们将在他的基础上做一些功能扩充和展示。我们所需要修改的只有一个代码文件:TutorialApplication.cpp,而且我们只需要关注成员函数:createScene()。OK,让我们边写代码边讲解吧,GO!为成员函数createScene()补充如下代码:void Tu
ogre 场景管理器 scenemanager
声明:本篇转自 痞子龙3D编程 优快云博客,仅留作学习交流之用 ^_^ 原文参照: http://blog.youkuaiyun.com/pizi0475/archive/2010/04/05/5451319.aspx OGRE除了我们已经见过的普通场景以外还支持大型复杂的场景,如:宽阔的野外地形和复杂的大楼和迷宫。3D引擎支持大型复杂场景的主要难度在于对场景的组织和裁减。一个大型场景的三角型数
Ogre的分页大地形场景管理器PLSM2使用手记
By MulinB 最近项目需要模拟一个3D场景飞机飞行的简单演示,主要功能就是提供一个比较大的地形高程图和一个飞机飞行路线,能在三维下显示演示飞机飞行。感觉以前自己见过不少类似的游戏,这无非是第一个人称射击类或者模拟飞行类的游戏的简化版,所以从避免重复制造轮子的角度决定查一下开源游戏引擎,看看有没有类似的可以很快开发出第一人称射击类游戏的引擎。经过查看了一些网上的评论和对比文章决定使用三
转:OGRE场景管理器介绍
一个场景代表在虚拟世界中显示的物品。场景可以包括静态几何体(比如地形或者室内),模型(比如树、椅子等),光和摄像机。场景有下面种类。室内场景:可能由走廊、有家具的屋子和挂着装饰品的墙组成。室外场景:可能由山,树木,微微摇动的草地,飘着云彩的天空组成。Ogre提供了一套不同的场景管理器,每一种特别支持某种场景,本文档将列出Ogre提供的场景管理器和它们的优缺点。 1选择一个...
OGRE - 场景管理器
OGRE教程 - 场景管理器 上次,我们讲了初始化OGRE,写完以后对自己很不满意,觉得写出来的东西没有什么实质内容,大家学不了什么东西.这次就讲点实际的吧. 首先讲解一点图形学知识. 基本变换 所谓变换,就是指物体的平移,旋转,缩放这几个最基本的操作
SceneManager 第五章 Ogre场景管理器
<br />第五章 Ogre场景管理器作者:赵光强 发表于 2010-8-2 16:58:49 在这里我可以大胆的断言,目前在地球上,所有的图形引擎都在使用场景图(Scene Graph)的概念来组织管理它里面可渲染的物体(我甚至怀疑外星人也在用这个)。 场景图在图形引擎中的地位是毋庸置疑的,它不仅提供了对用户在空间中查找和搜索物体提供了高速的优化,并且针对程序库(对我们而言就是Ogre)的渲染需要,提供了相应的搜索、排序以及剔除功能。在某些时候也被用来进行碰撞检测。在一些具体的设计里面,场景图甚至
Ogre基础教程(一)----- 场景管理器,场景节点和实体.
简介 在这篇教程里,我会向您介绍OGRE最基础的构架:场景管理器,场景节点和实体。由于我需要在这篇教程里把OGRE的基本概念介绍给你,所以我们不会接触太多的代码。 在您阅读这篇教程的同时,您应该自己一点一点的添加代码来体会代码的作用,只有这样才可以真正理解这些概念。 从这里开始 在这篇教程里,我们将使用已经写好的代码作为模版。除了我们将要在createScene函数里面添加的代码之外,您
9545



被折叠的 条评论
为什么被折叠?



