public void Add(Joint joint) { Debug.Assert(_jointCount < _jointCapacity); _joints[_jointCount++] = joint; }
public GearJointDef() { type = JointType.Gear; joint1 = null; joint2 = null; ratio = 1.0f; }
/// Destroy a joint. This may cause the connected bodies to begin colliding. /// @warning This function is locked during callbacks. public void DestroyJoint(Joint j) { Debug.Assert(!IsLocked); 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; Debug.Assert(_jointCount > 0); --_jointCount; // If the joint prevents collisions, then flag any contacts for filtering. if (collideConnected == false) { ContactEdge edge = bodyB.GetConactList(); 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; } } }
void DrawJoint(Joint joint) { Body b1 = joint.GetBody1(); Body b2 = joint.GetBody2(); XForm xf1, xf2; b1.GetXForm(out xf1); b2.GetXForm(out xf2); Vector2 x1 = xf1.Position; Vector2 x2 = xf2.Position; Vector2 p1 = joint.GetAnchor1(); Vector2 p2 = joint.GetAnchor2(); Color color = ColorEx.FromScRgb(0.5f, 0.8f, 0.8f); switch (joint.JointType) { case JointType.Distance: DebugDraw.DrawSegment(p1, p2, color); break; case JointType.Pulley: { PulleyJoint pulley = (PulleyJoint)joint; Vector2 s1 = pulley.GetGroundAnchor1(); Vector2 s2 = pulley.GetGroundAnchor2(); DebugDraw.DrawSegment(s1, p1, color); DebugDraw.DrawSegment(s2, p2, color); DebugDraw.DrawSegment(s1, s2, color); } break; case JointType.Mouse: // don't draw this break; default: DebugDraw.DrawSegment(x1, p1, color); DebugDraw.DrawSegment(p1, p2, color); DebugDraw.DrawSegment(x2, p2, color); break; } }
/// Create a joint to rain 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. public Joint CreateJoint(JointDef def) { Debug.Assert(!IsLocked); 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) { MathUtils.Swap(ref bodyA, ref bodyB); } ContactEdge edge = bodyB.GetConactList(); 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; }