public void insertNode(ref BSPNode node, int val) { // GH: First generation node, the root print(BSPNode.instanceCount.ToString() + " NODES"); if(node == null) { node = new BSPNode(val); node.left = node.right = null; return; } if(val < node.weight) { print("ADDING NODE TO THE LEFT"); //node.left.parent = node; insertNode(ref node.left, val); } else if( val >= node.weight) { print("ADDING NODE TO THE RIGHT"); //node.right.parent = node; insertNode(ref node.right, val); } }
public void init() { tiles = new GameObject[ROOM_WIDTH, ROOM_HEIGHT]; roomHolder = new GameObject("Room"); for(int i = 0 ; i < ROOM_WIDTH; i++) { for (int j = 0 ; j < ROOM_HEIGHT; j++) { tiles[i, j] = (GameObject)(GameObject.Instantiate(wallTile)); tiles[i, j].transform.position = new Vector3(i *100, 0, j * 100); tiles[i, j].transform.parent = roomHolder.transform; } } BSPNode root = null; trunk = root; insertNode(ref trunk, 25); insertNode(ref trunk, 8); insertNode(ref trunk, 5); insertNode(ref trunk, 10); insertNode(ref trunk, 8); insertNode(ref trunk, 5); partitionate(trunk, 0, 20, 0, 20); }
public BSPNode[] SplitNode(float percent, bool vertical) { for (int i = 0; i < Children.Length; i++) { Rect newRect; if (i == 0)// erstes child { 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// zweites child { 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 BSPNode(this, newRect, vertical); } return(Children); }
public BSPNode GetLeafNode() { if (roomRect != null) { return(this); } BSPNode leftLeaf = null; BSPNode rightLeaf = null; if (left != null) { leftLeaf = left.GetLeafNode(); } if (right != null) { rightLeaf = right.GetLeafNode(); } if (leftLeaf == null && rightLeaf == null) { return(null); } if (leftLeaf == null) { return(rightLeaf); } if (rightLeaf == null) { return(leftLeaf); } return(URandom.value > 0.5f ? leftLeaf : rightLeaf); }
void splitX(GameObject _aSection) { float xSplit = Random.Range(20, _aSection.transform.localScale.x - 20); if (xSplit > 20) { GameObject cube0 = GameObject.CreatePrimitive(PrimitiveType.Cube); cube0.transform.localScale = new Vector3(xSplit, _aSection.transform.localScale.y, _aSection.transform.localScale.z); cube0.transform.position = new Vector3( _aSection.transform.position.x - ((xSplit - _aSection.transform.localScale.x) / 2), _aSection.transform.position.y, _aSection.transform.position.z); cube0.GetComponent <Renderer>().material.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); cube0.tag = "GenSection"; leftNode = new BSPNode(); leftNode.setCube(cube0); leftNode.setParentNode(this); GameObject cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube); float split1 = _aSection.transform.localScale.x - xSplit; cube1.transform.localScale = new Vector3(split1, _aSection.transform.localScale.y, _aSection.transform.localScale.z); cube1.transform.position = new Vector3( _aSection.transform.position.x + ((split1 - _aSection.transform.localScale.x) / 2), _aSection.transform.position.y, _aSection.transform.position.z); cube1.GetComponent <Renderer>().material.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); cube1.tag = "GenSection"; rightNode = new BSPNode(); rightNode.setCube(cube1); rightNode.setParentNode(this); GameObject.DestroyImmediate(_aSection); } }
BSPNode FindFarthestNode(Farthest farthest, List <BSPNode> candidates) { BSPNode bestNode = candidates[0]; for (int i = 1; i < candidates.Count; i++) { switch (farthest) { case Farthest.Top: bestNode = candidates[i].room.yMax > bestNode.room.yMax ? candidates[i] : bestNode; break; case Farthest.Right: bestNode = candidates[i].room.xMax > bestNode.room.xMax ? candidates[i] : bestNode; break; case Farthest.Bottom: bestNode = candidates[i].room.y < bestNode.room.y ? candidates[i] : bestNode; break; case Farthest.Left: bestNode = candidates[i].room.x < bestNode.room.x ? candidates[i] : bestNode; break; default: break; } } return(bestNode); }
void ConnectRegions(int to) { BSPNode nearFromNode = null; BSPNode nearToNode = null; float nearDistance = -1; foreach (KeyValuePair <int, List <BSPNode> > iter in regions) { int from = iter.Key; if (from != to) { List <BSPNode> fromRegion = regions[from]; List <BSPNode> toRegion = regions[to]; foreach (var fromNode in fromRegion) { foreach (var toNode in toRegion) { float distance = Vector2.Distance(fromNode.rect.center, toNode.rect.center); if (nearDistance == -1 || distance < nearDistance) { nearDistance = distance; nearFromNode = fromNode; nearToNode = toNode; } } } } } nearToNode.AddConnection(nearFromNode); MergeRegions(nearToNode.regionId, nearFromNode.regionId); }
public void Connect(BSPNode tree, ref int[,] mapAux) { if (tree.left == null && tree.right == null) { return; } if (tree.left != null) { Connect(tree.left, ref mapAux); } if (tree.right != null) { Connect(tree.right, ref mapAux); } if (tree.left != null && tree.right != null) { BSPNode leftRoom = tree.left.GetLeafNode(); BSPNode rightRoom = tree.right.GetLeafNode(); if (leftRoom != null && rightRoom != null) { ConnectRooms(leftRoom.roomRect, rightRoom.roomRect, ref mapAux); } } }
public void SplitNode(ref Random random) { if (this.NodeComponent.RectBounds.z / 2 < MinRoomSize && this.NodeComponent.RectBounds.w / 2 < MinRoomSize) { this.NodeComponent.IsLeaf = 1; return; } var rectBounds = this.NodeComponent.RectBounds; bool splitHorizontal; if (rectBounds.w / (float)rectBounds.z > 1) { splitHorizontal = false; } else if (rectBounds.z / (float)rectBounds.w >= 1) { splitHorizontal = true; } else { splitHorizontal = random.NextBool(); } if (splitHorizontal) { var splitPosition = random.NextInt(MinRoomSize, rectBounds.z - MinRoomSize + 1); this.LeftChild = new BSPNode(new NodeComponent { RectBounds = new int4(rectBounds.x, rectBounds.y, splitPosition, rectBounds.w) }); this.RightChild = new BSPNode(new NodeComponent { RectBounds = new int4(rectBounds.x, rectBounds.y + splitPosition, rectBounds.z - splitPosition, rectBounds.w) }); } else { var splitPosition = random.NextInt(MinRoomSize, rectBounds.w - MinRoomSize + 1); this.LeftChild = new BSPNode(new NodeComponent { RectBounds = new int4(rectBounds.x, rectBounds.y, rectBounds.z, splitPosition) }); this.RightChild = new BSPNode(new NodeComponent { RectBounds = new int4(rectBounds.x + splitPosition, rectBounds.y, rectBounds.z, rectBounds.w - splitPosition) }); } //Parallel.Invoke( // () => this.LeftChild.SplitNode(ref random), // () => this.RightChild.SplitNode(ref random), //); this.LeftChild.SplitNode(ref random); this.RightChild.SplitNode(ref random); }
public BSPNode() { area = BSPRect.Zero; roomRect = null; parent = null; left = right = null; }
public void DivisionPhase(int frames) { for (int i = 0; i < frames; ++i) { if (_nodeQueue.Count == 0) { _numRoomsToMake = Mathf.Max(Mathf.RoundToInt(this.RoomToLeafRatio * _leaves.Count), 1); this.NextPhase(); break; } BSPNode node = _nodeQueue[0]; _nodeQueue.RemoveAt(0); node.Children = splitNode(node); if (node.Children != null) { _nodeQueue.Add(node.Children[0]); _nodeQueue.Add(node.Children[1]); } else { _leaves.Add(node); } } if (this.VisualizeSplitting) { applyOriginalMap(); visualizeNodes(true); } }
private void BuildTree() { generated.Clear(); tree.Clear(); Rect r = new Rect(); r.width = dungeonWidth; r.height = dungeonHeight; r.x = -(r.width / 2); r.y = -(r.height / 2); BSPNode n = new BSPNode(r); generated.Add(n); float area = GetAvgArea(generated.ToArray()); while (area >= minAreaForRoom) { expanded = new List <BSPNode>(generated); generated.Clear(); int i; for (i = 0; i < expanded.Count; i++) { tree.Add(expanded[i]); BSPNode nodeA = null; BSPNode nodeB = null; Split(expanded[i], ref nodeA, ref nodeB); generated.Add(nodeA); generated.Add(nodeB); } area = GetAvgArea(generated.ToArray()); } }
void splitZ(GameObject _aSection) { float zSplit = Random.Range(20, _aSection.transform.localScale.z - 20); float zSplit1 = _aSection.transform.localScale.z - zSplit; if (zSplit > 20) { GameObject cube0 = GameObject.CreatePrimitive(PrimitiveType.Cube); cube0.transform.localScale = new Vector3(_aSection.transform.localScale.x, _aSection.transform.localScale.y, zSplit); cube0.transform.position = new Vector3( _aSection.transform.position.x, _aSection.transform.position.y, _aSection.transform.position.z - ((zSplit - _aSection.transform.localScale.z) / 2)); cube0.renderer.material.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); cube0.tag = "GenSection"; leftNode = new BSPNode(); leftNode.setCube(cube0); leftNode.setParentNode(this); GameObject cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube); cube1.transform.localScale = new Vector3(_aSection.transform.localScale.x, _aSection.transform.localScale.y, zSplit1); cube1.transform.position = new Vector3( _aSection.transform.position.x, _aSection.transform.position.y, _aSection.transform.position.z + ((zSplit1 - _aSection.transform.localScale.z) / 2)); cube1.renderer.material.color = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)); cube1.tag = "GenSection"; rightNode = new BSPNode(); rightNode.setCube(cube1); rightNode.setParentNode(this); GameObject.DestroyImmediate(_aSection); } }
private void visualizeNode(BSPNode node, bool includeLeafOutlines) { // Visualize the carved area in the node foreach (LevelGenMap.Coordinate coord in node.CarvedArea) { this.Map.Grid[coord.x, coord.y] = this.FillTileType; } // Visualize leaf outlines if desired if (!includeLeafOutlines || node.Children == null) { return; } if (node.Children[0].Bounds.width == node.Bounds.width) { // Horizontal line for (int x = node.Children[0].Bounds.IntXMin(); x < node.Children[0].Bounds.IntXMax(); ++x) { this.Map.Grid[x, node.Children[0].Bounds.IntYMax()] = this.FillTileType; } } else { // Vertical line for (int y = node.Children[0].Bounds.IntYMin(); y < node.Children[0].Bounds.IntYMax(); ++y) { this.Map.Grid[node.Children[0].Bounds.IntXMax(), y] = this.FillTileType; } } }
public bool SplitAt(int position, int direction, float minWidth, float minHeight) { CustomRect rect1 = null; CustomRect rect2 = null; if (direction == 0) //Horizontal split { rect1 = (new CustomRect(rect.x, rect.y, rect.width, position - rect.y)); rect2 = (new CustomRect(rect.x, position, rect.width, rect.yMax - position)); } else if (direction == 1) // vertical split { rect1 = (new CustomRect(rect.x, rect.y, position - rect.x, rect.height)); rect2 = (new CustomRect(position, rect.y, rect.xMax - position, rect.height)); } if ((rect1.width >= minWidth && rect1.height >= minHeight) && (rect2.width >= minWidth && rect2.height >= minHeight)) { childNodes = new BSPNode[2]; childNodes[0] = new BSPNode(rect1); childNodes[1] = new BSPNode(rect2); rect = CustomRect.Zero; return(true); } return(false); }
public void RoomConnectionPhase(int frames) { for (int i = 0; i < frames; ++i) { if (_nodeList.Count <= 1) { _numExtraCorridorsToMake = Mathf.RoundToInt(_rooms.Count * this.ExtraCorridorsPerRoom); _leaves.Shuffle(); this.NextPhase(); break; } BSPNode node1 = _nodeList[_nodeList.Count - 1]; BSPNode node2 = _nodeList[_nodeList.Count - 2]; _nodeList.RemoveRange(_nodeList.Count - 2, 2); if (Random.Range(0, 2) == 0) { joinNodes(node1, node2, true); } else { joinNodes(node2, node1, true); } } }
private static void CM_BoxLeafs_Recursive(BSPNode node) { int s; while (!(node is BSPLeaf)) { s = Utils.BoxOnPlaneSide(leaf_mins, leaf_maxs, node.Plane); if (s == 1) { node = node.front_node; //M is this the correct child? - yes it is /M } else if (s == 2) { node = node.back_node; } else { //go down both if (leaf_topnode == null) { leaf_topnode = node; } CM_BoxLeafs_Recursive(node.front_node); node = node.back_node; } } if (leaf_count < leaf_maxcount) { leaf_list[leaf_count] = node as BSPLeaf; leaf_count++; } }
private BSPNodeWrapper Init(BSPNode <IPoly> node) { this.node = node; if (node.inside == null) { //var left = new GameObject("left: null"); //left.transform.parent = transform; } else { var left = Create("left", node.inside); left.transform.parent = transform; } if (node.outside == null) { //var right = new GameObject("right: null"); //right.transform.parent = transform; } else { var right = Create("right", node.outside); right.transform.parent = transform; } return(this); }
private void connectRooms(BSPNode _aNode) { if (_aNode.getLeftNode() != null){ connectRooms(_aNode.getLeftNode()); if (_aNode.getRoom() != null){ _aNode.getRoom().GetComponent<RoomCreator>().connect(); return; } }else{ if (_aNode.getRoom() != null){ _aNode.getRoom().GetComponent<RoomCreator>().connect(); return; } } if (_aNode.getRightNode() != null){ connectRooms(_aNode.getRightNode()); if (_aNode.getRoom() != null){ _aNode.getRoom().GetComponent<RoomCreator>().connect(); return; } }else{ if (_aNode.getRoom() != null){ _aNode.getRoom().GetComponent<RoomCreator>().connect(); return; } } }
public bool Iterate() { BSPNode maxAreaNode = _root; BSPNode node = FindNodeWithMoreArea(_root, ref maxAreaNode); return(Divide(node)); }
private List <BSPNode> GetSubtreeLeafs(BSPNode node) { List <BSPNode> result = new List <BSPNode>(); Stack <BSPNode> stack = new Stack <BSPNode>(); stack.Push(node); while (stack.Count > 0) { BSPNode n = stack.Pop(); if (n.isLeaf) { result.Add(n); } else { if (n.children[0] != null) { stack.Push(n.children[0]); } if (n.children[1] != null) { stack.Push(n.children[1]); } } } return(result); }
public void GenerateMap(ref int[] map, BaseMapContext mapGenContext) { _context = (BSPContext)mapGenContext; _bspGenData = (BSPGeneratorData)_context.GeneratorData; if (_bspGenData.IsSeeded) { URandom.state = JsonUtility.FromJson <URandom.State>(_bspGenData.Seed); } else { Debug.Log("Current state: " + JsonUtility.ToJson(URandom.state)); } int[,] mapAux = new int[_bspGenData.MapSize.x, _bspGenData.MapSize.y]; mapAux.Fill <int>(_bspGenData.NoTile); var tree = new BSPNode(); _context.Tree = tree; tree.context = _context; tree.left = tree.right = null; tree.area = new BSPRect(1, 1, _bspGenData.MapSize.x - 2, _bspGenData.MapSize.y - 2); GenerateRooms(ref mapAux); GeneratorUtils.ConvertGrid(mapAux, out map); }
public static BSPLeaf NodePointSearch(BSPNode node, Vector3 point) { float d; int i = 0; BSPNode sourcenode = node; while (!(sourcenode is BSPLeaf)) { i++; d = PlaneDiff(point, BSPFile.planes[sourcenode.plane]); if (d < 0) { sourcenode = sourcenode.back_node; } else { sourcenode = sourcenode.front_node; } if (i > 5000) { Console.DebugLog("node point doesnt seem to end"); return(null); } } return(sourcenode as BSPLeaf); }
public bool Split() { float hsplitRoll = URandom.value; BSPGeneratorData bspData = context.BSPData; bool horizontalSplit = hsplitRoll < bspData.HorizontalSplitChance; float hRatio = area.Width / (float)area.Height; float vRatio = 1 / hRatio; if (hRatio >= 1.0f + bspData.VerticalSplitRatio) { horizontalSplit = false; } else if (vRatio > 1.0f + bspData.HorizontalSplitRatio) { horizontalSplit = true; } int maxSize = 0; int minSize = 0; if (horizontalSplit) { maxSize = area.Height - bspData.MinAreaSize.x; minSize = bspData.MinAreaSize.x; } else { maxSize = area.Width - bspData.MinAreaSize.y; minSize = bspData.MinAreaSize.x; } if (maxSize <= minSize) { return(false); } int splitValue = URandom.Range(minSize, maxSize + 1); left = new BSPNode(); left.context = context; right = new BSPNode(); right.context = context; if (horizontalSplit) { left.area = new BSPRect(area.Row, area.Col, splitValue, area.Width); right.area = new BSPRect(area.Row + splitValue, area.Col, area.Height - splitValue, area.Width); } else { left.area = new BSPRect(area.Row, area.Col, area.Height, splitValue); right.area = new BSPRect(area.Row, area.Col + splitValue, area.Height, area.Width - splitValue); } left.Split(); right.Split(); return(true); }
public static void Split_CreatesTwoChildNodes() { var node = new BSPNode(); node.Split(); Assert.NotNull(node.leftChild_); Assert.NotNull(node.rightChild_); }
public BSPTree(int width, int height, int minNodeWidth, int minNodeHeight) { bool doSplitVertically = width >= height; this.minNodeWidth = minNodeWidth; this.minNodeHeight = minNodeHeight; root = new BSPNode(null, new RectInt(0, 0, width, height), doSplitVertically); Split(root); }
public void DrawNode(BSPNode n) { GameObject go = Instantiate(floorPrefab) as GameObject; Vector3 position = new Vector3(n.rect.x, 0f, n.rect.y); Vector3 scale = new Vector3(n.rect.width, 1f, n.rect.height); go.transform.position = position; go.transform.localScale = scale; }
private BSPNode createNode(Rect bounds) { BSPNode node = new BSPNode(); node.Bounds = bounds; node.Children = null; node.CarvedArea = new List <LevelGenMap.Coordinate>(); return(node); }
private void Draw <T>(BSPNode <T> node, Color color) where T : IPoly { if (node == null || node.poly == null || node.poly.working == null) { return; } node.poly.working.Draw(color); Draw(node.inside, color); Draw(node.outside, color); }
public BSPTree(int width, int height, int minRoomSize, ref Random random) { BSPNode.MinRoomSize = minRoomSize; this.Root = new BSPNode(new NodeComponent { RectBounds = new int4(0, 0, height, width) }); this.Root.SplitNode(ref random); this.Height = this.Root.TreeHeight(); }
public void connect() { getSibiling(); if (sibiling != null) { Vector3 startPos = new Vector3(); Vector3 endPos = new Vector3(); if (sibiling.transform.position.z + sibiling.transform.localScale.z < transform.position.z) { startPos = chooseDoorPoint(0); endPos = sibiling.GetComponent <RoomCreator>().chooseDoorPoint(2); } else if (sibiling.transform.position.z > transform.position.z + transform.localScale.z) { startPos = chooseDoorPoint(2); endPos = sibiling.GetComponent <RoomCreator>().chooseDoorPoint(1); } else if (sibiling.transform.position.x + sibiling.transform.localScale.x < transform.position.x) { startPos = chooseDoorPoint(3); endPos = sibiling.GetComponent <RoomCreator>().chooseDoorPoint(1); } else if (sibiling.transform.position.x > transform.position.x + transform.localScale.x) { startPos = chooseDoorPoint(1); endPos = sibiling.GetComponent <RoomCreator>().chooseDoorPoint(3); } GameObject aDigger = (GameObject)Instantiate(Resources.Load("Digger"), startPos, Quaternion.identity); aDigger.GetComponent <Digger>().begin(endPos); parentNode = findRoomlessParent(parentNode); if (parentNode != null) { int aC = Random.Range(0, 2); if (aC == 0) { parentNode.setRoom(this.gameObject); } else { parentNode.setRoom(sibiling.gameObject); } sibiling.GetComponent <RoomCreator>().setParentNode(parentNode); } } }
public void AddConnection(BSPNode node) { foreach (var connection in connectedNodes) { if (connection.id == node.id) { return; } } connectedNodes.Add(node); }
public BSPNode findRoomlessParent(BSPNode _aNode) { if (_aNode != null){ if (_aNode.getRoom() == null){ return _aNode; }else{ return findRoomlessParent(_aNode.getParentNode()); } } return null; }
//split the tree public void split(BSPNode _aNode) { if (_aNode.getLeftNode() != null){ split(_aNode.getLeftNode()); }else{ _aNode.cut(); return; } if (_aNode.getLeftNode() != null){ split(_aNode.getRightNode()); } }
List <BSPNode> FindOverlapping(BSPNode node, List <BSPNode> candidates, bool xDim) { List <BSPNode> overlapping = new List <BSPNode>(); for (int i = 0; i < candidates.Count; i++) { if (halfOverlap(node.room, candidates[i].room, xDim) > 1.5f) { overlapping.Add(candidates[i]); } } return(overlapping); }
private void RecursiveFill(Level level, BSPNode node) { if (node.isLeaf) { int width = node.max.x - node.min.x; int height = node.max.y - node.min.y; int shrinkWidthRange = width - _minRoomSize; if (shrinkWidthRange < 0) { shrinkWidthRange = 0; } int shrinkHeightRange = height - _minRoomSize; if (shrinkHeightRange < 0) { shrinkHeightRange = 0; } int shrinkHorizontal = UnityEngine.Random.Range(0, shrinkWidthRange); int shrinkLeft = shrinkHorizontal / 2; int shrinkRight = shrinkHorizontal / 2 + shrinkHorizontal % 2; int shrinkVertical = UnityEngine.Random.Range(0, shrinkHeightRange); int shrinkDown = shrinkVertical / 2; int shrinkUp = shrinkVertical / 2 + shrinkVertical % 2; node.realMin = new Vector2Int(node.min.x + shrinkLeft, node.min.y + shrinkDown); node.realMax = new Vector2Int(node.max.x - shrinkRight, node.max.y - shrinkUp); for (int i = node.realMin.x; i < node.realMax.x; i++) { for (int j = node.realMin.y; j < node.realMax.y; j++) { if (i == node.realMin.x || j == node.realMin.y || i == (node.realMax.x - 1) || j == (node.realMax.y - 1)) { level.Map[i, j] = CellType.Wall; } else { level.Map[i, j] = CellType.Floor; } } } } else { RecursiveFill(level, node.children[0]); RecursiveFill(level, node.children[1]); } }
private void addRoom(BSPNode _aNode) { GameObject aObj = _aNode.getCube(); GameObject aRoom = (GameObject) Instantiate(Resources.Load("BaseRoom"),aObj.transform.position,Quaternion.identity); aRoom.transform.localScale = new Vector3( (int)(Random.Range(10, aObj.transform.localScale.x-5)), aRoom.transform.localScale.y, (int)(Random.Range(10, aObj.transform.localScale.z-5))); aRoom.GetComponent<RoomCreator>().setup(); aRoom.GetComponent<RoomCreator>().setID(roomID); aRoom.GetComponent<RoomCreator>().setParentNode(_aNode); _aNode.setRoom(aRoom); roomID++; }
public void Init(GameObject pGameObj, Mesh pMesh) { gameObj = pGameObj; mesh = pMesh; triangles = new List<int>(mesh.triangles); vertices = new List<Vector3>(mesh.vertices); planeEquations = new List<Plane>(); CalcPlaneEquations(); root = new BSPNode(); root.subtreeNodes = planeEquations; ConstructTree(root); }
public BSPAccelerator (IEnumerable<RenderItem> items, SplitHeuristic sh, IEnumerable<Point3> facenormals, int maxDepth, int maxSize = 2) { double ta, tb; List<NormalInterval> fn = new List<NormalInterval>(); foreach(Point3 normal in facenormals) { double tta = double.PositiveInfinity; double ttb = double.NegativeInfinity; foreach(RenderItem ri in items) { ri.GetFaceNormalBounds(normal, out ta, out tb); tta = Math.Min(tta, ta); ttb = Math.Max(ttb, tb); } fn.Add(new NormalInterval(normal, tta, ttb)); } this.intervals = fn.ToArray(); LinkedList<RenderItem> caches = new LinkedList<RenderItem>(items); this.root = Split(caches, sh, fn, maxDepth, maxSize, 0x00); }
public void connect() { getSibiling(); if (sibiling != null){ Vector3 startPos = new Vector3(); Vector3 endPos = new Vector3(); if (sibiling.transform.position.z + sibiling.transform.localScale.z < transform.position.z){ startPos = chooseDoorPoint(0); endPos = sibiling.GetComponent<RoomCreator>().chooseDoorPoint(2); }else if (sibiling.transform.position.z > transform.position.z + transform.localScale.z){ startPos = chooseDoorPoint(2); endPos = sibiling.GetComponent<RoomCreator>().chooseDoorPoint(1); }else if (sibiling.transform.position.x + sibiling.transform.localScale.x < transform.position.x){ startPos = chooseDoorPoint(3); endPos = sibiling.GetComponent<RoomCreator>().chooseDoorPoint(1); }else if(sibiling.transform.position.x > transform.position.x + transform.localScale.x){ startPos = chooseDoorPoint(1); endPos = sibiling.GetComponent<RoomCreator>().chooseDoorPoint(3); } GameObject aDigger = (GameObject) Instantiate(Resources.Load("Digger"),startPos,Quaternion.identity); aDigger.GetComponent<Digger>().begin(endPos); parentNode = findRoomlessParent(parentNode); if (parentNode != null){ int aC = Random.Range(0,2); if (aC == 0){ parentNode.setRoom(this.gameObject); }else{ parentNode.setRoom(sibiling.gameObject); } sibiling.GetComponent<RoomCreator>().setParentNode(parentNode); } } }
void ConstructTree(BSPNode theRoot) { theRoot.node = theRoot.subtreeNodes[0]; for (int i = 1; i < theRoot.subtreeNodes.Count; i++) { FaceRelation relation = GetFaceRelation(theRoot.node, theRoot.subtreeNodes[i].indices); if (relation == FaceRelation.Front) { if (theRoot.frontNode == null) theRoot.frontNode = new BSPNode(); theRoot.frontNode.subtreeNodes.Add(theRoot.subtreeNodes[i]); } else if (relation == FaceRelation.Back) { if (theRoot.backNode == null) theRoot.backNode = new BSPNode(); theRoot.backNode.subtreeNodes.Add(theRoot.subtreeNodes[i]); } else if (relation == FaceRelation.Intersect) { // TODO } } theRoot.subtreeNodes.Clear(); if (theRoot.frontNode != null && theRoot.frontNode.subtreeNodes.Count != 0) ConstructTree(theRoot.frontNode); if (theRoot.backNode != null && theRoot.backNode.subtreeNodes.Count != 0) ConstructTree(theRoot.backNode); }
private BSPNode createNode(Rect bounds) { BSPNode node = new BSPNode(); node.Bounds = bounds; node.Children = null; node.CarvedArea = new List<LevelGenMap.Coordinate>(); return node; }
public static BSPNode ReadBSPNode(BinaryReader reader) { var node = new BSPNode { flags = ((BSPNodeFlags)reader.ReadByte()), negChild = reader.ReadInt16(), posChild = reader.ReadInt16(), planeDist = reader.ReadSingle() }; var numIndices = reader.ReadUInt16(); if (numIndices > 0) { var indices = new Index3[numIndices]; for (var i = 0; i < numIndices; i++) { indices[i] = reader.ReadIndex3(); } node.TriIndices = indices; } else { node.TriIndices = null; } return node; }
public static BSPTree ReadBSPTree(BinaryReader reader) { var rootId = reader.ReadInt16(); BSPNode[] nodes; var numNodes = reader.ReadUInt16(); if (numNodes > 0) { nodes = new BSPNode[numNodes]; for (var i = 0; i < numNodes; i++) { nodes[i] = ReadBSPNode(reader); } } else { nodes = null; } return new BSPTree(rootId, nodes); }
void MakeRooms( BSPNode node, ref HashSet<BSPNode> processed ) { if( node.isSplit_ ) { MakeRooms(node.leftChild_, ref processed); MakeRooms(node.rightChild_, ref processed); return; } if ( node.area_ != null && node.parent_ != null && node.parent_.isSplit_ && !processed.Contains( node ) ) { var leftArea = node.parent_.leftChild_.area_; var rightArea = node.parent_.rightChild_.area_; if (leftArea == null) Debug.Log("LEFT AREA IS NULL"); if (rightArea == null) Debug.Log("Right Area is null"); var roomA = DungeonArea.BuildRoomInArea(leftArea, minRoomSize_); var roomB = DungeonArea.BuildRoomInArea(rightArea, minRoomSize_); roomA.adjacentArea_.Add(roomB); roomB.adjacentArea_.Add(roomA); rooms_.Add(roomA); rooms_.Add(roomB); processed.Add(node.parent_.leftChild_); processed.Add(node.parent_.rightChild_); } }
public void setRightNode(BSPNode _aNode) { rightNode = _aNode; }
public void setLeftNode(BSPNode _aNode) { leftNode = _aNode; }
void Awake() { Random.seed = seed_; root_ = new BSPNode(new IntRect(0, 0, size_.x, size_.y)); }
private BSPNode[] splitNode(BSPNode parent) { bool tooThin = parent.Bounds.width <= this.MinLeafSize * 2; bool tooShort = parent.Bounds.height <= this.MinLeafSize * 2; if (tooThin && tooShort) return null; // Decide direction split the node bool verticalSplit; if (tooShort|| (parent.Bounds.width > parent.Bounds.height && parent.Bounds.height / parent.Bounds.width < this.MinNodeWHRatio)) { verticalSplit = true; } else if (tooThin || (parent.Bounds.height > parent.Bounds.width && parent.Bounds.width / parent.Bounds.height < this.MinNodeWHRatio)) { verticalSplit = false; } else { verticalSplit = Random.Range(0, 2) == 0 ? false : true; } // Find the point at which to cut the node and create the children BSPNode[] nodes = new BSPNode[2]; int divider = 0; if (verticalSplit) { divider = Random.Range(parent.Bounds.IntXMin() + this.MinLeafSize, parent.Bounds.IntXMax() - 1 - this.MinLeafSize); nodes[0] = createNode(new Rect(parent.Bounds.xMin, parent.Bounds.yMin, divider - parent.Bounds.IntXMin(), parent.Bounds.height)); nodes[1] = createNode(new Rect(nodes[0].Bounds.xMax, nodes[0].Bounds.yMin, parent.Bounds.IntXMax() - nodes[0].Bounds.xMax, parent.Bounds.height)); } else { divider = Random.Range(parent.Bounds.IntYMin() + this.MinLeafSize, parent.Bounds.IntYMax() - 1 - this.MinLeafSize); nodes[0] = createNode(new Rect(parent.Bounds.xMin, parent.Bounds.yMin, parent.Bounds.width, divider - parent.Bounds.IntYMin())); nodes[1] = createNode(new Rect(nodes[0].Bounds.xMin, nodes[0].Bounds.yMax, parent.Bounds.width, parent.Bounds.IntYMax() - nodes[0].Bounds.yMax)); } return nodes; }
public BSPNode (RenderItem[] items) { splitNormal = null; left = right = null; xa = xb = double.NaN; this.items = items; }
public BSPNode (Point3 splitNormal, double tm, double ta, double tb, double tM, BSPNode left, BSPNode right) { this.splitNormal = splitNormal; this.xm = tm; this.xa = ta; this.xb = tb; this.xM = tM; this.left = left; this.right = right; this.items = null; }
void CreateNodes(BSPTree bsp, IntGrid2 grid, int i) { int middle; bool horiz; if (grid.Columns <= 4 && grid.Rows <= 4) { Debugger.Break(); throw new Exception(); } else if (grid.Columns <= 4) { horiz = true; } else if (grid.Rows <= 4) { horiz = false; } else { horiz = grid.Columns < grid.Rows; } double m = GetRandomDouble(0.4, 0.6); if (horiz) middle = (int)(grid.Rows * m); else middle = (int)(grid.Columns * m); bsp[i] = new BSPNode(grid, horiz); if (bsp.IsLeaf(i)) return; int left = bsp.GetLeft(i); int right = bsp.GetRight(i); if (horiz) { // up var g1 = new IntGrid2(grid.X, grid.Y, grid.Columns, middle); CreateNodes(bsp, g1, left); // down var g2 = new IntGrid2(grid.X, grid.Y + middle + 1, grid.Columns, grid.Rows - middle - 1); CreateNodes(bsp, g2, right); } else { // left var g1 = new IntGrid2(grid.X, grid.Y, middle, grid.Rows); CreateNodes(bsp, g1, left); // right var g2 = new IntGrid2(grid.X + middle + 1, grid.Y, grid.Columns - middle - 1, grid.Rows); CreateNodes(bsp, g2, right); } }
private void createRoomInLeaf(BSPNode leaf) { int width = Random.Range(this.RoomMinSize, this.RoomMaxSize + 1); int height = Random.Range(this.RoomMinSize, this.RoomMaxSize + 1); if (width > leaf.Bounds.IntWidth()) width = leaf.Bounds.IntWidth(); if (height > leaf.Bounds.IntHeight()) height = leaf.Bounds.IntHeight(); int leftX = Random.Range(leaf.Bounds.IntXMin(), leaf.Bounds.IntXMin() + (leaf.Bounds.IntWidth() - width) + 1); int topY = Random.Range(leaf.Bounds.IntYMin(), leaf.Bounds.IntYMin() + (leaf.Bounds.IntHeight() - height) + 1); Rect roomRect = new Rect(leftX, topY, width, height); this.Map.FillRect(roomRect, this.FillTileType); leaf.CarvedArea.AddRange(this.Map.CoordinatesInRect(roomRect)); _rooms.Add(roomRect); }
public void Reset() { rooms_.Clear (); tunnels_.Clear(); root_ = new BSPNode(new IntRect(0, 0, size_.x, size_.y)); }
private void joinNodes(BSPNode node1, BSPNode node2, bool checkPathFind) { List<LevelGenMap.Coordinate> carvedArea1 = node1.GetTotalCarvedArea(); List<LevelGenMap.Coordinate> carvedArea2 = node2.GetTotalCarvedArea(); if (carvedArea1.Count == 0 || carvedArea2.Count == 0) return; // Depending on param, only connect nodes at this point if cannot already pathfind between them. if (checkPathFind && this.Map.CanPathBetweenCoordinates(carvedArea1[0], carvedArea2[0])) return; carvedArea1.Shuffle(); carvedArea2.Shuffle(); bool leftToRight = node1.Bounds.center.x < node2.Bounds.center.x; bool topToBottom = node1.Bounds.center.y < node2.Bounds.center.y; LevelGenMap.Coordinate? bestCoord1 = null; LevelGenMap.Coordinate? bestCoord2 = null; // Greater x distance if (Mathf.Abs(node1.Bounds.center.x - node2.Bounds.center.x) > Mathf.Abs(node1.Bounds.center.y - node2.Bounds.center.y)) { // Check if there is a shared y-coordinate in carved area foreach (LevelGenMap.Coordinate coord1 in carvedArea1) { if (bestCoord1.HasValue) { if (coord1.y == bestCoord1.Value.y && ((leftToRight && (coord1.x > bestCoord1.Value.x)) || (!leftToRight && (coord1.x < bestCoord1.Value.x)))) { bestCoord1 = coord1; } } else if (coord1.y >= node2.Bounds.IntYMin() && coord1.y < node2.Bounds.IntYMax()) { foreach (LevelGenMap.Coordinate coord2 in carvedArea2) { if (bestCoord2.HasValue) { if (coord2.y == bestCoord2.Value.y && ((leftToRight && (coord2.x < bestCoord2.Value.x)) || (!leftToRight && (coord2.x > bestCoord2.Value.x)))) { bestCoord2 = coord2; } } else if (coord1.y == coord2.y) { bestCoord1 = coord1; bestCoord2 = coord2; } } } } } // Greater y distance else { // Check if there is a shared x-coordinate in carved area foreach (LevelGenMap.Coordinate coord1 in carvedArea1) { if (bestCoord1.HasValue) { if (coord1.x == bestCoord1.Value.x && ((topToBottom && (coord1.y > bestCoord1.Value.y)) || (!topToBottom && (coord1.y < bestCoord1.Value.y)))) { bestCoord1 = coord1; } } else if (coord1.x >= node2.Bounds.IntXMin() && coord1.x < node2.Bounds.IntXMax()) { foreach (LevelGenMap.Coordinate coord2 in carvedArea2) { if (bestCoord2.HasValue) { if (coord2.x == bestCoord2.Value.x && ((topToBottom && (coord2.y < bestCoord2.Value.y)) || (!topToBottom && (coord2.y > bestCoord2.Value.y)))) { bestCoord2 = coord2; } } else if (coord1.x == coord2.x) { bestCoord1 = coord1; bestCoord2 = coord2; } } } } } // Did we find an ideal (straight-line) connection? if (!bestCoord1.HasValue) { // Otherwise, pick a random y in node1 and and random x in node2. // Pick closest tile in node1 with that y value to left or right (direction of node2). // Pick closest tile in node2 with that x value to up or down (direction of node1). foreach (LevelGenMap.Coordinate coord in carvedArea1) { if (!bestCoord1.HasValue || (coord.y == bestCoord1.Value.y && ((leftToRight && coord.x > bestCoord1.Value.x) || (!leftToRight && coord.x < bestCoord1.Value.x)))) { bestCoord1 = coord; } } foreach (LevelGenMap.Coordinate coord in carvedArea2) { if (!bestCoord2.HasValue || (coord.x == bestCoord2.Value.x && ((topToBottom && coord.y < bestCoord2.Value.y) || (!topToBottom && coord.y > bestCoord2.Value.y)))) { bestCoord2 = coord; } } } // Connect the points if (bestCoord1.HasValue && bestCoord2.HasValue) tracePathBetweenCoordinates(bestCoord1.Value, bestCoord2.Value); else Debug.Log("Didn't find coords to connect"); }
void splitZ(GameObject _aSection) { float zSplit = Random.Range(20,_aSection.transform.localScale.z-20); float zSplit1 = _aSection.transform.localScale.z - zSplit; if (zSplit > 20){ GameObject cube0 = GameObject.CreatePrimitive(PrimitiveType.Cube); cube0.transform.localScale = new Vector3 (_aSection.transform.localScale.x, _aSection.transform.localScale.y,zSplit); cube0.transform.position = new Vector3( _aSection.transform.position.x, _aSection.transform.position.y, _aSection.transform.position.z - ((zSplit - _aSection.transform.localScale.z)/2)); cube0.renderer.material.color = new Color(Random.Range(0.0f,1.0f),Random.Range(0.0f,1.0f), Random.Range(0.0f,1.0f)); cube0.tag = "GenSection"; leftNode = new BSPNode(); leftNode.setCube(cube0); leftNode.setParentNode(this); GameObject cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube); cube1.transform.localScale = new Vector3 (_aSection.transform.localScale.x, _aSection.transform.localScale.y,zSplit1); cube1.transform.position = new Vector3( _aSection.transform.position.x, _aSection.transform.position.y, _aSection.transform.position.z+ ((zSplit1 - _aSection.transform.localScale.z)/2)); cube1.renderer.material.color = new Color(Random.Range(0.0f,1.0f),Random.Range(0.0f,1.0f), Random.Range(0.0f,1.0f)); cube1.tag = "GenSection"; rightNode = new BSPNode(); rightNode.setCube(cube1); rightNode.setParentNode(this); GameObject.DestroyImmediate(_aSection); } }
public void setParentNode(BSPNode _aNode) { parentNode = _aNode; }
private void visualizeNode(BSPNode node, bool includeLeafOutlines) { // Visualize the carved area in the node foreach (LevelGenMap.Coordinate coord in node.CarvedArea) { this.Map.Grid[coord.x, coord.y] = this.FillTileType; } // Visualize leaf outlines if desired if (!includeLeafOutlines || node.Children == null) return; if (node.Children[0].Bounds.width == node.Bounds.width) { // Horizontal line for (int x = node.Children[0].Bounds.IntXMin(); x < node.Children[0].Bounds.IntXMax(); ++x) { this.Map.Grid[x, node.Children[0].Bounds.IntYMax()] = this.FillTileType; } } else { // Vertical line for (int y = node.Children[0].Bounds.IntYMin(); y < node.Children[0].Bounds.IntYMax(); ++y) { this.Map.Grid[node.Children[0].Bounds.IntXMax(), y] = this.FillTileType; } } }
public static void Split_ChildNode_AlwaysHasSibling() { var node = new BSPNode(); node.Split(); }
void Split( int minSize, SplitDirection dir, int position ) { int axis = dir == SplitDirection.Random ? Random.Range(0, 2) : (int)dir; int otherAxis = 1 - axis; if (position == -1) position = Random.Range(minSize, area_.size_[otherAxis] - minSize); // Debug.Log("Position: " + position); // Size of the "left over" area var remainingAreaOtherAxisSize = area_.size_[otherAxis] - position; // Size of the area inside the slice var slicedAreaOtherAxisSize = area_.size_[otherAxis] - remainingAreaOtherAxisSize; // Size of both new nodes along slice axis var axisSize = area_.size_[axis]; var remainingAreaSize = new IntVector2(); remainingAreaSize[axis] = axisSize; remainingAreaSize[otherAxis] = remainingAreaOtherAxisSize; var slicedAreaSize = new IntVector2(); slicedAreaSize[axis] = axisSize; slicedAreaSize[otherAxis] = slicedAreaOtherAxisSize; if (axis == 0) { IntRect remainingArea = new IntRect(area_.xMin_, area_.yMin_ + position, remainingAreaSize.x, remainingAreaSize.y); IntRect slicedArea = new IntRect(area_.xMin_, area_.yMin_, slicedAreaSize.x, slicedAreaSize.y); childNodes_[0] = new BSPNode(remainingArea); childNodes_[1] = new BSPNode(slicedArea); } if (axis == 1) { IntRect slicedArea = new IntRect(area_.xMin_, area_.yMin_, slicedAreaSize.x, slicedAreaSize.y); IntRect remainingArea = new IntRect(area_.xMin_ + slicedArea.w_, area_.yMin_, remainingAreaSize.x, remainingAreaSize.y); childNodes_[0] = new BSPNode(slicedArea); childNodes_[1] = new BSPNode(remainingArea); } childNodes_[0].parent_ = this; childNodes_[0].sibling_ = childNodes_[1]; childNodes_[1].sibling_ = childNodes_[0]; childNodes_[1].parent_ = this; }