public void UpdateTexture(TileLight[] lights) { for (int x = 0; x < chunkSize.x; x++) { for (int y = 0; y < chunkSize.y; y++) { int2 lightPosition = TileUtil.TileToWorldTile(new int2(x, y), chunkPosition, chunkSize); int index = TileUtil.To1DIndex(lightPosition, mapSize); int sunLight = lights[index].GetSunLight(); int torchRedLight = lights[index].GetRedLight(); int torchGreenLight = lights[index].GetGreenLight(); int torchBlueLight = lights[index].GetBlueLight(); byte redIntensity = (byte)Mathf.Max(torchRedLight, sunLight); byte greenIntensity = (byte)Mathf.Max(torchGreenLight, sunLight); byte blueIntensity = (byte)Mathf.Max(torchBlueLight, sunLight); Color32 color = new Color32(redIntensity, greenIntensity, blueIntensity, 255); texture.SetPixel(x, y, color); } } texture.Apply(); }
public bool SetLight(int2 worldTilePosition, int value, LightType type) { if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize)) { return(false); } int index = TileUtil.To1DIndex(worldTilePosition, mapSize); if (lights[index].GetLight(type) == value) { return(false); } int2 chunkPosition = TileUtil.WorldTileToChunk(worldTilePosition, chunkSize); if (chunks.TryGetValue(chunkPosition, out TileChunk chunk)) { chunk.SetLightDirty(); } else { TileChunk newChunk = GenerateChunk(chunkPosition); newChunk.SetLightDirty(); } lights[index].SetLight(value, type); return(true); }
void OnDrawGizmos() { if (tiles == null) { return; } Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); int2 worldtilePosition = TileUtil.WorldToWorldtile(mousePosition); if (!TileUtil.BoundaryCheck(worldtilePosition, mapSize)) { return; } int tileIndex = TileUtil.To1DIndex(worldtilePosition, mapSize); int tile = tiles[tileIndex]; if (tileInformations[tile].isSolid) { return; } Handles.Label(mousePosition, waterDensities[tileIndex].ToString()); }
public int GetTile(int2 worldTilePosition) { if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize)) { return(-1); } return(tiles[TileUtil.To1DIndex(worldTilePosition, mapSize)]); }
public int GetLight(int2 worldTilePosition, LightType type) { if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize)) { return(0); } return(lights[TileUtil.To1DIndex(worldTilePosition, mapSize)].GetLight(type)); }
void Update() { currentFlowSpeed = Mathf.Clamp01(flowSpeed * Time.deltaTime); if (fluidUpdator == null) { fluidUpdator = StartCoroutine(nameof(UpdateFluid)); } SunLightPropagation(); TorchLightPropagation(ref torchRedLightPropagationQueue, ref torchRedLightRemovalQueue, LightType.R); TorchLightPropagation(ref torchGreenLightPropagationQueue, ref torchGreenLightRemovalQueue, LightType.G); TorchLightPropagation(ref torchBlueLightPropagationQueue, ref torchBlueLightRemovalQueue, LightType.B); UpdateChunks(); Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); int2 worldTilePosition = TileUtil.WorldToWorldtile(mousePosition); if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize)) { return; } if (Input.GetMouseButton(0)) { SetTile(worldTilePosition, tileInformations[1].id); } else if (Input.GetMouseButton(1)) { SetTile(worldTilePosition, tileInformations[0].id); fluidQueue.Enqueue(new Tuple <int, float>(TileUtil.To1DIndex(worldTilePosition, mapSize), 0.0f)); } else if (Input.GetKeyDown(KeyCode.T)) { SetTile(worldTilePosition, tileInformations[3].id); } else if (Input.GetKey(KeyCode.W)) { SetTile(worldTilePosition, tileInformations[2].id); fluidQueue.Enqueue(new Tuple <int, float>(TileUtil.To1DIndex(worldTilePosition, mapSize), waterDensities[TileUtil.To1DIndex(worldTilePosition, mapSize)] + 3.0f)); } }
public bool SetTile(int2 worldTilePosition, int id) { if (!TileUtil.BoundaryCheck(worldTilePosition, mapSize)) { return(false); } int index = TileUtil.To1DIndex(worldTilePosition, mapSize); if (tiles[index] == id) { return(false); } int2 chunkPosition = TileUtil.WorldTileToChunk(worldTilePosition, chunkSize); if (chunks.TryGetValue(chunkPosition, out TileChunk chunk)) { chunk.SetMeshDirty(); } else { TileChunk newChunk = GenerateChunk(chunkPosition); newChunk.SetMeshDirty(); } if (tileInformations[id].isSolid) { fluidQueue.Enqueue(new Tuple <int, float>(index, 0.0f)); } LightEmission beforeEmission = tileInformations[tiles[index]].emission; tiles[index] = id; SetEmission(worldTilePosition, tileInformations[id].emission); CheckTileToUpdateLight(worldTilePosition, id, beforeEmission); return(true); }
void GenerateMesh(int[] tiles, float[] waterDensities) { vertices.Clear(); indices.Clear(); uvs.Clear(); colors.Clear(); paths.Clear();; visited.Clear(); int numQuads = 0; for (int x = 0; x < chunkSize.x; x++) { for (int y = 0; y < chunkSize.y;) { int2 tilePosition = TileUtil.TileToWorldTile(new int2(x, y), chunkPosition, chunkSize); int index = TileUtil.To1DIndex(tilePosition, mapSize); int tile = tiles[index]; if (tile == 0) { y++; continue; } if (visited.Contains(tilePosition)) { y++; continue; } visited.Add(tilePosition); int height; for (height = 1; height + y < chunkSize.y; height++) { int2 nextPosition = tilePosition + TileUtil.Up * height; if (!TileUtil.BoundaryCheck(nextPosition, chunkPosition, chunkSize)) { break; } int nextIndex = TileUtil.To1DIndex(nextPosition, mapSize); int nextTile = tiles[nextIndex]; if (nextTile != tile) { break; } if (!TileManager.tileInformations[tile].isSolid) { break; } if (visited.Contains(nextPosition)) { break; } visited.Add(nextPosition); } bool done = false; int width; for (width = 1; width + x < chunkSize.x; width++) { for (int dy = 0; dy < height; dy++) { int2 nextPosition = tilePosition + TileUtil.Up * dy + TileUtil.Right * width; if (!TileUtil.BoundaryCheck(nextPosition, chunkPosition, chunkSize)) { done = true; break; } int nextIndex = TileUtil.To1DIndex(nextPosition, mapSize); int nextTile = tiles[nextIndex]; if (nextTile != tile || visited.Contains(nextPosition)) { done = true; break; } if (!TileManager.tileInformations[tile].isSolid) { done = true; break; } } if (done) { break; } for (int dy = 0; dy < height; dy++) { int2 nextPosition = tilePosition + TileUtil.Up * dy + TileUtil.Right * width; visited.Add(nextPosition); } } float2 scale = new float2(width, height); List <Vector2> points = new List <Vector2>(); for (int i = 0; i < 4; i++) { Vector2 vertex = tileVertices[i] * scale + tilePosition; vertices.Add(vertex); Vector2 uv2 = tileVertices[i] * scale; Vector4 uv4 = new Vector4(uv2.x, uv2.y, scale.x, scale.y); uvs.Add(uv4); Color32 color = TileManager.tileInformations[tile].color; if (TileManager.tileInformations[tile].isSolid) { colors.Add(color); } else { float density = Mathf.Clamp(waterDensities[index], 0.0f, 1.0f); int2 upPosition = tilePosition + TileUtil.Up; if (TileUtil.BoundaryCheck(upPosition, mapSize)) { int upTile = tiles[TileUtil.To1DIndex(upPosition, mapSize)]; if (!TileManager.tileInformations[upTile].isSolid && upTile != 0) { density = 1.0f; } } int2 downPosition = tilePosition + TileUtil.Down; if (TileUtil.BoundaryCheck(downPosition, mapSize)) { int downTile = tiles[TileUtil.To1DIndex(downPosition, mapSize)]; if (!TileManager.tileInformations[downTile].isSolid && downTile == 0) { density = 1.0f; } } color.a = (byte)(byte.MaxValue * density); colors.Add(color); } // Not Optimized Collider Generation Vector2 point = colliderPoints[i] * scale + tilePosition; points.Add(point); } paths.Add(points); for (int i = 0; i < 6; i++) { indices.Add(tileIndices[i] + numQuads * 4); } y += height; numQuads++; } } }
public void Execute(int tileIndex) { int2 tilePosition = TileUtil.To2DIndex(tileIndex, mapSize); if (tiles[tileIndex] != waterID) { if (isSolid[tiles[tileIndex]]) { waterDensities[tileIndex] = 0.0f; } return; } if (waterDensities[tileIndex] < minDensity) { waterDensities[tileIndex] = 0; return; } float remainingDensity = waterDensities[tileIndex]; if (remainingDensity <= 0) { return; } waterChunkDirty[TileUtil.To1DIndex(TileUtil.WorldTileToChunk(tilePosition, chunkSize), numChunks)] = true; int2 downPosition = tilePosition + TileUtil.Down; int downIndex = TileUtil.To1DIndex(downPosition, mapSize); if (TileUtil.BoundaryCheck(downPosition, mapSize) && !isSolid[tiles[downIndex]]) { float flow = CalculateStableDensity(remainingDensity + waterDensities[downIndex]) - waterDensities[downIndex]; if (flow > minFlow) { flow *= flowSpeed; } flow = Mathf.Clamp(flow, 0, Mathf.Min(maxFlow, remainingDensity)); waterDiff[tileIndex] -= flow; waterDiff[downIndex] += flow; remainingDensity -= flow; } if (remainingDensity < minDensity) { waterDiff[tileIndex] -= remainingDensity; return; } int2 leftPosition = tilePosition + TileUtil.Left; int leftIndex = TileUtil.To1DIndex(leftPosition, mapSize); if (TileUtil.BoundaryCheck(leftIndex, mapSize) && !isSolid[tiles[leftIndex]]) { float flow = (remainingDensity - waterDensities[leftIndex]) / 4.0f; if (flow > minFlow) { flow *= flowSpeed; } flow = Mathf.Clamp(flow, 0, Mathf.Min(maxFlow, remainingDensity)); waterDiff[tileIndex] -= flow; waterDiff[leftIndex] += flow; remainingDensity -= flow; } if (remainingDensity < minDensity) { waterDiff[tileIndex] -= remainingDensity; return; } int2 rightPosition = tilePosition + TileUtil.Right; int rightIndex = TileUtil.To1DIndex(rightPosition, mapSize); if (TileUtil.BoundaryCheck(rightIndex, mapSize) && !isSolid[tiles[rightIndex]]) { float flow = (remainingDensity - waterDensities[rightIndex]) / 3.0f; if (flow > minFlow) { flow *= flowSpeed; } flow = Mathf.Clamp(flow, 0, Mathf.Min(maxFlow, remainingDensity)); waterDiff[tileIndex] -= flow; waterDiff[rightIndex] += flow; remainingDensity -= flow; } if (remainingDensity < minDensity) { waterDiff[tileIndex] -= remainingDensity; return; } int2 upPosition = tilePosition + TileUtil.Up; int upIndex = TileUtil.To1DIndex(upPosition, mapSize); if (TileUtil.BoundaryCheck(upIndex, mapSize) && !isSolid[tiles[upIndex]]) { float flow = remainingDensity - CalculateStableDensity(remainingDensity + waterDensities[upIndex]); if (flow > minFlow) { flow *= flowSpeed; } flow = Mathf.Clamp(flow, 0, Mathf.Min(maxFlow, remainingDensity)); waterDiff[tileIndex] -= flow; waterDiff[upIndex] += flow; remainingDensity -= flow; } if (remainingDensity < minDensity) { waterDiff[tileIndex] -= remainingDensity; } }