Box2D.Collision.Collision.CollidePolygonAndCircle C# (CSharp) Метод

CollidePolygonAndCircle() публичный Метод

Compute the collision manifold between a polygon and a circle.
public CollidePolygonAndCircle ( Manifold manifold, PolygonShape polygon, Transform xfA, CircleShape circle, Transform xfB ) : void
manifold Manifold
polygon Box2D.Collision.Shapes.PolygonShape
xfA Box2D.Common.Transform
circle Box2D.Collision.Shapes.CircleShape
xfB Box2D.Common.Transform
Результат void
        public void CollidePolygonAndCircle(Manifold manifold, PolygonShape polygon, Transform xfA, CircleShape circle, Transform xfB)
        {
            manifold.PointCount = 0;
            //Vec2 v = circle.m_p;

            // Compute circle position in the frame of the polygon.
            // before inline:
            Transform.MulToOut(xfB, circle.P, C);
            Transform.MulTransToOut(xfA, C, C_LOCAL);

            float cLocalx = C_LOCAL.X;
            float cLocaly = C_LOCAL.Y;
            // after inline:
            // final float cy = xfB.p.y + xfB.q.ex.y * v.x + xfB.q.ey.y * v.y;
            // final float cx = xfB.p.x + xfB.q.ex.x * v.x + xfB.q.ey.x * v.y;
            // final float v1x = cx - xfA.p.x;
            // final float v1y = cy - xfA.p.y;
            // final Vec2 b = xfA.q.ex;
            // final Vec2 b1 = xfA.q.ey;
            // final float cLocaly = v1x * b1.x + v1y * b1.y;
            // final float cLocalx = v1x * b.x + v1y * b.y;
            // end inline

            // Find the min separating edge.
            int normalIndex = 0;
            //UPGRADE_TODO: The equivalent in .NET for field 'java.lang.Float.MIN_VALUE' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
            float separation = Single.Epsilon;
            float radius = polygon.Radius + circle.Radius;
            int vertexCount = polygon.VertexCount;

            Vec2[] vertices = polygon.Vertices;
            Vec2[] normals = polygon.Normals;

            for (int i = 0; i < vertexCount; i++)
            {
                // before inline
                // temp.set(cLocal).subLocal(vertices[i]);
                // float s = Vec2.dot(normals[i], temp);
                // after inline
                Vec2 vertex = vertices[i];
                float tempx = cLocalx - vertex.X;
                float tempy = cLocaly - vertex.Y;
                Vec2 normal = normals[i];
                float s = normal.X * tempx + normal.Y * tempy;

                if (s > radius)
                {
                    // early out
                    return;
                }

                if (s > separation)
                {
                    separation = s;
                    normalIndex = i;
                }
            }

            // Vertices that subtend the incident face.
            int vertIndex1 = normalIndex;
            int vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
            Vec2 v1 = vertices[vertIndex1];
            Vec2 v2 = vertices[vertIndex2];

            // If the center is inside the polygon ...
            if (separation < Settings.EPSILON)
            {
                manifold.PointCount = 1;
                manifold.Type = Manifold.ManifoldType.FaceA;

                // before inline:
                // manifold.localNormal.set(normals[normalIndex]);
                // manifold.localPoint.set(v1).addLocal(v2).mulLocal(.5f);
                // manifold.points[0].localPoint.set(circle.m_p);
                // after inline:
                Vec2 normal = normals[normalIndex];
                manifold.LocalNormal.X = normal.X;
                manifold.LocalNormal.Y = normal.Y;
                manifold.LocalPoint.X = (v1.X + v2.X) * .5f;
                manifold.LocalPoint.Y = (v1.Y + v2.Y) * .5f;
                ManifoldPoint mpoint = manifold.Points[0];
                mpoint.LocalPoint.X = circle.P.X;
                mpoint.LocalPoint.Y = circle.P.Y;
                mpoint.Id.Zero();
                // end inline
                return;
            }

            // Compute barycentric coordinates
            // before inline:
            // temp.set(cLocal).subLocal(v1);
            // temp2.set(v2).subLocal(v1);
            // float u1 = Vec2.dot(temp, temp2);
            // temp.set(cLocal).subLocal(v2);
            // temp2.set(v1).subLocal(v2);
            // float u2 = Vec2.dot(temp, temp2);
            // after inline:
            float tempX = cLocalx - v1.X;
            float tempY = cLocaly - v1.Y;
            float temp2X = v2.X - v1.X;
            float temp2Y = v2.Y - v1.Y;
            float u1 = tempX * temp2X + tempY * temp2Y;

            float temp3X = cLocalx - v2.X;
            float temp3Y = cLocaly - v2.Y;
            float temp4X = v1.X - v2.X;
            float temp4Y = v1.Y - v2.Y;
            float u2 = temp3X * temp4X + temp3Y * temp4Y;
            // end inline

            if (u1 <= 0f)
            {
                // inlined
                float dx = cLocalx - v1.X;
                float dy = cLocaly - v1.Y;
                if (dx * dx + dy * dy > radius * radius)
                {
                    return;
                }

                manifold.PointCount = 1;
                manifold.Type = Manifold.ManifoldType.FaceA;
                // before inline:
                // manifold.localNormal.set(cLocal).subLocal(v1);
                // after inline:
                manifold.LocalNormal.X = cLocalx - v1.X;
                manifold.LocalNormal.Y = cLocaly - v1.Y;
                // end inline
                manifold.LocalNormal.Normalize();
                manifold.LocalPoint.Set(v1);
                manifold.Points[0].LocalPoint.Set(circle.P);
                manifold.Points[0].Id.Zero();
            }
            else if (u2 <= 0.0f)
            {
                // inlined
                float dx = cLocalx - v2.X;
                float dy = cLocaly - v2.Y;
                if (dx * dx + dy * dy > radius * radius)
                {
                    return;
                }

                manifold.PointCount = 1;
                manifold.Type = Manifold.ManifoldType.FaceA;
                // before inline:
                // manifold.localNormal.set(cLocal).subLocal(v2);
                // after inline:
                manifold.LocalNormal.X = cLocalx - v2.X;
                manifold.LocalNormal.Y = cLocaly - v2.Y;
                // end inline
                manifold.LocalNormal.Normalize();
                manifold.LocalPoint.Set(v2);
                manifold.Points[0].LocalPoint.Set(circle.P);
                manifold.Points[0].Id.Zero();
            }
            else
            {
                // Vec2 faceCenter = 0.5f * (v1 + v2);
                // (temp is faceCenter)
                // before inline:
                // temp.set(v1).addLocal(v2).mulLocal(.5f);
                //
                // temp2.set(cLocal).subLocal(temp);
                // separation = Vec2.dot(temp2, normals[vertIndex1]);
                // if (separation > radius) {
                // return;
                // }
                // after inline:
                float fcx = (v1.X + v2.X) * .5f;
                float fcy = (v1.Y + v2.Y) * .5f;

                float tx = cLocalx - fcx;
                float ty = cLocaly - fcy;
                Vec2 normal = normals[vertIndex1];
                separation = tx * normal.X + ty * normal.Y;
                if (separation > radius)
                {
                    return;
                }
                // end inline

                manifold.PointCount = 1;
                manifold.Type = Manifold.ManifoldType.FaceA;
                manifold.LocalNormal.Set(normals[vertIndex1]);
                manifold.LocalPoint.X = fcx; // (faceCenter)
                manifold.LocalPoint.Y = fcy;
                manifold.Points[0].LocalPoint.Set(circle.P);
                manifold.Points[0].Id.Zero();
            }
        }