public static bool boxAndBox( BoxRigid one, BoxRigid two, ref CollisionData data ) { if (!IntersectionTestsboxAndBox(one, two)) { return(false); } // Find the vector between the two centres Vector3 toCentre = two.PositionCenterEngine - one.PositionCenterEngine; // We start assuming there is no contact float pen = float.MaxValue; int best = 0xffffff; // Now we check each axes, returning if it gives us // a separating axis, and keeping track of the axis with // the smallest penetration otherwise. if (!tryAxis(one, two, (one).XAxis, toCentre, 0, ref pen, ref best)) { return(false); } if (!tryAxis(one, two, (one).YAxis, toCentre, 1, ref pen, ref best)) { return(false); } if (!tryAxis(one, two, (two).XAxis, toCentre, 2, ref pen, ref best)) { return(false); } if (!tryAxis(one, two, (two).YAxis, toCentre, 3, ref pen, ref best)) { return(false); } // Store the best axis-major, in case we run into almost // parallel edge collisions later int bestSingleAxis = best; // Make sure we've got a result. if (best != 0xffffff) { // We now know there's a collision, and we know which // of the axes gave the smallest penetration. We now // can deal with it in different ways depending on // the case. if (best < 2) { // We've got a vertex of box two on a face of box one. fillPointFaceBoxBox(one, two, toCentre, ref data, best, pen); one.SetCanSleep(true); two.SetCanSleep(true); data.addContacts(1); } else if (best < 4) { fillPointFaceBoxBox(two, one, toCentre * -1.0f, ref data, best - 2, pen); one.SetCanSleep(true); two.SetCanSleep(true); data.addContacts(1); } return(true); } return(false); }
public static bool boxAndHalfSpace( BoxRigid box, CollisionPlane plane, ref CollisionData data ) { // Make sure we have contacts if (data.contactsLeft <= 0) { return(false); } // Check for intersection if (!IntersectionTestboxAndHalfSpace(box, plane)) { return(false); } bool b = false; int contactsUsed = 0; for (int i = 0; i < 4; i++) { Vector3 vertexPos = ((BoxRigid)box).vertices[i].Position; // Calculate the distance from the plane float vertexDistance = Vector3.Dot(vertexPos, plane.Direction); // Compare this to the plane's distance if (vertexDistance <= plane.Offset) { b = true; // Create the contact data. // The contact point is halfway between the vertex and the // plane - we multiply the direction by half the separation // distance and add the vertex location. Contact c = new Contact(); c.ContactPoint = plane.Direction; c.ContactPoint *= (0.5f * (plane.Offset - vertexDistance)); c.ContactPoint = vertexPos; c.ContactNormal = plane.Direction; c.Penetration = plane.Offset - vertexDistance; c.Particle[0] = box; c.Particle[1] = null; c.Friction = data.friction; c.Restitution = data.restitution; c.Friction = StaticData.FrictionTable[(int)plane.Material][(int)box.GetMaterial()]; c.Restitution = StaticData.RestitutionTable[(int)plane.Material][(int)box.GetMaterial()]; c.ContactToWorld.M11 = plane.Direction.X; c.ContactToWorld.M12 = -plane.Direction.Y; c.ContactToWorld.M21 = plane.Direction.Y; c.ContactToWorld.M22 = plane.Direction.X; data.contacts.Add(c); box.SetCanSleep(true); data.index++; data.contactsLeft--; data.contactCount++; contactsUsed++; } } return(b); }