Not thread safe int[] pooling
Beispiel #1
1
        /// <summary>
        /// Create a convex hull from the given array of points.
        /// The count must be in the range [3, Settings.maxPolygonVertices].
        /// This method takes an arraypool for pooling
        /// </summary>
        /// <warning>the points may be re-ordered, even if they form a convex polygon</warning>
        /// <warning>collinear points are handled but not removed. Collinear points may lead to poor stacking behavior.</warning>
        public void Set(Vec2[] verts, int num, Vec2Array vecPool, IntArray intPool)
        {
            Debug.Assert(3 <= num && num <= Settings.MAX_POLYGON_VERTICES);
            if (num < 3)
            {
                SetAsBox(1.0f, 1.0f);
                return;
            }

            int n = MathUtils.Min(num, Settings.MAX_POLYGON_VERTICES);

            // Copy the vertices into a local buffer
            Vec2[] ps = (vecPool != null) ? vecPool.Get(n) : new Vec2[n];
            for (int i = 0; i < n; ++i)
            {
                ps[i] = verts[i];
            }

            // Create the convex hull using the Gift wrapping algorithm
            // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm

            // Find the right most point on the hull
            int i0 = 0;
            float x0 = ps[0].X;
            for (int i = 1; i < num; ++i)
            {
                float x = ps[i].X;
                if (x > x0 || (x == x0 && ps[i].Y < ps[i0].Y))
                {
                    i0 = i;
                    x0 = x;
                }
            }

            int[] hull = (intPool != null) ? intPool.Get(Settings.MAX_POLYGON_VERTICES) : new int[Settings.MAX_POLYGON_VERTICES];
            int m = 0;
            int ih = i0;

            while (true)
            {
                hull[m] = ih;

                int ie = 0;
                for (int j = 1; j < n; ++j)
                {
                    if (ie == ih)
                    {
                        ie = j;
                        continue;
                    }

                    Vec2 r = pool1.Set(ps[ie]).SubLocal(ps[hull[m]]);
                    Vec2 v = pool2.Set(ps[j]).SubLocal(ps[hull[m]]);
                    float c = Vec2.Cross(r, v);
                    if (c < 0.0f)
                    {
                        ie = j;
                    }

                    // Collinearity check
                    if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
                    {
                        ie = j;
                    }
                }

                ++m;
                ih = ie;

                if (ie == i0)
                {
                    break;
                }
            }

            VertexCount = m;

            // Copy vertices.
            for (int i = 0; i < VertexCount; ++i)
            {
                if (Vertices[i] == null)
                {
                    Vertices[i] = new Vec2();
                }
                Vertices[i].Set(ps[hull[i]]);
            }

            Vec2 edge = pool1;

            // Compute normals. Ensure the edges have non-zero length.
            for (int i = 0; i < VertexCount; ++i)
            {
                int i1 = i;
                int i2 = i + 1 < VertexCount ? i + 1 : 0;
                edge.Set(Vertices[i2]).SubLocal(Vertices[i1]);

                Debug.Assert(edge.LengthSquared() > Settings.EPSILON * Settings.EPSILON);
                Vec2.CrossToOutUnsafe(edge, 1f, Normals[i]);
                Normals[i].Normalize();
            }

            // Compute the polygon centroid.
            ComputeCentroidToOut(Vertices, VertexCount, Centroid);
        }
Beispiel #2
0
        /// <summary>
        /// Create a convex hull from the given array of points.
        /// The count must be in the range [3, Settings.maxPolygonVertices].
        /// This method takes an arraypool for pooling
        /// </summary>
        /// <warning>the points may be re-ordered, even if they form a convex polygon</warning>
        /// <warning>collinear points are handled but not removed. Collinear points may lead to poor stacking behavior.</warning>
        public void set_Renamed(Vec2[] verts, int num, Vec2Array vecPool, IntArray intPool)
        {
            Debug.Assert(3 <= num && num <= Settings.maxPolygonVertices);
            if (num < 3)
            {
                setAsBox(1.0f, 1.0f);
                return;
            }

            int n = MathUtils.min(num, Settings.maxPolygonVertices);

            // Copy the vertices into a local buffer
            Vec2[] ps = (vecPool != null) ? vecPool.get_Renamed(n) : new Vec2[n];
            for (int i = 0; i < n; ++i)
            {
                ps[i] = verts[i];
            }

            // Create the convex hull using the Gift wrapping algorithm
            // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm

            // Find the right most point on the hull
            int i0 = 0;
            float x0 = ps[0].x;
            for (int i = 1; i < num; ++i)
            {
                float x = ps[i].x;
                if (x > x0 || (x == x0 && ps[i].y < ps[i0].y))
                {
                    i0 = i;
                    x0 = x;
                }
            }

            int[] hull = (intPool != null) ? intPool.get_Renamed(Settings.maxPolygonVertices) : new int[Settings.maxPolygonVertices];
            int m = 0;
            int ih = i0;

            while (true)
            {
                hull[m] = ih;

                int ie = 0;
                for (int j = 1; j < n; ++j)
                {
                    if (ie == ih)
                    {
                        ie = j;
                        continue;
                    }

                    Vec2 r = pool1.set_Renamed(ps[ie]).subLocal(ps[hull[m]]);
                    Vec2 v = pool2.set_Renamed(ps[j]).subLocal(ps[hull[m]]);
                    float c = Vec2.cross(r, v);
                    if (c < 0.0f)
                    {
                        ie = j;
                    }

                    // Collinearity check
                    if (c == 0.0f && v.lengthSquared() > r.lengthSquared())
                    {
                        ie = j;
                    }
                }

                ++m;
                ih = ie;

                if (ie == i0)
                {
                    break;
                }
            }

            this.m_count = m;

            // Copy vertices.
            for (int i = 0; i < m_count; ++i)
            {
                if (m_vertices[i] == null)
                {
                    m_vertices[i] = new Vec2();
                }
                m_vertices[i].set_Renamed(ps[hull[i]]);
            }

            Vec2 edge = pool1;

            // Compute normals. Ensure the edges have non-zero length.
            for (int i = 0; i < m_count; ++i)
            {
                int i1 = i;
                int i2 = i + 1 < m_count ? i + 1 : 0;
                edge.set_Renamed(m_vertices[i2]).subLocal(m_vertices[i1]);

                Debug.Assert(edge.lengthSquared() > Settings.EPSILON * Settings.EPSILON);
                Vec2.crossToOutUnsafe(edge, 1f, m_normals[i]);
                m_normals[i].normalize();
            }

            // Compute the polygon centroid.
            computeCentroidToOut(m_vertices, m_count, m_centroid);
        }