PlaneGenerator.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. public class PlaneGenerator : MonoBehaviour
  4. {
  5. public Material material;
  6. public float noiseLevel = 0.1f;
  7. private const int pqsResolution = 16;
  8. private const int sphereRadius = 10;
  9. private List<Quad> quads;
  10. // Start is called once before the first execution of Update after the MonoBehaviour is created
  11. void Start()
  12. {
  13. BuildRootQuads();
  14. UpdateMeshes();
  15. }
  16. // Update is called once per frame
  17. void Update()
  18. {
  19. }
  20. private void BuildRootQuads()
  21. {
  22. quads = new List<Quad>
  23. {
  24. BuildQuad("quadY", new Vector3(0, 0, 0)),
  25. BuildQuad("quadY1", new Vector3(180, 0, 0)),
  26. BuildQuad("quadZ", new Vector3(90, 0, 0)),
  27. BuildQuad("quadZ1", new Vector3(-90, 0, 0)),
  28. BuildQuad("quadX", new Vector3(0, 0, 90)),
  29. BuildQuad("quadX1", new Vector3(0, 0, -90))
  30. };
  31. }
  32. private Quad BuildQuad(string name, Vector3 eulerAngles)
  33. {
  34. var (vertices, uv) = CreateVertices();
  35. Rotate(vertices, eulerAngles);
  36. var triangles = CreateTriangles();
  37. return new Quad
  38. {
  39. Name = name,
  40. Vertices = vertices,
  41. Triangles = triangles,
  42. Uv = uv
  43. };
  44. }
  45. private void UpdateMeshes()
  46. {
  47. foreach (var quad in quads)
  48. {
  49. CreateMesh(quad.Name, quad.Vertices, quad.Uv, quad.Triangles);
  50. }
  51. }
  52. private (Vector3[] vertices, Vector2[] uv) CreateVertices()
  53. {
  54. var half = sphereRadius / 2f;
  55. var vertices = new Vector3[(pqsResolution + 1) * (pqsResolution + 1)];
  56. Vector2[] uv = new Vector2[(pqsResolution + 1) * (pqsResolution + 1)];
  57. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  58. {
  59. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  60. {
  61. vertices[vertex] = new Vector3(half - (float)x / pqsResolution * sphereRadius, half, half - (float)z / pqsResolution * sphereRadius);
  62. uv[vertex] = new Vector2((float)x / pqsResolution, (float)z / pqsResolution);
  63. }
  64. }
  65. return (vertices, uv);
  66. }
  67. private int[] CreateTriangles()
  68. {
  69. var triangles = new int[(pqsResolution) * (pqsResolution) * 6];
  70. int triangle = 0;
  71. for (int x = 1, vertex = 0; x<pqsResolution + 1; x++, vertex++)
  72. {
  73. for (int z = 1; z<pqsResolution + 1; z++, vertex++)
  74. {
  75. triangles[triangle] = vertex;
  76. triangles[triangle + 1] = vertex + pqsResolution + 2;
  77. triangles[triangle + 2] = vertex + pqsResolution + 1;
  78. triangles[triangle + 3] = vertex;
  79. triangles[triangle + 4] = vertex + 1;
  80. triangles[triangle + 5] = vertex + pqsResolution + 2;
  81. triangle += 6;
  82. }
  83. }
  84. return triangles;
  85. }
  86. private void CreateMesh(string name, Vector3[] vertices, Vector2[] uv, int[] triangles)
  87. {
  88. var mesh = new GameObject(name, typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider));
  89. mesh.transform.localScale = new Vector3(1, 1, 1);
  90. var meshFilter = mesh.GetComponent<MeshFilter>();
  91. meshFilter.mesh.vertices = vertices;
  92. meshFilter.mesh.triangles = triangles;
  93. meshFilter.mesh.uv = uv;
  94. mesh.GetComponent<MeshCollider>().sharedMesh = meshFilter.mesh;
  95. meshFilter.mesh.RecalculateBounds();
  96. meshFilter.mesh.RecalculateNormals();
  97. mesh.GetComponent<MeshRenderer>().material = material;
  98. }
  99. private void Rotate(Vector3[] vertices, Vector3 eulerAngles)
  100. {
  101. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  102. {
  103. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  104. {
  105. vertices[vertex] = Rotate(vertices[vertex], eulerAngles);
  106. vertices[vertex] = Vector3.Normalize(vertices[vertex]);
  107. }
  108. }
  109. }
  110. private Vector3 Rotate(Vector3 vertex, Vector3 eulerAngles)
  111. {
  112. var result = vertex;
  113. if (eulerAngles.x != 0)
  114. result = RotateX(result, eulerAngles.x);
  115. if (eulerAngles.y != 0)
  116. result = RotateY(result, eulerAngles.y);
  117. if (eulerAngles.z != 0)
  118. result = RotateZ(result, eulerAngles.z);
  119. return result;
  120. }
  121. private Vector3 RotateX(Vector3 vertex, float angle)
  122. {
  123. var angleDeg = Mathf.Deg2Rad * angle;
  124. return new Vector3(
  125. x: vertex.x,
  126. y: vertex.y * Mathf.Cos(angleDeg) - vertex.z * Mathf.Sin(angleDeg),
  127. z: vertex.y * Mathf.Sin(angleDeg) + vertex.z * Mathf.Cos(angleDeg));
  128. }
  129. private Vector3 RotateY(Vector3 vertex, float angle)
  130. {
  131. var angleDeg = Mathf.Deg2Rad * angle;
  132. return new Vector3(
  133. x: vertex.x * Mathf.Cos(angleDeg) + vertex.z * Mathf.Sin(angleDeg),
  134. y: vertex.y,
  135. z: -vertex.x * Mathf.Sin(angleDeg) + vertex.z * Mathf.Cos(angleDeg));
  136. }
  137. private Vector3 RotateZ(Vector3 vertex, float angle)
  138. {
  139. var angleDeg = Mathf.Deg2Rad * angle;
  140. return new Vector3(
  141. x: vertex.x * Mathf.Cos(angleDeg) - vertex.y * Mathf.Sin(angleDeg),
  142. y: vertex.x * Mathf.Sin(angleDeg) + vertex.y * Mathf.Cos(angleDeg),
  143. z: vertex.z);
  144. }
  145. private float GetNoise(float x, float y)
  146. {
  147. return 1 + Mathf.PerlinNoise(x, y) * noiseLevel;
  148. }
  149. private void AddHeights(Vector3[] vertices)
  150. {
  151. for (int x = 0, vertex = 0; x < pqsResolution + 1; x++)
  152. {
  153. for (int z = 0; z < pqsResolution + 1; z++, vertex++)
  154. {
  155. var noise = 1; // GetNoise(vertices[vertex].x, vertices[vertex].y);
  156. vertices[vertex] = noise * sphereRadius * vertices[vertex];
  157. }
  158. }
  159. vertices[pqsResolution + 3] *= 2f;
  160. }
  161. }