예제 #1
0
        internal void Synchronize(BroadPhase broadPhase, ref Transform transform1, ref Transform transform2)
        {
            if (_proxyCount == 0)
            {
                return;
            }

            for (int i = 0; i < _proxyCount; ++i)
            {
                FixtureProxy proxy = _proxies[i];

                // Compute an AABB that covers the swept Shape (may miss some rotation effect).
                AABB 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);

                Vector2 displacement = transform2.Position - transform1.Position;

                broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, displacement);
            }
        }
예제 #2
0
	    // We need separation create/destroy functions from the constructor/destructor because
	    // the destructor cannot access the allocator or broad-phase (no destructor arguments allowed by C++).
	    internal void Create(Body body, FixtureDef def)
        {
            _userData = def.userData;
	        _friction = def.friction;
	        _restitution = def.restitution;

	        _body = body;
	        _next = null;

	        _filter = def.filter;

	        _isSensor = def.isSensor;

	        _shape = def.shape.Clone();

            // Reserve proxy space
	        int childCount = _shape.GetChildCount();
	        _proxies = new FixtureProxy[childCount];
	        for (int i = 0; i < childCount; ++i)
	        {
                _proxies[i] = new FixtureProxy();
		        _proxies[i].fixture = null;
		        _proxies[i].proxyId = BroadPhase.NullProxy;
	        }
	        _proxyCount = 0;

            _density = def.density;
        }
예제 #3
0
        // Broad-phase callback.
        internal void AddPair(FixtureProxy proxyA, FixtureProxy proxyB)
        {
            Fixture fixtureA = proxyA.fixture;
            Fixture fixtureB = proxyB.fixture;

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

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

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

            // Does a contact already exist?
            ContactEdge edge = bodyB.GetContactList();

            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.GetFixtureA();
                    Fixture 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 (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

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

            // 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._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;

            ++_contactCount;
        }
예제 #4
0
        bool QueryAABBCallbackWrapper(int proxyId)
        {
            FixtureProxy proxy = (FixtureProxy)_contactManager._broadPhase.GetUserData(proxyId);

            return(_queryAABBCallback(proxy));
        }
예제 #5
0
        /// Call this to draw shapes and other debug draw data.
        public void DrawDebugData()
        {
            if (DebugDraw == null)
            {
                return;
            }

            DebugDrawFlags flags = DebugDraw.Flags;

            if ((flags & DebugDrawFlags.Shape) == DebugDrawFlags.Shape)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        if (b.IsActive() == false)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.3f));
                        }
                        else if (b.GetType() == BodyType.Static)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.9f, 0.5f));
                        }
                        else if (b.GetType() == BodyType.Kinematic)
                        {
                            DrawShape(f, xf, new Color(0.5f, 0.5f, 0.9f));
                        }
                        else if (b.IsAwake() == false)
                        {
                            DrawShape(f, xf, new Color(0.6f, 0.6f, 0.6f));
                        }
                        else
                        {
                            DrawShape(f, xf, new Color(0.9f, 0.7f, 0.7f));
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.Joint) == DebugDrawFlags.Joint)
            {
                for (Joint j = _jointList; j != null; j = j.GetNext())
                {
                    DrawJoint(j);
                }
            }

            if ((flags & DebugDrawFlags.Pair) == DebugDrawFlags.Pair)
            {
                Color color = new Color(0.3f, 0.9f, 0.9f);
                for (Contact c = _contactManager._contactList; c != null; c = c.GetNext())
                {
                    /*
                     * Fixture fixtureA = c.GetFixtureA();
                     * Fixture fixtureB = c.GetFixtureB();
                     *
                     * AABB aabbA;
                     * AABB aabbB;
                     * fixtureA.GetAABB(out aabbA);
                     * fixtureB.GetAABB(out aabbB);
                     *
                     * Vector2 cA = aabbA.GetCenter();
                     * Vector2 cB = aabbB.GetCenter();
                     *
                     * DebugDraw.DrawSegment(cA, cB, color);
                     */
                }
            }

            if ((flags & DebugDrawFlags.AABB) == DebugDrawFlags.AABB)
            {
                Color      color = new Color(0.9f, 0.3f, 0.9f);
                BroadPhase bp    = _contactManager._broadPhase;

                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    if (b.IsActive() == false)
                    {
                        continue;
                    }

                    for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext())
                    {
                        for (int i = 0; i < f._proxyCount; ++i)
                        {
                            FixtureProxy proxy = f._proxies[i];
                            AABB         aabb;
                            bp.GetFatAABB(proxy.proxyId, out aabb);
                            FixedArray8 <Vector2> vs = new FixedArray8 <Vector2>();
                            vs[0] = new Vector2(aabb.lowerBound.X, aabb.lowerBound.Y);
                            vs[1] = new Vector2(aabb.upperBound.X, aabb.lowerBound.Y);
                            vs[2] = new Vector2(aabb.upperBound.X, aabb.upperBound.Y);
                            vs[3] = new Vector2(aabb.lowerBound.X, aabb.upperBound.Y);

                            DebugDraw.DrawPolygon(ref vs, 4, color);
                        }
                    }
                }
            }

            if ((flags & DebugDrawFlags.CenterOfMass) == DebugDrawFlags.CenterOfMass)
            {
                for (Body b = _bodyList; b != null; b = b.GetNext())
                {
                    Transform xf;
                    b.GetTransform(out xf);
                    xf.Position = b.GetWorldCenter();
                    DebugDraw.DrawTransform(ref xf);
                }
            }
        }
예제 #6
0
        // Broad-phase callback.
        internal void AddPair(FixtureProxy proxyA, FixtureProxy proxyB)
        {
            Fixture fixtureA = proxyA.fixture;
            Fixture fixtureB = proxyB.fixture;

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

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

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

            // Does a contact already exist?
            ContactEdge edge = bodyB.GetContactList();
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.GetFixtureA();
                    Fixture 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 (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

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

            // 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._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;

            ++_contactCount;
        }