public int Compare(int2 a, int2 b) { var e1a = edges[a.x]; var e1b = edges[a.y]; var e2a = edges[b.x]; var e2b = edges[b.y]; xvasort[0] = points[e1a.x].x; xvasort[1] = points[e1a.y].x; xvasort[2] = points[e1b.x].x; xvasort[3] = points[e1b.y].x; xvbsort[0] = points[e2a.x].x; xvbsort[1] = points[e2a.y].x; xvbsort[2] = points[e2b.x].x; xvbsort[3] = points[e2b.y].x; fixed(double *xvasortPtr = xvasort) { ModuleHandle.InsertionSort <double, XCompare>(xvasortPtr, 0, 3, new XCompare()); } fixed(double *xvbsortPtr = xvbsort) { ModuleHandle.InsertionSort <double, XCompare>(xvbsortPtr, 0, 3, new XCompare()); } for (int i = 0; i < 4; ++i) { if (xvasort[i] - xvbsort[i] != 0) { return(xvasort[i] < xvbsort[i] ? -1 : 1); } } return(points[e1a.x].y < points[e1a.x].y ? -1 : 1); }
internal bool Triangulate(NativeArray <float2> points, int pointCount, NativeArray <int2> edges, int edgeCount) { m_NumEdges = edgeCount; m_NumHulls = edgeCount * 2; m_NumPoints = pointCount; m_CellCount = 0; m_Cells = new NativeArray <int3>(ModuleHandle.kMaxTriangleCount, m_Allocator); m_ILArray = new NativeArray <int>(m_NumHulls * (m_NumHulls + 1), m_Allocator); // Make room for -1 node. m_IUArray = new NativeArray <int>(m_NumHulls * (m_NumHulls + 1), m_Allocator); // Make room for -1 node. NativeArray <UHull> hulls = new NativeArray <UHull>(m_NumPoints * 8, m_Allocator); int hullCount = 0; NativeArray <UEvent> events = new NativeArray <UEvent>(m_NumPoints + (m_NumEdges * 2), m_Allocator); int eventCount = 0; for (int i = 0; i < m_NumPoints; ++i) { UEvent evt = new UEvent(); evt.a = points[i]; evt.b = new float2(); evt.idx = i; evt.type = (int)UEventType.EVENT_POINT; events[eventCount++] = evt; } for (int i = 0; i < m_NumEdges; ++i) { int2 e = edges[i]; float2 a = points[e.x]; float2 b = points[e.y]; if (a.x < b.x) { UEvent _s = new UEvent(); _s.a = a; _s.b = b; _s.idx = i; _s.type = (int)UEventType.EVENT_START; UEvent _e = new UEvent(); _e.a = b; _e.b = a; _e.idx = i; _e.type = (int)UEventType.EVENT_END; events[eventCount++] = _s; events[eventCount++] = _e; } else if (a.x > b.x) { UEvent _s = new UEvent(); _s.a = b; _s.b = a; _s.idx = i; _s.type = (int)UEventType.EVENT_START; UEvent _e = new UEvent(); _e.a = a; _e.b = b; _e.idx = i; _e.type = (int)UEventType.EVENT_END; events[eventCount++] = _s; events[eventCount++] = _e; } } unsafe { ModuleHandle.InsertionSort <UEvent, TessEventCompare>( NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(events), 0, eventCount - 1, new TessEventCompare()); ; } var hullOp = true; float minX = events[0].a.x - (1 + math.abs(events[0].a.x)) * math.pow(2.0f, -16.0f); UHull hull; hull.a.x = minX; hull.a.y = 1; hull.b.x = minX; hull.b.y = 0; hull.idx = -1; hull.ilarray = new ArraySlice <int>(m_ILArray, m_NumHulls * m_NumHulls, m_NumHulls); // Last element hull.iuarray = new ArraySlice <int>(m_IUArray, m_NumHulls * m_NumHulls, m_NumHulls); hull.ilcount = 0; hull.iucount = 0; hulls[hullCount++] = hull; for (int i = 0, numEvents = eventCount; i < numEvents; ++i) { switch (events[i].type) { case (int)UEventType.EVENT_POINT: { hullOp = AddPoint(hulls, hullCount, points, events[i].a, events[i].idx); } break; case (int)UEventType.EVENT_START: { hullOp = SplitHulls(hulls, ref hullCount, points, events[i]); } break; default: { hullOp = MergeHulls(hulls, ref hullCount, points, events[i]); } break; } if (!hullOp) { break; } } events.Dispose(); hulls.Dispose(); return(hullOp); }
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 { ModuleHandle.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; } }
NativeArray <int3> Constrain(ref int count) { var cells = GetCells(ref count); int nc = count; for (int i = 0; i < nc; ++i) { int3 c = cells[i]; int x = c.x, y = c.y, z = c.z; if (y < z) { if (y < x) { c.x = y; c.y = z; c.z = x; } } else if (z < x) { c.x = z; c.y = x; c.z = y; } cells[i] = c; } unsafe { ModuleHandle.InsertionSort <int3, TessCellCompare>( NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(cells), 0, m_CellCount - 1, new TessCellCompare()); } // Out m_Flags = new NativeArray <int>(nc, m_Allocator); m_Neighbors = new NativeArray <int>(nc * 3, m_Allocator); m_Constraints = new NativeArray <int>(nc * 3, m_Allocator); var next = new NativeArray <int>(nc * 3, m_Allocator); var active = new NativeArray <int>(nc * 3, m_Allocator); int side = 1, nextCount = 0, activeCount = 0; for (int i = 0; i < nc; ++i) { int3 c = cells[i]; for (int j = 0; j < 3; ++j) { int x = j, y = (j + 1) % 3; x = (x == 0) ? c.x : (j == 1) ? c.y : c.z; y = (y == 0) ? c.x : (y == 1) ? c.y : c.z; int o = OppositeOf(y, x); int a = m_Neighbors[3 * i + j] = FindNeighbor(cells, count, y, x, o); int b = m_Constraints[3 * i + j] = (-1 != FindConstraint(x, y)) ? 1 : 0; if (a < 0) { if (0 != b) { next[nextCount++] = i; } else { active[activeCount++] = i; m_Flags[i] = 1; } } } } while (activeCount > 0 || nextCount > 0) { while (activeCount > 0) { int t = active[activeCount - 1]; activeCount--; if (m_Flags[t] == -side) { continue; } m_Flags[t] = side; int3 c = cells[t]; for (int j = 0; j < 3; ++j) { int f = m_Neighbors[3 * t + j]; if (f >= 0 && m_Flags[f] == 0) { if (0 != m_Constraints[3 * t + j]) { next[nextCount++] = f; } else { active[activeCount++] = f; m_Flags[f] = side; } } } } for (int e = 0; e < nextCount; e++) { active[e] = next[e]; } activeCount = nextCount; nextCount = 0; side = -side; } active.Dispose(); next.Dispose(); return(cells); }