static float FindSplit(UHull hull, UEvent edge) { float d = 0; if (hull.a.x < edge.a.x) { d = ModuleHandle.OrientFast(hull.a, hull.b, edge.a); } else { d = ModuleHandle.OrientFast(edge.b, edge.a, hull.a); } if (0 != d) { return(d); } if (edge.b.x < hull.b.x) { d = ModuleHandle.OrientFast(hull.a, hull.b, edge.b); } else { d = ModuleHandle.OrientFast(edge.b, edge.a, hull.b); } if (0 != d) { return(d); } return(hull.idx - edge.idx); }
bool MergeHulls(NativeArray <UHull> hulls, ref int hullCount, NativeArray <float2> points, UEvent evt) { float2 temp = evt.a; evt.a = evt.b; evt.b = temp; int index = ModuleHandle.GetEqual(hulls, hullCount, evt, new TestHullEventE()); if (index < 0) { return(false); } UHull upper = hulls[index]; UHull lower = hulls[index - 1]; lower.iucount = upper.iucount; for (int i = 0; i < lower.iucount; ++i) { lower.iuarray[i] = upper.iuarray[i]; } hulls[index - 1] = lower; EraseHull(hulls, index, ref hullCount); return(true); }
bool SplitHulls(NativeArray <UHull> hulls, ref int hullCount, NativeArray <float2> points, UEvent evt) { int index = ModuleHandle.GetLower(hulls, hullCount, evt, new TestHullEventLe()); if (index < 0) { return(false); } UHull hull = hulls[index]; UHull newHull; newHull.a = evt.a; newHull.b = evt.b; newHull.idx = evt.idx; int y = hull.iuarray[hull.iucount - 1]; newHull.iuarray = new ArraySlice <int>(m_IUArray, newHull.idx * m_NumHulls, m_NumHulls); newHull.iucount = hull.iucount; for (int i = 0; i < newHull.iucount; ++i) { newHull.iuarray[i] = hull.iuarray[i]; } hull.iuarray[0] = y; hull.iucount = 1; hulls[index] = hull; newHull.ilarray = new ArraySlice <int>(m_ILArray, newHull.idx * m_NumHulls, m_NumHulls); newHull.ilarray[0] = y; newHull.ilcount = 1; InsertHull(hulls, index + 1, ref hullCount, newHull); return(true); }
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); }