using FloodSWE.TileGraph; using UnityEngine; namespace FloodSWE.Streaming { public static class HeightmapExtractor { public static HeightmapPacket CreatePacketFromHeights(int frameId, TileId tile, int resolution, float[] heights) { return HeightmapPacket.FromHeights(frameId, tile, resolution, heights); } public static HeightmapPacket CreateMockPacket(int frameId, TileId tile, int resolution, float timeSeconds, float baseHeight, float amplitude) { int sampleCount = resolution * resolution; float[] heights = new float[sampleCount]; float invRes = 1.0f / Mathf.Max(1, resolution - 1); int index = 0; for (int y = 0; y < resolution; y++) { float fy = y * invRes; for (int x = 0; x < resolution; x++) { float fx = x * invRes; float wave = Mathf.Sin((fx + timeSeconds * 0.2f) * Mathf.PI * 2.0f) * Mathf.Cos((fy + timeSeconds * 0.15f) * Mathf.PI * 2.0f); heights[index++] = baseHeight + (amplitude * wave); } } return HeightmapPacket.FromHeights(frameId, tile, resolution, heights); } public static bool TryExtractFromTexture2D(Texture2D texture, int frameId, TileId tile, out HeightmapPacket packet) { packet = default; if (texture == null) { return false; } if (!texture.isReadable) { Debug.LogWarning("HeightmapExtractor: texture is not readable."); return false; } int width = texture.width; int height = texture.height; if (width != height) { Debug.LogWarning("HeightmapExtractor: texture must be square."); return false; } Color[] pixels = texture.GetPixels(); float[] heights = new float[pixels.Length]; for (int i = 0; i < pixels.Length; i++) { heights[i] = pixels[i].r; } packet = HeightmapPacket.FromHeights(frameId, tile, width, heights); return true; } public static bool TryExtractFromRenderTexture(RenderTexture source, int frameId, TileId tile, out HeightmapPacket packet) { packet = default; if (source == null) { return false; } int width = source.width; int height = source.height; if (width != height) { Debug.LogWarning("HeightmapExtractor: render texture must be square."); return false; } RenderTexture previous = RenderTexture.active; RenderTexture.active = source; Texture2D temp = new Texture2D(width, height, TextureFormat.RFloat, false, true); temp.ReadPixels(new Rect(0, 0, width, height), 0, 0); temp.Apply(false, true); RenderTexture.active = previous; bool success = TryExtractFromTexture2D(temp, frameId, tile, out packet); Object.Destroy(temp); return success; } } }