/// <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);
}