// Polygon versus 2-sided edge.
        public static void CollidePolyAndEdge(ref Manifold manifold, PolygonShape polygon, Transform TransformA, EdgeShape edge, Transform TransformB)
        {
            PolygonShape polygonB = new PolygonShape();
            polygonB.SetAsEdge(edge._v1, edge._v2);

            CollidePolygons(ref manifold, polygon, TransformA, polygonB, TransformB);
        }
        // This implements 2-sided edge vs circle collision.
        public static void CollideEdgeAndCircle(ref Manifold manifold, EdgeShape edge, Transform transformA, CircleShape circle, Transform transformB)
        {
            manifold.PointCount = 0;
            Vector2 cLocal = Common.Math.MulT(transformA, Common.Math.Mul(transformB, circle._position));
            Vector2 normal = edge._normal;
            Vector2 v1 = edge._v1;
            Vector2 v2 = edge._v2;
            float radius = edge._radius + circle._radius;

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

            if (u1 <= 0.0f)
            {
                // Behind v1
                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)
            {
                // Ahead of v2
                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
            {
                float separation = Vector2.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;
            }
        }
示例#3
0
 public void SetPrevEdge(EdgeShape edge, Vector2 cornerDir, bool convex)
 {
     _prevEdge      = edge;
     _cornerDir1    = cornerDir;
     _cornerConvex1 = convex;
 }
示例#4
0
 public void SetNextEdge(EdgeShape edge, Vector2 cornerDir, bool convex)
 {
     _nextEdge      = edge;
     _cornerDir2    = cornerDir;
     _cornerConvex2 = convex;
 }
示例#5
0
		public void SetNextEdge(EdgeShape edge, Vec2 cornerDir, bool convex)
		{
			_nextEdge = edge;
			_cornerDir2 = cornerDir;
			_cornerConvex2 = convex;
		}
示例#6
0
		public void SetPrevEdge(EdgeShape edge, Vec2 cornerDir, bool convex)
		{
			_prevEdge = edge;
			_cornerDir1 = cornerDir;
			_cornerConvex1 = convex;
		}
示例#7
0
        public void Create(BroadPhase broadPhase, Body body, XForm xf, FixtureDef def)
        {
            UserData = def.UserData;
            Friction = def.Friction;
            Restitution = def.Restitution;
            Density = def.Density;

            _body = body;
            _next = null;

            Filter = def.Filter;

            _isSensor = def.IsSensor;

            _type = def.Type;

            // Allocate and initialize the child shape.
            switch (_type)
            {
                case ShapeType.CircleShape:
                    {
                        CircleShape circle = new CircleShape();
                        CircleDef circleDef = (CircleDef)def;
                        circle._position = circleDef.LocalPosition;
                        circle._radius = circleDef.Radius;
                        _shape = circle;
                    }
                    break;

                case ShapeType.PolygonShape:
                    {
                        PolygonShape polygon = new PolygonShape();
                        PolygonDef polygonDef = (PolygonDef)def;
                        polygon.Set(polygonDef.Vertices, polygonDef.VertexCount);
                        _shape = polygon;
                    }
                    break;

                case ShapeType.EdgeShape:
                    {
                        EdgeShape edge = new EdgeShape();
                        EdgeDef edgeDef = (EdgeDef)def;
                        edge.Set(edgeDef.Vertex1, edgeDef.Vertex2);
                        _shape = edge;
                    }
                    break;

                default:
                    Box2DXDebug.Assert(false);
                    break;
            }

            // Create proxy in the broad-phase.
            AABB aabb;
            _shape.ComputeAABB(out aabb, xf);

            bool inRange = broadPhase.InRange(aabb);

            // You are creating a shape outside the world box.
            Box2DXDebug.Assert(inRange);

            if (inRange)
            {
                _proxyId = broadPhase.CreateProxy(aabb, this);
            }
            else
            {
                _proxyId = PairManager.NullProxy;
            }
        }
        // Polygon versus 2-sided edge.
        public static void CollidePolyAndEdge(ref Manifold manifold, PolygonShape polygon, Transform TransformA, EdgeShape edge, Transform TransformB)
        {
            PolygonShape polygonB = new PolygonShape();

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

            CollidePolygons(ref manifold, polygon, TransformA, polygonB, TransformB);
        }
        // This implements 2-sided edge vs circle collision.
        public static void CollideEdgeAndCircle(ref Manifold manifold, EdgeShape edge, Transform transformA, CircleShape circle, Transform transformB)
        {
            manifold.PointCount = 0;
            Vector2 cLocal = Common.Math.MulT(transformA, Common.Math.Mul(transformB, circle._position));
            Vector2 normal = edge._normal;
            Vector2 v1     = edge._v1;
            Vector2 v2     = edge._v2;
            float   radius = edge._radius + circle._radius;

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

            if (u1 <= 0.0f)
            {
                // Behind v1
                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)
            {
                // Ahead of v2
                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
            {
                float separation = Vector2.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;
            }
        }