public static bool ClosestPointOnSurface(Collider col, Vector3 to, float radius, out Vector3 concatPoint) { bool isConcated = true; if (col is BoxCollider) { concatPoint = ClosestOnOBB((BoxCollider)col, to); } else if (col is SphereCollider) { concatPoint = col.ClosestPointOnBounds(to); } else if (col is MeshCollider) { BSPTree bsp = col.gameObject.GetComponent <BSPTree>(); if (bsp != null) { concatPoint = bsp.ClosestPointOn(to, radius); } else { concatPoint = col.ClosestPointOnBounds(to); } } else { concatPoint = Vector3.zero; isConcated = false; } return(isConcated); }
public CellStruct(DatLoader.Entity.CellStruct cellStruct) { NumPortals = cellStruct.Portals.Count; NumPolygons = cellStruct.Polygons.Count; NumPhysicsPolygons = cellStruct.PhysicsPolygons.Count; Polygons = new Dictionary <ushort, Polygon>(); foreach (var poly in cellStruct.Polygons) { Polygons.Add(poly.Key, new Polygon(poly.Value, cellStruct.VertexArray)); } Portals = new List <Polygon>(); foreach (var portal in cellStruct.Portals) { Portals.Add(Polygons[portal]); } PhysicsPolygons = new Dictionary <ushort, Polygon>(); foreach (var poly in cellStruct.PhysicsPolygons) // todo: link to regular polys { PhysicsPolygons.Add(poly.Key, new Polygon(poly.Value, cellStruct.VertexArray)); } if (cellStruct.CellBSP != null) { CellBSP = new BSPTree(cellStruct.CellBSP, cellStruct.PhysicsPolygons, cellStruct.VertexArray); // physics or drawing? } if (cellStruct.DrawingBSP != null) { DrawingBSP = new BSPTree(cellStruct.DrawingBSP, cellStruct.Polygons, cellStruct.VertexArray); } if (cellStruct.PhysicsBSP != null) { PhysicsBSP = new BSPTree(cellStruct.PhysicsBSP, cellStruct.PhysicsPolygons, cellStruct.VertexArray); } }
public static Vector3 ClosestPointOnSurface(Collider collider, Vector3 to, float radius) { if (collider is BoxCollider) { return(SuperCollider.ClosestPointOnSurface((BoxCollider)collider, to)); } else if (collider is SphereCollider) { return(SuperCollider.ClosestPointOnSurface((SphereCollider)collider, to)); } else if (collider is CapsuleCollider) { return(SuperCollider.ClosestPointOnSurface((CapsuleCollider)collider, to)); } else if (collider is MeshCollider) { BSPTree bsp = collider.GetComponent <BSPTree>(); if (bsp != null) { return(bsp.ClosestPointOn(to, radius)); } BruteForceMesh bfm = collider.GetComponent <BruteForceMesh>(); if (bfm != null) { return(bfm.ClosestPointOn(to)); } } return(Vector3.zero); }
public void setup() { transform.position = new Vector3((int)transform.position.x, (int)transform.position.y, (int)transform.position.z); transform.position = new Vector3(transform.position.x - (transform.localScale.x / 2), transform.position.y, transform.position.z - (transform.localScale.z / 2)); for (int i = (int)transform.position.x; i < (int)transform.position.x + transform.localScale.x; i++) { for (int j = (int)transform.position.z; j < (int)transform.position.z + transform.localScale.z; j++) { BSPTree.setTile(i, j, 1); } } for (int i = 0; i < transform.localScale.x + 1; i++) { BSPTree.setTile((int)transform.position.x + i, (int)transform.position.z, 2); BSPTree.setTile((int)transform.position.x + i, (int)(transform.position.z + transform.localScale.z), 2); } for (int i = 0; i < transform.localScale.z + 1; i++) { BSPTree.setTile((int)transform.position.x, (int)transform.position.z + i, 2); BSPTree.setTile((int)(transform.position.x + transform.localScale.x), (int)transform.position.z + i, 2); } }
void CreateBSPTree() { bsp = new BSPTree(width, height, minSplitableNodeWidth, minSplitableNodeHeight); bsp.CreateNodeLists(); //TODO moeglicher refactor CreateGeometry(); vis = true; }
private void main() { Partition Board = new Partition(new Rect(0, 0, boardRows, boardColumns)); Floor = new GameObject[boardRows, boardColumns]; RoomManager objRoomManager = new RoomManager( trim, boardRows, boardColumns); BSPTree objBspTree = new BSPTree( maxRoomWidth, maxRoomHeight, spiltProb); for (int i = -1; i < bspIteration; ++i) { objBspTree.CreateBSP(Board); } objBspTree.InstantiateRooms(Board); objRoomManager.Rooms = objBspTree.getRooms(Board); // DrawRooms(objRoomManager.Rooms); List <Rect> trimmed = objRoomManager.trimRooms(); DrawRooms(trimmed); }
public CellStruct(DatLoader.Entity.CellStruct cellStruct) { Polygons = new Dictionary <ushort, Polygon>(); foreach (var poly in cellStruct.Polygons) { Polygons.Add(poly.Key, PolygonCache.Get(poly.Value, cellStruct.VertexArray)); } Portals = new List <Polygon>(); foreach (var portal in cellStruct.Portals) { Portals.Add(Polygons[portal]); } PhysicsPolygons = new Dictionary <ushort, Polygon>(); foreach (var poly in cellStruct.PhysicsPolygons) { PhysicsPolygons.Add(poly.Key, PolygonCache.Get(poly.Value, cellStruct.VertexArray)); } if (cellStruct.CellBSP != null) { CellBSP = BSPCache.Get(cellStruct.CellBSP, cellStruct.PhysicsPolygons, cellStruct.VertexArray); } if (cellStruct.DrawingBSP != null) { DrawingBSP = BSPCache.Get(cellStruct.DrawingBSP, cellStruct.Polygons, cellStruct.VertexArray); } if (cellStruct.PhysicsBSP != null) { PhysicsBSP = BSPCache.Get(cellStruct.PhysicsBSP, cellStruct.PhysicsPolygons, cellStruct.VertexArray); } }
public void ClassifyFaceSpanTest() { // Arrange BSPFace face = new BSPFace(); face.Points.Add(new BSPVertex { Point = new Vector3(-1.0f, -2.0f, 0.0f) }); face.Points.Add(new BSPVertex { Point = new Vector3(0.0f, 2.0f, 0.0f) }); face.Points.Add(new BSPVertex { Point = new Vector3(1.0f, -2.0f, 0.0f) }); face.Point = face.Points[0].Point; face.Normal = new Vector3(0.0f, 0.0f, 1.0f); Vector3 planePoint = new Vector3(0.0f, 1.0f, 0.0f); // Just a basic plane Vector3 planeNormal = new Vector3(0.0f, 1.0f, 0.0f); BSPTree tree = new BSPTree(); // Act tree.ClassifyFace(face, planePoint, planeNormal); // Assert Assert.AreEqual(BSPClassification.Spanning, face.Classification); }
private List <Polygon> SubtractPolygon(Polygon start, Polygon toRemove) { var tree = new BSPTree(start); tree.Subtract(toRemove); return(tree.GetFrontLeaves()); }
protected override void StartGenerate() { m_tree = new BSPTree(m_mapSize, m_minBSPSize, m_minRoomSizeRatio); for (int i = 0; i < m_splitIteration; i++) { m_tree.Split(); } m_leafNodes = m_tree.GetAllLeafNodes(); for (int i = 0; i < m_leafNodes.Count; i++) { m_leafNodes[i].GenerateRoomRect(); } List <BSPNode> levelNodes = null; for (int i = m_splitIteration; i >= 0; i--) { levelNodes = m_tree.GetNodesByLevel(i); for (int j = 0; j < levelNodes.Count; j++) { levelNodes[j].GenerateCorridorRect(); } } m_parentNodes = m_tree.GetAllParentNodes(); if (m_generateObjects) { List <Room> rooms = new List <Room>(); for (int i = 0; i < m_leafNodes.Count; i++) { if (m_leafNodes[i].Room == null) { continue; } rooms.Add(m_leafNodes[i].Room); } List <Corridor> corridors = new List <Corridor>(); for (int i = 0; i < m_parentNodes.Count; i++) { if (m_parentNodes[i].Corridor == null) { continue; } corridors.Add(m_parentNodes[i].Corridor); } GenerateObjects(rooms.ToArray(), corridors.ToArray()); } }
static void Main(string[] args) { XmlConfigurator.Configure(); try { Size sz = new Size(1000, 1000); Graphics3DImage g = new Graphics3DImage(sz) { CameraPosition = new Vector3D(-10000.0, -10000.0, 10000.0), Target = Vector3D.Zero }; g.SetViewport(-500.0f, -500.0f, 500.0f, 500.0f); Box b1 = new Box(0, 400, 300, 200, new BoxPosition(Vector3D.Zero, HalfAxis.HAxis.AXIS_X_P, HalfAxis.HAxis.AXIS_Y_P)) { }; b1.SetAllFacesColor(Color.Chocolate); Box b2 = new Box(1, 400, 300, 200, new BoxPosition(new Vector3D(600.0, 0.0, 0.0), HalfAxis.HAxis.AXIS_Z_P, HalfAxis.HAxis.AXIS_Y_P)) { }; b2.SetAllFacesColor(Color.BurlyWood); Box b3 = new Box(2, 400, 300, 200, new BoxPosition(new Vector3D(300.0, 300.0, 0.0), HalfAxis.HAxis.AXIS_Y_P, HalfAxis.HAxis.AXIS_X_N)) { }; b3.SetAllFacesColor(Color.Chartreuse); Box b4 = new Box(3, 300, 200, 50, new BoxPosition(new Vector3D(50.0, 50.0, 200.0), HalfAxis.HAxis.AXIS_X_P, HalfAxis.HAxis.AXIS_Y_P)) { }; b4.SetAllFacesColor(Color.Coral); Box b5 = new Box(4, 300, 200, 50, new BoxPosition(new Vector3D(50.0, 250.0, 200.0), HalfAxis.HAxis.AXIS_X_P, HalfAxis.HAxis.AXIS_Y_P)) { }; b5.SetAllFacesColor(Color.Aquamarine); Box b6 = new Box(5, 400, 250, 150, new BoxPosition(new Vector3D(575.0, 0.0, 400.0), HalfAxis.HAxis.AXIS_Z_P, HalfAxis.HAxis.AXIS_Y_P)) { }; b6.SetAllFacesColor(Color.Yellow); List <Box> boxes = new List <Box> { b1, b2, b3, b4, b5, b6 }; BSPTree bspTree = new BSPTree(); foreach (Box b in boxes) { bspTree.InsertBox(b); } bspTree.Draw(g); g.Bitmap.Save(@"D:\GitHub\StackBuilder\Sources\Test\treeDiM.StackBuilder.Graphics.TestBSPTree\bin\Release\output.png"); } catch (Exception ex) { _log.Error(ex.ToString()); } }
public static BSPTree Get(DatLoader.Entity.BSPTree _bspTree, Dictionary <ushort, DatLoader.Entity.Polygon> polys, DatLoader.Entity.CVertexArray vertexArray) { var bspTree = new BSPTree(_bspTree, polys, vertexArray); if (!Enabled) { return(bspTree); } return(Get(bspTree)); }
void CreateDungeon() { int h = MyMath.Log2(m_size.Width) - 0; var bsp = new BSPTree(h); for (int z = m_size.Depth - 3; z > 0; z -= 2) { CreateDungeonLevel(bsp, z); } }
public static bool ClosestPointOnSurface(Collider collider, Vector3 to, float radius, out Vector3 closestPointOnSurface) { if (collider is BoxCollider) { closestPointOnSurface = SuperCollider.ClosestPointOnSurface((BoxCollider)collider, to); return(true); } else if (collider is SphereCollider) { closestPointOnSurface = SuperCollider.ClosestPointOnSurface((SphereCollider)collider, to); return(true); } else if (collider is CapsuleCollider) { closestPointOnSurface = SuperCollider.ClosestPointOnSurface((CapsuleCollider)collider, to); return(true); } else if (collider is MeshCollider) { BSPTree bspTree = collider.GetComponent <BSPTree>(); if (bspTree != null) { closestPointOnSurface = bspTree.ClosestPointOn(to, radius); return(true); } BSPTree bsp = collider.GetComponent <BSPTree>(); if (bsp != null) { closestPointOnSurface = bsp.ClosestPointOn(to, radius); return(true); } BruteForceMesh bfm = collider.GetComponent <BruteForceMesh>(); if (bfm != null) { closestPointOnSurface = bfm.ClosestPointOn(to); return(true); } } else if (collider is TerrainCollider) { closestPointOnSurface = SuperCollider.ClosestPointOnSurface((TerrainCollider)collider, to, radius, false); return(true); } Debug.LogError(string.Format("{0} does not have an implementation for ClosestPointOnSurface; GameObject.Name='{1}'", collider.GetType(), collider.gameObject.name)); closestPointOnSurface = Vector3.zero; return(false); }
// Try our best to determine how to apply our mesh. public void BuildDecal() { buildingMesh = true; // Clear whatever mesh we might have generated already. StartBuildMesh(); // Separate our affected objects into moving and static objects. affectedObjects = GetAffectedObjects(); List <GameObject> movingObjects = new List <GameObject> (); List <GameObject> staticObjects = new List <GameObject> (); foreach (GameObject obj in affectedObjects) { if (obj.GetComponent <Movable> () != null || obj.GetComponent <Rigidbody> () != null) { movingObjects.Add(obj); } else { staticObjects.Add(obj); } } foreach (GameObject obj in movingObjects) { BSPTree affectedMesh = obj.GetComponent <BSPTree> (); DecalBuilder builder = new DecalBuilder(); builder.mat = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; builder.position = affectedMesh.transform.InverseTransformPoint(transform.position); builder.scale = (transform.lossyScale.magnitude / 2f) / affectedMesh.transform.lossyScale.magnitude; builder.tree = affectedMesh; builder.offset = offset * Random.Range(0.1f, 1f); builder.decal = this; builder.target = obj; builder.isStatic = false; builder.Start(); jobs.Add(builder); } // Try building a mesh for each static object. foreach (GameObject obj in staticObjects) { BSPTree affectedMesh = obj.GetComponent <BSPTree> (); DecalBuilder builder = new DecalBuilder(); builder.mat = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; builder.position = affectedMesh.transform.InverseTransformPoint(transform.position); builder.scale = (transform.lossyScale.magnitude / 2f) / affectedMesh.transform.lossyScale.magnitude; builder.tree = affectedMesh; builder.offset = offset * Random.Range(0.1f, 1f); builder.decal = this; builder.target = obj; builder.isStatic = true; builder.Start(); jobs.Add(builder); } }
void CreateDungeonLevel(BSPTree bsp, int z) { var root = new IntGrid2(0, 0, m_size.Width, m_size.Height); CreateNodes(bsp, root, 0); var td = TileData.EmptyTileData; int leafs = MyMath.Pow2(bsp.Depth - 1); var rooms = new List <IntGrid2>(); // Shrink the full sized leaf nodes for rooms for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var n = bsp[i]; var grid = n.Grid; var xm = GetRandomDouble(0.2, 0.5); var ym = GetRandomDouble(0.2, 0.5); int columns = (int)((grid.Columns - 1) * xm); int rows = (int)((grid.Rows - 1) * ym); int x = m_random.Next(grid.Columns - columns) + grid.X; int y = m_random.Next(grid.Rows - rows) + grid.Y; n.Grid = new IntGrid2(x, y, columns, rows); bsp[i] = n; rooms.Add(n.Grid); } m_rooms[z] = rooms.ToArray(); for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var grid = bsp[i].Grid; foreach (var p2 in grid.Range()) { var p = new IntVector3(p2, z); SetTileData(p, td); } } Connect(bsp, 0, true, z); }
private static void WriteBSPTree(BinaryWriter writer, WMOGroup group) { var tree = new BSPTree(group.BSPNodes); writer.Write(tree.rootId); writer.Write(tree.nodes.Count); foreach (var node in tree.nodes) { WriteBSPNode(writer, node); } }
private void updateTile() { BSPTree.setTile((int)transform.position.x, (int)transform.position.z, 1); BSPTree.setTile((int)transform.position.x + 1, (int)transform.position.z, 1); BSPTree.setTile((int)transform.position.x - 1, (int)transform.position.z, 1); BSPTree.setTile((int)transform.position.x, (int)transform.position.z + 1, 1); BSPTree.setTile((int)transform.position.x, (int)transform.position.z - 1, 1); surroundTilesWithWall((int)transform.position.x + 1, (int)transform.position.z); surroundTilesWithWall((int)transform.position.x - 1, (int)transform.position.z); surroundTilesWithWall((int)transform.position.x, (int)transform.position.z + 1); surroundTilesWithWall((int)transform.position.x, (int)transform.position.z - 1); }
public override void Clear() { base.Clear(); IsInitialized = false; DestroyRooms(); _fog.Clear(); map = null; _tree = null; _roomIds.Clear(); regions.Clear(); roomsIdsConnectingExit.Clear(); doorConfigsConnectingExit.Clear(); }
public int maxCorridorWidth = 2; // [1,2] // bool ONE_DOOR_PER_CORRIDOR = true; override protected void GenerateWithAlgorithm(VirtualMap map, VirtualMap vmapBelow) { // Start full of rocks map.ResetToRocks(); //return; // Pick the cell to start from CellLocation starting_location = default(CellLocation); if (vmapBelow != null) { starting_location = vmapBelow.end; } else { starting_location = CellLocation.INVALID; } //Debug.Log(starting_location); // We start our tree with the full dungeon bounds (only counting FLOOR cells) BSPTree tree = new BSPTree(); tree.root = new BSPTreeNode(0, 0, map.ActualWidth, map.ActualHeight); // Pick a random initial direction BSPSplitDirection splitDir = (BSPSplitDirection)DungeonGenerator.Random.Instance.Next(0, (int)BSPSplitDirection.MAX - 1); // Start the algorithm List <BSPTreeNode> leafNodes = new List <BSPTreeNode>(); SplitNode(tree.root, splitDir, splitRange, nSplits, leafNodes); // Create the rooms RoomGenerator roomGenerator = new RoomGenerator(); map.rooms = new List <VirtualRoom>(); foreach (BSPTreeNode node in leafNodes) { VirtualRoom room = CreateRoom(map, roomGenerator, node, starting_location); if (room != null) { room.sequentialId = map.rooms.Count; map.rooms.Add(room); } } // Create the corridors LinkCorridors(tree.root, map, 0); }
void Connect(BSPTree bsp, int i, bool isLeft, int z) { if (bsp.IsLeaf(i)) return; var left = bsp.GetLeft(i); var right = bsp.GetRight(i); Connect(bsp, left, true, z); Connect(bsp, right, false, z); var leftRoom = FindNearestRoom(bsp, left, bsp[right].Grid.Center); var rightRoom = FindNearestRoom(bsp, right, bsp[left].Grid.Center); ConnectRooms(bsp[leftRoom].Grid, bsp[rightRoom].Grid, z); }
public static Vector3 ClosestPointOnSurface(Collider collider, Vector3 to, float radius) { if (collider is BoxCollider) { return(SuperCollider.ClosestPointOnSurface((BoxCollider)collider, to)); } else if (collider is SphereCollider) { return(SuperCollider.ClosestPointOnSurface((SphereCollider)collider, to)); } else if (collider is CapsuleCollider) { return(SuperCollider.ClosestPointOnSurface((CapsuleCollider)collider, to)); } else if (collider is MeshCollider) { RPGMesh rpgMesh = collider.GetComponent <RPGMesh>(); if (rpgMesh != null) { return(rpgMesh.ClosestPointOn(to, radius, false, false)); } BSPTree bsp = collider.GetComponent <BSPTree>(); if (bsp != null) { return(bsp.ClosestPointOn(to, radius)); } BruteForceMesh bfm = collider.GetComponent <BruteForceMesh>(); if (bfm != null) { return(bfm.ClosestPointOn(to)); } } else if (collider is TerrainCollider) { return(SuperCollider.ClosestPointOnSurface((TerrainCollider)collider, to, radius, false)); } Debug.LogError(string.Format("{0} does not have an implementation for ClosestPointOnSurface", collider.GetType())); return(Vector3.zero); }
void Connect(BSPTree bsp, int i, bool isLeft, int z) { if (bsp.IsLeaf(i)) { return; } var left = bsp.GetLeft(i); var right = bsp.GetRight(i); Connect(bsp, left, true, z); Connect(bsp, right, false, z); var leftRoom = FindNearestRoom(bsp, left, bsp[right].Grid.Center); var rightRoom = FindNearestRoom(bsp, right, bsp[left].Grid.Center); ConnectRooms(bsp[leftRoom].Grid, bsp[rightRoom].Grid, z); }
public static BSPTree Get(BSPTree bspTree) { Requests++; //if (Requests % 1000 == 0) //Console.WriteLine($"BSPCache: Requests={Requests}, Hits={Hits}"); BSPTrees.TryGetValue(bspTree, out var result); if (result != null) { Hits++; return(result); } // not cached, add it BSPTrees.Add(bspTree); return(bspTree); }
public void Start() { List <IPoly> polygons = new List <IPoly>(); for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { if (true) { polygons.Add(Primitive.MakeBox(new Vector3(i * 1.1f + (j % 2) * 0.5f, 0f, j * 1.1f), Vector2.one)); } } } tree = new BSPTree <IPoly>(polygons.ToArray(), true); BSPNode <IPoly> root = tree.root; BSPNodeWrapper.Create("root", root); }
public void surroundTilesWithWall(int _x, int _y) { if (BSPTree.getGrid().getTile(_x + 1, _y) == 0) { BSPTree.setTile(_x + 1, _y, 2); } if (BSPTree.getGrid().getTile(_x - 1, _y) == 0) { BSPTree.setTile(_x - 1, _y, 2); } if (BSPTree.getGrid().getTile(_x, _y + 1) == 0) { BSPTree.setTile(_x, _y + 1, 2); } if (BSPTree.getGrid().getTile(_x, _y - 1) == 0) { BSPTree.setTile(_x, _y - 1, 2); } }
int FindNearestRoom(BSPTree bsp, int i, IntVector2 p) { if (bsp.IsLeaf(i)) { return(i); } else { int left = FindNearestRoom(bsp, bsp.GetLeft(i), p); int right = FindNearestRoom(bsp, bsp.GetRight(i), p); double dl = (bsp[left].Grid.Center - p).Length; double rl = (bsp[right].Grid.Center - p).Length; if (dl < rl) { return(left); } else { return(right); } } }
public static void ShowWindow() { SceneView.onSceneGUIDelegate -= OnSceneGUI; SceneView.onSceneGUIDelegate += OnSceneGUI; //BSPTree tree = new BSPTree(Selection.activeGameObject, Selection.activeGameObject.GetComponent<MeshFilter>().sharedMesh); btree = ScriptableObject.CreateInstance(typeof(BSPTree)) as BSPTree; btree.Init(Selection.activeGameObject, Selection.activeGameObject.GetComponent<MeshFilter>().sharedMesh); hasfinished = true; }
public static Vector3 ClosestPointOnSurface(TerrainCollider collider, Vector3 to, float radius, bool debug = false) { var terrainData = collider.terrainData; var local = collider.transform.InverseTransformPoint(to); // Calculate the size of each tile on the terrain horizontally and vertically float pixelSizeX = terrainData.size.x / (terrainData.heightmapResolution - 1); float pixelSizeZ = terrainData.size.z / (terrainData.heightmapResolution - 1); var percentZ = Mathf.Clamp01(local.z / terrainData.size.z); var percentX = Mathf.Clamp01(local.x / terrainData.size.x); float positionX = percentX * (terrainData.heightmapResolution - 1); float positionZ = percentZ * (terrainData.heightmapResolution - 1); // Calculate our position, in tiles, on the terrain int pixelX = Mathf.FloorToInt(positionX); int pixelZ = Mathf.FloorToInt(positionZ); // Calculate the distance from our point to the edge of the tile we are in float distanceX = (positionX - pixelX) * pixelSizeX; float distanceZ = (positionZ - pixelZ) * pixelSizeZ; // Find out how many tiles we are overlapping on the X plane float radiusExtentsLeftX = radius - distanceX; float radiusExtentsRightX = radius - (pixelSizeX - distanceX); int overlappedTilesXLeft = radiusExtentsLeftX > 0 ? Mathf.FloorToInt(radiusExtentsLeftX / pixelSizeX) + 1 : 0; int overlappedTilesXRight = radiusExtentsRightX > 0 ? Mathf.FloorToInt(radiusExtentsRightX / pixelSizeX) + 1 : 0; // Find out how many tiles we are overlapping on the Z plane float radiusExtentsLeftZ = radius - distanceZ; float radiusExtentsRightZ = radius - (pixelSizeZ - distanceZ); int overlappedTilesZLeft = radiusExtentsLeftZ > 0 ? Mathf.FloorToInt(radiusExtentsLeftZ / pixelSizeZ) + 1 : 0; int overlappedTilesZRight = radiusExtentsRightZ > 0 ? Mathf.FloorToInt(radiusExtentsRightZ / pixelSizeZ) + 1 : 0; // Retrieve the heights of the pixels we are testing against int startPositionX = pixelX - overlappedTilesXLeft; int startPositionZ = pixelZ - overlappedTilesZLeft; int numberOfXPixels = overlappedTilesXRight + overlappedTilesXLeft + 1; int numberOfZPixels = overlappedTilesZRight + overlappedTilesZLeft + 1; // Account for if we are off the terrain if (startPositionX < 0) { numberOfXPixels -= Mathf.Abs(startPositionX); startPositionX = 0; } if (startPositionZ < 0) { numberOfZPixels -= Mathf.Abs(startPositionZ); startPositionZ = 0; } if (startPositionX + numberOfXPixels + 1 > terrainData.heightmapResolution) { numberOfXPixels = terrainData.heightmapResolution - startPositionX - 1; } if (startPositionZ + numberOfZPixels + 1 > terrainData.heightmapResolution) { numberOfZPixels = terrainData.heightmapResolution - startPositionZ - 1; } // Retrieve the heights of the tile we are in and all overlapped tiles var heights = terrainData.GetHeights(startPositionX, startPositionZ, numberOfXPixels + 1, numberOfZPixels + 1); // Pre-scale the heights data to be world-scale instead of 0...1 for (int i = 0; i < numberOfXPixels + 1; i++) { for (int j = 0; j < numberOfZPixels + 1; j++) { heights[j, i] *= terrainData.size.y; } } // Find the shortest distance to any triangle in the set gathered float shortestDistance = float.MaxValue; Vector3 shortestPoint = Vector3.zero; for (int x = 0; x < numberOfXPixels; x++) { for (int z = 0; z < numberOfZPixels; z++) { // Build the set of points that creates the two triangles that form this tile Vector3 a = new Vector3((startPositionX + x) * pixelSizeX, heights[z, x], (startPositionZ + z) * pixelSizeZ); Vector3 b = new Vector3((startPositionX + x + 1) * pixelSizeX, heights[z, x + 1], (startPositionZ + z) * pixelSizeZ); Vector3 c = new Vector3((startPositionX + x) * pixelSizeX, heights[z + 1, x], (startPositionZ + z + 1) * pixelSizeZ); Vector3 d = new Vector3((startPositionX + x + 1) * pixelSizeX, heights[z + 1, x + 1], (startPositionZ + z + 1) * pixelSizeZ); Vector3 nearest; BSPTree.ClosestPointOnTriangleToPoint(ref a, ref d, ref c, ref local, out nearest); float distance = (local - nearest).sqrMagnitude; if (distance <= shortestDistance) { shortestDistance = distance; shortestPoint = nearest; } BSPTree.ClosestPointOnTriangleToPoint(ref a, ref b, ref d, ref local, out nearest); distance = (local - nearest).sqrMagnitude; if (distance <= shortestDistance) { shortestDistance = distance; shortestPoint = nearest; } if (debug) { DebugDraw.DrawTriangle(a, d, c, Color.cyan); DebugDraw.DrawTriangle(a, b, d, Color.red); } } } return(collider.transform.TransformPoint(shortestPoint)); }
static void DrawNode(BSPTree tree, BSPNode node) { //Debug.Log("aaaaaa"); GL.Begin(GL.TRIANGLES); GL.Color(new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), 0.5f)); GL.Vertex(tree.toWorldCoord(node.node.indices[0]) + Vector3.up * 5); GL.Vertex(tree.toWorldCoord(node.node.indices[1]) + Vector3.up * 5); GL.Vertex(tree.toWorldCoord(node.node.indices[2]) + Vector3.up * 5); GL.End(); if (node.frontNode != null) DrawNode(tree, node.frontNode); if (node.backNode != null) DrawNode(tree, node.backNode); }
//void Update() //{ // if (Input.GetMouseButtonUp(0)) // { // if (_rooms != null) // { // foreach (var room in _rooms) // { // Destroy(room.gameObject); // } // _rooms.Clear(); // } // Start(); // } //} void Start() { _tree = new BSPTree(0, 0, width, height, minWidth, minHeight, maxWidth, maxHeight, quadSize); int roomsCreated = 0; while (roomsCreated != numOfPacks) { if (_tree.Iterate()) { roomsCreated++; } } _tree.PrintTree(); CreateRooms(_tree.data); //process data int runningRegionId = 0; foreach (var item in _tree.data) { if (item.regionId == -1) { item.regionId = runningRegionId++; } foreach (var connection in item.connectedNodes) { connection.regionId = item.regionId; connection.color = item.color; } } //create regions regions = new Dictionary <int, List <BSPNode> >(); foreach (var item in _tree.data) { if (!regions.ContainsKey(item.regionId)) { regions[item.regionId] = new List <BSPNode>(); } regions[item.regionId].Add(item); } //connect regions till no missing regions while (regions.Count != 1) { int key = GetKeyAtIndex(0); ConnectRegions(key); } //find single exit rooms Dictionary <int, int> numConnections = new Dictionary <int, int>(); foreach (var item in _tree.data) { int roomId = item.id; foreach (var room in _tree.data) { if (room.id != roomId) { foreach (var connection in room.connectedNodes) { if (connection.id == roomId) { if (!numConnections.ContainsKey(roomId)) { numConnections[roomId] = 0; } numConnections[roomId]++; } } } else { if (!numConnections.ContainsKey(roomId)) { numConnections[roomId] = 0; } numConnections[roomId] += room.connectedNodes.Count; } } } foreach (KeyValuePair <int, int> numConnect in numConnections) { if (numConnect.Value == 1) { BSPNode node = FindRoomWithId(numConnect.Key); node.hasSingleExit = true; } } //create exit config BSPPathGenerator pathGenerator = new BSPPathGenerator(); pathGenerator.UpdatePathData(_tree.data); //create room mesh if (generateMesh) { _rooms = new List <Room>(); foreach (var pack in _tree.data) { Room room = new Room("Prefabs/Room", Mathf.CeilToInt(pack.rect.width), Mathf.CeilToInt(pack.rect.height), quadSize, borderSize, wallHeight, pack); room.generateMesh(); room.gameObject.transform.position = new Vector3(pack.rect.x, 1, pack.rect.y); _rooms.Add(room); } } }
int FindNearestRoom(BSPTree bsp, int i, IntVector2 p) { if (bsp.IsLeaf(i)) { return i; } else { int left = FindNearestRoom(bsp, bsp.GetLeft(i), p); int right = FindNearestRoom(bsp, bsp.GetRight(i), p); double dl = (bsp[left].Grid.Center - p).Length; double rl = (bsp[right].Grid.Center - p).Length; if (dl < rl) return left; else return right; } }
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); } }
void CreateDungeonLevel(BSPTree bsp, int z) { var root = new IntGrid2(0, 0, m_size.Width, m_size.Height); CreateNodes(bsp, root, 0); var td = TileData.EmptyTileData; int leafs = MyMath.Pow2(bsp.Depth - 1); var rooms = new List<IntGrid2>(); // Shrink the full sized leaf nodes for rooms for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var n = bsp[i]; var grid = n.Grid; var xm = GetRandomDouble(0.2, 0.5); var ym = GetRandomDouble(0.2, 0.5); int columns = (int)((grid.Columns - 1) * xm); int rows = (int)((grid.Rows - 1) * ym); int x = m_random.Next(grid.Columns - columns) + grid.X; int y = m_random.Next(grid.Rows - rows) + grid.Y; n.Grid = new IntGrid2(x, y, columns, rows); bsp[i] = n; rooms.Add(n.Grid); } m_rooms[z] = rooms.ToArray(); for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var grid = bsp[i].Grid; foreach (var p2 in grid.Range()) { var p = new IntVector3(p2, z); SetTileData(p, td); } } Connect(bsp, 0, true, z); }
void CreateDungeon() { int h = MyMath.Log2(m_size.Width) - 0; var bsp = new BSPTree(h); for (int z = m_size.Depth - 3; z > 0; z -= 2) CreateDungeonLevel(bsp, z); }
public static GfxObj ReadFromDat(uint fileId) { // Check the FileCache so we don't need to hit the FileSystem repeatedly if (DatManager.PortalDat.FileCache.ContainsKey(fileId)) { return((GfxObj)DatManager.PortalDat.FileCache[fileId]); } else { DatReader datReader = DatManager.PortalDat.GetReaderForFile(fileId); GfxObj obj = new GfxObj(); obj.Id = datReader.ReadUInt32(); obj.Flags = datReader.ReadUInt32(); short num_surfaces = datReader.ReadPackedByte(); for (short i = 0; i < num_surfaces; i++) { obj.Surfaces.Add(datReader.ReadUInt32()); } obj.VertexArray = CVertexArray.Read(datReader); // Has Physics if ((obj.Flags & 1) > 0) { short num_physics_polygons = datReader.ReadPackedByte(); for (ushort i = 0; i < num_physics_polygons; i++) { ushort poly_id = datReader.ReadUInt16(); obj.PhysicsPolygons.Add(poly_id, Polygon.Read(datReader)); } obj.PhysicsBSP = BSPTree.Read(datReader, BSPType.Physics); } obj.SortCenter = PositionExtensions.ReadPositionFrame(datReader); // Has Drawing if ((obj.Flags & 2) > 0) { short num_polygons = datReader.ReadPackedByte(); for (ushort i = 0; i < num_polygons; i++) { ushort poly_id = datReader.ReadUInt16(); obj.Polygons.Add(poly_id, Polygon.Read(datReader)); } obj.DrawingBSP = BSPTree.Read(datReader, BSPType.Drawing); } if ((obj.Flags & 8) > 0) { obj.DIDDegrade = datReader.ReadUInt32(); } // Store this object in the FileCache DatManager.PortalDat.FileCache[fileId] = obj; return(obj); } }
public override void Init() { base.Init(); LevelConfig config = ConfigModel.Instance.GetConfigForLevel(GameModel.Instance.currLevel); width = config.dungeon.width; height = config.dungeon.height; minWidth = config.dungeon.minWidth; maxWidth = config.dungeon.maxWidth; minHeight = config.dungeon.minHeight; maxHeight = config.dungeon.maxHeight; quadSize = config.dungeon.quadSize; numOfPacks = config.dungeon.numPacks; wallHeight = 15; borderSize = 2; //create FOW _fog.GenerateFOW(width / quadSize, height / quadSize, quadSize, wallHeight + 3); _tree = new BSPTree(0, 0, width, height, minWidth, minHeight, maxWidth, maxHeight, quadSize); int roomsCreated = 0; int count = 0; const int MAX_TRY = 10; while (count < MAX_TRY && roomsCreated != numOfPacks) { if (_tree.Iterate()) { roomsCreated++; count = 0; } else { count++; } } _tree.PrintTree(); CreateRooms(_tree.data); //process data int runningRegionId = 0; foreach (var item in _tree.data) { if (item.regionId == -1) { item.regionId = runningRegionId++; } foreach (var connection in item.connectedNodes) { connection.regionId = item.regionId; connection.color = item.color; } } //create regions regions = new Dictionary <int, List <BSPNode> >(); foreach (var item in _tree.data) { if (!regions.ContainsKey(item.regionId)) { regions[item.regionId] = new List <BSPNode>(); } regions[item.regionId].Add(item); } //clone the regions for later use clonedRegions = new Dictionary <int, List <BSPNode> >(); foreach (KeyValuePair <int, List <BSPNode> > iter in regions) { if (!clonedRegions.ContainsKey(iter.Key)) { clonedRegions[iter.Key] = new List <BSPNode>(); } foreach (var item in iter.Value) { clonedRegions[iter.Key].Add(item.Clone()); } } //connect regions till no missing regions while (regions.Count != 1) { int key = GetKeyAtIndex(0); ConnectRegions(key); } //find single exit rooms Dictionary <int, int> numConnections = new Dictionary <int, int>(); foreach (var item in _tree.data) { int roomId = item.id; foreach (var room in _tree.data) { if (room.id != roomId) { foreach (var connection in room.connectedNodes) { if (connection.id == roomId) { if (!numConnections.ContainsKey(roomId)) { numConnections[roomId] = 0; } numConnections[roomId]++; } } } else { if (!numConnections.ContainsKey(roomId)) { numConnections[roomId] = 0; } numConnections[roomId] += room.connectedNodes.Count; } } } foreach (KeyValuePair <int, int> numConnect in numConnections) { if (numConnect.Value == 1) { BSPNode node = FindNodeWithId(numConnect.Key); node.hasSingleExit = true; } } //create exit config BSPPathGenerator pathGenerator = new BSPPathGenerator(); pathGenerator.UpdatePathData(_tree.data); //create room mesh { _rooms = new List <Room>(); _roomIds = new List <int>(); foreach (var pack in _tree.data) { Room room = new Room(Mathf.CeilToInt(pack.rect.width), Mathf.CeilToInt(pack.rect.height), quadSize, borderSize, wallHeight, pack); room.gameObject.transform.SetParent(transform); room.generateMesh(); room.gameObject.transform.position = new Vector3(pack.rect.x, 1, pack.rect.y); _rooms.Add(room); _roomIds.Add(room.roomData.id); } } //Create doors CreateDoors(); //Update Path Finder map = new int[width / quadSize + 1, height / quadSize + 1]; foreach (Room room in _rooms) { int[,] roomMap = room.meshData.roomBorderMesh.getMap(); for (int row = 0; row < roomMap.GetLength(0); row++) { for (int col = 0; col < roomMap.GetLength(1); col++) { map[(int)(room.roomData.rect.x / room.quadSize) + row, (int)(room.roomData.rect.y / room.quadSize) + col] = roomMap[row, col]; } } } PathFinder.GetInstance().tileSize = quadSize; PathFinder.GetInstance().map = map; }
void CreateDungeonLevel(BSPTree bsp, int z) { var root = new IntGrid2(0, 0, m_size.Width, m_size.Height); CreateNodes(bsp, root, 0); var td = new TileData(); td.TerrainID = TerrainID.NaturalFloor; td.TerrainMaterialID = MaterialID.Granite; td.InteriorID = InteriorID.Empty; td.InteriorMaterialID = MaterialID.Undefined; int leafs = MyMath.Pow2(bsp.Depth - 1); var rooms = new List<IntGrid2>(); // Shrink the full sized leaf nodes for rooms for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var n = bsp[i]; var grid = n.Grid; var xm = GetRandomDouble(0.2, 0.5); var ym = GetRandomDouble(0.2, 0.5); int columns = (int)((grid.Columns - 1) * xm); int rows = (int)((grid.Rows - 1) * ym); int x = m_random.Next(grid.Columns - columns) + grid.X; int y = m_random.Next(grid.Rows - rows) + grid.Y; n.Grid = new IntGrid2(x, y, columns, rows); bsp[i] = n; rooms.Add(n.Grid); } m_rooms[z] = rooms.ToArray(); for (int l = 0; l < leafs; ++l) { int i = bsp.Length - l - 1; var grid = bsp[i].Grid; foreach (var p2 in grid.Range()) { var p = new IntPoint3(p2, z); var _td = GetTileData(p); if (_td.TerrainID == td.TerrainID) Debugger.Break(); SetTileData(p, td); } } Connect(bsp, 0, true, z); }