Пример #1
0
            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);
            }
Пример #2
0
            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);
            }
Пример #3
0
            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);
            }
Пример #4
0
            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();
            }
Пример #5
0
            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);
            }
Пример #6
0
            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);
            }