A fixture is used to attach a shape to a body for collision detection. A fixture inherits its transform from its parent. Fixtures hold additional non-geometric data such as friction, collision filters, etc. Fixtures are created via Body::CreateFixture.
Beispiel #1
0
 public Fixture()
 {
     m_userData = null;
     m_body = null;
     m_next = null;
     m_proxies = null;
     m_proxyCount = 0;
     m_shape = null;
     m_filter = new Filter();
 }
Beispiel #2
0
        /// <summary>
        /// Return true if contact calculations should be performed between these two shapes.
        /// </summary>
        /// <warning>
        /// for performance reasons this is only called when the AABBs begin to overlap.
        /// </warning>
        /// <param name="fixtureA"></param>
        /// <param name="fixtureB"></param>
        /// <returns></returns>
        public virtual bool shouldCollide(Fixture fixtureA, Fixture fixtureB)
        {
            Filter filterA = fixtureA.FilterData;
            Filter filterB = fixtureB.FilterData;

            if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0)
            {
                return filterA.groupIndex > 0;
            }

            bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0;
            return collide;
        }
Beispiel #3
0
        /// <summary>
        /// Return true if contact calculations should be performed between these two shapes.
        /// </summary>
        /// <warning>
        /// for performance reasons this is only called when the AABBs begin to overlap.
        /// </warning>
        /// <param name="fixtureA"></param>
        /// <param name="fixtureB"></param>
        /// <returns></returns>
        public bool ShouldCollide(Fixture fixtureA, Fixture fixtureB)
        {
            var filterA = fixtureA.FilterData;
            var filterB = fixtureB.FilterData;

            if (filterA.GroupIndex == filterB.GroupIndex && filterA.GroupIndex != 0)
            {
                return filterA.GroupIndex > 0;
            }

            bool collide = (filterA.MaskBits & filterB.CategoryBits) != 0 && (filterA.CategoryBits & filterB.MaskBits) != 0;
            return collide;
        }
Beispiel #4
0
        public virtual Contact popContact(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB)
        {
            ShapeType type1 = fixtureA.Type;
            ShapeType type2 = fixtureB.Type;

            ContactRegister reg = contactStacks[(int)type1][(int)type2];
            IDynamicStack<Contact> creator = reg.creator;

            if (creator != null)
            {
                if (reg.primary)
                {
                    Contact c = creator.pop();
                    c.init(fixtureA, indexA, fixtureB, indexB);
                    return c;
                }
                else
                {
                    Contact c = creator.pop();
                    c.init(fixtureB, indexB, fixtureA, indexA);
                    return c;
                }
            }
            else
            {
                return null;
            }
        }
Beispiel #5
0
        private void drawShape(Fixture fixture, Transform xf, Color3f color)
        {
            switch (fixture.Type)
            {

                case ShapeType.CIRCLE:
                    {
                        CircleShape circle = (CircleShape)fixture.Shape;

                        // Vec2 center = Mul(xf, circle.m_p);
                        Transform.mulToOutUnsafe(xf, circle.m_p, center);
                        float radius = circle.m_radius;
                        xf.q.getXAxis(axis);

                        if (fixture.UserData != null && fixture.UserData.Equals(LIQUID_INT))
                        {
                            Body b = fixture.Body;
                            liquidOffset.set_Renamed(b.m_linearVelocity);
                            float linVelLength = b.m_linearVelocity.length();
                            if (averageLinearVel == -1)
                            {
                                averageLinearVel = linVelLength;
                            }
                            else
                            {
                                averageLinearVel = .98f * averageLinearVel + .02f * linVelLength;
                            }
                            liquidOffset.mulLocal(liquidLength / averageLinearVel / 2);
                            circCenterMoved.set_Renamed(center).addLocal(liquidOffset);
                            center.subLocal(liquidOffset);
                            m_debugDraw.drawSegment(center, circCenterMoved, liquidColor);
                            return;
                        }

                        m_debugDraw.drawSolidCircle(center, radius, axis, color);
                    }
                    break;

                case ShapeType.POLYGON:
                    {
                        PolygonShape poly = (PolygonShape)fixture.Shape;
                        int vertexCount = poly.m_count;
                        Debug.Assert(vertexCount <= Settings.maxPolygonVertices);
                        Vec2[] vertices = tlvertices.get_Renamed(Settings.maxPolygonVertices);

                        for (int i = 0; i < vertexCount; ++i)
                        {
                            // vertices[i] = Mul(xf, poly.m_vertices[i]);
                            Transform.mulToOutUnsafe(xf, poly.m_vertices[i], vertices[i]);
                        }

                        m_debugDraw.drawSolidPolygon(vertices, vertexCount, color);
                    }
                    break;

                case ShapeType.EDGE:
                    {
                        EdgeShape edge = (EdgeShape)fixture.Shape;
                        Transform.mulToOutUnsafe(xf, edge.m_vertex1, v1);
                        Transform.mulToOutUnsafe(xf, edge.m_vertex2, v2);
                        m_debugDraw.drawSegment(v1, v2, color);
                    }
                    break;

                case ShapeType.CHAIN:
                    {
                        ChainShape chain = (ChainShape)fixture.Shape;
                        int count = chain.m_count;
                        Vec2[] vertices = chain.m_vertices;

                        Transform.mulToOutUnsafe(xf, vertices[0], v1);
                        for (int i = 1; i < count; ++i)
                        {
                            Transform.mulToOutUnsafe(xf, vertices[i], v2);
                            m_debugDraw.drawSegment(v1, v2, color);
                            m_debugDraw.drawCircle(v1, 0.05f, color);
                            v1.set_Renamed(v2);
                        }
                    }
                    break;

                default:
                    break;

            }
        }
Beispiel #6
0
        public Body(BodyDef bd, World world)
        {
            Debug.Assert(bd.position.Valid);
            Debug.Assert(bd.linearVelocity.Valid);
            Debug.Assert(bd.gravityScale >= 0.0f);
            Debug.Assert(bd.angularDamping >= 0.0f);
            Debug.Assert(bd.linearDamping >= 0.0f);

            m_flags = 0;

            if (bd.bullet)
            {
                m_flags |= e_bulletFlag;
            }
            if (bd.fixedRotation)
            {
                m_flags |= e_fixedRotationFlag;
            }
            if (bd.allowSleep)
            {
                m_flags |= e_autoSleepFlag;
            }
            if (bd.awake)
            {
                m_flags |= e_awakeFlag;
            }
            if (bd.active)
            {
                m_flags |= e_activeFlag;
            }

            m_world = world;

            m_xf.p.set_Renamed(bd.position);
            m_xf.q.set_Renamed(bd.angle);

            m_sweep.localCenter.setZero();
            m_sweep.c0.set_Renamed(m_xf.p);
            m_sweep.c.set_Renamed(m_xf.p);
            m_sweep.a0 = bd.angle;
            m_sweep.a = bd.angle;
            m_sweep.alpha0 = 0.0f;

            m_jointList = null;
            m_contactList = null;
            m_prev = null;
            m_next = null;

            m_linearVelocity.set_Renamed(bd.linearVelocity);
            m_angularVelocity = bd.angularVelocity;

            m_linearDamping = bd.linearDamping;
            m_angularDamping = bd.angularDamping;
            m_gravityScale = bd.gravityScale;

            m_force.setZero();
            m_torque = 0.0f;

            m_sleepTime = 0.0f;

            m_type = bd.type;

            if (m_type == BodyType.DYNAMIC)
            {
                m_mass = 1f;
                m_invMass = 1f;
            }
            else
            {
                m_mass = 0f;
                m_invMass = 0f;
            }

            m_I = 0.0f;
            m_invI = 0.0f;

            m_userData = bd.userData;

            m_fixtureList = null;
            m_fixtureCount = 0;
        }
Beispiel #7
0
        /// <summary>
        /// Destroy a fixture. This removes the fixture from the broad-phase and destroys all contacts
        /// associated with this fixture. This will automatically adjust the mass of the body if the body
        /// is dynamic and the fixture has positive density. All fixtures attached to a body are implicitly
        /// destroyed when the body is destroyed.
        /// </summary>
        /// <param name="fixture">the fixture to be removed.</param>
        /// <warning>This function is locked during callbacks.</warning>
        public void destroyFixture(Fixture fixture)
        {
            Debug.Assert(m_world.Locked == false);
            if (m_world.Locked == true)
            {
                return;
            }

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

            // Remove the fixture from this body's singly linked list.
            Debug.Assert(m_fixtureCount > 0);
            Fixture node = m_fixtureList;
            Fixture last = null; // java change
            bool found = false;
            while (node != null)
            {
                if (node == fixture)
                {
                    node = fixture.m_next;
                    found = true;
                    break;
                }
                last = node;
                node = node.m_next;
            }

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

            // java change, remove it from the list
            if (last == null)
            {
                m_fixtureList = fixture.m_next;
            }
            else
            {
                last.m_next = fixture.m_next;
            }

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

                Fixture fixtureA = c.FixtureA;
                Fixture fixtureB = c.FixtureB;

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

            if ((m_flags & e_activeFlag) == e_activeFlag)
            {
                BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
                fixture.destroyProxies(broadPhase);
            }

            fixture.destroy();
            fixture.m_body = null;
            fixture.m_next = null;
            fixture = null;

            --m_fixtureCount;

            // Reset the mass data.
            resetMassData();
        }
Beispiel #8
0
        // TODO djm: check out about this new fixture here
        /// <summary>
        /// Creates a fixture and attach it to this body. Use this function if you need to set some fixture
        /// parameters, like friction. Otherwise you can create the fixture directly from a shape. If the
        /// density is non-zero, this function automatically updates the mass of the body. Contacts are not
        /// created until the next time step.
        /// </summary>
        /// <param name="def">the fixture definition.</param>
        /// <warning>This function is locked during callbacks.</warning>
        public Fixture createFixture(FixtureDef def)
        {
            Debug.Assert(m_world.Locked == false);

            if (m_world.Locked == true)
            {
                return null;
            }

            // djm TODO from pool?
            Fixture fixture = new Fixture();
            fixture.create(this, def);

            if ((m_flags & e_activeFlag) == e_activeFlag)
            {
                BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
                fixture.createProxies(broadPhase, m_xf);
            }

            fixture.m_next = m_fixtureList;
            m_fixtureList = fixture;
            ++m_fixtureCount;

            fixture.m_body = this;

            // Adjust mass properties if needed.
            if (fixture.m_density > 0.0f)
            {
                resetMassData();
            }

            // Let the world know we have a new fixture. This will cause new contacts
            // to be created at the beginning of the next time step.
            m_world.m_flags |= World.NEW_FIXTURE;

            return fixture;
        }
Beispiel #9
0
        private void DrawShape(Fixture fixture, Transform xf, Color3f color)
        {
            switch (fixture.Type)
            {

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

                        // Vec2 center = Mul(xf, circle.m_p);
                        Transform.MulToOutUnsafe(xf, circle.P, center);
                        float radius = circle.Radius;
                        xf.Q.GetXAxis(axis);

                        if (fixture.UserData != null && fixture.UserData.Equals(LIQUID_INT))
                        {
                            Body b = fixture.Body;
                            liquidOffset.Set(b.LinearVelocity);
                            float linVelLength = b.LinearVelocity.Length();
                            if (averageLinearVel == -1)
                            {
                                averageLinearVel = linVelLength;
                            }
                            else
                            {
                                averageLinearVel = .98f * averageLinearVel + .02f * linVelLength;
                            }
                            liquidOffset.MulLocal(LIQUID_LENGTH / averageLinearVel / 2);
                            circCenterMoved.Set(center).AddLocal(liquidOffset);
                            center.SubLocal(liquidOffset);
                            DebugDraw.DrawSegment(center, circCenterMoved, liquidColor);
                            return;
                        }

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

                case ShapeType.Polygon:
                    {
                        PolygonShape poly = (PolygonShape)fixture.Shape;
                        int vertexCount = poly.VertexCount;
                        Debug.Assert(vertexCount <= Settings.MAX_POLYGON_VERTICES);
                        Vec2[] vertices = tlvertices.Get(Settings.MAX_POLYGON_VERTICES);

                        for (int i = 0; i < vertexCount; ++i)
                        {
                            // vertices[i] = Mul(xf, poly.m_vertices[i]);
                            Transform.MulToOutUnsafe(xf, poly.Vertices[i], vertices[i]);
                        }

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

                case ShapeType.Edge:
                    {
                        EdgeShape edge = (EdgeShape)fixture.Shape;
                        Transform.MulToOutUnsafe(xf, edge.Vertex1, v1);
                        Transform.MulToOutUnsafe(xf, edge.Vertex2, v2);
                        DebugDraw.DrawSegment(v1, v2, color);
                    }
                    break;

                case ShapeType.Chain:
                    {
                        ChainShape chain = (ChainShape)fixture.Shape;
                        int count = chain.Count;
                        Vec2[] vertices = chain.Vertices;

                        Transform.MulToOutUnsafe(xf, vertices[0], v1);
                        for (int i = 1; i < count; ++i)
                        {
                            Transform.MulToOutUnsafe(xf, vertices[i], v2);
                            DebugDraw.DrawSegment(v1, v2, color);
                            DebugDraw.DrawCircle(v1, 0.05f, color);
                            v1.Set(v2);
                        }
                    }
                    break;
            }
        }
Beispiel #10
0
        public virtual void destroy()
        {
            // The proxies must be destroyed before calling this.
            Debug.Assert(m_proxyCount == 0);

            // Free the child shape.
            m_shape = null;
            m_proxies = null;
            m_next = null;

            // TODO pool shapes
            // TODO pool fixtures
        }
Beispiel #11
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;
        }
Beispiel #12
0
        // TODO djm: check out about this new fixture here
        /// <summary>
        /// Creates a fixture and attach it to this body. Use this function if you need to set some fixture
        /// parameters, like friction. Otherwise you can create the fixture directly from a shape. If the
        /// density is non-zero, this function automatically updates the mass of the body. Contacts are not
        /// created until the next time step.
        /// </summary>
        /// <param name="def">the fixture definition.</param>
        /// <warning>This function is locked during callbacks.</warning>
        public Fixture CreateFixture(FixtureDef def)
        {
            Debug.Assert(World.Locked == false);

            if (World.Locked == true)
            {
                return null;
            }

            // djm TODO from pool?
            Fixture fixture = new Fixture();
            fixture.Create(this, def);

            if ((Flags & TypeFlags.Active) == TypeFlags.Active)
            {
                BroadPhase broadPhase = World.ContactManager.BroadPhase;
                fixture.CreateProxies(broadPhase, Xf);
            }

            fixture.Next = FixtureList;
            FixtureList = fixture;
            ++FixtureCount;

            fixture.Body = this;

            // Adjust mass properties if needed.
            if (fixture.Density > 0.0f)
            {
                ResetMassData();
            }

            // Let the world know we have a new fixture. This will cause new contacts
            // to be created at the beginning of the next time step.
            World.Flags |= World.NEW_FIXTURE;

            return fixture;
        }