void AddTriangle(int i, int j, int k) { UStar si = m_Stars[i]; UStar sj = m_Stars[j]; UStar sk = m_Stars[k]; si.points[si.pointCount++] = j; si.points[si.pointCount++] = k; sj.points[sj.pointCount++] = k; sj.points[sj.pointCount++] = i; sk.points[sk.pointCount++] = i; sk.points[sk.pointCount++] = j; m_Stars[i] = si; m_Stars[j] = sj; m_Stars[k] = sk; }
void RemovePair(int r, int j, int k) { UStar s = m_Stars[r]; ArraySlice <int> points = s.points; for (int i = 1, n = s.pointCount; i < n; i += 2) { if (points[i - 1] == j && points[i] == k) { points[i - 1] = points[n - 2]; points[i] = points[n - 1]; s.points = points; s.pointCount = s.pointCount - 2; m_Stars[r] = s; return; } } }
internal bool ApplyDelaunay(NativeArray <float2> points, NativeArray <int2> edges) { NativeArray <int> stack = new NativeArray <int>(m_NumPoints * (m_NumPoints + 1), m_Allocator); int stackCount = 0; var valid = true; PrepareDelaunay(edges, m_NumEdges); for (int a = 0; valid && (a < m_NumPoints); ++a) { UStar star = m_Stars[a]; for (int j = 1; j < star.pointCount; j += 2) { int b = star.points[j]; if (b < a) { continue; } if (FindConstraint(a, b) >= 0) { continue; } int x = star.points[j - 1], y = -1; for (int k = 1; k < star.pointCount; k += 2) { if (star.points[k - 1] == b) { y = star.points[k]; break; } } if (y < 0) { continue; } if (UTess.IsInsideCircle(points[a], points[b], points[x], points[y])) { if ((2 + stackCount) >= stack.Length) { valid = false; break; } stack[stackCount++] = a; stack[stackCount++] = b; } } } var flipFlops = m_NumPoints * m_NumPoints; while (stackCount > 0 && valid) { int b = stack[stackCount - 1]; stackCount--; int a = stack[stackCount - 1]; stackCount--; int x = -1, y = -1; UStar star = m_Stars[a]; for (int i = 1; i < star.pointCount; i += 2) { int s = star.points[i - 1]; int t = star.points[i]; if (s == b) { y = t; } else if (t == b) { x = s; } } if (x < 0 || y < 0) { continue; } if (!UTess.IsInsideCircle(points[a], points[b], points[x], points[y])) { continue; } EdgeFlip(a, b); valid = Flip(points, ref stack, ref stackCount, x, a, y); valid = valid && Flip(points, ref stack, ref stackCount, a, y, x); valid = valid && Flip(points, ref stack, ref stackCount, y, b, x); valid = valid && Flip(points, ref stack, ref stackCount, b, x, y); valid = valid && (--flipFlops > 0); } stack.Dispose(); return(valid); }
void PrepareDelaunay(NativeArray <int2> edges, int edgeCount) { m_StarCount = m_CellCount * 3; m_Stars = new NativeArray <UStar>(m_StarCount, m_Allocator); m_SPArray = new NativeArray <int>(m_StarCount * m_StarCount, m_Allocator); var UEdgeCount = 0; var UEdges = new NativeArray <int2>(m_StarCount, m_Allocator); // Input Edges. for (int i = 0; i < edgeCount; ++i) { int2 e = edges[i]; e.x = (edges[i].x < edges[i].y) ? edges[i].x : edges[i].y; e.y = (edges[i].x > edges[i].y) ? edges[i].x : edges[i].y; edges[i] = e; InsertUniqueEdge(UEdges, e, ref UEdgeCount); } m_Edges = new NativeArray <int2>(UEdgeCount, m_Allocator); for (int i = 0; i < UEdgeCount; ++i) { m_Edges[i] = UEdges[i]; } UEdges.Dispose(); unsafe { UTess.InsertionSort <int2, TessEdgeCompare>( NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(m_Edges), 0, m_Edges.Length - 1, new TessEdgeCompare()); } // Init Stars. for (int i = 0; i < m_StarCount; ++i) { UStar s = m_Stars[i]; s.points = new ArraySlice <int>(m_SPArray, i * m_StarCount, m_StarCount); s.pointCount = 0; m_Stars[i] = s; } // Fill stars. for (int i = 0; i < m_CellCount; ++i) { int a = m_Cells[i].x; int b = m_Cells[i].y; int c = m_Cells[i].z; UStar sa = m_Stars[a]; UStar sb = m_Stars[b]; UStar sc = m_Stars[c]; sa.points[sa.pointCount++] = b; sa.points[sa.pointCount++] = c; sb.points[sb.pointCount++] = c; sb.points[sb.pointCount++] = a; sc.points[sc.pointCount++] = a; sc.points[sc.pointCount++] = b; m_Stars[a] = sa; m_Stars[b] = sb; m_Stars[c] = sc; } }