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

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

public static CollidePolygonAndCircle ( Manifold &manifold, PolygonShape polygon, Box2DX.Common.Transform xf1, CircleShape circle, Box2DX.Common.Transform xf2 ) : void
manifold Manifold
polygon PolygonShape
xf1 Box2DX.Common.Transform
circle CircleShape
xf2 Box2DX.Common.Transform
Результат void
        public static void CollidePolygonAndCircle(ref Manifold manifold, PolygonShape polygon, Transform xf1, CircleShape circle, Transform xf2)
        {
            manifold.PointCount = 0;

            // Compute circle position in the frame of the polygon.
            Vector2 c = xf2.TransformPoint(circle._position);
            Vector2 cLocal = xf1.InverseTransformPoint(c);

            // Find the min separating edge.
            int normalIndex = 0;
            float separation = -Settings.FLT_MAX;
            float radius = polygon._radius + circle._radius;
            int vertexCount = polygon._vertexCount;
            Vector2[] vertices = polygon._vertices;
            Vector2[] normals = polygon._normals;

            for (int i = 0; i < vertexCount; ++i)
            {
                float s = Vector2.Dot(normals[i], cLocal - vertices[i]);
                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;
            Vector2 v1 = vertices[vertIndex1];
            Vector2 v2 = vertices[vertIndex2];

            // If the center is inside the polygon ...
            if (separation < Common.Settings.FLT_EPSILON)
            {
                manifold.PointCount = 1;
                manifold.Type = ManifoldType.FaceA;
                manifold.LocalPlaneNormal = normals[normalIndex];
                manifold.LocalPoint = 0.5f * (v1 + v2);
                manifold.Points[0].LocalPoint = circle._position;
                manifold.Points[0].ID.Key = 0;
                return;
            }

            // Compute barycentric coordinates
            float u1 = Vector2.Dot(cLocal - v1, v2 - v1);
            float u2 = Vector2.Dot(cLocal - v2, v1 - v2);
            if (u1 <= 0.0f)
            {
                if ((cLocal - v1).sqrMagnitude > radius * radius)
                {
                    return;
                }

                manifold.PointCount = 1;
                manifold.Type = ManifoldType.FaceA;
                manifold.LocalPlaneNormal = cLocal - v1;
                manifold.LocalPlaneNormal.Normalize();
                manifold.LocalPoint = v1;
                manifold.Points[0].LocalPoint = circle._position;
                manifold.Points[0].ID.Key = 0;
            }
            else if (u2 <= 0.0f)
            {
                if ((cLocal - v2).sqrMagnitude > radius * radius)
                {
                    return;
                }

                manifold.PointCount = 1;
                manifold.Type = ManifoldType.FaceA;
                manifold.LocalPlaneNormal = cLocal - v2;
                manifold.LocalPlaneNormal.Normalize();
                manifold.LocalPoint = v2;
                manifold.Points[0].LocalPoint = circle._position;
                manifold.Points[0].ID.Key = 0;
            }
            else
            {
                Vector2 faceCenter = 0.5f * (v1 + v2);
                float separation_ = Vector2.Dot(cLocal - faceCenter, normals[vertIndex1]);
                if (separation_ > radius)
                {
                    return;
                }

                manifold.PointCount = 1;
                manifold.Type = ManifoldType.FaceA;
                manifold.LocalPlaneNormal = normals[vertIndex1];
                manifold.LocalPoint = faceCenter;
                manifold.Points[0].LocalPoint = circle._position;
                manifold.Points[0].ID.Key = 0;
            }
        }