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);
        }
示例#6
0
 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);
                        }
                    }
                }
            }
        }
示例#10
0
 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);
                }
            }
        }
示例#15
0
 public void Draw(SpriteBatch spriteBatch)
 {
     GroundLayer.Draw(spriteBatch);
     MiddleLayer.Draw(spriteBatch);
     TopLayer.Draw(spriteBatch);
 }
示例#16
0
 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);
                }
            }
        }
示例#18
0
 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;
            }
        }