More on Scene Management

来源:互联网 发布:网络电视哪个软件高清 编辑:程序博客网 时间:2024/05/09 20:24

 More on Scene Management

仅供个人学习使用,请勿转载,勿用于任何商业用途。

 

     相信很多人都看过Tom Forsyth那篇著名的文章<<Scene Graph – just say no>>。我第一次看时,只觉得是Tom开的一个小玩笑。不过最近,随着对scene management研究的深入,感觉对于大多数游戏来说,scene graph确实不是那么必须。

      由于scene graph实在是一个被严重滥用和误用的词,虽然以前的文章介绍过scene graph,为了避免不必要的误解,再次列出关于SG的概念:纯粹的SG只用来描述场景中物体间的空间逻辑关系而不是简单的空间关系。如果SG中包含任何的quadtree/octree, bsp等空间数据结构,那么这肯定不是一个SG;不应该使用SG进行裁剪或者碰撞检测。简单来说,SG就是一棵n叉熟。

      游戏中什么对象需要描述空间逻辑关系呢?显然,对于静态物体来说是没有必要的,即使它包含空间逻辑关系,但由于本身“不会移动”的特性,可以在加载这个物体时就预计算出它的绝对世界坐标。对于可移动物体,骨骼动画显然是最适合用SG来描述的,比如人物身体各部分之间的移动关系。不过更常见的情况是把同一骨骼下的物体作为一个整体,并用一个特殊的内部结构来描述其空间逻辑关系。比如整个人物是一个model对象,身体每个部份是model内的subMesh对象(类似Ogre里Entity和SubEntity的关系)。

     仔细想想,游戏中似乎只有几种情况下可能需要使用scene graph,以wow为例:1,人物身上可附加的装备,比如剑,帽子;2,当人物骑到坐骑上;3,跟随某个角色移动。目前为止,我只想到这3点。

     我现在的设计中,SG非常简单,只包含可移动的物体,不会出现很深的分支,并且整个树结构将会非常flat——大部分可移动物体都直接连接到根节点。当然,对于游戏编辑器来说则不太一样,编辑器中,所有物体都是可移动的,并且通常需要移动一整个对象组,这时,SG中就包含了所有物体。

     那么如何进行场景管理,culling和collision detection呢?把场景中所有物体都抽象为SceneObject。场景管理通过SceneManager完成,SM内部维护了多种数据结构,分别是Dictionary,SceneGraph,StaticSpatialGraph,DynamicSpatialGraph。SpatialGraph是用来进行空间划分的数据结构,引擎将通过它实现culling和collision detection。StaticSpatialGraph并不必须是某种特定的数据结构,比如grid, quadtree,octree,bsp或者pvs,而可以是由多种结构组成的混合树:每个SpatialNode只需要实现ICullable接口,实际的SpatialNode可以是前面提到的任何一种结构,非常具有灵活性,当然,子节点所覆盖的范围不能超出父节点。理论上,DynamicSpatialGraph也可以由多种节点组成,但由于其本身的动态特性——会动态改变树形结构,所以实时生成各种不同的节点并不现实。当一个so加入到sm时,sm将会把这个物体添加到Dictionary之中,以便以后访问;之后,检查so是否可移动,如果可以,同时添加到SceneGraph和DynamicSpatialGraph中,如果是静态的,则只添加到StaticSpatialGraph。对SceneObject来说,SpatialGraph是透明的,SceneObject完全不需要知道SpatialGraph的存在。

 

(update on 5.5 09):

      前几天刚好看到有人在讨论sceneObject与sceneNode应该分开还是合并, 从上面的讨论可以看到,sceneObject并不总是sceneNode,两者的职责是非常不同的,合并到一起会让整个系统非常难以扩展和修改,每次scene graph的管理方式改变,都会影响到所有sceneObject。SceneObject并不需要知道关于场景结构的任何信息,sceneNode通过接口负责为sceneObject提供最终的世界坐标,你可以用任何管理方式(group策略)进行场景管理,不会影响sceneObject系统。在任何设计良好的引擎中,都应该把sceneNode和sceneObject分开,max,maya甚至ogre都是这样。