zoukankan      html  css  js  c++  java
  • More on Scene Management

    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的存在。

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

  • 相关阅读:
    Python入门-函数进阶
    Python入门-初始函数
    Leetcode300. Longest Increasing Subsequence最长上升子序列
    Leetcode139. Word Break单词拆分
    Leetcode279. Perfect Squares完全平方数
    Leetcode319. Bulb Switcher灯泡开关
    Leetcode322. Coin Change零钱兑换
    二叉树三种遍历两种方法(递归和迭代)
    Leetcode145. Binary Tree Postorder Traversal二叉树的后序遍历
    Leetcode515. Find Largest Value in Each Tree Row在每个树行中找最大值
  • 原文地址:https://www.cnblogs.com/clayman/p/1458972.html
Copyright © 2011-2022 走看看