// 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; } }
public void SetPrevEdge(EdgeShape edge, Vector2 cornerDir, bool convex) { _prevEdge = edge; _cornerDir1 = cornerDir; _cornerConvex1 = convex; }
public void SetNextEdge(EdgeShape edge, Vector2 cornerDir, bool convex) { _nextEdge = edge; _cornerDir2 = cornerDir; _cornerConvex2 = convex; }
public void SetNextEdge(EdgeShape edge, Vec2 cornerDir, bool convex) { _nextEdge = edge; _cornerDir2 = cornerDir; _cornerConvex2 = convex; }
public void SetPrevEdge(EdgeShape edge, Vec2 cornerDir, bool convex) { _prevEdge = edge; _cornerDir1 = cornerDir; _cornerConvex1 = convex; }
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; } }
// 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; } }