暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TriangulationUtility.cs 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. using System;
  2. using System.Collections.Generic;
  3. using Unity.Collections;
  4. using Unity.Collections.LowLevel.Unsafe;
  5. using Unity.Burst;
  6. using Unity.Mathematics;
  7. using UnityEngine;
  8. using ModuleHandle = UnityEngine.U2D.Common.UTess.ModuleHandle;
  9. using Unity.Jobs;
  10. namespace UnityEditor.U2D.Animation
  11. {
  12. [BurstCompile]
  13. internal struct TriangulateJob : IJob
  14. {
  15. // Input Dataset
  16. [DeallocateOnJobCompletion]
  17. internal NativeArray<float2> inputVertices;
  18. [DeallocateOnJobCompletion]
  19. internal NativeArray<int2> inputEdges;
  20. // Output Dataset.
  21. internal NativeArray<int> outputIndices;
  22. internal NativeArray<int2> outputEdges;
  23. internal NativeArray<float2> outputVertices;
  24. internal NativeArray<int4> result;
  25. public void Execute()
  26. {
  27. int outputVertexCount = 0, outputIndexCount = 0, outputEdgeCount = 0;
  28. ModuleHandle.Tessellate(Allocator.Temp, inputVertices, inputEdges, ref outputVertices, out outputVertexCount, ref outputIndices, out outputIndexCount, ref outputEdges, out outputEdgeCount, true);
  29. result[0] = new int4(outputVertexCount, outputIndexCount, outputEdgeCount, 0);
  30. }
  31. }
  32. [BurstCompile]
  33. internal struct TessellateJob : IJob
  34. {
  35. // Input Parameters.
  36. internal int refineIterations;
  37. internal int smoothIterations;
  38. internal float minAngle;
  39. internal float maxAngle;
  40. internal float meshArea;
  41. internal float targetArea;
  42. internal float largestTriangleAreaFactor;
  43. // Input Dataset
  44. [DeallocateOnJobCompletion]
  45. internal NativeArray<float2> inputVertices;
  46. [DeallocateOnJobCompletion]
  47. internal NativeArray<int2> inputEdges;
  48. // Output Dataset.
  49. internal NativeArray<int> outputIndices;
  50. internal NativeArray<int2> outputEdges;
  51. internal NativeArray<float2> outputVertices;
  52. internal NativeArray<int4> result;
  53. public void Execute()
  54. {
  55. int outputVertexCount = 0, outputIndexCount = 0, outputEdgeCount = 0;
  56. ModuleHandle.Subdivide(Allocator.Temp, inputVertices, inputEdges, ref outputVertices, ref outputVertexCount, ref outputIndices, ref outputIndexCount, ref outputEdges, ref outputEdgeCount, largestTriangleAreaFactor, targetArea, refineIterations, smoothIterations);
  57. result[0] = new int4(outputVertexCount, outputIndexCount, outputEdgeCount, 0);
  58. }
  59. }
  60. [BurstCompile]
  61. internal class TriangulationUtility
  62. {
  63. // Adjust Tolerance for Collinear Check.
  64. static readonly float k_CollinearTolerance = 0.0001f;
  65. [BurstCompile]
  66. static unsafe int ValidateCollinear(float2* points, int pointCount, float epsilon)
  67. {
  68. if (pointCount < 3)
  69. return 0;
  70. for (int i = 0; i < pointCount - 2; ++i)
  71. {
  72. double2 a = points[i];
  73. double2 b = points[i + 1];
  74. double2 c = points[i + 2];
  75. // Just check area of triangle and see if its non-zero.
  76. var x = math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
  77. if (x > epsilon)
  78. return 1;
  79. }
  80. return 0;
  81. }
  82. [BurstCompile]
  83. static unsafe void TessellateBurst(Allocator allocator, float2* points, int pointCount, int2* edges, int edgeCount, float2* outVertices, int* outIndices, int2* outEdges, int arrayCount, int3* result)
  84. {
  85. var _edges = new NativeArray<int2>(edgeCount, allocator);
  86. for (int i = 0; i < _edges.Length; ++i)
  87. _edges[i] = edges[i];
  88. var _points = new NativeArray<float2>(pointCount, allocator);
  89. for (int i = 0; i < _points.Length; ++i)
  90. _points[i] = points[i];
  91. var _outIndices = new NativeArray<int>(arrayCount, allocator);
  92. var _outEdges = new NativeArray<int2>(arrayCount, allocator);
  93. var _outVertices = new NativeArray<float2>(arrayCount, allocator);
  94. var outEdgeCount = 0;
  95. var outIndexCount = 0;
  96. var outVertexCount = 0;
  97. var check = ValidateCollinear((float2*)_points.GetUnsafeReadOnlyPtr(), pointCount, k_CollinearTolerance);
  98. if (0 != check)
  99. ModuleHandle.Tessellate(allocator, in _points, in _edges, ref _outVertices, out outVertexCount, ref _outIndices, out outIndexCount, ref _outEdges, out outEdgeCount, true);
  100. for (var i = 0; i < outEdgeCount; ++i)
  101. outEdges[i] = _outEdges[i];
  102. for (var i = 0; i < outIndexCount; ++i)
  103. outIndices[i] = _outIndices[i];
  104. for (var i = 0; i < outVertexCount; ++i)
  105. outVertices[i] = _outVertices[i];
  106. result->x = outVertexCount;
  107. result->y = outIndexCount;
  108. result->z = outEdgeCount;
  109. _outVertices.Dispose();
  110. _outEdges.Dispose();
  111. _outIndices.Dispose();
  112. _points.Dispose();
  113. _edges.Dispose();
  114. }
  115. [BurstCompile]
  116. static unsafe void SubdivideBurst(Allocator allocator, float2* points, int pointCount, int2* edges, int edgeCount, float2* outVertices, int* outIndices, int2* outEdges, int arrayCount, float areaFactor, float areaThreshold, int refineIterations, int smoothenIterations, int3* result)
  117. {
  118. var _edges = new NativeArray<int2>(edgeCount, allocator);
  119. for (int i = 0; i < _edges.Length; ++i)
  120. _edges[i] = edges[i];
  121. var _points = new NativeArray<float2>(pointCount, allocator);
  122. for (int i = 0; i < _points.Length; ++i)
  123. _points[i] = points[i];
  124. var _outIndices = new NativeArray<int>(arrayCount, allocator);
  125. var _outEdges = new NativeArray<int2>(arrayCount, allocator);
  126. var _outVertices = new NativeArray<float2>(arrayCount, allocator);
  127. var outEdgeCount = 0;
  128. var outIndexCount = 0;
  129. var outVertexCount = 0;
  130. ModuleHandle.Subdivide(allocator, _points, _edges, ref _outVertices, ref outVertexCount, ref _outIndices, ref outIndexCount, ref _outEdges, ref outEdgeCount, areaFactor, areaThreshold, refineIterations, smoothenIterations);
  131. for (var i = 0; i < outEdgeCount; ++i)
  132. outEdges[i] = _outEdges[i];
  133. for (var i = 0; i < outIndexCount; ++i)
  134. outIndices[i] = _outIndices[i];
  135. for (var i = 0; i < outVertexCount; ++i)
  136. outVertices[i] = _outVertices[i];
  137. result->x = outVertexCount;
  138. result->y = outIndexCount;
  139. result->z = outEdgeCount;
  140. _outVertices.Dispose();
  141. _outEdges.Dispose();
  142. _outIndices.Dispose();
  143. _points.Dispose();
  144. _edges.Dispose();
  145. }
  146. static bool TessellateSafe(in NativeArray<float2> points, in NativeArray<int2> edges, ref NativeArray<float2> outVertices, ref int outVertexCount, ref NativeArray<int> outIndices, ref int outIndexCount, ref NativeArray<int2> outEdges, ref int outEdgeCount)
  147. {
  148. unsafe
  149. {
  150. var check = ValidateCollinear((float2*)points.GetUnsafeReadOnlyPtr(), points.Length, k_CollinearTolerance);
  151. if (0 == check)
  152. return false;
  153. }
  154. try
  155. {
  156. ModuleHandle.Tessellate(Allocator.Persistent, in points, in edges, ref outVertices, out outVertexCount, ref outIndices, out outIndexCount, ref outEdges, out outEdgeCount, true);
  157. }
  158. catch (Exception)
  159. {
  160. return false;
  161. }
  162. return true;
  163. }
  164. static bool SubdivideSafe(NativeArray<float2> points, NativeArray<int2> edges, ref NativeArray<float2> outVertices, ref int outVertexCount, ref NativeArray<int> outIndices, ref int outIndexCount, ref NativeArray<int2> outEdges, ref int outEdgeCount, float areaFactor, float areaThreshold, int refineIterations, int smoothenIterations)
  165. {
  166. try
  167. {
  168. ModuleHandle.Subdivide(Allocator.Persistent, points, edges, ref outVertices, ref outVertexCount, ref outIndices, ref outIndexCount, ref outEdges, ref outEdgeCount, areaFactor, areaThreshold, refineIterations, smoothenIterations);
  169. }
  170. catch (Exception)
  171. {
  172. return false;
  173. }
  174. return true;
  175. }
  176. internal static void Quad(IList<Vector2> vertices, IList<Vector2Int> edges, IList<int> indices, Allocator allocator)
  177. {
  178. if (vertices.Count < 3)
  179. return;
  180. var points = new NativeArray<float2>(vertices.Count, allocator);
  181. for (var i = 0; i < vertices.Count; ++i)
  182. points[i] = vertices[i];
  183. var arrayCount = vertices.Count * vertices.Count * 4;
  184. int vertexCount = 0, indexCount = 0, edgeCount = 0;
  185. var outputIndices = new NativeArray<int>(arrayCount, allocator);
  186. var outputEdges = new NativeArray<int2>(arrayCount, allocator);
  187. var outputVertices = new NativeArray<float2>(arrayCount, allocator);
  188. var fallback = new NativeArray<int2>(0, allocator);
  189. TessellateSafe(in points, in fallback, ref outputVertices, ref vertexCount, ref outputIndices,
  190. ref indexCount, ref outputEdges, ref edgeCount);
  191. fallback.Dispose();
  192. vertices.Clear();
  193. for (var i = 0; i < vertexCount; ++i)
  194. vertices.Add(outputVertices[i]);
  195. indices.Clear();
  196. for (var i = 0; i < indexCount; ++i)
  197. indices.Add(outputIndices[i]);
  198. edges.Clear();
  199. for (var i = 0; i < edgeCount; ++i)
  200. edges.Add(new Vector2Int(outputEdges[i].x, outputEdges[i].y));
  201. outputEdges.Dispose();
  202. outputIndices.Dispose();
  203. outputVertices.Dispose();
  204. points.Dispose();
  205. }
  206. internal static void Triangulate(ref int2[] edges, ref float2[] vertices, out int[] indices, Allocator allocator)
  207. {
  208. if (vertices.Length < 3)
  209. {
  210. indices = new int[0];
  211. return;
  212. }
  213. var points = new NativeArray<float2>(vertices, allocator);
  214. var inputEdges = new NativeArray<int2>(edges, allocator);
  215. var arrayCount = vertices.Length * vertices.Length * 4;
  216. int vertexCount = 0, indexCount = 0, edgeCount = 0;
  217. var outputIndices = new NativeArray<int>(arrayCount, allocator);
  218. var outputEdges = new NativeArray<int2>(arrayCount, allocator);
  219. var outputResult = new NativeArray<int3>(1, allocator);
  220. var outputVertices = new NativeArray<float2>(arrayCount, allocator);
  221. unsafe
  222. {
  223. TessellateBurst(allocator, (float2*)points.GetUnsafePtr(), points.Length, (int2*)inputEdges.GetUnsafePtr(), inputEdges.Length, (float2*)outputVertices.GetUnsafePtr(), (int*)outputIndices.GetUnsafePtr(), (int2*)outputEdges.GetUnsafePtr(), arrayCount, (int3*)outputResult.GetUnsafePtr());
  224. vertexCount = outputResult[0].x;
  225. indexCount = outputResult[0].y;
  226. edgeCount = outputResult[0].z;
  227. }
  228. // Fallback on numerical precision errors.
  229. if (vertexCount <= 8 || indexCount == 0)
  230. TessellateSafe(in points, in inputEdges, ref outputVertices, ref vertexCount, ref outputIndices, ref indexCount, ref outputEdges, ref edgeCount);
  231. vertices = new float2[vertexCount];
  232. for (var i = 0; i < vertexCount; ++i)
  233. vertices[i] = outputVertices[i];
  234. indices = new int[indexCount];
  235. for (var i = 0; i < indexCount; ++i)
  236. indices[i] = outputIndices[i];
  237. edges = new int2[edgeCount];
  238. for (var i = 0; i < edgeCount; ++i)
  239. edges[i] = outputEdges[i];
  240. outputEdges.Dispose();
  241. outputResult.Dispose();
  242. outputIndices.Dispose();
  243. outputVertices.Dispose();
  244. inputEdges.Dispose();
  245. points.Dispose();
  246. }
  247. internal static bool TriangulateSafe(ref float2[] vertices, ref int2[] edges, out int[] indices)
  248. {
  249. indices = new int[0];
  250. if (vertices.Length < 3)
  251. return false;
  252. var points = new NativeArray<float2>(vertices, Allocator.Persistent);
  253. var inputEdges = new NativeArray<int2>(edges, Allocator.Persistent);
  254. var arrayCount = vertices.Length * vertices.Length * 4;
  255. int vertexCount = 0, indexCount = 0, edgeCount = 0;
  256. var outputIndices = new NativeArray<int>(arrayCount, Allocator.Persistent);
  257. var outputEdges = new NativeArray<int2>(arrayCount, Allocator.Persistent);
  258. var outputVertices = new NativeArray<float2>(arrayCount, Allocator.Persistent);
  259. var ok = TessellateSafe(in points, in inputEdges, ref outputVertices, ref vertexCount, ref outputIndices, ref indexCount, ref outputEdges, ref edgeCount);
  260. if (ok)
  261. {
  262. vertices = new float2[vertexCount];
  263. for (var i = 0; i < vertexCount; ++i)
  264. vertices[i] = outputVertices[i];
  265. edges = new int2[edgeCount];
  266. for (var i = 0; i < edgeCount; ++i)
  267. edges[i] = outputEdges[i];
  268. indices = new int[indexCount];
  269. for (var i = 0; i < indexCount; ++i)
  270. indices[i] = outputIndices[i];
  271. }
  272. outputEdges.Dispose();
  273. outputIndices.Dispose();
  274. outputVertices.Dispose();
  275. inputEdges.Dispose();
  276. points.Dispose();
  277. return ok;
  278. }
  279. public static void Tessellate(float minAngle, float maxAngle, float meshAreaFactor, float largestTriangleAreaFactor, float targetArea, int refineIterations, int smoothenIterations, ref float2[] vertices, ref int2[] edges, out int[] indices, Allocator allocator)
  280. {
  281. indices = new int[0];
  282. if (vertices.Length < 3)
  283. return;
  284. largestTriangleAreaFactor = Mathf.Clamp01(largestTriangleAreaFactor);
  285. var points = new NativeArray<float2>(vertices.Length, allocator);
  286. for (var i = 0; i < vertices.Length; ++i)
  287. points[i] = vertices[i];
  288. var inputEdges = new NativeArray<int2>(edges.Length, allocator);
  289. for (var i = 0; i < edges.Length; ++i)
  290. inputEdges[i] = new int2(edges[i].x, edges[i].y);
  291. const int maxDataCount = 65536;
  292. int vertexCount = 0, indexCount = 0, edgeCount = 0;
  293. var outputIndices = new NativeArray<int>(maxDataCount, allocator);
  294. var outputEdges = new NativeArray<int2>(maxDataCount, allocator);
  295. var outputResult = new NativeArray<int3>(1, allocator);
  296. var outputVertices = new NativeArray<float2>(maxDataCount, allocator);
  297. unsafe
  298. {
  299. SubdivideBurst(allocator, (float2*)points.GetUnsafePtr(), points.Length, (int2*)inputEdges.GetUnsafePtr(), inputEdges.Length, (float2*)outputVertices.GetUnsafePtr(), (int*)outputIndices.GetUnsafePtr(), (int2*)outputEdges.GetUnsafePtr(), maxDataCount, largestTriangleAreaFactor, targetArea, refineIterations, smoothenIterations, (int3*)outputResult.GetUnsafePtr());
  300. vertexCount = outputResult[0].x;
  301. indexCount = outputResult[0].y;
  302. edgeCount = outputResult[0].z;
  303. }
  304. // Fallback on numerical precision errors.
  305. if (vertexCount <= 8)
  306. SubdivideSafe(points, inputEdges, ref outputVertices, ref vertexCount, ref outputIndices, ref indexCount, ref outputEdges, ref edgeCount, largestTriangleAreaFactor, targetArea, refineIterations, smoothenIterations);
  307. vertices = new float2[vertexCount];
  308. for (var i = 0; i < vertexCount; ++i)
  309. vertices[i] = outputVertices[i];
  310. edges = new int2[edgeCount];
  311. for (var i = 0; i < edgeCount; ++i)
  312. edges[i] = outputEdges[i];
  313. indices = new int[indexCount];
  314. for (var i = 0; i < indexCount; ++i)
  315. indices[i] = outputIndices[i];
  316. outputEdges.Dispose();
  317. outputResult.Dispose();
  318. outputIndices.Dispose();
  319. outputVertices.Dispose();
  320. inputEdges.Dispose();
  321. points.Dispose();
  322. }
  323. public static JobHandle ScheduleTriangulate(in float2[] vertices, in int2[] edges, ref NativeArray<float2> outputVertices, ref NativeArray<int2> outputEdges, ref NativeArray<int> outputIndices, ref NativeArray<int4> result)
  324. {
  325. if (vertices.Length < 3)
  326. return default(JobHandle);
  327. var inputVertices = new NativeArray<float2>(vertices.Length, Allocator.TempJob);
  328. for (var i = 0; i < vertices.Length; ++i)
  329. inputVertices[i] = vertices[i];
  330. var inputEdges = new NativeArray<int2>(edges.Length, Allocator.TempJob);
  331. for (var i = 0; i < edges.Length; ++i)
  332. inputEdges[i] = new int2(edges[i].x, edges[i].y);
  333. var tessAsJob = new TriangulateJob();
  334. tessAsJob.inputVertices = inputVertices;
  335. tessAsJob.inputEdges = inputEdges;
  336. tessAsJob.outputVertices = outputVertices;
  337. tessAsJob.outputIndices = outputIndices;
  338. tessAsJob.outputEdges = outputEdges;
  339. tessAsJob.result = result;
  340. return tessAsJob.Schedule();
  341. }
  342. public static JobHandle ScheduleTessellate(float minAngle, float maxAngle, float meshAreaFactor, float largestTriangleAreaFactor, float targetArea, int refineIterations, int smoothenIterations, in float2[] vertices, in int2[] edges, ref NativeArray<float2> outputVertices, ref NativeArray<int2> outputEdges, ref NativeArray<int> outputIndices, ref NativeArray<int4> result)
  343. {
  344. if (vertices.Length < 3)
  345. return default(JobHandle);
  346. largestTriangleAreaFactor = Mathf.Clamp01(largestTriangleAreaFactor);
  347. var inputVertices = new NativeArray<float2>(vertices.Length, Allocator.TempJob);
  348. for (var i = 0; i < vertices.Length; ++i)
  349. inputVertices[i] = vertices[i];
  350. var inputEdges = new NativeArray<int2>(edges.Length, Allocator.TempJob);
  351. for (var i = 0; i < edges.Length; ++i)
  352. inputEdges[i] = new int2(edges[i].x, edges[i].y);
  353. var tessAsJob = new TessellateJob();
  354. tessAsJob.minAngle = minAngle;
  355. tessAsJob.maxAngle = maxAngle;
  356. tessAsJob.meshArea = meshAreaFactor;
  357. tessAsJob.largestTriangleAreaFactor = largestTriangleAreaFactor;
  358. tessAsJob.targetArea = targetArea;
  359. tessAsJob.refineIterations = refineIterations;
  360. tessAsJob.smoothIterations = smoothenIterations;
  361. tessAsJob.inputVertices = inputVertices;
  362. tessAsJob.inputEdges = inputEdges;
  363. tessAsJob.outputVertices = outputVertices;
  364. tessAsJob.outputIndices = outputIndices;
  365. tessAsJob.outputEdges = outputEdges;
  366. tessAsJob.result = result;
  367. return tessAsJob.Schedule();
  368. }
  369. public static void TessellateSafe(float largestTriangleAreaFactor, float targetArea, int refineIterations, int smoothenIterations, ref float2[] vertices, ref int2[] edges, out int[] indices)
  370. {
  371. indices = new int[0];
  372. if (vertices.Length < 3)
  373. return;
  374. largestTriangleAreaFactor = Mathf.Clamp01(largestTriangleAreaFactor);
  375. var points = new NativeArray<float2>(vertices, Allocator.Persistent);
  376. var inputEdges = new NativeArray<int2>(edges, Allocator.Persistent);
  377. int vertexCount = 0, indexCount = 0, edgeCount = 0, maxDataCount = 65536;
  378. var outputVertices = new NativeArray<float2>(maxDataCount, Allocator.Persistent);
  379. var outputIndices = new NativeArray<int>(maxDataCount, Allocator.Persistent);
  380. var outputEdges = new NativeArray<int2>(maxDataCount, Allocator.Persistent);
  381. var ok = SubdivideSafe(points, inputEdges, ref outputVertices, ref vertexCount, ref outputIndices, ref indexCount, ref outputEdges, ref edgeCount, largestTriangleAreaFactor, targetArea, refineIterations, smoothenIterations) ;
  382. if (ok)
  383. {
  384. vertices = new float2[vertexCount];
  385. for (var i = 0; i < vertices.Length; ++i)
  386. vertices[i] = outputVertices[i];
  387. indices = new int[indexCount];
  388. for (var i = 0; i < indices.Length; ++i)
  389. indices[i] = outputIndices[i];
  390. edges = new int2[edgeCount];
  391. for (var i = 0; i < edges.Length; ++i)
  392. edges[i] = outputEdges[i];
  393. }
  394. outputEdges.Dispose();
  395. outputIndices.Dispose();
  396. outputVertices.Dispose();
  397. inputEdges.Dispose();
  398. points.Dispose();
  399. }
  400. // Triangulate Bone Samplers. todo: Burst it.
  401. internal static void TriangulateSamplers(in float2[] samplers, ref List<float2> triVertices, ref List<int> triIndices)
  402. {
  403. foreach(var v in samplers)
  404. {
  405. var vertexCount = triVertices.Count;
  406. for (var i = 0; i < triIndices.Count / 3; ++i)
  407. {
  408. var i1 = triIndices[0 + (i * 3)];
  409. var i2 = triIndices[1 + (i * 3)];
  410. var i3 = triIndices[2 + (i * 3)];
  411. var v1 = triVertices[i1];
  412. var v2 = triVertices[i2];
  413. var v3 = triVertices[i3];
  414. var inside = ModuleHandle.IsInsideTriangle(v, v1, v2, v3);
  415. if (inside)
  416. {
  417. triVertices.Add(v);
  418. triIndices.Add(i1); triIndices.Add(i2); triIndices.Add(vertexCount);
  419. triIndices.Add(i2); triIndices.Add(i3); triIndices.Add(vertexCount);
  420. triIndices.Add(i3); triIndices.Add(i1); triIndices.Add(vertexCount);
  421. break;
  422. }
  423. }
  424. }
  425. }
  426. // Triangulate Skipped Original Points. These points are discarded during PlanarGrapg cleanup. But bbw only cares if these are part of any geometry. So just insert them. todo: Burst it.
  427. internal static void TriangulateInternal(in int[] internalIndices, in float2[] triVertices, ref List<int> triIndices)
  428. {
  429. var triangleCount = triIndices.Count / 3;
  430. foreach(var index in internalIndices)
  431. {
  432. var v = triVertices[index];
  433. for (var i = 0; i < triangleCount; ++i)
  434. {
  435. var i1 = triIndices[0 + (i * 3)];
  436. var i2 = triIndices[1 + (i * 3)];
  437. var i3 = triIndices[2 + (i * 3)];
  438. var v1 = triVertices[i1];
  439. var v2 = triVertices[i2];
  440. var v3 = triVertices[i3];
  441. var c1 = (float)Math.Round(ModuleHandle.OrientFast(v1, v2, v), 2);
  442. if (c1 == 0)
  443. {
  444. triIndices[0 + (i * 3)] = i1; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i3;
  445. triIndices.Add(index); triIndices.Add(i2); triIndices.Add(i3);
  446. }
  447. else
  448. {
  449. var c2 = (float)Math.Round(ModuleHandle.OrientFast(v2, v3, v), 2);
  450. if (c2 == 0)
  451. {
  452. triIndices[0 + (i * 3)] = i2; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i1;
  453. triIndices.Add(index); triIndices.Add(i3); triIndices.Add(i1);
  454. }
  455. else
  456. {
  457. var c3 = (float)Math.Round(ModuleHandle.OrientFast(v3, v1, v), 2);
  458. if (c3 == 0)
  459. {
  460. triIndices[0 + (i * 3)] = i3; triIndices[1 + (i * 3)] = index; triIndices[2 + (i * 3)] = i2;
  461. triIndices.Add(index); triIndices.Add(i1); triIndices.Add(i2);
  462. }
  463. }
  464. }
  465. }
  466. }
  467. }
  468. }
  469. }