Aucune description
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

MeshUtilities.cs 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using Unity.Burst;
  2. using Unity.Collections;
  3. using Unity.Collections.LowLevel.Unsafe;
  4. using Unity.Mathematics;
  5. namespace UnityEngine.U2D.Animation
  6. {
  7. [BurstCompile]
  8. internal static class MeshUtilities
  9. {
  10. /// <summary>
  11. /// Get the outline edges from a set of indices.
  12. /// This method expects the index array to be laid out with one triangle for every 3 indices.
  13. /// E.g. triangle 0: index 0 - 2, triangle 1: index 3 - 5, etc.
  14. /// </summary>
  15. /// <returns>Returns a NativeArray of sorted edges. It is up to the caller to dispose this array.</returns>
  16. public static NativeArray<int2> GetOutlineEdges(in NativeArray<ushort> indices)
  17. {
  18. var edges = new UnsafeHashMap<int, int3>(indices.Length, Allocator.Persistent);
  19. for (var i = 0; i < indices.Length; i += 3)
  20. {
  21. var i0 = indices[i];
  22. var i1 = indices[i + 1];
  23. var i2 = indices[i + 2];
  24. var edge0 = new int2(i0, i1);
  25. var edge1 = new int2(i1, i2);
  26. var edge2 = new int2(i2, i0);
  27. AddToEdgeMap(edge0, ref edges);
  28. AddToEdgeMap(edge1, ref edges);
  29. AddToEdgeMap(edge2, ref edges);
  30. }
  31. #if COLLECTIONS_2_0_OR_ABOVE
  32. var outlineEdges = new NativeList<int2>(edges.Count, Allocator.Temp);
  33. #else
  34. var outlineEdges = new NativeList<int2>(edges.Count(), Allocator.Temp);
  35. #endif
  36. foreach(var edgePair in edges)
  37. {
  38. // If an edge is only used in one triangle, it is an outline edge.
  39. if (edgePair.Value.z == 1)
  40. outlineEdges.Add(edgePair.Value.xy);
  41. }
  42. edges.Dispose();
  43. SortEdges(outlineEdges.AsArray(), out var sortedEdges);
  44. return sortedEdges;
  45. }
  46. [BurstCompile]
  47. static void AddToEdgeMap(in int2 edge, ref UnsafeHashMap<int, int3> edgeMap)
  48. {
  49. var tmpEdge = math.min(edge.x, edge.y) == edge.x ? edge.xy : edge.yx;
  50. var hashCode = tmpEdge.GetHashCode();
  51. // We store the hashCode as key, so that we can do less GetHashCode-calls.
  52. // Then we store the count the int3s z-value.
  53. if (!edgeMap.ContainsKey(hashCode))
  54. edgeMap[hashCode] = new int3(edge, 1);
  55. else
  56. {
  57. var val = edgeMap[hashCode];
  58. val.z++;
  59. edgeMap[hashCode] = val;
  60. }
  61. }
  62. [BurstCompile]
  63. static void SortEdges(in NativeArray<int2> unsortedEdges, out NativeArray<int2> sortedEdges)
  64. {
  65. var tmpEdges = new NativeArray<int2>(unsortedEdges.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
  66. var shapeStartingEdge = new NativeList<int>(1, Allocator.Persistent);
  67. var edgeMap = new UnsafeHashMap<int, int>(unsortedEdges.Length, Allocator.Persistent);
  68. var usedEdges = new NativeArray<bool>(unsortedEdges.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
  69. for (var i = 0; i < unsortedEdges.Length; i++)
  70. {
  71. edgeMap[unsortedEdges[i].x] = i;
  72. usedEdges[i] = false;
  73. }
  74. var findStartingEdge = true;
  75. var edgeIndex = -1;
  76. var startingEdge = 0;
  77. for (var i = 0; i < unsortedEdges.Length; i++)
  78. {
  79. if (findStartingEdge)
  80. {
  81. edgeIndex = GetFirstUnusedIndex(usedEdges);
  82. startingEdge = edgeIndex;
  83. findStartingEdge = false;
  84. shapeStartingEdge.Add(i);
  85. }
  86. usedEdges[edgeIndex] = true;
  87. tmpEdges[i] = unsortedEdges[edgeIndex];
  88. var nextVertex = unsortedEdges[edgeIndex].y;
  89. edgeIndex = edgeMap[nextVertex];
  90. if (edgeIndex == startingEdge)
  91. findStartingEdge = true;
  92. }
  93. var finalEdgeArrLength = unsortedEdges.Length;
  94. sortedEdges = new NativeArray<int2>(finalEdgeArrLength, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
  95. var count = 0;
  96. for (var i = 0; i < shapeStartingEdge.Length; ++i)
  97. {
  98. var edgeStart = shapeStartingEdge[i];
  99. var edgeEnd = (i + 1) == shapeStartingEdge.Length ? tmpEdges.Length : shapeStartingEdge[i + 1];
  100. for (var m = edgeStart; m < edgeEnd; ++m)
  101. sortedEdges[count++] = tmpEdges[m];
  102. }
  103. usedEdges.Dispose();
  104. edgeMap.Dispose();
  105. shapeStartingEdge.Dispose();
  106. tmpEdges.Dispose();
  107. }
  108. [BurstCompile]
  109. static int GetFirstUnusedIndex(in NativeArray<bool> usedValues)
  110. {
  111. for (var i = 0; i < usedValues.Length; i++)
  112. {
  113. if (!usedValues[i])
  114. return i;
  115. }
  116. return -1;
  117. }
  118. }
  119. }