概念解释:
结构化面: 参与分割的多变形。多边形对应的平面列表为其 分割面列表。
备选平面:在这里就是结构化面。
细节面:不参与分割的平面。
首先,自然是要先产生一个根节点,并把所有的顶点表、结构化三角形表和平面表一股脑塞进这个根节点中咯。
然后,分割的流程大抵如下:
1 遍历当前节点的所有备选平面,寻找一个合适的分割平面。
满足一定条件,左右个数基本一致。如果是凸多面体,那么就认为是找不到。
2 如果找不到合适的分割平面,这个节点是一个叶子,Return。
3 如果找到了,Mark这个平面已经被使用过。
4 New两个新节点,一个为正向节点,一个为负向节点,挂接到本节点下。
5 遍历所有结构化面。
6 如果结构化面在分割平面的:
正向:将这个结构化面和结构化面所对应的平面放入到正向节点。
//结构化面:节点所代表的多边形。
//结构化面对应的平面:分割面,放入的这些分割面就是新的子节点的分割面列表。
负向,放入到负向节点。
如果结构化面被分割平面分割,则分割此三角形,并将分割后的结果放入相应的子节点。
//下面这句话的意思是:判断结构化面所对应的平面是否已经作为分割面,如果是,那么应该从分割面列表中排除这个面。
(注意,这一步当发现结构化面所对应的平面已经被Mark的时候,就只放结构化面,不放分割平面了,以防止同一个平面用于分割两个以上空间,违反BSP空间二分逻辑的唯一性)
7 遍历所有细节面。细节面的处理与结构化面类似,只不过这里不用考虑到细节面对应的平面问题,更简单。
所谓的细节面对应的平面问题是指:它是否已经是分割面,下面这句话不用考虑。
(注意,这一步当发现结构化面所对应的平面已经被Mark的时候,就只放结构化面,不放分割平面了,以防止同一个平面用于分割两个以上空间,违反BSP空间二分逻辑的唯一性)
8 遍历完毕,由于所有的结构化三角形、平面和细节面已经转移到两个子节点中了,因此从本节点中解掉所有的结构化三角形、平面和细节面的引用。节点所需保留的数据只需要是分割平面和两个下级节点的指针即可。
//上面这句话的意思是:转移!!
//可以简单地把ISLEAF设为false,然后将自己的结构化面和分割面以及细节面列表清空。就像蓝色地方所说。
9 对两个子节点,分别从1开始递归执行。
大概的节点结构如下:
class Node{
//分割面:
float[4] flat;
//是否为节点
bool IsLeaf
//分割面列表
DividerList div;
//结构化面列表
structList strut;
//细节面列表
material m_list
//前节点
FrontNode* front;
//后节点
BackNode* front;
};