// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.

        /// <summary>
        /// Initialize the proxy using the given shape. The shape
        /// must remain in scope while the proxy is in use.
        /// </summary>
        /// <param name="shape">The shape.</param>
        /// <param name="index">The index.</param>
        public void Set(Shape shape, int index)
        {
            switch (shape.ShapeType)
            {
            case ShapeType.Circle:
            {
                CircleShape circle = (CircleShape)shape;
                Vertices.Clear();
                Vertices.Add(circle.Position);
                Radius = circle.Radius;
            }
            break;

            case ShapeType.Polygon:
            {
                PolygonShape polygon = (PolygonShape)shape;
                Vertices.Clear();
                for (int i = 0; i < polygon.Vertices.Count; i++)
                {
                    Vertices.Add(polygon.Vertices[i]);
                }
                Radius = polygon.Radius;
            }
            break;

            case ShapeType.Chain:
            {
                ChainShape chain = (ChainShape)shape;
                Debug.Assert(0 <= index && index < chain.Vertices.Count);
                Vertices.Clear();
                Vertices.Add(chain.Vertices[index]);
                Vertices.Add(index + 1 < chain.Vertices.Count ? chain.Vertices[index + 1] : chain.Vertices[0]);

                Radius = chain.Radius;
            }
            break;

            case ShapeType.Edge:
            {
                EdgeShape edge = (EdgeShape)shape;
                Vertices.Clear();
                Vertices.Add(edge.Vertex1);
                Vertices.Add(edge.Vertex2);
                Radius = edge.Radius;
            }
            break;

            default:
                Debug.Assert(false);
                break;
            }
        }
        public override Shape Clone()
        {
            ChainShape clone = new ChainShape();

            clone.ShapeType      = ShapeType;
            clone._density       = _density;
            clone._radius        = _radius;
            clone.PrevVertex     = _prevVertex;
            clone.NextVertex     = _nextVertex;
            clone._hasNextVertex = _hasNextVertex;
            clone._hasPrevVertex = _hasPrevVertex;
            clone.Vertices       = new Vertices(Vertices);
            clone.MassData       = MassData;
            return(clone);
        }
        /// <summary>
        /// Compare the chain to another chain
        /// </summary>
        /// <param name="shape">The other chain</param>
        /// <returns>True if the two chain shapes are the same</returns>
        public bool CompareTo(ChainShape shape)
        {
            if (Vertices.Count != shape.Vertices.Count)
            {
                return(false);
            }

            for (int i = 0; i < Vertices.Count; i++)
            {
                if (Vertices[i] != shape.Vertices[i])
                {
                    return(false);
                }
            }

            return(PrevVertex == shape.PrevVertex && NextVertex == shape.NextVertex);
        }
        //Contributed by Matthew Bettcher

        /// <summary>
        /// Convert a path into a set of edges and attaches them to the specified body.
        /// Note: use only for static edges.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="body">The body.</param>
        /// <param name="subdivisions">The subdivisions.</param>
        public static void ConvertPathToEdges(Path path, Body body, int subdivisions)
        {
            Vertices verts = path.GetVertices(subdivisions);

            if (path.Closed)
            {
                ChainShape chain = new ChainShape(verts, true);
                body.CreateFixture(chain);
            }
            else
            {
                for (int i = 1; i < verts.Count; i++)
                {
                    body.CreateFixture(new EdgeShape(verts[i], verts[i - 1]));
                }
            }
        }
        /// <summary>
        /// Evaluate this contact with your own manifold and transforms.
        /// </summary>
        /// <param name="manifold">The manifold.</param>
        /// <param name="transformA">The first transform.</param>
        /// <param name="transformB">The second transform.</param>
        private void Evaluate(ref Manifold manifold, ref Transform transformA, ref Transform transformB)
        {
            switch (_type)
            {
            case ContactType.Polygon:
                Collision.CollidePolygons(ref manifold, (PolygonShape)FixtureA.Shape, ref transformA, (PolygonShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.PolygonAndCircle:
                Collision.CollidePolygonAndCircle(ref manifold, (PolygonShape)FixtureA.Shape, ref transformA, (CircleShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.EdgeAndCircle:
                Collision.CollideEdgeAndCircle(ref manifold, (EdgeShape)FixtureA.Shape, ref transformA, (CircleShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.EdgeAndPolygon:
                Collision.CollideEdgeAndPolygon(ref manifold, (EdgeShape)FixtureA.Shape, ref transformA, (PolygonShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.ChainAndCircle:
                ChainShape chain = (ChainShape)FixtureA.Shape;
                chain.GetChildEdge(_edge, ChildIndexA);
                Collision.CollideEdgeAndCircle(ref manifold, _edge, ref transformA, (CircleShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.ChainAndPolygon:
                ChainShape loop2 = (ChainShape)FixtureA.Shape;
                loop2.GetChildEdge(_edge, ChildIndexA);
                Collision.CollideEdgeAndPolygon(ref manifold, _edge, ref transformA, (PolygonShape)FixtureB.Shape, ref transformB);
                break;

            case ContactType.Circle:
                Collision.CollideCircles(ref manifold, (CircleShape)FixtureA.Shape, ref transformA, (CircleShape)FixtureB.Shape, ref transformB);
                break;
            }
        }
示例#6
0
        public static Fixture AttachLoopShape(Vertices vertices, Body body, object userData = null)
        {
            ChainShape shape = new ChainShape(vertices, true);

            return(body.CreateFixture(shape, userData));
        }