using UnityEngine; namespace Utils { public static class MeshGenerator { public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2.0f; float topLeftZ = (height - 1) / 2.0f; int simplificationIncrement = levelOfDetail == 0 ? 1 : levelOfDetail * 2; int verticesPerLine = (width - 1) / simplificationIncrement + 1; MeshData data = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += simplificationIncrement) for (int x = 0; x < width; x += simplificationIncrement) { data.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); data.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { data.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); data.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } return data; } } public struct MeshData { public readonly Vector3[] vertices; public readonly int[] triangles; public readonly Vector2[] uvs; private int triangleIndex; public MeshData(int width, int height) { vertices = new Vector3[width * height]; uvs = new Vector2[vertices.Length]; triangles = new int[(width - 1) * (height - 1) * 6]; triangleIndex = 0; } public void AddTriangle(int a, int b, int c) { triangles[triangleIndex] = a; triangles[triangleIndex + 1] = b; triangles[triangleIndex + 2] = c; triangleIndex += 3; } public Mesh CreateMesh() { Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = triangles; mesh.uv = uvs; mesh.RecalculateNormals(); return mesh; } } }