/// <summary> /// Create a joint to constrain bodies together. No reference to the definition /// is retained. This may cause the connected bodies to cease colliding. /// @warning This function is locked during callbacks. /// </summary> /// <param name="def"></param> /// <returns></returns> public Joint CreateJoint(JointDef def) { Box2DXDebug.Assert(IsLocked() == false); if (IsLocked()) { return(null); } Joint j = Joint.Create(def); // Connect to the world list. j._prev = null; j._next = _jointList; if (_jointList != null) { _jointList._prev = j; } _jointList = j; ++_jointCount; // Connect to the bodies' doubly linked lists. j._edgeA.Joint = j; j._edgeA.Other = j._bodyB; j._edgeA.Prev = null; j._edgeA.Next = j._bodyA._jointList; if (j._bodyA._jointList != null) { j._bodyA._jointList.Prev = j._edgeA; } j._bodyA._jointList = j._edgeA; j._edgeB.Joint = j; j._edgeB.Other = j._bodyA; j._edgeB.Prev = null; j._edgeB.Next = j._bodyB._jointList; if (j._bodyB._jointList != null) { j._bodyB._jointList.Prev = j._edgeB; } j._bodyB._jointList = j._edgeB; Body bodyA = def.Body1; Body bodyB = def.Body2; bool staticA = bodyA.IsStatic(); bool staticB = bodyB.IsStatic(); // If the joint prevents collisions, then flag any contacts for filtering. if (def.CollideConnected == false && (staticA == false || staticB == false)) { // Ensure we iterate over contacts on a dynamic body (usually have less contacts // than a static body). Ideally we will have a contact count on both bodies. if (staticB) { Math.Swap(ref bodyA, ref bodyB); } 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; } } // Note: creating a joint doesn't wake the bodies. return(j); }