private void Start() { Random.InitState(this.seed); this.floors = new Floor[this.numFloors]; this.layers = new MiddleLayer[this.numFloors - 1]; for (int i = 0; i < this.numFloors; i++) { Floor f = Instantiate(this.floorPrefab); f.transform.position = new Vector3(this.floorStart.position.x, this.floorStart.position.y - 20 * i, this.floorStart.position.z); f.transform.rotation = this.floorStart.rotation; f.transform.localScale = this.floorStart.localScale; f.Squares = this.floorRasterizer.InitialzeGrid(f.rasterizationGrid); this.floors[i] = f; } for (int i = 0; i < this.numFloors - 1; i++) { MiddleLayer l = Instantiate(this.layerPrefab); l.transform.position = new Vector3(this.floorStart.position.x, this.floorStart.position.y - 20 * (i + 1), this.floorStart.position.z); l.transform.rotation = this.floorStart.rotation; l.transform.localScale = this.floorStart.localScale; l.Squares = this.layerRasterizer.InitialzeGrid(l.rasterizationGrid); this.layers[i] = l; } StartCoroutine(StartUpAsync()); }
private bool CheckCircleBlocked(Vector3 center, float radius, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { foreach (Room r in floor.Rooms) { if (r.IsIntersectingCircle(center, radius)) { return(true); } } if (upperLayer != null) { foreach (LayerPath l in upperLayer.Paths) { if (l.IsIntersectingCircle(center, radius)) { return(true); } } } if (lowerLayer != null) { foreach (LayerPath l in lowerLayer.Paths) { if (l.IsIntersectingCircle(center, radius)) { return(true); } } } return(false); }
public IEnumerator RasterizeLayer(MiddleLayer l, Floor upper, Floor lower) { Square[,,,] squares = l.Squares; Vector3 tl, tr, bl, br; foreach (LayerPath p in l.Paths) { //if (p.Start is CircleRoom) //{ // CircleRoom circle = (CircleRoom)p.Start; // RasterizeCircle(squares, l.rasterizationGrid, circle.Position, circle.Radius); //} //else //{ // RectangleRoom rect = (RectangleRoom)p.Start; // rect.BoxBounds(out tl, out tr, out bl, out br); // RasterizeBox(squares, l.rasterizationGrid, tl, tr, bl, br); //} //if (p.End is CircleRoom) //{ // CircleRoom circle = (CircleRoom)p.End; // RasterizeCircle(squares, l.rasterizationGrid, circle.Position, circle.Radius); //} //else //{ // RectangleRoom rect = (RectangleRoom)p.End; // rect.BoxBounds(out tl, out tr, out bl, out br); // RasterizeBox(squares, l.rasterizationGrid, tl, tr, bl, br); //} GenerationUtility.BoxBounds(p.Start.Position, p.End.Position, p.Width, out tl, out tr, out bl, out br); RasterizeBox(squares, l.rasterizationGrid, tl, tr, bl, br); yield return(null); } foreach (LayerPath p in l.Paths) { Vector3 start = GetRoomEdgePoint(p.Start, p); Vector3 end = GetRoomEdgePoint(p.End, p); MarkForKeeping(squares, l.rasterizationGrid, start, end, p.Width); ReserveGridSquares(upper, start, Vector3.Lerp(start, end, .02f), p.Width); ReserveGridSquares(lower, Vector3.Lerp(start, end, .98f), end, p.Width); Vector3 startHeight = l.transform.InverseTransformPoint(p.Start.WorldPosition); Vector3 endHeight = l.transform.InverseTransformPoint(p.End.WorldPosition); RaiseMesh(squares, l.rasterizationGrid, start, end, p.Width, startHeight, endHeight); yield return(null); } l.Squares = squares; }
public void Draw(MiddleLayer l, Vector2Int draw) { for (int r = 0; r < this.SectorDimension.x; r++) { for (int c = 0; c < this.SectorDimension.y; c++) { Vector2 boxCenter = GetPosition(r, c, this.topLeft.localPosition, this.SectorSize); Gizmos.color = Color.red; Gizmos.DrawWireCube(boxCenter, this.SectorSize); Gizmos.color = Color.white; } } Vector3 sectorTopLeft = SectorTopLeft(draw); for (int r = 0; r < this.GridDimension.x; r++) { for (int c = 0; c < this.GridDimension.y; c++) { if (l.Squares != null) { if (l.Squares[draw.x, draw.y, r, c].Reserved) { Gizmos.color = Color.blue; } if (l.Squares[draw.x, draw.y, r, c].Marked) { Gizmos.color = Color.green; } } Vector3 center = GetPosition(r, c, sectorTopLeft, this.gridSize); Gizmos.DrawWireCube(center, this.gridSize); if (l.Squares != null && l.Squares[draw.x, draw.y, r, c].Filled) { Gizmos.DrawCube(center, this.GridSize / 2f); } Gizmos.color = Color.white; } } }
/// <summary> Finds all the allowed floor paths for the given floor. </summary> /// <param name="floor"> The floor. </param> /// <param name="upperLayer"> The layer above this floor. </param> /// <param name="upperLayer"> The layer below this floor. </param> public IEnumerator FindFloorPathsAsync(Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { List <FloorPath> basePaths = new List <FloorPath>(); List <Room> objects = new List <Room>(); foreach (Room r1 in floor.Rooms) { foreach (Room r2 in floor.Rooms) { if (r1 != r2) { TryAddPath(r1, r2, basePaths, floor, upperLayer, lowerLayer); } } objects.Add(r1); yield return(null); } floor.Paths = Kruskals(basePaths, objects); }
public IEnumerator GenerateMesh(MiddleLayer l) { List <Vector3>[,] verts = new List <Vector3> [l.rasterizationGrid.SectorDimension.x, l.rasterizationGrid.SectorDimension.y]; List <int>[,] tris = new List <int> [l.rasterizationGrid.SectorDimension.x, l.rasterizationGrid.SectorDimension.y]; for (int r = 0; r < l.rasterizationGrid.SectorDimension.x; r++) { for (int c = 0; c < l.rasterizationGrid.SectorDimension.y; c++) { verts[r, c] = new List <Vector3>(); tris[r, c] = new List <int>(); EvaluateGrid(new Vector2Int(r, c), l.Squares, l.rasterizationGrid, verts[r, c], tris[r, c], true); GameObject mesh = SpawnMesh(verts[r, c], tris[r, c]); Vector3 pos = mesh.transform.position; Quaternion rot = mesh.transform.rotation; Vector3 size = mesh.transform.localScale; mesh.transform.SetParent(l.meshParent); mesh.transform.localPosition = pos; mesh.transform.localRotation = rot; mesh.transform.localScale = size; } yield return(null); } }
static void HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top) { middle.Event += top.TopLayerHandler; middle.HookUpEvent(bottom); System.Console.Write("HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom:"); bottom.callEvent(); }
static void HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top) { middle.HookUpEvent(bottom); middle.Event += top.TopLayerHandler; try { bottom.callEvent(); } catch(System.NullReferenceException) { System.Console.Write("HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom: Event was null\n"); } }
private IEnumerator StartUpAsync() { System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); if (this.placeRoomsOnStart) { stopwatch.Start(); for (int i = 0; i < this.floors.Length; i++) { yield return(StartCoroutine(this.roomGenerator.PlaceRoomsAsync(this.floors[i]))); } stopwatch.Stop(); Debug.Log("finished placing rooms in " + stopwatch.Elapsed); stopwatch.Reset(); if (this.placePathsOnStart) { if (this.layers.Length > 0) { stopwatch.Start(); for (int i = 0; i < this.layers.Length; i++) { yield return(StartCoroutine(this.layerPathGenerator.FindMiddleLayerPathsAsync(this.floors[i], this.floors[i + 1], this.layers[i]))); } stopwatch.Stop(); Debug.Log("finished finding layer paths in " + stopwatch.Elapsed); stopwatch.Reset(); } stopwatch.Start(); for (int i = 0; i < this.floors.Length; i++) { MiddleLayer up = null, down = null; if (this.layers.Length > 0) { if (i > 0) { up = this.layers[i - 1]; } if (i < this.floors.Length - 1) { down = this.layers[i]; } } yield return(StartCoroutine(this.floorPathGenerator.FindFloorPathsAsync(this.floors[i], up, down))); } stopwatch.Stop(); Debug.Log("finished finding floor paths in " + stopwatch.Elapsed); stopwatch.Reset(); } if (this.rasterizeOnStart) { if (this.layers.Length > 0) { stopwatch.Start(); for (int i = 0; i < this.layers.Length; i++) { yield return(StartCoroutine(this.layerRasterizer.RasterizeLayer(this.layers[i], this.floors[i], this.floors[i + 1]))); } stopwatch.Stop(); Debug.Log("finished rasterizing layer paths in " + stopwatch.Elapsed); stopwatch.Reset(); } stopwatch.Start(); for (int i = 0; i < this.floors.Length; i++) { yield return(StartCoroutine(this.floorRasterizer.RasterizeFloor(this.floors[i]))); } stopwatch.Stop(); Debug.Log("finished rasterizing floors in " + stopwatch.Elapsed); stopwatch.Reset(); if (this.generateMeshOnStart) { if (this.layers.Length > 0) { stopwatch.Start(); for (int i = 0; i < this.layers.Length; i++) { yield return(StartCoroutine(this.meshGenerator.GenerateMesh(this.layers[i]))); } stopwatch.Stop(); Debug.Log("finished generating layer mashes in " + stopwatch.Elapsed); stopwatch.Reset(); } stopwatch.Start(); for (int i = 0; i < this.floors.Length; i++) { yield return(StartCoroutine(this.meshGenerator.GenerateMesh(this.floors[i]))); } stopwatch.Stop(); Debug.Log("finished generating floor meshs in " + stopwatch.Elapsed); stopwatch.Reset(); } } if (this.toggleRoomsOnStart) { foreach (Floor f in this.floors) { foreach (Room r in f.Rooms) { r.gameObject.SetActive(false); } } } } }
public void UnloadContent() { GroundLayer.UnloadContent(); MiddleLayer.UnloadContent(); TopLayer.UnloadContent(); }
private void TryAddPath(Room r1, Room r2, List <FloorPath> basePaths, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { if (!CheckPathBlocked(r1.Position, r2.Position, r1, r2, 0, floor, upperLayer, lowerLayer)) { bool duplicate = false; foreach (FloorPath e in basePaths) { if ((e.Start == r1 || e.End == r1) && (e.Start == r2 || e.End == r2)) { duplicate = true; } } if (!duplicate) { List <Edge> edges = FindPath( r1.Position, r2.Position, r1, r2, new List <Edge>(), 0, floor, upperLayer, lowerLayer); float dist = 0; foreach (Edge e in edges) { dist += e.Distance; } FloorPath path = new FloorPath { Start = r1, End = r2, Distance = dist, Width = this.pathWidth, Edges = edges.ToArray() }; basePaths.Add(path); } } }
private bool FindCenterOffset(Vector3 left, float pathWidth, ref Vector3 center, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { int leftAttempts = 0; int rightAttempts = 0; bool leftFound = false; bool rightFound = false; Vector3 leftCenter = Vector3.zero; Vector3 rightCenter = Vector3.zero; while (leftAttempts < maxOffsetAttempts && !leftFound) { Vector3 temp = center + left * (leftAttempts * pathWidth / 2f); if (!CheckCircleBlocked(temp, this.pathWidth, floor, upperLayer, lowerLayer)) { leftCenter = temp; leftFound = true; } else { leftAttempts++; } } while (rightAttempts < maxOffsetAttempts && !rightFound) { Vector3 temp = center - left * (rightAttempts * pathWidth / 2f); if (!CheckCircleBlocked(temp, this.pathWidth, floor, upperLayer, lowerLayer)) { rightCenter = temp; rightFound = true; } else { rightAttempts++; } } if (leftFound && rightFound) { if (leftAttempts < rightAttempts) { center = leftCenter; } else { center = rightCenter; } return(true); } else if (leftFound) { center = leftCenter; return(true); } else if (rightFound) { center = rightCenter; return(true); } else { return(false); } }
/// <summary> Checks if the given edge is blocked. </summary> /// <param name="begin"> The start of the edge. </param> /// <param name="end"> The end of the edge. </param> /// <param name="r1"> The starting room of the path. </param> /// <param name="r2"> The ending room of the path. </param> /// <param name="floor"> The floor this path is on. </param> /// <param name="upperLayer"> The Layer above this path's floor. </param> /// <param name="lowerLayer"> The layer below this path's floor. </param> /// <returns> True if there is something blocking this edge. </returns> private bool CheckEdgeBlocked(Vector3 begin, Vector3 end, Room r1, Room r2, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { Vector3 tl, tr, bl, br; GenerationUtility.BoxBounds(begin, end, this.pathWidth, out tl, out tr, out bl, out br); foreach (Room r in floor.Rooms) { if (r != r1 && r != r2) { if (r.IsIntersectingLine(tl, bl)) { return(true); } if (r.IsIntersectingLine(tr, br)) { return(true); } } } if (upperLayer != null) { foreach (LayerPath l in upperLayer.Paths) { if (l.IsIntersectingLine(tl, bl)) { Vector3 pos = GenerationUtility.LineLineIntersection(tl, bl, l.Start.Position, l.End.Position); bool inRoom = IsInRoom(pos, l.Start, l.End); if (!inRoom) { return(true); } } if (l.IsIntersectingLine(tr, br)) { Vector3 pos = GenerationUtility.LineLineIntersection(tr, br, l.Start.Position, l.End.Position); bool inRoom = IsInRoom(pos, l.Start, l.End); if (!inRoom) { return(true); } } } } if (lowerLayer != null) { foreach (LayerPath l in lowerLayer.Paths) { if (l.IsIntersectingLine(tl, bl)) { Vector3 pos = GenerationUtility.LineLineIntersection(tl, bl, l.Start.Position, l.End.Position); bool inRoom = IsInRoom(pos, l.Start, l.End); if (!inRoom) { return(true); } } if (l.IsIntersectingLine(tr, br)) { Vector3 pos = GenerationUtility.LineLineIntersection(tr, br, l.Start.Position, l.End.Position); bool inRoom = IsInRoom(pos, l.Start, l.End); if (!inRoom) { return(true); } } } } return(false); }
/// <summary> Checks if the given path is blocked. </summary> /// <param name="point1"> The start of the path. </param> /// <param name="point2"> The end of the path. </param> /// <param name="room1"> The starting room of the path. </param> /// <param name="room2"> The ending room of the path. </param> /// <param name="depth"> The current recursion depth. </param> /// <param name="floor"> The floor this path is on. </param> /// <param name="upperLayer"> The Layer above this path's floor. </param> /// <param name="lowerLayer"> The layer below this path's floor. </param> /// <returns> True if there is something blocking this path. </returns> private bool CheckPathBlocked(Vector3 point1, Vector3 point2, Room room1, Room room2, int depth, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { if (depth > this.maxRecursionDepth) { return(true); } if (!CheckEdgeBlocked(point1, point2, room1, room2, floor, upperLayer, lowerLayer)) { return(false); } else { Vector3 center = Vector3.Lerp(point1, point2, .5f); Vector3 p12 = Vector3.Normalize(point1 - point2); Vector3 left = new Vector3(-p12.y, p12.x, p12.z); if (FindCenterOffset(left, this.pathWidth, ref center, floor, upperLayer, lowerLayer)) { bool blocked = CheckPathBlocked(point1, center, room1, null, depth + 1, floor, upperLayer, lowerLayer); if (blocked) { return(true); } blocked = CheckPathBlocked(center, point2, null, room2, depth + 1, floor, upperLayer, lowerLayer); return(blocked); } else { return(true); } } }
public void Draw(SpriteBatch spriteBatch) { GroundLayer.Draw(spriteBatch); MiddleLayer.Draw(spriteBatch); TopLayer.Draw(spriteBatch); }
public void LoadContent() { GroundLayer.LoadContent(); MiddleLayer.LoadContent(); TopLayer.LoadContent(); }
private List <Edge> FindPath(Vector3 point1, Vector3 point2, Room room1, Room room2, List <Edge> edges, int depth, Floor floor, MiddleLayer upperLayer, MiddleLayer lowerLayer) { if (depth > this.maxRecursionDepth) { return(null); } if (!CheckEdgeBlocked(point1, point2, room1, room2, floor, upperLayer, lowerLayer)) { Edge e = new Edge { Start = point1, End = point2, Distance = Vector3.Distance(point1, point2), Width = this.pathWidth, TailEdge = room2 != null }; edges.Add(e); return(edges); } else { Vector3 center = Vector3.Lerp(point1, point2, .5f); Vector3 p12 = Vector3.Normalize(point1 - point2); Vector3 left = new Vector3(-p12.y, p12.x, p12.z); if (FindCenterOffset(left, this.pathWidth, ref center, floor, upperLayer, lowerLayer)) { edges = FindPath(point1, center, room1, null, edges, depth + 1, floor, upperLayer, lowerLayer); if (edges == null) { return(null); } edges = FindPath(center, point2, null, room2, edges, depth + 1, floor, upperLayer, lowerLayer); return(edges); } else { return(null); } } }
public void Update(GameTime gameTime) { GroundLayer.Update(gameTime); MiddleLayer.Update(gameTime); TopLayer.Update(gameTime); }
/// <summary> Finds all the allowed middle layer paths for the given floors. </summary> /// <param name="floor1"> The top floor. </param> /// <param name="floor2"> The bottom floor. </param> /// <param name="layer"> The layer to hold the paths. </param> public IEnumerator FindMiddleLayerPathsAsync(Floor floor1, Floor floor2, MiddleLayer layer) { foreach (Room r in floor1.Rooms) { r.GetComponent <Collider>().enabled = true; } foreach (Room r in floor2.Rooms) { r.GetComponent <Collider>().enabled = true; } List <LayerPath> paths = new List <LayerPath>(); foreach (Room r1 in floor1.Rooms) { foreach (Room r2 in floor2.Rooms) { LayerPath p = CompareRoom(r1, r2, floor1, floor2, this.layerPathWidth * layer.WidthScale, paths); if (p != null) { paths.Add(p); } } yield return(null); } List <LayerPath> finalPaths = new List <LayerPath>(); int i = 0; while (i < this.pathsToKeep && i < paths.Count) { LayerPath path = paths[Random.Range(0, paths.Count - 1)]; bool blocked = false; foreach (LayerPath p in finalPaths) { if (GenerationUtility.CheckLineLineIntersection( path.Start.Position, path.End.Position, p.Start.Position, p.End.Position)) { blocked = true; } } if (!blocked) { i++; finalPaths.Add(path); } } layer.Paths = finalPaths; foreach (Room r in floor1.Rooms) { r.GetComponent <Collider>().enabled = false; } foreach (Room r in floor2.Rooms) { r.GetComponent <Collider>().enabled = false; } }