q3 bsp随笔

阅读q3的bsp实现,做一些随笔记录,免得自己也忘了。


首先谈到的是brush概念。

笔者用最通俗的方法来解释一下brush


用q3场景编缉,画一个六面体(长方体),观察得到的map文件

会看到里面记录了一个brush信息,其实就是记录了brush的六个面!

这就是brush。

假设我们的场景都是由长方体构成,那么场景里有brush信息就都是长方体的信息

(q3的brush当然不止长方体,但在理解bsp代码之前,就认为brush是一个长方体,这里能更容易地理解代码)


接下来是winding,

简单的说

brush是记录长方体的六个平面,winding就是根据这六个平面参数,得到的8个顶点

在q3里,长方体的每个"面"被称为side,每个side有一个winding,这个winding就是该"面"的4个点


winding就是brush信息的另一种展现显示


接下来q3就开始分割空间。

记录下当前场景里所有brush的平面,去重,根据这些平面划分空间,就会得到一棵bsp树

这是一棵完全的bsp树,场景中所有的brush平面均参与了空间分割。


接下来抛弃一个实心空间?比如,一个brush长方体,它的内部空间,有分割时,会形成一个叶子节点

这个节点是要抛弃的,因为玩家不会出现在一个实力长方体里面。


有了bsp树,就可以根据玩家的位置,找到玩家所有的叶子节点。

绘制当前叶子节点,也就是玩家可以看见的面,这里就涉及到pvs的预计算


生成port,就是为了预计算pvs。

假设玩家在一个房间里,这个房间有一个门,这个门就是port,玩家除了看到房间的四面墙,还会通过门到看外面的一些面。

这些面,是需要预计算,保存下来的。


可以想像,port一定是在生成bsp树时,分割空间的平面上,随着空间的分割,port也被分割。

所以q3遍历bsp树,用bsp树的分割平面,被port依次分割,最后得到port 的winding.

因为bsp是完全的,场景中所有的平面都参与了bsp分割,这样q3的计算每个port的可见性时

就不用再考虑场景中的多边形对port的切割了,只根据port的winding信息,来计算port之间的可见性。


先写到着,代码看完再接着写。


基本上,q3代码要分两部分看,只看游戏运行时的那部分代码,会觉得一头雾水,但多少能猜出bsp的大概。

完成领会q3的bsp,场影编缉器的代码是一定要看的。


这也是为什么光看ogre与鬼火,完全无法看懂bsp,开源引擎只负责解析q3生成的文件,没有相应的生成代码。


ps:q3生成pvs的时候,使用了多线程,算是最早的map reduce了吧,呵呵(单机版的)



posted @ 2013-07-27 23:58  飞天大蟾蜍  阅读(20)  评论(0编辑  收藏  举报