Ejemplo n.º 1
0
 internal Fixture()
 {
     _userData = null;
     _body = null;
     _next = null;
     _proxyId = BroadPhase.NullProxy;
     _shape = null;
 }
Ejemplo n.º 2
0
 internal PolygonAndCircleContact(Fixture fixtureA, Fixture fixtureB)
     : base(fixtureA, fixtureB)
 {
     Debug.Assert(_fixtureA.ShapeType == ShapeType.Polygon);
     Debug.Assert(_fixtureB.ShapeType == ShapeType.Circle);
 }
Ejemplo n.º 3
0
        // Broad-phase callback.
        internal void AddPair(Fixture proxyUserDataA, Fixture proxyUserDataB)
        {
            Fixture fixtureA = proxyUserDataA;
            Fixture fixtureB = proxyUserDataB;

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

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

            // Are both bodies static?
            if (bodyA.IsStatic && bodyB.IsStatic)
            {
                return;
            }

            // Does a contact already exist?
            ContactEdge edge = bodyB.GetConactList();
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.GetFixtureA();
                    Fixture fB = edge.Contact.GetFixtureB();
                    if (fA == fixtureA && fB == fixtureB)
                    {
                        // A contact already exists.
                        return;
                    }

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

                edge = edge.Next;
            }

            // Does a joint override collision?
            if (bodyB.IsConnected(bodyA))
            {
                return;
            }

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

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

            // Contact creation may swap fixtures.
            fixtureA = c.GetFixtureA();
            fixtureB = c.GetFixtureB();
            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;
        }
Ejemplo n.º 4
0
        // We need separation create/destroy functions from the ructor/destructor because
        // the destructor cannot access the allocator or broad-phase (no destructor arguments allowed by C++).
        internal void Create(BroadPhase broadPhase, Body body, ref XForm xf, FixtureDef def)
        {
            _userData = def.userData;
            _friction = def.friction;
            _restitution = def.restitution;
            _density = def.density;

            _body = body;
            _next = null;

            _filter = def.filter;

            _isSensor = def.isSensor;

            _shape = def.shape.Clone();

            // Create proxy in the broad-phase.
            AABB aabb;
            _shape.ComputeAABB(out aabb, ref xf);

            _proxyId = broadPhase.CreateProxy(ref aabb, this);
        }
Ejemplo n.º 5
0
        internal XForm _xf; // the body origin transform

        #endregion Fields

        #region Constructors

        internal Body(BodyDef bd, World world)
        {
            _flags = 0;

            if (bd.isBullet)
            {
                _flags |= BodyFlags.Bullet;
            }
            if (bd.fixedRotation)
            {
                _flags |= BodyFlags.FixedRotation;
            }
            if (bd.allowSleep)
            {
                _flags |= BodyFlags.AllowSleep;
            }
            if (bd.isSleeping)
            {
                _flags |= BodyFlags.Sleep;
            }

            _world = world;

            _xf.Position = bd.position;
            _xf.R.Set(bd.angle);

            _sweep.localCenter = bd.massData.center;
            _sweep.t0 = 1.0f;
            _sweep.a0 = _sweep.a = bd.angle;
            _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);

            _jointList = null;
            _contactList = null;
            _prev = null;
            _next = null;

            _linearVelocity = bd.linearVelocity;
            _angularVelocity = bd.angularVelocity;

            _linearDamping = bd.linearDamping;
            _angularDamping = bd.angularDamping;

            _force = new Vector2(0.0f, 0.0f);
            _torque = 0.0f;

            _linearVelocity = Vector2.Zero;
            _angularVelocity = 0.0f;

            _sleepTime = 0.0f;

            _invMass = 0.0f;
            _I = 0.0f;
            _invI = 0.0f;

            _mass = bd.massData.mass;

            if (_mass > 0.0f)
            {
                _invMass = 1.0f / _mass;
            }

            _I = bd.massData.i;

            if (_I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0)
            {
                _invI = 1.0f / _I;
            }

            if (_invMass == 0.0f && _invI == 0.0f)
            {
                _type = BodyType.Static;
            }
            else
            {
                _type = BodyType.Dynamic;
            }

            _userData = bd.userData;

            _fixtureList = null;
            _fixtureCount = 0;
        }
Ejemplo n.º 6
0
        /// Destroy a fixture. This removes the fixture from the broad-phase and
        /// therefore destroys any contacts associated with this fixture. All fixtures
        /// attached to a body are implicitly destroyed when the body is destroyed.
        /// @param fixture the fixture to be removed.
        /// @warning This function is locked during callbacks.
        public void DestroyFixture(Fixture fixture)
        {
            Debug.Assert(_world.IsLocked == false);
            if (_world.IsLocked == true)
            {
                return;
            }

            Debug.Assert(fixture._body == this);

            // Remove the fixture from this body's singly linked list.
            Debug.Assert(_fixtureCount > 0);
            Fixture node = _fixtureList;
            bool found = false;
            while (node != null)
            {
                if (node == fixture)
                {
                    _fixtureList = fixture._next;
                    found = true;
                    break;
                }

                node = node._next;
            }

            // You tried to remove a shape that is not attached to this body.
            Debug.Assert(found);

            // Destroy any contacts associated with the fixture.
            ContactEdge edge = _contactList;
            while (edge != null)
            {
                Contact c = edge.Contact;
                edge = edge.Next;

                Fixture fixtureA = c.GetFixtureA();
                Fixture fixtureB = c.GetFixtureB();

                if (fixture == fixtureA || fixture == fixtureB)
                {
                    // This destroys the contact and removes it from
                    // this body's contact list.
                    _world._contactManager.Destroy(c);
                }
            }

            BroadPhase broadPhase = _world._contactManager._broadPhase;

            fixture.Destroy(broadPhase);
            fixture._body = null;
            fixture._next = null;
            --_fixtureCount;
        }
Ejemplo n.º 7
0
        /// Creates a fixture from a shape and attach it to this body.
        /// This is a convenience function. Use FixtureDef if you need to set parameters
        /// like friction, restitution, user data, or filtering.
        /// @param shape the shape to be cloned.
        /// @param density the shape density (set to zero for static bodies).
        /// @warning This function is locked during callbacks.
        public Fixture CreateFixture(Shape shape, float density)
        {
            Debug.Assert(_world.IsLocked == false);
            if (_world.IsLocked == true)
            {
                return null;
            }

            BroadPhase broadPhase = _world._contactManager._broadPhase;

            FixtureDef def = new FixtureDef();
            def.shape = shape;
            def.density = density;

            Fixture fixture = new Fixture();
            fixture.Create(broadPhase, this, ref _xf, def);

            fixture._next = _fixtureList;
            _fixtureList = fixture;
            ++_fixtureCount;

            fixture._body = this;

            // Let the world know we have a new fixture.
            _world._flags |= WorldFlags.NewFixture;

            return fixture;
        }
Ejemplo n.º 8
0
        void DrawShape(Fixture fixture, XForm xf, Color color)
        {
            Color coreColor = ColorEx.FromScRgb(0.9f, 0.6f, 0.6f);

            switch (fixture.ShapeType)
            {
            case ShapeType.Circle:
                {
                    CircleShape circle = (CircleShape)fixture.GetShape();

                    Vector2 center = MathUtils.Multiply(ref xf, circle._p);
                    float radius = circle._radius;
                    Vector2 axis = xf.R.col1;

                    DebugDraw.DrawSolidCircle(center, radius, axis, color);
                }
                break;

            case ShapeType.Polygon:
                {
                    PolygonShape poly = (PolygonShape)fixture.GetShape();
                    int vertexCount = poly._vertexCount;
                    Debug.Assert(vertexCount <= Settings.b2_maxPolygonVertices);
                    FixedArray8<Vector2> vertices = new FixedArray8<Vector2>();

                    for (int i = 0; i < vertexCount; ++i)
                    {
                        vertices[i] = MathUtils.Multiply(ref xf, poly._vertices[i]);
                    }

                    DebugDraw.DrawSolidPolygon(ref vertices, vertexCount, color);
                }
                break;
            }
        }