The class manages contact between two shapes. A contact exists for each overlapping AABB in the broad-phase (except if filtered). Therefore a contact object may exist that has no contact points.
Esempio n. 1
0
 public ContactManager(World argPool)
 {
     ContactList = null;
     ContactCount = 0;
     ContactFilter = new ContactFilter();
     ContactListener = null;
     BroadPhase = new BroadPhase();
     pool = argPool;
 }
Esempio n. 2
0
        public virtual void pushContact(Contact contact)
        {
            if (contact.m_manifold.pointCount > 0)
            {
                contact.FixtureA.Body.Awake = true;
                contact.FixtureB.Body.Awake = true;
            }

            ShapeType type1 = contact.FixtureA.Type;
            ShapeType type2 = contact.FixtureB.Type;

            IDynamicStack<Contact> creator = contactStacks[(int)type1][(int)type2].creator;
            creator.push(contact);
        }
Esempio n. 3
0
        /// <summary>
        /// initialization for pooling
        /// </summary>
        public virtual void init(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            m_flags = 0;

            m_fixtureA = fA;
            m_fixtureB = fB;

            m_indexA = indexA;
            m_indexB = indexB;

            m_manifold.pointCount = 0;

            m_prev = null;
            m_next = null;

            m_nodeA.contact = null;
            m_nodeA.prev = null;
            m_nodeA.next = null;
            m_nodeA.other = null;

            m_nodeB.contact = null;
            m_nodeB.prev = null;
            m_nodeB.next = null;
            m_nodeB.other = null;

            m_toiCount = 0;
            m_friction = mixFriction(fA.m_friction, fB.m_friction);
            m_restitution = mixRestitution(fA.m_restitution, fB.m_restitution);

            m_tangentSpeed = 0;
        }
Esempio n. 4
0
 public void Add(Contact contact)
 {
     Debug.Assert(ContactCount < ContactCapacity);
     Contacts[ContactCount++] = contact;
 }
Esempio n. 5
0
        /// <summary>
        /// initialization for pooling
        /// </summary>
        public virtual void Init(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = 0;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev = null;
            NodeA.Next = null;
            NodeA.Other = null;

            NodeB.Contact = null;
            NodeB.Prev = null;
            NodeB.Next = null;
            NodeB.Other = null;

            ToiCount = 0;
            Friction = MixFriction(fA.Friction, fB.Friction);
            Restitution = MixRestitution(fA.Restitution, fB.Restitution);

            TangentSpeed = 0;
        }
Esempio n. 6
0
        /// <summary>
        /// Broad-phase callback.
        /// </summary>
        /// <param name="proxyUserDataA"></param>
        /// <param name="proxyUserDataB"></param>
        public void AddPair(object proxyUserDataA, object proxyUserDataB)
        {
            FixtureProxy proxyA = (FixtureProxy)proxyUserDataA;
            FixtureProxy proxyB = (FixtureProxy)proxyUserDataB;

            Fixture fixtureA = proxyA.Fixture;
            Fixture fixtureB = proxyB.Fixture;

            int indexA = proxyA.ChildIndex;
            int indexB = proxyB.ChildIndex;

            Body bodyA = fixtureA.Body;
            Body bodyB = fixtureB.Body;

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // TODO_ERIN use a hash table to remove a potential bottleneck when both
            // bodies have a lot of contacts.
            // Does a contact already exist?
            ContactEdge edge = bodyB.ContactList;
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.FixtureA;
                    Fixture fB = edge.Contact.FixtureB;
                    int iA = edge.Contact.ChildIndexA;
                    int iB = edge.Contact.ChildIndexB;

                    if (fA == fixtureA && iA == indexA && fB == fixtureB && iB == indexB)
                    {
                        // A contact already exists.
                        return;
                    }

                    if (fA == fixtureB && iA == indexB && fB == fixtureA && iB == indexA)
                    {
                        // A contact already exists.
                        return;
                    }
                }

                edge = edge.Next;
            }

            // Does a joint override collision? is at least one body dynamic?
            if (bodyB.ShouldCollide(bodyA) == false)
            {
                return;
            }

            // Check user filtering.
            if (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

            // Call the factory.
            Contact c = pool.PopContact(fixtureA, indexA, fixtureB, indexB);
            if (c == null)
            {
                return;
            }

            // Contact creation may swap fixtures.
            fixtureA = c.FixtureA;
            fixtureB = c.FixtureB;
            bodyA = fixtureA.Body;
            bodyB = fixtureB.Body;

            // Insert into the world.
            c.Prev = null;
            c.Next = ContactList;
            if (ContactList != null)
            {
                ContactList.Prev = c;
            }
            ContactList = c;

            // Connect to island graph.

            // Connect to body A
            c.NodeA.Contact = c;
            c.NodeA.Other = bodyB;

            c.NodeA.Prev = null;
            c.NodeA.Next = bodyA.ContactList;
            if (bodyA.ContactList != null)
            {
                bodyA.ContactList.Prev = c.NodeA;
            }
            bodyA.ContactList = c.NodeA;

            // Connect to body B
            c.NodeB.Contact = c;
            c.NodeB.Other = bodyA;

            c.NodeB.Prev = null;
            c.NodeB.Next = bodyB.ContactList;
            if (bodyB.ContactList != null)
            {
                bodyB.ContactList.Prev = c.NodeB;
            }
            bodyB.ContactList = c.NodeB;

            // wake up the bodies
            bodyA.Awake = true;
            bodyB.Awake = true;

            ++ContactCount;
        }
Esempio n. 7
0
        public void Destroy(Contact c)
        {
            Fixture fixtureA = c.FixtureA;
            Fixture fixtureB = c.FixtureB;
            Body bodyA = fixtureA.Body;
            Body bodyB = fixtureB.Body;

            if (ContactListener != null && c.Touching)
            {
                ContactListener.EndContact(c);
            }

            // Remove from the world.
            if (c.Prev != null)
            {
                c.Prev.Next = c.Next;
            }

            if (c.Next != null)
            {
                c.Next.Prev = c.Prev;
            }

            if (c == ContactList)
            {
                ContactList = c.Next;
            }

            // Remove from body 1
            if (c.NodeA.Prev != null)
            {
                c.NodeA.Prev.Next = c.NodeA.Next;
            }

            if (c.NodeA.Next != null)
            {
                c.NodeA.Next.Prev = c.NodeA.Prev;
            }

            if (c.NodeA == bodyA.ContactList)
            {
                bodyA.ContactList = c.NodeA.Next;
            }

            // Remove from body 2
            if (c.NodeB.Prev != null)
            {
                c.NodeB.Prev.Next = c.NodeB.Next;
            }

            if (c.NodeB.Next != null)
            {
                c.NodeB.Next.Prev = c.NodeB.Prev;
            }

            if (c.NodeB == bodyB.ContactList)
            {
                bodyB.ContactList = c.NodeB.Next;
            }

            // Call the factory.
            pool.PushContact(c);
            --ContactCount;
        }
Esempio n. 8
0
 public virtual void add(Contact contact)
 {
     Debug.Assert(m_contactCount < m_contactCapacity);
     m_contacts[m_contactCount++] = contact;
 }