BSP(二叉空间分割Binary Space Partitioning)树是另一种类型的空间分割技术,在游戏工业上广泛应用。
目录
一. BSP Tree 生成步骤
1)首先,选择一个超平面和根节点。我们2D选择的是一条线分割空间,3d就是用面来分割空间。
2)用超平面分割初始的空间,分割后两个空间保存为左孩子和右孩子,并将分割后的多边形村住在List中。
3)取出存住List中的多边形,通过迭代或者递归,产生新的节点并加在父节点上。
迭代和递归都可以用于BSP Tree算法,递归更加容易理解。这里递归的Base Case 使用的是产生空间的数量控制,或者是切割最小空间的size控制。
二、BSP Tree 怎样实现?
要和设计一个tree,我们要分析每个node要做什么,由什么组成。在分析树要做什么,base case是什么。下图是我们预期想得到的地图和装饰后的地图:
1、Node 组成
1)parent Node
2)leftChildren Node, rightChildren node
3)node data,在Project3 的case中,node data 是 Room data,Path data
2. Tree 生成
这里Tree生成参考了Dungeon BSP 地图生成算法,当我们Partition 多边形的时候,我们需要什么?
1)这条线横着割还是竖着割
2)在哪里割
3)space长和宽,和位置position
4)如果space中有Room,需要Room 的长和宽,位置Position
5)如果有路径,存储路径path的 List<Point>
6) 相对容易access sbiling node
我们开一动手实现啦,首先需要两个类。一个是Node Class 一个是Tree Class。下面的伪码展示了如何用递归的方法实现BSP算法构造出Room分布漂亮的地图。
3.代码实现
下面以CS61B Project Build My Own World 建立地图为例。Start Code 看上一篇帖子。
1)Room 类
Room 类相对简单容易写:
class Room {
Point p;//left bottom
int width;
int height;
public Room(Point point,int w, int h) {
p = point;
width = w;
height = h;
}
public int height() {
return height;
}
public int width() {
return width;
}
public Point position() {
return p;
}
public Point CenterPoint() {
int setX = p.x + width/2 ;
int setY = p.y + height/2 ;
return new Point(setX, setY);
}
public HashSet<Point> roomPoint() {
HashSet<Point> points = new HashSet<>();
for(int x = 0; x<width-1; x++) {
for(int y = 0; y< height-1;y++) {
points.add(new Point(p.x+x, p.y+y));
}
}
return points;
}
}
2)Path 类
Path Class 实现从一个点到另外一个点的链接,形状是Z型或者L型。
class Path {