// public static void SetAndSwitchCell(ChunkWithNeighbors chunkWithNeighbors, int2 oldCellPosition, int2 absoluteNewCellPosition, Cell cell) // { // if (GetRelativeCellPosition(chunkWithNeighbors, absoluteNewCellPosition, out var newChunkPosition, // out var newCellPosition)) // { // var oldCellChunk = chunkWithNeighbors.Chunk; // var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition); // // var existingCell = oldCellChunk.GetCell(oldCellPosition); // // oldCellChunk.SetCell(oldCellPosition, existingCell); // newCellChunk.SetCell(newCellPosition, cell); // } // } // public static bool MoveToIfEmpty(ChunkWithNeighbors chunkWithNeighbors, int2 oldCellPosition, int2 newCellPosition, Cell cell) // { // if (GetCellAtPosition(chunkWithNeighbors, newCellPosition, out var neighborChunkPosition, out var neighborCellPosition)) // { // var neighborChunk = chunkWithNeighbors.ChunkFromPosition(neighborChunkPosition); // var neighborCell = neighborChunk.GetCell(oldCellPosition); // // if (neighborCell.type == CellType.None) // { // chunkWithNeighbors.Chunk.SetCell(newCellPosition, default); // neighborChunk.SetCell(neighborCellPosition, cell); // // return true; // } // } // // return false; // } // public static bool SwitchCellsIfTargetEmpty(ChunkWithNeighbors chunkWithNeighbors, int2 absoluteCurrentCellPosition, // int2 absoluteTargetCellPosition) // { // if (GetCellAtPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition, // out var oldCellPosition)) // { // if (GetCellAtPosition(chunkWithNeighbors, absoluteTargetCellPosition, out var newChunkPosition, // out var newCellPosition)) // { // var oldCellChunk = chunkWithNeighbors.Chunk; // var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition); // // var oldCell = oldCellChunk.GetCell(oldCellPosition); // var newCell = newCellChunk.GetCell(newCellPosition); // // if (newCell.type == CellType.None) // { // oldCellChunk.SetCell(oldCellPosition, newCell); // newCellChunk.SetCell(newCellPosition, oldCell); // // return true; // } // } // } // } public static bool SwitchCellsIfTargetEmpty(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 absoluteCurrentCellPosition, int2 absoluteTargetCellPosition) { if (GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition, out var oldCellPosition)) { if (GetRelativeCellPosition(chunkWithNeighbors, absoluteTargetCellPosition, out var newChunkPosition, out var newCellPosition)) { var oldCellChunk = chunkWithNeighbors.Value; var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition); if (newCellChunk.IsOutOfBounds) { return(false); } var oldCell = oldCellChunk.GetCell(oldCellPosition); var newCell = newCellChunk.GetCell(newCellPosition); if (newCell.type == CellType.None) { oldCellChunk.SetCell(oldCellPosition, newCell); newCellChunk.SetCell(newCellPosition, oldCell); return(true); } } } return(false); }
// public static void SwitchCells(ChunkWithNeighbors chunkWithNeighbors, int2 absoluteOldCellPosition, int2 absoluteNewCellPosition, Cell cell) // { // if (GetRelativeCellPosition(chunkWithNeighbors, absoluteNewCellPosition, out var newChunkPosition, // out var newCellPosition)) // { // var oldCellChunk = chunkWithNeighbors.Chunk; // var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition); // // var existingCell = oldCellChunk.GetCell(oldCellPosition); // // oldCellChunk.SetCell(oldCellPosition, existingCell); // newCellChunk.SetCell(newCellPosition, cell); // } // } // public static bool SwitchCells(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 absoluteCurrentCellPosition, int2 offset) { if (!GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition, out var oldChunkPosition, out var oldCellPosition)) { return(false); } if (!GetRelativeCellPosition(chunkWithNeighbors, absoluteCurrentCellPosition + offset, out var newChunkPosition, out var newCellPosition)) { return(false); } var oldCellChunk = chunkWithNeighbors.Value; var newCellChunk = chunkWithNeighbors.ChunkFromPosition(newChunkPosition); if (newCellChunk.IsOutOfBounds) { return(false); } var oldCell = oldCellChunk.GetCell(oldCellPosition); var newCell = newCellChunk.GetCell(newCellPosition); oldCellChunk.SetCell(oldCellPosition, newCell); newCellChunk.SetCell(newCellPosition, oldCell); return(true); }
public static Cell?GetCellAtPosition(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition) { if (GetRelativeCellPosition(chunkWithNeighbors, cellPosition, out var relativeChunkPosition, out var relativeCellPosition)) { return(chunkWithNeighbors.ChunkFromPosition(relativeChunkPosition).GetCell(relativeCellPosition)); } return(null); }
public UpdateChunkJob(ValueWithNeighbors <Chunk> chunkWithNeighbors, uint frameCount, Unity.Mathematics.Random random, CommandBuilder drawingCommands, float2 chunkPosition, float chunkScale, float simulationStep) { this.chunkWithNeighbors = chunkWithNeighbors; this.frameCount = frameCount; this.random = random; this.drawingCommands = drawingCommands; this.chunkPosition = chunkPosition; this.chunkScale = chunkScale; this.simulationStep = simulationStep; }
public static bool GetRelativeCellPosition(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, out int2 relativeChunkPosition, out int2 relativeCellPosition) { var chunkOffset = math.int2(math.floor(math.float2(cellPosition) / math.float2(chunkSize, chunkSize))); var relativeTargetCell = (cellPosition - (chunkOffset * chunkSize)); var neighborChunk = chunkWithNeighbors.ChunkFromPosition(chunkOffset); if (neighborChunk.IsOutOfBounds) { relativeChunkPosition = default; relativeCellPosition = default; return(false); } relativeChunkPosition = chunkOffset; relativeCellPosition = relativeTargetCell; return(true); }
public bool Update(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, Random random) { Cell?GetCellAtOffset(int2 offset) { return(CellUtils.GetCellAtPosition(chunkWithNeighbors, cellPosition + offset)); } bool MoveTo(int2 offset) { return(CellUtils.SwitchCells(chunkWithNeighbors, cellPosition, offset)); } var randomDirection = random.NextBool() ? -1 : 1; { var cellType = GetCellAtOffset(int2(0, -1))?.type; if (cellType == CellType.None || cellType == CellType.Water) { return(MoveTo(int2(0, -1))); } } { var cellType = GetCellAtOffset(int2(randomDirection, -1))?.type; if (cellType == CellType.None || cellType == CellType.Water) { return(MoveTo(int2(randomDirection, -1))); } } { var cellType = GetCellAtOffset(int2(-randomDirection, -1))?.type; if (cellType == CellType.None || cellType == CellType.Water) { return(MoveTo(int2(-randomDirection, -1))); } } return(false); }
private IEnumerator UpdateWorldCoroutine() { var random = new System.Random(); while (true) { if (loadedChunks.Count == 0) { yield return(new WaitForSeconds(simulationStep)); continue; } using var drawingCommands = DrawingManager.GetBuilder(); var minChunkX = loadedChunks.Min(a => a.Key.x); var minChunkY = loadedChunks.Min(a => a.Key.y); var maxChunkX = loadedChunks.Max(a => a.Key.x); var maxChunkY = loadedChunks.Max(a => a.Key.y); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { JobHandle?jobHandle = null; for (var chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) { for (var chunkY = minChunkY; chunkY <= maxChunkY; chunkY++) { if (!((abs(chunkX % 2) == i) || (abs(chunkY % 2) == j))) { continue; } var chunkPosition = int2(chunkX, chunkY); if (!loadedChunks.TryGetValue(chunkPosition, out var chunkContainer)) { continue; } var chunkContainersWithNeighbors = new ValueWithNeighbors <ChunkContainer?> { Value = chunkContainer, North = loadedChunks.TryGetValue(chunkPosition + int2(0, 1)), NorthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, 1)), East = loadedChunks.TryGetValue(chunkPosition + int2(1, 0)), SouthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, -1)), South = loadedChunks.TryGetValue(chunkPosition + int2(0, -1)), SouthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, -1)), West = loadedChunks.TryGetValue(chunkPosition + int2(-1, 0)), NorthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, 1)), }; var chunkWithNeighbors = new ValueWithNeighbors <Chunk> { Value = chunkContainer.Chunk, North = chunkContainersWithNeighbors.North?.Chunk ?? outOfBoundsChunk, NorthEast = chunkContainersWithNeighbors.NorthEast?.Chunk ?? outOfBoundsChunk, East = chunkContainersWithNeighbors.East?.Chunk ?? outOfBoundsChunk, SouthEast = chunkContainersWithNeighbors.SouthEast?.Chunk ?? outOfBoundsChunk, South = chunkContainersWithNeighbors.South?.Chunk ?? outOfBoundsChunk, SouthWest = chunkContainersWithNeighbors.SouthWest?.Chunk ?? outOfBoundsChunk, West = chunkContainersWithNeighbors.West?.Chunk ?? outOfBoundsChunk, NorthWest = chunkContainersWithNeighbors.NorthWest?.Chunk ?? outOfBoundsChunk }; var job = new UpdateChunkJob(chunkWithNeighbors, (uint)Time.frameCount, new Unity.Mathematics.Random((uint)random.Next()), drawingCommands, (float2)chunkPosition * ChunkScale, ChunkScale, simulationStep); var newJobHandle = job.Schedule(); if (jobHandle == null) { jobHandle = newJobHandle; } else { jobHandle = JobHandle.CombineDependencies(jobHandle.Value, newJobHandle); } } } if (jobHandle != null) { jobHandle.Value.Complete(); } } } yield return(new WaitForSeconds(simulationStep)); } }
public bool Update(ValueWithNeighbors <Chunk> chunkWithNeighbors, int2 cellPosition, Random random) { Cell?GetCellAtOffset(int2 offset) { return(CellUtils.GetCellAtPosition(chunkWithNeighbors, cellPosition + offset)); } bool MoveTo(int2 offset) { return(CellUtils.SwitchCells(chunkWithNeighbors, cellPosition, offset)); } var randomDirection = random.NextBool() ? -1 : 1; if (GetCellAtOffset(int2(0, -1))?.type == CellType.None) { return(MoveTo(int2(0, -1))); } else if (GetCellAtOffset(int2(randomDirection, -1))?.type == CellType.None) { if (GetCellAtOffset(int2(randomDirection * 2, -2))?.type == CellType.None) { return(MoveTo(int2(randomDirection * 2, -2))); } else { return(MoveTo(int2(randomDirection, -1))); } } else if (GetCellAtOffset(int2(-randomDirection, -1))?.type == CellType.None) { if (GetCellAtOffset(int2(-randomDirection * 2, -2))?.type == CellType.None) { return(MoveTo(int2(-randomDirection * 2, -2))); } else { return(MoveTo(int2(-randomDirection, -1))); } } else if (GetCellAtOffset(int2(randomDirection, 0))?.type == CellType.None) { if (GetCellAtOffset(int2(randomDirection * 2, 0))?.type == CellType.None) { return(MoveTo(int2(randomDirection * 2, 0))); } else { return(MoveTo(int2(randomDirection, 0))); } } else if (GetCellAtOffset(int2(-randomDirection, 0))?.type == CellType.None) { if (GetCellAtOffset(int2(-randomDirection * 2, 0))?.type == CellType.None) { return(MoveTo(int2(-randomDirection * 2, 0))); } else { return(MoveTo(int2(-randomDirection, 0))); } } // return // TryMoveTo(math.int2(0, -1)) || // TryMoveTo(math.int2(randomDirection * 2, -1)) || // TryMoveTo(math.int2(-randomDirection * 2, -1)) || // TryMoveTo(math.int2(randomDirection * 2, 0)) || // TryMoveTo(math.int2(-randomDirection * 2, 0)) || // TryMoveTo(math.int2(randomDirection, -1)) || // TryMoveTo(math.int2(-randomDirection, -1)) || // TryMoveTo(math.int2(randomDirection, 0)) || // TryMoveTo(math.int2(-randomDirection, 0)); return(false); }