/// <summary> /// Destroy a joint. This may cause the connected bodies to begin colliding. /// @warning This function is locked during callbacks. /// </summary> /// <param name="j"></param> public void DestroyJoint(Joint j) { Box2DXDebug.Assert(IsLocked() == false); if (IsLocked()) { return; } bool collideConnected = j._collideConnected; // Remove from the doubly linked list. if (j._prev != null) { j._prev._next = j._next; } if (j._next != null) { j._next._prev = j._prev; } if (j == _jointList) { _jointList = j._next; } // Disconnect from island graph. Body bodyA = j._bodyA; Body bodyB = j._bodyB; // Wake up connected bodies. bodyA.WakeUp(); bodyB.WakeUp(); // Remove from body 1. if (j._edgeA.Prev != null) { j._edgeA.Prev.Next = j._edgeA.Next; } if (j._edgeA.Next != null) { j._edgeA.Next.Prev = j._edgeA.Prev; } if (j._edgeA == bodyA._jointList) { bodyA._jointList = j._edgeA.Next; } j._edgeA.Prev = null; j._edgeA.Next = null; // Remove from body 2 if (j._edgeB.Prev != null) { j._edgeB.Prev.Next = j._edgeB.Next; } if (j._edgeB.Next != null) { j._edgeB.Next.Prev = j._edgeB.Prev; } if (j._edgeB == bodyB._jointList) { bodyB._jointList = j._edgeB.Next; } j._edgeB.Prev = null; j._edgeB.Next = null; Joint.Destroy(j); Box2DXDebug.Assert(_jointCount > 0); --_jointCount; // If the joint prevents collisions, then flag any contacts for filtering. if (collideConnected == false) { ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { // Flag the contact for filtering at the next time step (where either // body is awake). edge.Contact.FlagForFiltering(); } edge = edge.Next; } } }