Example #1
0
        private void GenerateTrees(ArrayGrid <MapElement> map)
        {
            var openGroundSpaces = map.GetPositionsOfType(defaultFillElement);
            int spacesToFill     = (int)(openGroundSpaces.Count * percentageOfGroundToFillWithTrees);
            //Debug.Log("trees = " + spacesToFill);
            int abort = 0;

            for (int i = 0; i < spacesToFill; ++i)
            {
                Vector2Int spotToFill = openGroundSpaces.GetRandomElementFromList();
                //Debug.Log("trying to put tree at " + spotToFill);
                var nearby = map.GetAdjacentElementsOfType(spotToFill, true, defaultBuildingWallElement);

                //TODO: fix this
                if (nearby.Count <= 0)
                {
                    //Debug.Log("Planting tree at " + spotToFill);
                    map[spotToFill] = defaultTreeElement;
                    openGroundSpaces.Remove(spotToFill);
                }
                else
                {
                    --i;
                    abort++;
                }

                if (abort >= 10000)
                {
                    break;
                }
            }
        }
Example #2
0
        public IEnumerator Create1000by1000andPathFrom0_0to999_999AndWriteToPNGFile()
        {
            float size           = 1000f;
            var   mapRect        = new Rect(-size / 2f, -size / 2f, size, size);
            var   map            = new ArrayGrid <int>(mapRect.size.ToInt());
            var   start          = new Vector2Int(0, 0);
            var   end            = map.MaxValidPosition;
            bool  searchDiagonal = true;
            bool  debug          = false;

            AStar pathFinder = new AStar();

            yield return(pathFinder.FindPath(map, start, end, null, searchDiagonal, debug));

            Assert.That(pathFinder.result != null, Is.True, "Path failed to generate.");

            var path = pathFinder.result;

            map.SetElements(path, 3);
            Texture2D mapTex;

            mapTex = map.ToTexture(WriteColor);
            yield return(WriteToFile(mapTex, testOutputPath + "1000by1000BasicTestOutputPath.png"));

            Assert.That(File.Exists(testOutputPath + "1000by1000BasicTestOutputPath.png"), Is.True, "Failed to write test output to file.");

            yield break;
        }
Example #3
0
        private Rectangle GetVisibleTiles(ArrayGrid <Sprite> grid, Vector2 cameraPosition, Point viewportSize,
                                          Vector2 layerOffset)
        {
            var gridPosition = grid.Position + layerOffset;

            Rectangle visibleCoordinates;
            Point     offset;

            switch (grid.Perspective)
            {
            case Perspective.Standard:
                visibleCoordinates = GetVisibleCartesianCoordinates(cameraPosition, viewportSize, grid.TileSize, 1);
                offset             = Projector.PixelsToCartesian(gridPosition, grid.TileSize).ToPoint();
                break;

            case Perspective.Isometric:
                visibleCoordinates = GetVisibleIsometricCoordinates(cameraPosition, viewportSize, grid.TileSize, 1);
                offset             = Projector.PixelsToIsometric(gridPosition, grid.TileSize).ToPoint();
                break;

            default:
                throw new InvalidOperationException($"Can not process {grid.Perspective} perspective.");
            }

            visibleCoordinates.Location -= offset; // Is this right?

            return(visibleCoordinates);
        }
Example #4
0
        protected void AddDoors(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap, float doorProbability = 1f)
        {
            IEnumerator <Vector2Int> mapIter = IterateOverMap(map);

            while (mapIter.MoveNext())
            {
                Vector2Int current          = mapIter.Current;
                var        adjacentElements = map.GetAdjacentElements(current, true);

                int roomCells     = adjacentElements.Where(x => x == defaultRoomElement).Count();
                int corridorCells = adjacentElements.Where(x => x == defaultCorridorElement).Count();
                int doorCells     = adjacentElements.Where(x => x == defaultDoorElement).Count();

                if (map[current] == defaultCorridorElement)
                {
                    if ((corridorCells == 1 && doorCells == 0 && roomCells > 0 && roomCells < 4) ||
                        (corridorCells == 0 && doorCells == 0))
                    {
                        float exist = GameRNG.Randf();
                        if (exist < doorProbability)
                        {
                            map[current] = defaultDoorElement;
                        }
                    }
                }
            }
        }
Example #5
0
        public static Texture2D ArrayGridToTexture <T>(ArrayGrid <T> data, System.Func <T, Color> toColor = null)
        {
            Texture2D tex = new Texture2D((int)data.w, (int)data.h, TextureFormat.ARGB32, false, false);

            tex.filterMode = FilterMode.Point;
            for (int j = 0; j < (int)data.h; ++j)
            {
                for (int i = 0; i < (int)data.w; ++i)
                {
                    if (toColor == null)
                    {
                        if (data[i, j] != null)
                        {
                            tex.SetPixel(i, j, Color.red);
                        }
                        else
                        {
                            tex.SetPixel(i, j, Color.black);
                        }
                    }
                    else
                    {
                        tex.SetPixel(i, j, toColor(data[i, j]));
                    }
                }
            }
            tex.Apply();
            return(tex);
        }
Example #6
0
        public static List <List <U> > ToData <T, U>(this ArrayGrid <T> grid, System.Func <T, U> toData = null)
        {
            List <List <U> > outData = (new List <U> [grid.h]).ToList();

            for (int i = 0; i < outData.Count; ++i)
            {
                outData[i] = (new U[grid.w]).ToList();
            }

            for (int j = 0; j < (int)grid.h; ++j)
            {
                for (int i = 0; i < (int)grid.w; ++i)
                {
                    if (toData == null)
                    {
                        if (grid[i, j] != null)
                        {
                            outData[i][j] = default(U);
                        }
                        else
                        {
                            //outData[i][j] = default(U);
                        }
                    }
                    else
                    {
                        outData[i][j] = toData(grid[i, j]);
                    }
                }
            }
            return(outData);
        }
Example #7
0
        /// <summary>
        /// Fills in background tiles for any non-empty cell that is adjacent to a background tile. Returns true if any changes were made.
        /// </summary>
        /// <param name="mapGrid"></param>
        /// <param name="grassMap"></param>
        /// <returns></returns>
        public static void CalculateObscuredTiles(ArrayGrid <ImageCellType> mapGrid, TileMaskMap bgMap)
        {
            List <Vector2> tilesToAdd     = new List <Vector2>();
            List <Vector2> tilesToRecheck = new List <Vector2>();

            foreach (var tile in mapGrid.PointItems)
            {
                if (bgMap.TileFlags.GetFromPoint(tile.Position) == TileMaskValue.Filled)
                {
                    continue;
                }

                if (tile.Value == ImageCellType.Empty)
                {
                    continue;
                }

                if (tile.Value.IsSolid())
                {
                    bgMap.TileFlags.Set(tile.Position, TileMaskValue.Obscured);
                }
                else if (tile.Position.GetAdjacentPoints(true).Select(bgMap.TileFlags.GetFromPoint).Where(p => p == TileMaskValue.Filled).Any())
                {
                    bgMap.TileFlags.Set(tile.Position, TileMaskValue.Filled);
                }
            }
        }
Example #8
0
        /// <summary>
        /// Wraps the given point "around" to the other side of the grid if it's off the boundry
        /// </summary>
        public static Vector2Int Wrap <T>(this ArrayGrid <T> grid, Vector2Int p)
        {
            int w = p.x / grid.w;
            int h = p.y / grid.h;

            int modx = p.x - w * grid.w;
            int mody = p.y - h * grid.h;

            int x;
            int y;

            if (modx < 0)
            {
                x = grid.w + modx;
            }
            else
            {
                x = modx;
            }

            if (mody < 0)
            {
                y = grid.h + mody;
            }
            else
            {
                y = mody;
            }

            return(new Vector2Int(x, y));
        }
Example #9
0
        public void TriangulateRows(ArrayGrid <MapElement> mesh_input)
        {
            for (int j = 0; j < mesh_input.ValidArea.size.y; ++j)
            {
                SwapRowCaches();
                CacheFirstCorner(mesh_input[0, j + 1], new Vector2Int(0, j + 1));
                CacheNextMiddleEdge(mesh_input[0, j], mesh_input[0, j + 1], new Vector2Int(0, j), new Vector2Int(0, j + 1));

                for (int i = 0; i < mesh_input.ValidArea.size.x; ++i)
                {
                    int cacheIndex = i * 2;

                    CacheNextEdgeAndCorner(cacheIndex, mesh_input[i, j + 1], mesh_input[i + 1, j + 1], new Vector2Int(i, j + 1), new Vector2Int(i + 1, j + 1));

                    CacheNextMiddleEdge(mesh_input[i + 1, j], mesh_input[i + 1, j + 1], new Vector2Int(i + 1, j), new Vector2Int(i + 1, j + 1));

                    TriangulateCell(cacheIndex
                                    , mesh_input[i, j]
                                    , mesh_input[i + 1, j]
                                    , mesh_input[i, j + 1]
                                    , mesh_input[i + 1, j + 1]);
                }
                if (xNeighbor != null)
                {
                    TriangulateGapCell(mesh_input, j);
                }
            }
            if (yNeighbor != null)
            {
                TriangulateGapRow(mesh_input);
            }
        }
    private IGrid createGraph()
    {
        // Convert visible grid to memory grid
        var grid     = GridController.Ground;
        var pathGrid = GridController.Path;

        var sizeX = GridController.active.size.x;
        var sizeY = GridController.active.size.y;

        var memoryGrid = new ArrayGrid(sizeX, sizeY);

        for (var x = 0; x < sizeX; x++)
        {
            for (var y = 0; y < sizeY; y++)
            {
                var tile = grid.GetTile(new Vector3Int(x, y, 0));
                if (tile == GridController.active.blocked)
                {
                    memoryGrid.SetWeight(x, y, (int)CellType.Blocked);
                }
                else if (tile == GridController.active.road)
                {
                    memoryGrid.SetWeight(x, y, (int)CellType.Road);
                }
                else if (tile == GridController.active.walkable)
                {
                    memoryGrid.SetWeight(x, y, (int)CellType.Walkable);
                }
            }
        }

        return(memoryGrid);
    }
Example #11
0
        protected virtual IEnumerator WriteTestOutput(ArrayGrid <MapElement> map)
        {
            string    testOutputPath = "Assets/common/lib/MapGeneration/";
            Texture2D debugOutput    = map.ToTexture(WriteColor);

            yield return(WriteToFile(debugOutput, testOutputPath + this.GetType().Name + ".png"));
        }
Example #12
0
        protected void FillDisconnectedRoomsWithDifferentValues(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap, ref int countOfRoomsFilled)
        {
            IEnumerator <Vector2Int> mapIter = IterateOverMap(map);

            while (mapIter.MoveNext())
            {
                Vector2Int current = mapIter.Current;
                if (map[current] == defaultRoomElement)
                {
                    valueMap[current] = valueRoom;
                }
                else if (map[current] == defaultWallElement)
                {
                    valueMap[current] = valueWall;
                }
            }

            mapIter = IterateOverMap(map);
            int roomNumber = 0;

            while (mapIter.MoveNext())
            {
                Vector2Int current = mapIter.Current;
                if (valueMap[current] == valueRoom)
                {
                    valueMap.FloodFill(current, new List <int>()
                    {
                        valueWall
                    }, false, 1 + (roomNumber++));
                }
            }

            countOfRoomsFilled = roomNumber;
        }
Example #13
0
        protected virtual IEnumerator WriteTestOutput(ArrayGrid <int> map)
        {
            Func <int, int> func           = (int t) => { return(t); };
            string          testOutputPath = "Assets/common/lib/MapGeneration/";
            var             debugOutput    = map.ToData <int, int>(func);

            yield return(WriteToFile(debugOutput, testOutputPath + this.GetType().Name + "_values.txt"));
        }
Example #14
0
        void GenerateBuildingRooms(ArrayGrid <MapElement> map, Vector2Int buildingPos, Vector2Int roomSize)
        {
            Rect building = new Rect();
            Rect smaller  = new Rect();

            buildingPos.x++;
            buildingPos.y++;

            building.position = buildingPos;
            building.size     = roomSize;

            smaller = building;

            smaller.min = smaller.min + Vector2Int.one;
            smaller.max = smaller.max - Vector2Int.one;

            map.FillArea(building, defaultBuildingWallElement);
            map.FillArea(smaller, defaultRoomElement);

            AddRecursiveRooms(map, defaultBuildingWallElement, new Vector2Int(innerBuildingRoomSize, innerBuildingRoomSize), smaller);

            // add a door leading out (improve to lead to nearest road)
            if (GameRNG.CoinToss())
            {
                if (GameRNG.CoinToss())
                {
                    int x = (int)building.min.x + GameRNG.Rand((int)roomSize.x - 2) + 1;
                    int y = (int)building.min.y;

                    map[x, y] = defaultDoorElement;
                }
                else
                {
                    int x = (int)building.min.x + GameRNG.Rand((int)roomSize.x - 2) + 1;
                    int y = (int)building.max.y - 1;

                    map[x, y] = defaultDoorElement;
                }
            }
            else
            {
                if (GameRNG.CoinToss())
                {
                    int x = (int)building.min.x;
                    int y = (int)building.min.y + GameRNG.Rand((int)roomSize.y - 2) + 1;

                    map[x, y] = defaultDoorElement;
                }
                else
                {
                    int x = (int)building.max.x - 1;
                    int y = (int)building.min.y + GameRNG.Rand((int)roomSize.y - 2) + 1;

                    map[x, y] = defaultDoorElement;
                }
            }
        }
Example #15
0
        public static IEnumerator <Vector2Int> GetEnumerator2D <T>(this ArrayGrid <T> grid)
        {
            IEnumerator <Vector2Int> iterator = Mathnv.GetAreaEnumerator(grid.w, grid.h);

            while (iterator.MoveNext())
            {
                yield return(iterator.Current);
            }
        }
Example #16
0
        float GetCost<T>( ArrayGrid<T> map, Vector2 from, Vector2 to )
        {
            if( !map.IsPositionEmpty( to ) )
            {
                return float.MaxValue;
            }

            return ( to - from ).magnitude;
        }
Example #17
0
        static protected IEnumerator <Vector2Int> IterateOverMap <T>(ArrayGrid <T> map)
        {
            IEnumerator <Vector2Int> iterator = IterateOverArea(map.w, map.h);

            while (iterator.MoveNext())
            {
                yield return(iterator.Current);
            }
        }
Example #18
0
        bool GenerateMap(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap)
        {
            // create a game of life cave

            int densityCount = Mathf.FloorToInt(map.Count * density);

            //fill with random walls
            for (int i = 0; i < densityCount; ++i)
            {
                Vector2Int?fillPos = map.GetRandomPositionOfType(defaultFillElement);

                if (fillPos == null || !fillPos.HasValue)
                {
                    return(false);
                }

                map[fillPos.Value] = defaultWallElement;
            }

            for (int i = 0; i < iterations; ++i)
            {
                IEnumerator <Vector2Int> mapIter = IterateOverMap(map);

                while (mapIter.MoveNext())
                {
                    Vector2Int current = mapIter.Current;

                    int n = map.GetAdjacentPositionsOfType(current, true, defaultWallElement).Count;

                    if (map[current] == defaultWallElement)
                    {
                        if (n < 4)
                        {
                            map[current] = defaultRoomElement;
                        }
                    }
                    else
                    {
                        if (n > 4)
                        {
                            map[current] = defaultWallElement;
                        }
                    }

                    if (map.IsPositionOnEdge(current))
                    {
                        map[current] = defaultWallElement;
                    }
                }
            }

            ConnectClosestRooms(map, valueMap, false, false);
            ConvertValuesToTiles(map, valueMap);

            return(true);
        }
Example #19
0
        private void TriangulateGapRow(ArrayGrid <MapElement> mesh_input)
        {
            Vector3 offset = new Vector3(0, 0, ChunkSize.y);

            SwapRowCaches();
            MapElement ta = mesh_input[0, (int)mesh_input.ValidArea.size.y];
            MapElement tb = mesh_input[1, (int)mesh_input.ValidArea.size.y];
            MapElement tc = yNeighbor.MapData[0, 0];
            MapElement td = yNeighbor.MapData[1, 0];

            //-----CacheFirstCornerWithOffset( tc, offset );
            //-----CacheNextMiddleEdgeWithOffset( mesh_input[ (int)mesh_input.ValidArea.size.y * Resolution ], tc, offset );
            CacheFirstCornerWithOffset(tc, offset, new Vector2Int(0, 0));
            CacheNextMiddleEdge(mesh_input[(int)mesh_input.ValidArea.size.y * ChunkSize.y], tc, mesh_input.GetPositionFromIndex((int)mesh_input.ValidArea.size.y * ChunkSize.y), new Vector2Int(0, 0));

            //-----CacheFirstCornerWithOffset( yNeighbor.map.First[ 0, 0 ], offset );
            //-----CacheNextMiddleEdgeWithOffset( yNeighbor.map.First[ 1, 0 ], yNeighbor.map.First[ 0, 0 ], offset );

            for (int i = 0; i < (int)mesh_input.ValidArea.size.y; ++i)
            {
                MapElement a = mesh_input[i, (int)mesh_input.ValidArea.size.y];
                MapElement b = mesh_input[i + 1, (int)mesh_input.ValidArea.size.y];
                MapElement c = yNeighbor.MapData[i, 0];
                MapElement d = yNeighbor.MapData[i + 1, 0];

                int cacheIndex = i * 2;

                CacheNextEdgeAndCornerWithOffset(cacheIndex, c, d, offset, offset, new Vector2Int(i, 0), new Vector2Int(i + 1, 0));
                CacheNextMiddleEdge(b, d, new Vector2Int(i + 1, (int)mesh_input.ValidArea.size.y), new Vector2Int(i + 1, 0));

                TriangulateCell(cacheIndex, a, b, c, d);
                //-----TriangulateCellWithOffset( a, b, c, d, Vector3.zero, Vector3.zero, offset, offset);
            }

            if (xyNeighbor != null)
            {
                MapElement ax = mesh_input[(int)mesh_input.ValidArea.size.y, (int)mesh_input.ValidArea.size.y];
                MapElement bx = xNeighbor.MapData[0, (int)mesh_input.ValidArea.size.y];
                MapElement cx = yNeighbor.MapData[(int)mesh_input.ValidArea.size.y, 0];
                MapElement dx = xyNeighbor.MapData[0, 0];

                Vector3 offsetx = new Vector3(ChunkSize.x, 0, 0);
                Vector3 offsetz = new Vector3(0, 0, ChunkSize.y);

                int cacheIndex = ((int)mesh_input.ValidArea.size.y) * 2;

                CacheNextEdgeAndCornerWithOffset(cacheIndex, cx, dx, offsetz, offsetx + offsetz, new Vector2Int((int)mesh_input.ValidArea.size.y, 0), new Vector2Int(0, 0));
                CacheNextMiddleEdgeWithOffset(bx, dx, offsetx, new Vector2Int(0, (int)mesh_input.ValidArea.size.y), new Vector2Int(0, 0));

                //-----TriangulateCellWithOffset( ax, bx, cx, dx, Vector3.zero, offsetx, offsetz, offsetx + offsetz );
                TriangulateCell(cacheIndex, ax, bx, cx, dx);
            }
        }
Example #20
0
 List<Vector2> ReconstructPath( ArrayGrid<Vector2> cameFrom, Vector2 start, Vector2 reconstructionStartPoint )
 {
     List<Vector2> path = new List<Vector2>();
     path.Add( reconstructionStartPoint );
     Vector2 current = reconstructionStartPoint;
     while( !IsGoal( current, start ) )
     {
         current = cameFrom[ current ];
         path.Add( current );
     }
     return path;
 }
Example #21
0
        private void TestDoesntCrash(int a, int b, int c, int d, int e, int f, int g, int h)
        {
            // ARRANGE
            float[,,] cells = new float[, , ] {
                { { a, b }, { c, d } },
                { { e, f }, { g, h } }
            };

            ArrayGrid   grid = new ArrayGrid(cells, Vector3.Zero, Vector3.One);
            ListSurface s    = new ListSurface();

            // ACT & ASSERT
            Assert.DoesNotThrow(() => MarchingCubes.MarchIntoSurface(grid, 0, s));
        }
Example #22
0
        private bool GenerateBuildings(ArrayGrid <MapElement> map)
        {
            while (buildingCount < requiredMinNumberOfBuildings)
            {
                Vector2Int roomSize   = new Vector2Int((int)(buildingSizeLimitX.Max * 2), (int)(buildingSizeLimitY.Max * 2));
                int        bufferSize = 2;

                for (;;)
                {
                    Vector2Int newBuildingAreaSize = new Vector2Int(roomSize.x + bufferSize, roomSize.y + bufferSize);
                    Vector2Int buildingPos         = Vector2Int.zero;
                    bool       result = map.GetPositionOfRandomAreaOfType(defaultFillElement, newBuildingAreaSize, ref buildingPos);
                    if (result)
                    {
                        //Debug.Log("Creating a building at " + buildingPos + " of size " + roomSize);
                        GenerateBuildingRooms(map, buildingPos, roomSize);
                        //map.FillArea(new Rect(buildingPos, roomSize), defaultDoorElement);
                        //map.FillArea(new Rect(buildingPos, Vector2.one), defaultTreeElement);
                        buildingCount++;
                        if (buildingCount >= requiredMinNumberOfBuildings)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        if (GameRNG.CoinToss())
                        {
                            roomSize.x -= 1;
                        }
                        else
                        {
                            roomSize.y -= 1;
                        }

                        //time to start over
                        if (roomSize.x < buildingSizeLimitX.Min || roomSize.y < buildingSizeLimitY.Min)
                        {
                            Debug.Log("starting over because building size is too small and we don't have enough buildings. " + roomSize + " rooms so far: " + buildingCount);
                            buildingCount = 0;
                            generationAttempts++;
                            return(false);
                        }
                    }
                }
            }

            return(false);
        }
Example #23
0
        public void FillFirstRowCache(ArrayGrid <MapElement> mesh_input)
        {
            CacheFirstCorner(mesh_input[0, 0], Vector2Int.zero);
            int i = 0;

            for (; i < ChunkSize.x - 1; i++)
            {
                CacheNextEdgeAndCorner(i * 2, mesh_input[i], mesh_input[i + 1], mesh_input.GetPositionFromIndex(i), mesh_input.GetPositionFromIndex(i + 1));
            }
            if (xNeighbor != null)
            {
                Vector3 offsetx = new Vector3(ChunkSize.x, 0, 0);
                CacheNextEdgeAndCornerWithOffset(i * 2, mesh_input[i], xNeighbor.MapData[0], offsetx, mesh_input.GetPositionFromIndex(i), xNeighbor.MapData.GetPositionFromIndex(0));
            }
        }
Example #24
0
        public MapTemplate(string mapfile, Vector2 cellSize)
        {
            CellSize = cellSize;
            var colors = TextureInfoReader.Instance.TextureToColors(mapfile);

            Cells = colors.Map(ColorToType);
            Cells.OutOfBoundsFixedValue = ImageCellType.MapBoundary;

            InitMaps();
            MapRegions.AddRange(FindRegions().Select(p => new Rectangle(p.Left * cellSize.X, p.Top * cellSize.Y, p.Width * cellSize.X, p.Height * cellSize.Y)));
            VerifyMinimumRegionSize();

            foreach (var cell in Cells.PointItems)
            {
                if (cell.Value == ImageCellType.MapBoundary)
                {
                    bool aboveIsBoundary = cell.GetAdjacent(Direction.Up).Value == ImageCellType.MapBoundary;
                    bool belowIsBoundary = cell.GetAdjacent(Direction.Down).Value == ImageCellType.MapBoundary;
                    bool leftIsBoundary  = cell.GetAdjacent(Direction.Left).Value == ImageCellType.MapBoundary;
                    bool rightisBoundary = cell.GetAdjacent(Direction.Right).Value == ImageCellType.MapBoundary;

                    List <Direction> possibleCopyDirections = new List <Direction>();

                    if ((aboveIsBoundary || belowIsBoundary) && !leftIsBoundary && !rightisBoundary)
                    {
                        possibleCopyDirections.Add(Direction.Left);
                        possibleCopyDirections.Add(Direction.Right);
                    }
                    else if ((leftIsBoundary || rightisBoundary) && !aboveIsBoundary && !belowIsBoundary)
                    {
                        possibleCopyDirections.Add(Direction.Up);
                        possibleCopyDirections.Add(Direction.Down);
                    }
                    else
                    {
                        possibleCopyDirections.AddRange(EnumHelper.GetValues <Direction>());
                    }

                    var copyDirection = possibleCopyDirections.Where(p => cell.GetAdjacent(p).Value != ImageCellType.MapBoundary)
                                        .OrderBy(p => cell.GetAdjacent(p).Value.IsSolid() ? 0 : 1)
                                        .FirstOrDefault();


                    var adjacent = cell.GetAdjacent(copyDirection);
                    cell.Set(adjacent.Value);
                }
            }
        }
Example #25
0
        private void UniformTest(float value, int width, float iso)
        {
            // ARRANGE
            ArrayGrid grid = GenerateUniform(value, width);

            // ACT
            ListSurface s = new ListSurface();

            MarchingCubes.MarchIntoSurface(grid, iso, s);
            int[]     triangles = s.GetTriangles();
            Vector3[] vertices  = s.GetVertices();

            // ASSERT
            Assert.That(triangles, Has.Length.EqualTo(0));
            Assert.That(vertices, Has.Length.EqualTo(0));
        }
Example #26
0
        /// <summary>
        /// Tests a specific example of a cell. Assumes that delta in the grid is 1, origin is 0 and isovalue is 0
        /// </summary>
        public static bool TestSpecific(float[,,] cells, IEnumerable <ListSurface> expecteds)
        {
            ArrayGrid   grid = new ArrayGrid(cells, Vector3.Zero, Vector3.One);
            ListSurface s    = new ListSurface();

            MarchingCubes.MarchIntoSurface(grid, 0, s);

            foreach (ListSurface e in expecteds)
            {
                if (ListSurface.AreSurfacesEquivalent(e, s))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #27
0
        public IEnumerator Create1000by1000andPathFrom0_0to999_999()
        {
            float size           = 1000f;
            var   mapRect        = new Rect(-size / 2f, -size / 2f, size, size);
            var   map            = new ArrayGrid <int>(mapRect.size.ToInt());
            var   start          = new Vector2Int(0, 0);
            var   end            = map.MaxValidPosition;
            bool  searchDiagonal = true;
            bool  debug          = false;

            AStar pathFinder = new AStar();

            yield return(pathFinder.FindPath(map, start, end, null, searchDiagonal, debug));

            Assert.That(pathFinder.result != null, Is.True, "Path failed to generate.");
            yield break;
        }
Example #28
0
        private void SingleNodeCellTest(float valueSingle, float valueOther, int cellVertex, float iso)
        {
            // ARRANGE
            ArrayGrid grid = GenerateSingle(valueSingle, valueOther, cellVertex);

            // ACT
            ListSurface s = new ListSurface();

            MarchingCubes.MarchIntoSurface(grid, iso, s);
            int[]     triangles = s.GetTriangles();
            Vector3[] vertices  = s.GetVertices();

            // ASSERT
            // Should have one triangle with three vertices
            Assert.That(triangles, Has.Length.EqualTo(3));
            Assert.That(vertices, Has.Length.EqualTo(3));
        }
Example #29
0
        public static ArrayGrid <T> MapToSubGrid <T>(this ArrayGrid <T> grid, Vector2Int sourceAreaPos, Vector2Int sourceAreaSize, Vector2Int subGridSize, bool clampOutOfBounds = true)
        {
            if (!clampOutOfBounds)
            {
                if (!grid.IsValidPosition(sourceAreaPos))
                {
                    return(new ArrayGrid <T>());
                }

                if (!grid.IsValidPosition(sourceAreaPos + sourceAreaSize - Vector2Int.one))
                {
                    return(new ArrayGrid <T>());
                }
            }
            else
            {
                sourceAreaPos.Clamp(Vector2Int.zero, grid.MaxValidPosition);

                Vector2Int sourceAreaMax = sourceAreaPos + sourceAreaSize;
                sourceAreaMax.Clamp(Vector2Int.zero, grid.Size);

                sourceAreaSize = sourceAreaMax - sourceAreaPos;

                if (sourceAreaSize.x <= 0 || sourceAreaSize.y <= 0)
                {
                    return(new ArrayGrid <T>());
                }
            }

            ArrayGrid <T> subGrid = new ArrayGrid <T>(subGridSize);

            var subGridIter = subGrid.GetEnumerator2D();

            Vector2 scale = new Vector2((float)sourceAreaSize.x / subGridSize.x, (float)sourceAreaSize.y / subGridSize.y);

            while (subGridIter.MoveNext())
            {
                Vector2Int subCurrent       = subGridIter.Current;
                Vector2    scaledSubCurrent = new Vector2(subCurrent.x * scale.x, subCurrent.y * scale.y);
                Vector2Int sourcePos        = sourceAreaPos + Vector2Int.FloorToInt(scaledSubCurrent);

                subGrid[subCurrent] = grid[sourcePos];
            }

            return(subGrid);
        }
Example #30
0
        private void TriangulateGapCell(ArrayGrid <MapElement> mesh_input, int row)
        {
            MapElement a = mesh_input[(int)mesh_input.ValidArea.size.x, row];
            MapElement b = xNeighbor.MapData[0, row];
            MapElement c = mesh_input[(int)mesh_input.ValidArea.size.x, row + 1];
            MapElement d = xNeighbor.MapData[0, row + 1];

            Vector3 offset = new Vector3(ChunkSize.x, 0, 0);

            int cacheIndex = ((int)mesh_input.ValidArea.size.y) * 2;

            CacheNextEdgeAndCornerWithOffset(cacheIndex, c, d, offset, new Vector2Int((int)mesh_input.ValidArea.size.x, row + 1), new Vector2Int(0, row + 1));
            CacheNextMiddleEdgeWithOffset(b, d, offset, new Vector2Int(0, row), new Vector2Int(0, row + 1));

            TriangulateCell(cacheIndex, a, b, c, d);
            //-----TriangulateCellWithOffset( a, b, c, d, Vector3.zero, offset, Vector3.zero, offset );
        }