Beispiel #1
0
        /** @private */
        virtual public void Reset(b2Fixture fixtureA = null, b2Fixture fixtureB = null)
        {
            m_flags = e_enabledFlag;

            if (fixtureA == null || fixtureB == null)
            {
                m_fixtureA = null;
                m_fixtureB = null;
                return;
            }

            if (fixtureA.IsSensor() || fixtureB.IsSensor())
            {
                m_flags |= e_sensorFlag;
            }

            b2Body bodyA = fixtureA.GetBody();
            b2Body bodyB = fixtureB.GetBody();

            if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet())
            {
                m_flags |= e_continuousFlag;
            }

            m_fixtureA = fixtureA;
            m_fixtureB = fixtureB;

            m_manifold.m_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;
        }
Beispiel #2
0
    internal static void Destroy(ref b2Contact contact)
    {
        Debug.Assert(s_initialized == true);

        b2Fixture fixtureA = contact.m_fixtureA;
        b2Fixture fixtureB = contact.m_fixtureB;

        if (contact.m_manifold.pointCount > 0 && fixtureA.IsSensor() == false && fixtureB.IsSensor() == false)
        {
            fixtureA.GetBody().SetAwake(true);
            fixtureB.GetBody().SetAwake(true);
        }

        b2Shape.Type typeA = fixtureA.GetType();
        b2Shape.Type typeB = fixtureB.GetType();

        Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount);
        Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount);

        b2ContactDestroyFcn destroyFcn = s_registers[(int)typeA, (int)typeB].destroyFcn;

        destroyFcn(ref contact);
    }
    // Broad-phase callback.
    public void AddPair(object proxyUserDataA, object proxyUserDataB)
    {
        b2FixtureProxy proxyA = (b2FixtureProxy)proxyUserDataA;
        b2FixtureProxy proxyB = (b2FixtureProxy)proxyUserDataB;

        b2Fixture fixtureA = proxyA.fixture;
        b2Fixture fixtureB = proxyB.fixture;

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

        b2Body bodyA = fixtureA.GetBody();
        b2Body bodyB = fixtureB.GetBody();

        // 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?
        b2ContactEdge edge = bodyB.GetContactList();

        while (edge != null)
        {
            if (edge.other == bodyA)
            {
                b2Fixture fA = edge.contact.GetFixtureA();
                b2Fixture fB = edge.contact.GetFixtureB();
                int       iA = edge.contact.GetChildIndexA();
                int       iB = edge.contact.GetChildIndexB();

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

                if (fA == fixtureB && fB == fixtureA && iA == indexB && 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 (m_contactFilter != null && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
        {
            return;
        }

        // Call the factory.
        b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB);

        if (c == null)
        {
            return;
        }

        // Contact creation may swap fixtures.
        fixtureA = c.GetFixtureA();
        fixtureB = c.GetFixtureB();
        indexA   = c.GetChildIndexA();
        indexB   = c.GetChildIndexB();
        bodyA    = fixtureA.GetBody();
        bodyB    = fixtureB.GetBody();

        // Insert into the world.
        c.m_prev = null;
        c.m_next = m_contactList;
        if (m_contactList != null)
        {
            m_contactList.m_prev = c;
        }
        m_contactList = c;

        // Connect to island graph.

        // Connect to body A
        c.m_nodeA.contact = c;
        c.m_nodeA.other   = bodyB;

        c.m_nodeA.prev = null;
        c.m_nodeA.next = bodyA.m_contactList;
        if (bodyA.m_contactList != null)
        {
            bodyA.m_contactList.prev = c.m_nodeA;
        }
        bodyA.m_contactList = c.m_nodeA;

        // Connect to body B
        c.m_nodeB.contact = c;
        c.m_nodeB.other   = bodyA;

        c.m_nodeB.prev = null;
        c.m_nodeB.next = bodyB.m_contactList;
        if (bodyB.m_contactList != null)
        {
            bodyB.m_contactList.prev = c.m_nodeB;
        }
        bodyB.m_contactList = c.m_nodeB;

        // Wake up the bodies
        if (fixtureA.IsSensor() == false && fixtureB.IsSensor() == false)
        {
            bodyA.SetAwake(true);
            bodyB.SetAwake(true);
        }

        ++m_contactCount;
    }