private bool DoExternalSeparated(TriangleShape triangle, out TinyStructList <ContactData> contactList) { if (GJKToolbox.AreShapesIntersecting(convex, triangle, ref Toolbox.RigidIdentity, ref Toolbox.RigidIdentity, ref localSeparatingAxis)) { state = CollisionState.ExternalNear; return(DoExternalNear(triangle, out contactList)); } TryToEscape(); contactList = new TinyStructList <ContactData>(); return(false); }
///<summary> /// Generates a contact between the objects, if possible. ///</summary> ///<param name="contact">Contact created between the pair, if possible.</param> ///<returns>Whether or not the objects were colliding.</returns> public bool GenerateContactCandidate(out ContactData contact) { //Generate contacts. This will just find one closest point using general supportmapping based systems like MPR and GJK. //The collision system moves through a state machine depending on the latest collision generation result. //At first, assume that the pair is completely separating. This is almost always the correct guess for new pairs. //An extremely fast, warm-startable boolean GJK test can be performed. If it returns with nonintersection, we can quit and do nothing. //If the initial boolean GJK test finds intersection, move onto a shallow contact test. //The shallow contact test is a different kind of GJK test that finds the closest points between the shape pair. It's not as speedy as the boolean version. //The algorithm is run between the marginless versions of the shapes, so that the closest points will form a contact somewhere in the space separating the cores. //If the closest point system finds no intersection and returns the closest points, the state is changed to ShallowContact. //If the closest point system finds intersection of the core shapes, then the state is changed to DeepContact, and MPR is run to determine contact information. //The system tries to escape from deep contact to shallow contact, and from shallow contact to separated whenever possible. //Here's the state flow: //On Separated: BooleanGJK // -Intersecting -> Go to ShallowContact. // -Nonintersecting -> Do nothing. //On ShallowContact: ClosestPointsGJK // -Intersecting -> Go to DeepContact. // -Nonintersecting: Go to Separated (without test) if squared distance > margin squared, otherwise use closest points to make contact. //On DeepContact: MPR // -Intersecting -> Go to ShallowContact if penetration depth < margin // -Nonintersecting -> This case is rare, but not impossible. Go to Separated (without test). previousState = state; switch (state) { case CollisionState.Separated: if (GJKToolbox.AreShapesIntersecting(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref localSeparatingAxis)) { state = CollisionState.ShallowContact; return(DoShallowContact(out contact)); } contact = new ContactData(); return(false); case CollisionState.ShallowContact: return(DoShallowContact(out contact)); case CollisionState.DeepContact: return(DoDeepContact(out contact)); } contact = new ContactData(); return(false); }