This proxy is used internally to connect fixtures to the broad-phase.
示例#1
0
        // We need separation create/destroy functions from the constructor/destructor because
        // the destructor cannot access the allocator (no destructor arguments allowed by C++).
        public void Create(Body body, FixtureDef def)
        {
            UserData = def.UserData;
            Friction = def.Friction;
            Restitution = def.Restitution;

            Body = body;
            Next = null;

            Filter.Set(def.Filter);

            IsSensor = def.IsSensor;

            Shape = def.Shape.Clone();

            // Reserve proxy space
            int childCount = Shape.ChildCount;
            if (Proxies == null)
            {
                Proxies = new FixtureProxy[childCount];
                for (int i = 0; i < childCount; i++)
                {
                    Proxies[i] = new FixtureProxy {Fixture = null, ProxyId = BroadPhase.NULL_PROXY};
                }
            }

            if (Proxies.Length < childCount)
            {
                FixtureProxy[] old = Proxies;
                int newLen = MathUtils.Max(old.Length * 2, childCount);
                Proxies = new FixtureProxy[newLen];
                Array.Copy(old, 0, Proxies, 0, old.Length);
                for (int i = 0; i < newLen; i++)
                {
                    if (i >= old.Length)
                    {
                        Proxies[i] = new FixtureProxy();
                    }
                    Proxies[i].Fixture = null;
                    Proxies[i].ProxyId = BroadPhase.NULL_PROXY;
                }
            }
            ProxyCount = 0;

            m_density = def.Density;
        }
示例#2
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;
        }
示例#3
0
        // We need separation create/destroy functions from the constructor/destructor because
        // the destructor cannot access the allocator (no destructor arguments allowed by C++).
        public virtual void create(Body body, FixtureDef def)
        {
            m_userData = def.userData;
            m_friction = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            m_next = null;

            m_filter.set_Renamed(def.filter);

            m_isSensor = def.isSensor;

            m_shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = m_shape.ChildCount;
            if (m_proxies == null)
            {
                m_proxies = new FixtureProxy[childCount];
                for (int i = 0; i < childCount; i++)
                {
                    m_proxies[i] = new FixtureProxy();
                    m_proxies[i].fixture = null;
                    m_proxies[i].proxyId = BroadPhase.NULL_PROXY;
                }
            }

            if (m_proxies.Length < childCount)
            {
                FixtureProxy[] old = m_proxies;
                int newLen = MathUtils.max(old.Length * 2, childCount);
                m_proxies = new FixtureProxy[newLen];
                Array.Copy(old, 0, m_proxies, 0, old.Length);
                for (int i = 0; i < newLen; i++)
                {
                    if (i >= old.Length)
                    {
                        m_proxies[i] = new FixtureProxy();
                    }
                    m_proxies[i].fixture = null;
                    m_proxies[i].proxyId = BroadPhase.NULL_PROXY;
                }
            }
            m_proxyCount = 0;

            m_density = def.density;
        }