BSP树

来源:互联网 发布:steam动态桌面软件 编辑:程序博客网 时间:2024/06/02 01:10

原理:
首先,将整个场景包围在一个AABB(外包盒)中,然后以递归形式将此外包盒分为若干比较小的盒子。通常是选取盒子的一个轴,生成与之垂直的平面,将其分为两个小盒子。一般是将盒子分为完全相同的两个部分。与分割平面相交的物体,或存储在此层次上,成为两个子集中的一员;或被这个平面分割成两个不同的物体。重复这个平面分割过程,就可以对每个AABB进行递归细分,直到满足某个标准。通常这个标准是用户定义的树的最大深度,或者是盒子内所包含的集合图元数量低于用户定义的某个值,或是到达叶子节点(全部节点都为凸包–最小凸多边形)。

简单说来,这种思想就是以平面来递归分割场景的。场景中会有许多物体,我们以每个物体的每个Polygon当成一个平面,而每个平面会有正反两个面,就可把场景分两部分,先从第一个平面开始分,再从这分出的两部分各别再以同样方式细分……如此进行,就可把场景建构出一颗二叉树。

//定义BSP树节点类template<class T>struct BSPTreeNode{T data; //节点数据T xmin,xmax; //节点坐标,即六面体各顶点的坐标T ymin,ymax;T zmin,zmax;BSPTreeNode <T> *left,*right; //该节点的个子结点,即左右两个子六面体节点BSPTreeNode //节点类(T nodeValue = T(),T xminValue = T(),T xmaxValue = T(),T yminValue = T(),T ymaxValue = T(),T zminValue = T(),T zmaxValue = T(),BSPTreeNode<T>* left_Node = NULL,BSPTreeNode<T>* right_Node = NULL ):data(nodeValue),xmin(xminValue),xmax(xmaxValue),ymin(yminValue),ymax(ymaxValue),zmin(zminValue),zmax(zmaxValue),left(left_Node),right(right_Node){}};//创建BSP树int scale = -1; //切割平面属性初始化,根据切割平面属性决定当前切割的面是与X轴垂直的平面,还是Y轴的或Z轴的template <class T>void createBSPTree(BSPTreeNode<T> * &root,int maxdepth,double xmin,double xmax,double ymin,double ymax,double zmin,double zmax){cout<<"处理中,请稍候……"<<endl;maxdepth=maxdepth-1; //每递归一次就将最大递归深度-1scale++; //每递归一次就将切割平面属性+1,使下一次切割的平面更改一下if(3==scale) scale=0; //如果切割属性达到峰值,则初始化if(maxdepth>=0){root=new BSPTreeNode<T>();root->data = 9; //为节点赋值,可以存储节点信息,如物体可见性。由于是简单实现BSP树功能,简单赋值为。root->xmin=xmin; //为节点坐标赋值root->xmax=xmax;root->ymin=ymin;root->ymax=ymax;root->zmin=zmin;root->zmax=zmax;double xm=(xmax-xmin)/2;//计算节点个维度上的半边长double ym=(ymax-ymin)/2;double zm=(zmax-zmin)/2;//递归创建子树if(0==scale) //切割属性为,沿与X轴垂直的平面切割{createBSPTree(root->left,maxdepth,xmin,xmax-xm,ymin,ymax,zmin,zmax);//根据当前切割平面的属性决定其子结点的坐标createBSPTree(root->right,maxdepth,xmax-xm,xmax,ymin,ymax,zmin,zmax);}else if(1==scale) //切割属性为,沿与Y轴垂直的平面切割{createBSPTree(root->left,maxdepth,xmin,xmax,ymin,ymax-ym,zmin,zmax);//根据当前切割平面的属性决定其子结点的坐标createBSPTree(root->right,maxdepth,xmin,xmax,ymax-ym,ymax,zmin,zmax);}else if(2==scale) //切割属性为,沿与Z轴垂直的平面切割{createBSPTree(root->left,maxdepth,xmin,xmax,ymin,ymax,zmin,zmax-zm);//根据当前切割平面的属性决定其子结点的坐标createBSPTree(root->right,maxdepth,xmin,xmax,ymin,ymax,zmax-zm,zmax);}}}

BSP树与八叉树的区别:
4、BSP Tree和Octree对比

a) BSP Tree使用1个面分割场景,而Octree使用3个面分割。

b) BSP Tree每个节点有2个子结点,而Octree有8个子结点

因此BSP Tree可以用在不论几维的场景中,都没有问题,而Octree则 常用于三维场景(拓展到N维中就会十分复杂了)。

0 0
原创粉丝点击