Esempio n. 1
0
        public void Create(b2Body body, b2FixtureDef def)
        {
            m_userData    = def.userData;
            m_friction    = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            Next   = null;

            m_filter = def.filter;

            m_isSensor = def.isSensor;

            m_shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = m_shape.GetChildCount();

            for (int i = 0; i < childCount; ++i)
            {
                b2FixtureProxy proxy = new b2FixtureProxy();
                proxy.fixture = null;
                proxy.proxyId = b2BroadPhase.e_nullProxy;
                m_proxies.Add(proxy);
            }
            m_proxyCount = 0;

            m_density = def.density;
        }
Esempio n. 2
0
        public virtual void Synchronize(b2BroadPhase broadPhase, ref b2Transform transform1, ref b2Transform transform2)
        {
            if (m_proxyCount == 0)
            {
                return;
            }

            for (int i = 0, count = m_proxyCount; i < count; ++i)
            {
                b2FixtureProxy proxy = m_proxies[i];

                // Compute an AABB that covers the swept shape (may miss some rotation effect).
                b2AABB aabb1, aabb2;
                Shape.ComputeAABB(out aabb1, ref transform1, proxy.childIndex);
                Shape.ComputeAABB(out aabb2, ref transform2, proxy.childIndex);

                proxy.aabb.Combine(ref aabb1, ref aabb2);

                b2Vec2 displacement;
                displacement.x = transform2.p.x - transform1.p.x;
                displacement.y = transform2.p.y - transform1.p.y;

                broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, ref displacement);
            }
        }
Esempio n. 3
0
 public virtual void DestroyProxies(b2BroadPhase broadPhase)
 {
     // Destroy proxies in the broad-phase.
     for (int i = 0; i < m_proxyCount; ++i)
     {
         b2FixtureProxy proxy = m_proxies[i];
         broadPhase.DestroyProxy(proxy.proxyId);
         proxy.proxyId = b2BroadPhase.e_nullProxy;
     }
     m_proxies.Clear();
     m_proxyCount = 0;
 }
Esempio n. 4
0
        public virtual void CreateProxies(b2BroadPhase broadPhase, b2Transform xf)
        {
            // Create proxies in the broad-phase.
            m_proxyCount = m_shape.GetChildCount();

            for (int i = 0; i < m_proxyCount; ++i)
            {
                b2FixtureProxy proxy = m_proxies[i];
                proxy.aabb       = m_shape.ComputeAABB(xf, i);
                proxy.proxyId    = broadPhase.CreateProxy(proxy.aabb, proxy);
                proxy.fixture    = this;
                proxy.childIndex = i;
            }
        }
        public float RayCastCallback(ref b2RayCastInput input, int proxyId)
        {
            b2FixtureProxy  proxy   = broadPhase.GetUserData(proxyId);
            b2Fixture       fixture = proxy.fixture;
            int             index   = proxy.childIndex;
            b2RayCastOutput output;
            bool            hit = fixture.RayCast(out output, input, index);

            if (hit)
            {
                float  fraction = output.fraction;
                b2Vec2 point    = (1.0f - fraction) * input.p1 + fraction * input.p2;
                return(callback.ReportFixture(fixture, point, output.normal, fraction));
            }

            return(input.maxFraction);
        }
Esempio n. 6
0
        public virtual void Synchronize(b2BroadPhase broadPhase, b2Transform transform1, b2Transform transform2)
        {
            if (m_proxyCount == 0)
            {
                return;
            }

            for (int i = 0; i < m_proxyCount; ++i)
            {
                b2FixtureProxy proxy = m_proxies[i];

                // Compute an AABB that covers the swept shape (may miss some rotation effect).
                b2AABB aabb1, aabb2;
                aabb1 = m_shape.ComputeAABB(transform1, proxy.childIndex);
                aabb2 = m_shape.ComputeAABB(transform2, proxy.childIndex);

                proxy.aabb.Combine(aabb1, aabb2);

                b2Vec2 displacement = transform2.p - transform1.p;

                broadPhase.MoveProxy(proxy.proxyId, proxy.aabb, displacement);
            }
        }
Esempio n. 7
0
        public void DrawDebugData()
        {
            if (m_debugDraw == null)
            {
                return;
            }

            b2DrawFlags flags = m_debugDraw.GetFlags();

            if (flags & b2DrawFlags.e_shapeBit)
            {
                for (b2Body b = m_bodyList; b; b = b.Next)
                {
                    b2Transform xf = b.Transform;
                    for (b2Fixture f = b.FixtureList; f != null; f = f.Next)
                    {
                        if (b.IsActive() == false)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.3f));
                        }
                        else if (b.GetType() == b2BodyType.b2_staticBody)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.9f, 0.5f));
                        }
                        else if (b.GetType() == b2BodyType.b2_kinematicBody)
                        {
                            DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.9f));
                        }
                        else if (b.IsAwake() == false)
                        {
                            DrawShape(f, xf, new b2Color(0.6f, 0.6f, 0.6f));
                        }
                        else
                        {
                            DrawShape(f, xf, new b2Color(0.9f, 0.7f, 0.7f));
                        }
                    }
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_jointBit))
            {
                for (b2Joint j = m_jointList; j != null; j = j.GetNext())
                {
                    DrawJoint(j);
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_pairBit))
            {
                b2Color color = new b2Color(0.3f, 0.9f, 0.9f);
                for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
                {
                    //b2Fixture fixtureA = c.GetFixtureA();
                    //b2Fixture fixtureB = c.GetFixtureB();

                    //b2Vec2 cA = fixtureA.GetAABB().GetCenter();
                    //b2Vec2 cB = fixtureB.GetAABB().GetCenter();

                    //m_debugDraw.DrawSegment(cA, cB, color);
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_aabbBit))
            {
                b2Color color(0.9f, 0.3f, 0.9f);

                b2BroadPhase bp = m_contactManager.BroadPhase;

                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    if (b.IsActive() == false)
                    {
                        continue;
                    }

                    for (b2Fixture f = b.FixtureList; f != null; f = f.Next)
                    {
                        for (int i = 0; i < f.ProxyCount; ++i)
                        {
                            b2FixtureProxy proxy = f.Proxies[i];
                            b2AABB         aabb  = bp.GetFatAABB(proxy.proxyId);
                            b2Vec2[]       vs    = new b2Vec2[4];
                            vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
                            vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
                            vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
                            vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);

                            m_debugDraw.DrawPolygon(vs, 4, color);
                        }
                    }
                }
            }

            if (flags.HasFlag(b2DrawFlags.e_centerOfMassBit))
            {
                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    b2Transform xf = b.Transform;
                    xf.p = b.WorldCenter;
                    m_debugDraw.DrawTransform(xf);
                }
            }
        }
        public bool QueryCallback(int proxyId)
        {
            b2FixtureProxy proxy = (b2FixtureProxy)broadPhase.GetUserData(proxyId);

            return(callback.ReportFixture(proxy.fixture));
        }
Esempio n. 9
0
        public void Create(b2Body body, b2FixtureDef def)
        {
            m_userData = def.userData;
            m_friction = def.friction;
            m_restitution = def.restitution;

            m_body = body;
            Next = null;

            m_filter = def.filter;

            m_isSensor = def.isSensor;

            m_shape = def.shape.Clone();

            // Reserve proxy space
            int childCount = m_shape.GetChildCount();
            for (int i = 0; i < childCount; ++i)
            {
                b2FixtureProxy proxy = new b2FixtureProxy();
                proxy.fixture = null;
                proxy.proxyId = b2BroadPhase.e_nullProxy;
                m_proxies.Add(proxy);
            }
            m_proxyCount = 0;

            m_density = def.density;
        }
Esempio n. 10
0
        public void AddPair(ref b2FixtureProxy proxyA, ref b2FixtureProxy proxyB)
        {
            b2Fixture fixtureA = proxyA.fixture;
            b2Fixture fixtureB = proxyB.fixture;

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

            b2Body bodyA = fixtureA.Body;
            b2Body 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?
            b2ContactEdge edge = bodyB.ContactList;
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    b2Fixture fA = edge.Contact.FixtureA;
                    b2Fixture fB = edge.Contact.FixtureB;
                    int iA = edge.Contact.m_indexA;
                    int iB = edge.Contact.m_indexB;

                    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))
            {
                return;
            }

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

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

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

            // Insert into the world.
            c.Prev = null;
            c.Next = m_contactList;
            if (m_contactList != null)
            {
                m_contactList.Prev = c;
            }
            m_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.SetAwake(true);
            bodyB.SetAwake(true);

            ++m_contactCount;
        }
Esempio n. 11
0
        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)
            {
                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 && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

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

            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
            bodyA.SetAwake(true);
            bodyB.SetAwake(true);

            ++m_contactCount;
        }
Esempio n. 12
0
        public void AddPair(ref b2FixtureProxy proxyA, ref b2FixtureProxy proxyB)
        {
            b2Fixture fixtureA = proxyA.fixture;
            b2Fixture fixtureB = proxyB.fixture;

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

            b2Body bodyA = fixtureA.Body;
            b2Body 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?
            b2ContactEdge edge = bodyB.ContactList;

            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    b2Fixture fA = edge.Contact.FixtureA;
                    b2Fixture fB = edge.Contact.FixtureB;
                    int       iA = edge.Contact.m_indexA;
                    int       iB = edge.Contact.m_indexB;

                    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))
            {
                return;
            }

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

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

            if (c == null)
            {
                return;
            }

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

            // Insert into the world.
            c.Prev = null;
            c.Next = m_contactList;
            if (m_contactList != null)
            {
                m_contactList.Prev = c;
            }
            m_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.SetAwake(true);
            bodyB.SetAwake(true);

            ++m_contactCount;
        }