public BSP_Tree(int width, int height, int minNodeWidth, int minNodeHeight) { root = new BSP_Node(null, new Rect(0f, 0f, width, height), true); this.minNodeWidth = minNodeWidth; this.minNodeHeight = minNodeHeight; Split(root); }
public BSP_Node[] SplitNode(float percent, bool vertical) { for (int i = 0; i < children.Length; i++) { Rect newRect; if (i == 0) { if (!vertical) { newRect = new Rect(rect.x, rect.y, rect.width, rect.height * percent); } else { newRect = new Rect(rect.x, rect.y, rect.width * percent, rect.height); } } else { if (!vertical) { newRect = new Rect(rect.x, rect.y + rect.height * percent, rect.width, rect.height * (1 - percent)); } else { newRect = new Rect(rect.x + rect.width * percent, rect.y, rect.width * (1 - percent), rect.height); } } children[i] = new BSP_Node(this, newRect, vertical); } children[0].sibling = children[1]; children[1].sibling = children[0]; return(children); }
BSP_Node FindBottommostNode(List <BSP_Node> candidates) { BSP_Node bottommostNode = candidates[0]; for (int i = 1; i < candidates.Count; i++) { if (candidates[i].room.yMax < bottommostNode.room.yMax) { bottommostNode = candidates[i]; } } return(bottommostNode); }
BSP_Node FindTopmostNode(List <BSP_Node> candidates) { BSP_Node topmostNode = candidates[0]; for (int i = 1; i < candidates.Count; i++) { if (candidates[i].room.yMin > topmostNode.room.yMin) { topmostNode = candidates[i]; } } return(topmostNode); }
BSP_Node FindLeftmostNode(List <BSP_Node> candidates) { BSP_Node leftmostNode = candidates[0]; for (int i = 1; i < candidates.Count; i++) { if (candidates[i].room.xMin > leftmostNode.room.xMin) { leftmostNode = candidates[i]; } } return(leftmostNode); }
BSP_Node FindRightmostNode(List <BSP_Node> candidates) { BSP_Node rightmostNode = candidates[0]; for (int i = 1; i < candidates.Count; i++) { if (candidates[i].room.xMax < rightmostNode.room.xMax) { rightmostNode = candidates[i]; } } return(rightmostNode); }
List <BSP_Node> FindXOverlapping(BSP_Node node, List <BSP_Node> candidates) { List <BSP_Node> xOverlapping = new List <BSP_Node>(); for (int i = 0; i < candidates.Count; i++) { float overlappingSize = halfXOverlap(node.room, candidates[i].room); if (overlappingSize > 0) { xOverlapping.Add(candidates[i]); } } return(xOverlapping); }
public BSP_Node(BSP_Node parent, Rect rect, bool splitVertical) { this.parent = parent; this.rect = rect; this.splitVertical = splitVertical; if (parent != null) { Level = parent.Level + 1; root = parent.root; root.maxLevel = Level; } else { Level = 0; root = this; } }
public void Split(BSP_Node node) { allNodes.Add(node); bool vertical = !node.splitVertical; bool bigEnough = vertical ? node.rect.width > minNodeWidth : node.rect.height > minNodeHeight; if (!bigEnough) { leafs.Add(node); } else { float percent = Random.Range(0.3f, 0.7f); BSP_Node[] currentChildren = node.SplitNode(percent, vertical); for (int i = 0; i < currentChildren.Length; i++) { Split(currentChildren[i]); } } }
void GenerateCorridor2(BSP_Node node) { BSP_Node sibling = node.sibling; int minX; int maxX; int minY; int maxY; if (node.splitVertical) { bool nodeLeftOfSibling = node.rect.center.x > sibling.rect.center.x; if (!nodeLeftOfSibling) { return; } List <BSP_Node> candidates = new List <BSP_Node>(); candidates.Add(node); node.FillListWithChildren(candidates); BSP_Node rightmostNode = FindRightmostNode(candidates); candidates = new List <BSP_Node>(); candidates.Add(sibling); sibling.FillListWithChildren(candidates); List <BSP_Node> yOverlapping = FindYOverlapping(rightmostNode, candidates); if (yOverlapping.Count == 0) { return; } numberOfCorridors++; BSP_Node bestSibling = FindLeftmostNode(yOverlapping); Rect leftRoom = rightmostNode.room; Rect rightRoom = bestSibling.room; minY = (int)(Mathf.Max(leftRoom.yMin, rightRoom.yMin) + halfYOverlap(leftRoom, rightRoom)); maxY = minY + 1; maxX = (int)rightmostNode.room.xMin; minX = (int)bestSibling.room.xMax; } else { bool nodeLowerThanSibling = node.room.center.y < sibling.room.center.y; if (!nodeLowerThanSibling) { return; } List <BSP_Node> candidates = new List <BSP_Node>(); candidates.Add(node); node.FillListWithChildren(candidates); BSP_Node topmostNode = FindTopmostNode(candidates); candidates = new List <BSP_Node>(); candidates.Add(sibling); sibling.FillListWithChildren(candidates); List <BSP_Node> xOverlapping = FindXOverlapping(topmostNode, candidates); if (xOverlapping.Count == 0) { return; } numberOfCorridors++; BSP_Node bestSibling = FindBottommostNode(xOverlapping); Rect topRoom = topmostNode.room; Rect bottomRoom = bestSibling.room; minX = (int)(Mathf.Max(topRoom.xMin, bottomRoom.xMin) + halfXOverlap(topRoom, bottomRoom)); maxX = minX + 1; minY = (int)topmostNode.room.yMax; maxY = (int)bestSibling.room.yMin; } node.parent.room = new Rect(minX, minY, maxX - minX, maxY - minY); }