| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- using UnityEngine;
- public static class MeshGenerator
- {
- public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail)
- {
- AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);
- int width = heightMap.GetLength(0);
- int height = heightMap.GetLength(1);
- float topLeftX = (width - 1) / -2f;
- float topLeftZ = (height - 1) / 2f;
- int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
- int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1;
- MeshData meshData = new MeshData(verticesPerLine, verticesPerLine);
- int vertexIndex = 0;
- for(int y = 0; y < height; y += meshSimplificationIncrement)
- {
- for(int x = 0; x < width; x += meshSimplificationIncrement)
- {
- meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x,y])* heightMultiplier, topLeftZ - y);
- meshData.uvs[vertexIndex] = new Vector2(x/(float)width, y/(float)height);
- if(x < width - 1 && y < height - 1)
- {
- meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);
- meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
- }
-
- vertexIndex++;
- }
- }
- return meshData;
- }
- }
- public class MeshData
- {
- public Vector3[] vertices;
- public int[] triangles;
- public Vector2[] uvs;
- int triangleIndex;
- public MeshData(int meshWidth, int meshHeight)
- {
- vertices = new Vector3[meshWidth * meshHeight];
- uvs = new Vector2[meshWidth * meshHeight];
- triangles = new int[(meshWidth-1) * (meshHeight-1) * 6];
- }
- public void AddTriangle(int a, int b, int c)
- {
- triangles[triangleIndex] = a;
- triangles[triangleIndex+1] = b;
- triangles[triangleIndex+2] = c;
- triangleIndex += 3;
- }
- Vector3[] CalculateNormals()
- {
- Vector3[] vertexNormals = new Vector3[vertices.Length];
- int triangleCount = triangles.Length / 3;
- for (int i = 0; i < triangleCount; i++)
- {
- int normalTriangleIndex = i * 3;
- int vertexIndexA = triangles[normalTriangleIndex];
- int vertexIndexB = triangles[normalTriangleIndex + 1];
- int vertexIndexC = triangles[normalTriangleIndex + 2];
- Vector3 triangleNormal = SurfaceNormalFromIndices(vertexIndexA, vertexIndexB, vertexIndexC);
- vertexNormals[vertexIndexA] += triangleNormal;
- vertexNormals[vertexIndexB] += triangleNormal;
- vertexNormals[vertexIndexC] += triangleNormal;
- }
- for(int i = 0; i < vertexNormals.Length; i++)
- {
- vertexNormals[i].Normalize();
- }
- return vertexNormals;
- }
- Vector3 SurfaceNormalFromIndices(int indexA, int indexB, int indexC)
- {
- Vector3 pointA = vertices[indexA];
- Vector3 pointB = vertices[indexB];
- Vector3 pointC = vertices[indexC];
- Vector3 sideAB = pointB - pointA;
- Vector3 sideAC = pointC - pointA;
- return Vector3.Cross(sideAB, sideAC).normalized;
- }
- public Mesh CreateMesh()
- {
- Mesh mesh = new Mesh();
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- mesh.uv = uvs;
- mesh.normals = CalculateNormals();
- return mesh;
- }
- }
|