void SplitHulls(NativeArray <TessHull> hulls, ref int hullCount, NativeArray <float2> points, TessEvent evt) { int index = GetLowerEqualHullForEvent(hulls, hullCount, evt); TessHull hull = hulls[index]; TessHull 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_NumPoints, m_NumPoints); 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_NumPoints, m_NumPoints); newHull.ilarray[0] = y; newHull.ilcount = 1; InsertHull(hulls, index + 1, ref hullCount, newHull); }
static float FindSplit(TessHull hull, TessEvent edge) { float d = 0; if (hull.a.x < edge.a.x) { d = TessUtils.OrientFast(hull.a, hull.b, edge.a); } else { d = TessUtils.OrientFast(edge.b, edge.a, hull.a); } if (0 != d) { return(d); } if (edge.b.x < hull.b.x) { d = TessUtils.OrientFast(hull.a, hull.b, edge.b); } else { d = TessUtils.OrientFast(edge.b, edge.a, hull.b); } if (0 != d) { return(d); } return(hull.idx - edge.idx); }
void MergeHulls(NativeArray <TessHull> hulls, ref int hullCount, NativeArray <float2> points, TessEvent evt) { float2 temp = evt.a; evt.a = evt.b; evt.b = temp; int index = GetEqualHullForEvent(hulls, hullCount, evt); TessHull upper = hulls[index]; TessHull 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); }
internal void Triangulate(NativeArray <float2> points, NativeArray <TessEdge> edgesIn) { int numEdges = edgesIn.Length; const int kStarEdges = 16; m_NumPoints = points.Length; m_StarCount = m_NumPoints > kStarEdges ? m_NumPoints : kStarEdges; m_StarCount = m_StarCount * 2; m_CellCount = 0; m_Cells = new NativeArray <TessCell>(m_NumPoints * (m_NumPoints + 1), Allocator.Temp); m_ILArray = new NativeArray <int>(m_NumPoints * (m_NumPoints + 1), Allocator.Temp); // Make room for -1 node. m_IUArray = new NativeArray <int>(m_NumPoints * (m_NumPoints + 1), Allocator.Temp); // Make room for -1 node. m_SPArray = new NativeArray <int>(m_NumPoints * (m_StarCount), Allocator.Temp); // Make room for -1 node. NativeArray <TessHull> hulls = new NativeArray <TessHull>(m_NumPoints * 8, Allocator.Temp); int hullCount = 0; NativeArray <TessEvent> events = new NativeArray <TessEvent>(m_NumPoints + (numEdges * 2), Allocator.Temp); int eventCount = 0; for (int i = 0; i < m_NumPoints; ++i) { TessEvent evt = new TessEvent(); evt.a = points[i]; evt.b = new float2(); evt.idx = i; evt.type = (int)TessEventType.EVENT_POINT; events[eventCount++] = evt; } for (int i = 0; i < numEdges; ++i) { TessEdge e = edgesIn[i]; float2 a = points[e.a]; float2 b = points[e.b]; if (a.x < b.x) { TessEvent _s = new TessEvent(); _s.a = a; _s.b = b; _s.idx = i; _s.type = (int)TessEventType.EVENT_START; TessEvent _e = new TessEvent(); _e.a = b; _e.b = a; _e.idx = i; _e.type = (int)TessEventType.EVENT_END; events[eventCount++] = _s; events[eventCount++] = _e; } else if (a.x > b.x) { TessEvent _s = new TessEvent(); _s.a = b; _s.b = a; _s.idx = i; _s.type = (int)TessEventType.EVENT_START; TessEvent _e = new TessEvent(); _e.a = a; _e.b = b; _e.idx = i; _e.type = (int)TessEventType.EVENT_END; events[eventCount++] = _s; events[eventCount++] = _e; } } unsafe { TessUtils.InsertionSort <TessEvent, TessEventCompare>( NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(events), 0, eventCount - 1, new TessEventCompare()); ; } float minX = events[0].a.x - (1 + math.abs(events[0].a.x)) * math.pow(2.0f, -16.0f); TessHull 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_NumPoints * m_NumPoints, m_NumPoints); // Last element hull.iuarray = new ArraySlice <int>(m_IUArray, m_NumPoints * m_NumPoints, m_NumPoints); hull.ilcount = 0; hull.iucount = 0; hulls[hullCount++] = hull; for (int i = 0, numEvents = eventCount; i < numEvents; ++i) { switch (events[i].type) { case (int)TessEventType.EVENT_POINT: { AddPoint(hulls, hullCount, points, events[i].a, events[i].idx); } break; case (int)TessEventType.EVENT_START: { SplitHulls(hulls, ref hullCount, points, events[i]); } break; default: { MergeHulls(hulls, ref hullCount, points, events[i]); } break; } } hulls.Dispose(); events.Dispose(); }
static int GetEqualHullForEvent(NativeArray <TessHull> hulls, int hullCount, TessEvent p) { int l = 0; int h = hullCount - 1; while (l <= h) { int m; m = ((int)(l + h)) >> 1; float f = FindSplit(hulls[m], p); if (f == 0) { return(m); } else if (f <= 0) { l = m + 1; } else { h = m - 1; } } return(-1); }
static int GetLowerEqualHullForEvent(NativeArray <TessHull> hulls, int hullCount, TessEvent p) { int i; int l = 0; int h = hullCount - 1; i = l - 1; while (l <= h) { int m; m = ((int)(l + h)) >> 1; if (FindSplit(hulls[m], p) <= 0) { i = m; l = m + 1; } else { h = m - 1; } } return(i); }