BackgroundMeshGenerator.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO.IsolatedStorage;
  6. using System.Linq;
  7. using Random = UnityEngine.Random;
  8. namespace Devodg.SciFiDesign.UI
  9. {
  10. public class BackgroundMeshGenerator : MonoBehaviour
  11. {
  12. public struct Triangle
  13. {
  14. public int a, b, c;
  15. }
  16. public int vertices = 20;
  17. public Color startColor;
  18. public Color endColor;
  19. public bool debug = false;
  20. private Material _material;
  21. private MeshRenderer _renderer;
  22. protected void Awake()
  23. {
  24. _material = new Material(Shader.Find("Devdog/UI/BackgroundMesh"));
  25. _renderer = GetOrAddComponent<MeshRenderer>();
  26. var meshFilter = GetOrAddComponent<MeshFilter>();
  27. meshFilter.mesh = Generate2DVoronoiMesh(new Rect(0, 0, Screen.width, Screen.height), vertices);
  28. _renderer.material = _material;
  29. #if UNITY_5_4_OR_NEWER
  30. Random.InitState(DateTime.Now.Second);
  31. #else
  32. Random.seed = DateTime.Now.Second;
  33. #endif
  34. }
  35. private T GetOrAddComponent<T>() where T: UnityEngine.Component
  36. {
  37. var t = GetComponent<T>();
  38. if (t != null)
  39. {
  40. return t;
  41. }
  42. return gameObject.AddComponent<T>();
  43. }
  44. protected Mesh Generate2DVoronoiMesh(Rect inRect, int amount)
  45. {
  46. var mesh = new Mesh();
  47. var vertices = new List<Vector3>(amount + 4); // + 4 for all edges
  48. vertices.Add(Vector3.zero);
  49. vertices.Add(Vector3.up * Screen.height);
  50. vertices.Add(Vector3.right * Screen.width);
  51. vertices.Add(new Vector3(1f * Screen.width, 1f * Screen.height, 0f));
  52. for (int i = 0; i < amount - 4; i++)
  53. {
  54. var randomPoint = new Vector3(Random.Range(inRect.x, inRect.x + inRect.width),
  55. Random.Range(inRect.y, inRect.y + inRect.height),
  56. 0f);
  57. vertices.Add(randomPoint);
  58. }
  59. vertices = vertices.OrderBy(o => o.x).ThenBy(o => o.y).ToList();
  60. var arr = vertices.ToArray();
  61. if (debug)
  62. {
  63. for (int i = 0; i < vertices.Count; i++)
  64. {
  65. var obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
  66. obj.transform.SetParent(transform);
  67. obj.transform.localPosition = vertices[i];
  68. obj.transform.localScale = Vector3.one * 10f;
  69. obj.transform.localRotation = Quaternion.identity;
  70. obj.layer = gameObject.layer;
  71. }
  72. }
  73. // Connect triangles
  74. DelaunayTriangulation(arr);
  75. mesh.vertices = arr;
  76. // mesh.triangles = triangles;
  77. // mesh.normals = normals;
  78. mesh.RecalculateNormals();
  79. return mesh;
  80. }
  81. protected void DelaunayTriangulation(Vector3[] v)
  82. {
  83. var leftHalfCount = v.Length/2;
  84. var leftHalf = v.Take(leftHalfCount).ToArray();
  85. var rightHalf = v.Skip(leftHalfCount).Take(v.Length - leftHalfCount).ToArray();
  86. if (leftHalf.Length > 3)
  87. {
  88. Debug.Log("Delaunay left : " + leftHalf.Length);
  89. DelaunayTriangulation(leftHalf);
  90. }
  91. else
  92. {
  93. Debug.Log("<color=green>Triangulate left</color>: " + leftHalf.Length);
  94. }
  95. if (rightHalf.Length > 3)
  96. {
  97. Debug.Log("Delaunay right : " + leftHalf.Length);
  98. DelaunayTriangulation(rightHalf);
  99. }
  100. else
  101. {
  102. Debug.Log("<color=yellow>Triangulate right</color>: " + rightHalf.Length);
  103. }
  104. // Merge left half with right half (LL, LR)
  105. for (int i = 0; i < leftHalf.Length; i++)
  106. {
  107. }
  108. }
  109. protected int GetClosestVertexIndex(Vector3[] vertices, int fromIndex)
  110. {
  111. var curPos = vertices[fromIndex];
  112. int closestIndex = -1;
  113. float closest = 9999;
  114. for (int i = 0; i < vertices.Length; i++)
  115. {
  116. var dist = Vector3.Distance(vertices[i], curPos);
  117. if (dist < closest)
  118. {
  119. closest = dist;
  120. closestIndex = i;
  121. }
  122. }
  123. return closestIndex;
  124. }
  125. }
  126. }