|
本帖最后由 daiday 于 2013-12-11 09:45 编辑
想要将场景利用八叉树管理起来。虽然资料很多,但是却理不出一个头绪来。
首先来说,这个八叉树该如何组织?看过osg cookbook的示例代码,是将场景按照空间位置进行严格排列划分,一个八叉树节点就是一个lod节点,下面含有8个子lod节点,一层一层的使用。这种方式和我阅读的其他八叉树资料感觉相差挺大的。。。
对此我的做法是,自定义一个Group节点,将要绘制的所有子节点并列的挂在该节点下,然后内部维护一个八叉树,八叉树中存储的就是子节点的指针们。我会在该节点的traverse函数中进行裁减处理,大概思路如下所示:
- void traverse(NodeVisitor& nv)
- {
- if (nv.type==CULL_VISITOR)
- {
- // 执行自己的裁减函数,对于要渲染的节点,执行accept(nv)的操作
- }
- else
- {
- // 执行Group中原来的traverse代码
- }
- }
复制代码
这个八叉树基本上就是从cookbook中copy下来的代码。。。这样做虽然测试着确实快了一点点(仅仅是一点点,而且还不确定是否正确),觉得哪里不对劲。
我按照上面的方法去做,是否合适呢?希望大拿们能对上面的思路批评指正。
接下来:
然后我又看了OGRE中的代码,OGRE中的八叉树和cookbook中的类似(开始没觉出来,后来越看越像),只是没有单独层中子节点最大数目的限制。不过对于OGRE中,有渲染队列的概念。OGRE八叉树管理器在遍历完八叉树之后,可以将要绘制的内容发送到渲染队列中。
现在我越来越迷糊了。。我想OGRE也是一个成熟的渲染引擎(好歹有个火炬之光真心不错),所以想着把OGRE中的八叉树部分提取出来,应用到OSG中。说了这么多,问题就又来了:
1. 对于OGRE中的场景管理器,我将其处理成了一个单独的自定义Group节点,然后内部维护一个八叉树不知道这样做是否恰当?
2. 对于那个渲染队列,我是否仍然像开始说的那样处理呢?把要绘制的子节点一股脑挂在根节点下,然后在traverse中进行裁剪,决定是否为子节点传递cull visitor?或者我该自定义一下cull visitor?
其实我觉得对于八叉树,我脑子里面还没有这么个成型的概念,希望大家能够能提供一些相关的资料或者代码参考,简言之:指条明路吧!
最后我很想知道的是,osg中的BVH结构相对于八叉树结构来说,在裁剪方面性能差距能有多大?osg为什么没有八叉树的管理方式呢?(或者为啥没有使用八叉树结构?这个问题还真是蠢啊。。不过我还是想知道具体原因) |
|