public static int SphereAndTruePlane(CollisionSphere sphere, CollisionPlane plane, ref CollisionData data) { if (data.ContactsLeft <= 0) return 0; Vector3 position = sphere.GetAxis(3); float centreDistance = Vector3.Dot(plane.Normal, position) - plane.D; if (centreDistance * centreDistance > sphere.Radius * sphere.Radius) { return 0; } Vector3 normal = plane.Normal; float penetration = -centreDistance; if (centreDistance < 0) { normal *= -1; penetration = -penetration; } penetration += sphere.Radius; Contact contact = new Contact(); contact.ContactNormal = normal; contact.Penetration = penetration; contact.ContactPoint = position - plane.Normal * centreDistance; contact.SetData(sphere.Body, null, data.Friction, data.Restitution); data.Contacts.Add(contact); data.AddContacts(1); return 1; }
public static int SphereAndHalfSpace(CollisionSphere sphere, CollisionPlane plane, ref CollisionData data) { if (data.ContactsLeft <= 0) return 0; Vector3 position = sphere.GetAxis(3); float ballDistance = Vector3.Dot(plane.Normal, position) - sphere.Radius - plane.D; if (ballDistance >= 0) return 0; Contact contact = new Contact(); contact.ContactNormal = plane.Normal; contact.Penetration = -ballDistance; contact.ContactPoint = position - plane.Normal * (ballDistance + sphere.Radius); contact.SetData(sphere.Body, null, data.Friction, data.Restitution); data.Contacts.Add(contact); data.AddContacts(1); return 1; }
public static int SphereAndSphere(CollisionSphere one, CollisionSphere two, ref CollisionData data) { if (data.ContactsLeft <= 0) return 0; Vector3 positionOne = one.GetAxis(3); Vector3 positionTwo = two.GetAxis(3); Vector3 midline = positionOne - positionTwo; float size = midline.Magnitude; if (size <= 0.0f || size >= one.Radius + two.Radius) { return 0; } Vector3 normal = midline * ((1.0f) / size); Contact contact = new Contact(); contact.ContactNormal = normal; contact.ContactPoint = positionOne + midline * (float)0.5; contact.Penetration = (one.Radius + two.Radius - size); contact.SetData(one.Body, two.Body, data.Friction, data.Restitution); data.Contacts.Add(new Contact()); data.AddContacts(1); return 1; }
public static bool SphereAndSphere(CollisionSphere one, CollisionSphere two) { Vector3 midline = one.GetAxis(3) - two.GetAxis(3); return midline.SquaredMagnitude < (one.Radius + two.Radius) * (one.Radius + two.Radius); }
public static bool SphereAndHalfSpace(CollisionSphere sphere, CollisionPlane plane) { float ballDistance = Vector3.Dot(plane.Normal, sphere.GetAxis(3)) - sphere.Radius; return ballDistance <= plane.D; }
public static int BoxAndSphere(CollisionBox box, CollisionSphere sphere, ref CollisionData data) { Vector3 centre = sphere.GetAxis(3); Vector3 relCentre = box.Transform.TransformInverse(centre); if (MathHelper.Abs(relCentre.X) - sphere.Radius > box.HalfSize.X || MathHelper.Abs(relCentre.Y) - sphere.Radius > box.HalfSize.Y || MathHelper.Abs(relCentre.Z) - sphere.Radius > box.HalfSize.Z) { return 0; } Vector3 closestPt = new Vector3(); float dist; dist = relCentre.X; if (dist > box.HalfSize.X) dist = box.HalfSize.X; if (dist < -box.HalfSize.X) dist = -box.HalfSize.X; closestPt.X = dist; dist = relCentre.Y; if (dist > box.HalfSize.Y) dist = box.HalfSize.Y; if (dist < -box.HalfSize.Y) dist = -box.HalfSize.Y; closestPt.Y = dist; dist = relCentre.Z; if (dist > box.HalfSize.Z) dist = box.HalfSize.Z; if (dist < -box.HalfSize.Z) dist = -box.HalfSize.Z; closestPt.Z = dist; dist = (closestPt - relCentre).SquaredMagnitude; if (dist > sphere.Radius * sphere.Radius) return 0; Vector3 closestPtWorld = box.Transform.Transform(closestPt); Contact contact = new Contact(); contact.ContactNormal = (closestPtWorld - centre); contact.ContactNormal.Normalize(); contact.ContactPoint = closestPtWorld; contact.Penetration = sphere.Radius - MathHelper.Sqrt(dist); contact.SetData(box.Body, sphere.Body, data.Friction, data.Restitution); data.Contacts.Add(contact); data.AddContacts(1); return 1; }