// Polygon versus 2-sided edge.
        public static void CollidePolyAndEdge(ref Manifold manifold, PolygonShape polygon, XForm transformA, EdgeShape edge, XForm transformB)
        {
            PolygonShape polygonB = new PolygonShape();

            polygonB.SetAsEdge(edge._v1, edge._v2);

            CollidePolygons(ref manifold, polygon, transformA, polygonB, transformB);
        }
Ejemplo n.º 2
0
 public void SetNextEdge(EdgeShape edge, Vector2 cornerDir, bool convex)
 {
     _nextEdge      = edge;
     _cornerDir2    = cornerDir;
     _cornerConvex2 = convex;
 }
        // This implements 2-sided edge vs circle collision.
        public static void CollideEdgeAndCircle(ref Manifold manifold, EdgeShape edge, XForm transformA, CircleShape circle, XForm transformB)
        {
            manifold.PointCount = 0;
            Vec2  cLocal = Common.MathB2.MulT(transformA, Common.MathB2.Mul(transformB, circle._position));
            Vec2  normal = edge._normal;
            Vec2  v1     = edge._v1;
            Vec2  v2     = edge._v2;
            float radius = edge._radius + circle._radius;

            // Barycentric coordinates
            float u1 = Vec2.Dot(cLocal - v1, v2 - v1);
            float u2 = Vec2.Dot(cLocal - v2, v1 - v2);

            if (u1 <= 0.0f)
            {
                // Behind v1
                if (Vec2.DistanceSquared(cLocal, v1) > 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)
            {
                // Ahead of v2
                if (Vec2.DistanceSquared(cLocal, v2) > 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
            {
                float separation = Vec2.Dot(cLocal - v1, normal);
                if (separation < -radius || radius < separation)
                {
                    return;
                }

                manifold.PointCount           = 1;
                manifold.Type                 = ManifoldType.FaceA;
                manifold.LocalPlaneNormal     = separation < 0.0f ? -normal : normal;
                manifold.LocalPoint           = 0.5f * (v1 + v2);
                manifold.Points[0].LocalPoint = circle._position;
                manifold.Points[0].ID.Key     = 0;
            }
        }
Ejemplo n.º 4
0
 public void SetPrevEdge(EdgeShape edge, Vector2 cornerDir, bool convex)
 {
     _prevEdge      = edge;
     _cornerDir1    = cornerDir;
     _cornerConvex1 = convex;
 }