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; } } }
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; }
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); }
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; } } } } }
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); }
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); }
/// <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); } } }
/// <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)); }
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); }
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")); }
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; }
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")); }
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; } } }
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); } }
float GetCost<T>( ArrayGrid<T> map, Vector2 from, Vector2 to ) { if( !map.IsPositionEmpty( to ) ) { return float.MaxValue; } return ( to - from ).magnitude; }
static protected IEnumerator <Vector2Int> IterateOverMap <T>(ArrayGrid <T> map) { IEnumerator <Vector2Int> iterator = IterateOverArea(map.w, map.h); while (iterator.MoveNext()) { yield return(iterator.Current); } }
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); }
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); } }
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; }
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)); }
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); }
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)); } }
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); } } }
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)); }
/// <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); }
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; }
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)); }
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); }
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 ); }