MeshGenerator.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using UnityEngine;
  2. public static class MeshGenerator
  3. {
  4. public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail)
  5. {
  6. AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys);
  7. int width = heightMap.GetLength(0);
  8. int height = heightMap.GetLength(1);
  9. float topLeftX = (width - 1) / -2f;
  10. float topLeftZ = (height - 1) / 2f;
  11. int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2;
  12. int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1;
  13. MeshData meshData = new MeshData(verticesPerLine, verticesPerLine);
  14. int vertexIndex = 0;
  15. for(int y = 0; y < height; y += meshSimplificationIncrement)
  16. {
  17. for(int x = 0; x < width; x += meshSimplificationIncrement)
  18. {
  19. meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x,y])* heightMultiplier, topLeftZ - y);
  20. meshData.uvs[vertexIndex] = new Vector2(x/(float)width, y/(float)height);
  21. if(x < width - 1 && y < height - 1)
  22. {
  23. meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine);
  24. meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1);
  25. }
  26. vertexIndex++;
  27. }
  28. }
  29. return meshData;
  30. }
  31. }
  32. public class MeshData
  33. {
  34. public Vector3[] vertices;
  35. public int[] triangles;
  36. public Vector2[] uvs;
  37. int triangleIndex;
  38. public MeshData(int meshWidth, int meshHeight)
  39. {
  40. vertices = new Vector3[meshWidth * meshHeight];
  41. uvs = new Vector2[meshWidth * meshHeight];
  42. triangles = new int[(meshWidth-1) * (meshHeight-1) * 6];
  43. }
  44. public void AddTriangle(int a, int b, int c)
  45. {
  46. triangles[triangleIndex] = a;
  47. triangles[triangleIndex+1] = b;
  48. triangles[triangleIndex+2] = c;
  49. triangleIndex += 3;
  50. }
  51. Vector3[] CalculateNormals()
  52. {
  53. Vector3[] vertexNormals = new Vector3[vertices.Length];
  54. int triangleCount = triangles.Length / 3;
  55. for (int i = 0; i < triangleCount; i++)
  56. {
  57. int normalTriangleIndex = i * 3;
  58. int vertexIndexA = triangles[normalTriangleIndex];
  59. int vertexIndexB = triangles[normalTriangleIndex + 1];
  60. int vertexIndexC = triangles[normalTriangleIndex + 2];
  61. Vector3 triangleNormal = SurfaceNormalFromIndices(vertexIndexA, vertexIndexB, vertexIndexC);
  62. vertexNormals[vertexIndexA] += triangleNormal;
  63. vertexNormals[vertexIndexB] += triangleNormal;
  64. vertexNormals[vertexIndexC] += triangleNormal;
  65. }
  66. for(int i = 0; i < vertexNormals.Length; i++)
  67. {
  68. vertexNormals[i].Normalize();
  69. }
  70. return vertexNormals;
  71. }
  72. Vector3 SurfaceNormalFromIndices(int indexA, int indexB, int indexC)
  73. {
  74. Vector3 pointA = vertices[indexA];
  75. Vector3 pointB = vertices[indexB];
  76. Vector3 pointC = vertices[indexC];
  77. Vector3 sideAB = pointB - pointA;
  78. Vector3 sideAC = pointC - pointA;
  79. return Vector3.Cross(sideAB, sideAC).normalized;
  80. }
  81. public Mesh CreateMesh()
  82. {
  83. Mesh mesh = new Mesh();
  84. mesh.vertices = vertices;
  85. mesh.triangles = triangles;
  86. mesh.uv = uvs;
  87. mesh.normals = CalculateNormals();
  88. return mesh;
  89. }
  90. }