TriangulationUtility.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using UnityEngine.U2D.Animation.TriangleNet.Geometry;
  4. using UnityEngine.U2D.Animation.TriangleNet.Meshing;
  5. using UnityEngine.U2D.Animation.TriangleNet.Smoothing;
  6. using UnityEngine.U2D.Animation.TriangleNet.Tools;
  7. namespace UnityEditor.U2D.Animation
  8. {
  9. internal class TriangulationUtility
  10. {
  11. public static void Triangulate(IList<Vector2> vertices, IList<Edge> edges, IList<int> indices)
  12. {
  13. indices.Clear();
  14. if (vertices.Count < 3)
  15. return;
  16. var polygon = new Polygon(vertices.Count);
  17. for (int i = 0; i < vertices.Count; ++i)
  18. {
  19. Vector2 position = vertices[i];
  20. polygon.Add(new Vertex(position.x, position.y, 1));
  21. }
  22. for (int i = 0; i < edges.Count; ++i)
  23. {
  24. Edge edge = edges[i];
  25. polygon.Add(new Segment(polygon.Points[edge.index1], polygon.Points[edge.index2]));
  26. }
  27. var mesh = polygon.Triangulate();
  28. foreach (ITriangle triangle in mesh.Triangles)
  29. {
  30. int id0 = triangle.GetVertexID(0);
  31. int id1 = triangle.GetVertexID(1);
  32. int id2 = triangle.GetVertexID(2);
  33. if (id0 < 0 || id1 < 0 || id2 < 0 || id0 >= vertices.Count || id1 >= vertices.Count || id2 >= vertices.Count)
  34. continue;
  35. indices.Add(id0);
  36. indices.Add(id2);
  37. indices.Add(id1);
  38. }
  39. }
  40. public static void Tessellate(float minAngle, float maxAngle, float meshAreaFactor, float largestTriangleAreaFactor, int smoothIterations, IList<Vector2> vertices, IList<Edge> edges, IList<int> indices)
  41. {
  42. if (vertices.Count < 3)
  43. return;
  44. largestTriangleAreaFactor = Mathf.Clamp01(largestTriangleAreaFactor);
  45. var polygon = new Polygon(vertices.Count);
  46. for (int i = 0; i < vertices.Count; ++i)
  47. {
  48. Vector2 position = vertices[i];
  49. polygon.Add(new Vertex(position.x, position.y, 1));
  50. }
  51. for (int i = 0; i < edges.Count; ++i)
  52. {
  53. Edge edge = edges[i];
  54. polygon.Add(new Segment(polygon.Points[edge.index1], polygon.Points[edge.index2]));
  55. }
  56. var mesh = polygon.Triangulate();
  57. var statistic = new Statistic();
  58. statistic.Update((UnityEngine.U2D.Animation.TriangleNet.Mesh)mesh, 1);
  59. if (statistic.LargestArea < 0.01f)
  60. throw new System.Exception("Invalid Mesh: Largest triangle area too small");
  61. var maxAreaToApply = (double)Mathf.Max((float)statistic.LargestArea * largestTriangleAreaFactor, (float)(statistic.MeshArea * meshAreaFactor));
  62. var qualityOptions = new QualityOptions() { SteinerPoints = 0 };
  63. if (maxAreaToApply > 0f)
  64. qualityOptions.MaximumArea = maxAreaToApply;
  65. qualityOptions.MinimumAngle = minAngle;
  66. qualityOptions.MaximumAngle = maxAngle;
  67. mesh.Refine(qualityOptions, false);
  68. mesh.Renumber();
  69. if (smoothIterations > 0)
  70. {
  71. try
  72. {
  73. var smoother = new SimpleSmoother();
  74. smoother.Smooth(mesh, smoothIterations);
  75. }
  76. catch (System.Exception)
  77. {
  78. Debug.Log(TextContent.smoothMeshError);
  79. }
  80. }
  81. vertices.Clear();
  82. edges.Clear();
  83. indices.Clear();
  84. foreach (Vertex vertex in mesh.Vertices)
  85. {
  86. vertices.Add(new Vector2((float)vertex.X, (float)vertex.Y));
  87. }
  88. foreach (ISegment segment in mesh.Segments)
  89. {
  90. edges.Add(new Edge(segment.P0, segment.P1));
  91. }
  92. foreach (ITriangle triangle in mesh.Triangles)
  93. {
  94. int id0 = triangle.GetVertexID(0);
  95. int id1 = triangle.GetVertexID(1);
  96. int id2 = triangle.GetVertexID(2);
  97. if (id0 < 0 || id1 < 0 || id2 < 0 || id0 >= vertices.Count || id1 >= vertices.Count || id2 >= vertices.Count)
  98. continue;
  99. indices.Add(id0);
  100. indices.Add(id2);
  101. indices.Add(id1);
  102. }
  103. }
  104. }
  105. }