Beispiel #1
0
 public void Add(Joint joint)
 {
     Debug.Assert(_jointCount < _jointCapacity);
     _joints[_jointCount++] = joint;
 }
Beispiel #2
0
 public GearJointDef()
 {
     type = JointType.Gear;
     joint1 = null;
     joint2 = null;
     ratio = 1.0f;
 }
Beispiel #3
0
        /// 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;
                }
            }
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        /// 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;
        }