Ejemplo n.º 1
0
        public b2ContactEdge GetContactList()
        {
            global::System.IntPtr cPtr = Box2DPINVOKE.b2Body_GetContactList__SWIG_0(swigCPtr);
            b2ContactEdge         ret  = (cPtr == global::System.IntPtr.Zero) ? null : new b2ContactEdge(cPtr, false);

            return(ret);
        }
Ejemplo n.º 2
0
        /**
         * Set if this fixture is a sensor.
         */
        public void SetSensor(bool sensor)
        {
            if (m_isSensor == sensor)
            {
                return;
            }

            m_isSensor = sensor;

            if (m_body == null)
            {
                return;
            }

            b2ContactEdge edge = m_body.GetContactList();

            while (edge != null)
            {
                b2Contact contact  = edge.contact;
                b2Fixture fixtureA = contact.GetFixtureA();
                b2Fixture fixtureB = contact.GetFixtureB();
                if (fixtureA == this || fixtureB == this)
                {
                    contact.SetSensor(fixtureA.IsSensor() || fixtureB.IsSensor());
                }
                edge = edge.next;
            }
        }
Ejemplo n.º 3
0
    /// Set the type of this body. This may alter the mass and velocity.
    public void SetType(BodyType type)
    {
        Debug.Assert(m_world.IsLocked() == false);
        if (m_world.IsLocked() == true)
        {
            return;
        }

        if (m_type == type)
        {
            return;
        }

        m_type = type;

        ResetMassData();

        if (m_type == BodyType.b2_staticBody)
        {
            m_linearVelocity.SetZero();
            m_angularVelocity = 0.0f;
            m_sweep.a0        = m_sweep.a;


            m_sweep.c0 = m_sweep.c;
            SynchronizeFixtures();
        }

        SetAwake(true);

        m_force.SetZero();
        m_torque = 0.0f;

        // Delete the attached contacts.
        b2ContactEdge ce = m_contactList;

        while (ce != null)
        {
            b2ContactEdge ce0 = ce;
            ce = ce.next;
            m_world.m_contactManager.Destroy(ce0.contact);
        }
        m_contactList = null;

        // Touch the proxies so that new contacts will be created (when appropriate)
        b2BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;

        for (b2Fixture f = m_fixtureList; f != null; f = f.m_next)
        {
            int proxyCount = f.m_proxyCount;
            for (int i = 0; i < proxyCount; ++i)
            {
                broadPhase.TouchProxy(f.m_proxies[i].proxyId);
            }
        }
    }
Ejemplo n.º 4
0
    /// Set the active state of the body. An inactive body is not
    /// simulated and cannot be collided with or woken up.
    /// If you pass a flag of true, all fixtures will be added to the
    /// broad-phase.
    /// If you pass a flag of false, all fixtures will be removed from
    /// the broad-phase and all contacts will be destroyed.
    /// Fixtures and joints are otherwise unaffected. You may continue
    /// to create/destroy fixtures and joints on inactive bodies.
    /// Fixtures on an inactive body are implicitly inactive and will
    /// not participate in collisions, ray-casts, or queries.
    /// Joints connected to an inactive body are implicitly inactive.
    /// An inactive body is still owned by a b2World object and remains
    /// in the body list.
    public void SetActive(bool flag)
    {
        Debug.Assert(m_world.IsLocked() == false);

        if (flag == IsActive())
        {
            return;
        }

        if (flag)
        {
            m_flags |= BodyFlags.e_activeFlag;

            // Create all proxies.
            b2BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
            for (b2Fixture f = m_fixtureList; f != null; f = f.m_next)
            {
                f.CreateProxies(broadPhase, m_xf);
            }

            // Contacts are created the next time step.
        }
        else
        {
            m_flags &= ~BodyFlags.e_activeFlag;

            // Destroy all proxies.
            b2BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase;
            for (b2Fixture f = m_fixtureList; f != null; f = f.m_next)
            {
                f.DestroyProxies(broadPhase);
            }

            // Destroy the attached contacts.
            b2ContactEdge ce = m_contactList;
            while (ce != null)
            {
                b2ContactEdge ce0 = ce;
                ce = ce.next;
                m_world.m_contactManager.Destroy(ce0.contact);
            }
            m_contactList = null;
        }
    }
Ejemplo n.º 5
0
        public virtual void SetActive(bool flag)
        {
            if (flag == IsActive())
            {
                return;
            }

            if (flag)
            {
                m_flags |= b2BodyFlags.e_activeFlag;

                // Create all proxies.
                b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
                for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
                {
                    f.CreateProxies(broadPhase, m_xf);
                }

                // Contacts are created the next time step.
            }
            else
            {
                m_flags &= ~b2BodyFlags.e_activeFlag;

                // Destroy all proxies.
                b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
                for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
                {
                    f.DestroyProxies(broadPhase);
                }

                // Destroy the attached contacts.
                b2ContactEdge ce = m_contactList;
                while (ce != null)
                {
                    b2ContactEdge ce0 = ce;
                    ce = ce.Next;
                    m_world.ContactManager.Destroy(ce0.Contact);
                }
                m_contactList = null;
            }
        }
Ejemplo n.º 6
0
        public virtual void Refilter()
        {
            if (m_body == null)
            {
                return;
            }

            // Flag associated contacts for filtering.
            b2ContactEdge edge = m_body.ContactList;

            while (edge != null)
            {
                b2Contact contact  = edge.Contact;
                b2Fixture fixtureA = contact.GetFixtureA();
                b2Fixture fixtureB = contact.GetFixtureB();
                if (fixtureA == this || fixtureB == this)
                {
                    contact.FlagForFiltering();
                }

                edge = edge.Next;
            }

            b2World world = m_body.World;

            if (world == null)
            {
                return;
            }

            // Touch each proxy so that new pairs may be created
            b2BroadPhase broadPhase = world.ContactManager.BroadPhase;

            for (int i = 0; i < m_proxyCount; ++i)
            {
                broadPhase.TouchProxy(m_proxies[i].proxyId);
            }
        }
Ejemplo n.º 7
0
        /**
         * Set the contact filtering data. This will not update contacts until the next time
         * step when either parent body is active and awake.
         */
        public void SetFilterData(b2FilterData filter)
        {
            m_filter = filter.Copy();

            if (m_body != null)
            {
                return;
            }

            b2ContactEdge edge = m_body.GetContactList();

            while (edge != null)
            {
                b2Contact contact  = edge.contact;
                b2Fixture fixtureA = contact.GetFixtureA();
                b2Fixture fixtureB = contact.GetFixtureB();
                if (fixtureA == this || fixtureB == this)
                {
                    contact.FlagForFiltering();
                }
                edge = edge.next;
            }
        }
Ejemplo n.º 8
0
        public b2Body(b2BodyDef bd, b2World world)
        {
            m_flags = 0;

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

            m_world = world;

            m_xf.p = bd.position;
            m_xf.q.Set(bd.angle);

            m_sweep.localCenter.SetZero();
            m_sweep.c0 = m_xf.p;
            m_sweep.c = 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 = 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 == b2BodyType.b2_dynamicBody)
            {
                m_mass = 1.0f;
                m_invMass = 1.0f;
            }
            else
            {
                m_mass = 0.0f;
                m_invMass = 0.0f;
            }

            m_I = 0.0f;
            m_invI = 0.0f;

            m_userData = bd.userData;

            m_fixtureList = null;
            m_fixtureCount = 0;
        }
Ejemplo n.º 9
0
        public virtual void DestroyFixture(b2Fixture fixture)
        {
            Debug.Assert(m_world.IsLocked == false);
            if (m_world.IsLocked)
            {
                return;
            }

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

            // Remove the fixture from this body's singly linked list.
            Debug.Assert(m_fixtureCount > 0);
            b2Fixture node  = m_fixtureList;
            bool      found = false;

            while (node != null)
            {
                if (node == fixture)
                {
                    node  = 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.
            b2ContactEdge edge = m_contactList;

            while (edge != null)
            {
                b2Contact c = edge.Contact;
                edge = edge.Next;

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

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


            if (m_flags.HasFlag(b2BodyFlags.e_activeFlag))
            {
                b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
                fixture.DestroyProxies(broadPhase);
            }

            fixture.Body = null;
            fixture.Next = null;

            --m_fixtureCount;

            // Reset the mass data.
            ResetMassData();
        }
Ejemplo n.º 10
0
        public b2Body(b2BodyDef bd, b2World world)
        {
            m_flags = 0;

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

            m_world = world;

            m_xf.p = bd.position;
            m_xf.q.Set(bd.angle);

            Sweep.localCenter.SetZero();
            Sweep.c0     = m_xf.p;
            Sweep.c      = m_xf.p;
            Sweep.a0     = bd.angle;
            Sweep.a      = bd.angle;
            Sweep.alpha0 = 0.0f;

            m_jointList   = null;
            m_contactList = null;
            Prev          = null;
            Next          = null;

            m_linearVelocity  = 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 == b2BodyType.b2_dynamicBody)
            {
                m_mass    = 1.0f;
                m_invMass = 1.0f;
            }
            else
            {
                m_mass    = 0.0f;
                m_invMass = 0.0f;
            }

            m_I    = 0.0f;
            m_invI = 0.0f;

            m_userData = bd.userData;

            m_fixtureList  = null;
            m_fixtureCount = 0;
        }
Ejemplo n.º 11
0
        // Find TOI contacts and solve them.
        public void SolveTOI(b2TimeStep step)
        {
            b2Island island = new b2Island(2 * b2Settings.b2_maxTOIContacts, b2Settings.b2_maxTOIContacts, 0, m_contactManager.ContactListener);

            if (m_stepComplete)
            {
                for (b2Body b = m_bodyList; b; b = b.Next)
                {
                    b.BodyFlags     &= ~b2Body.e_islandFlag;
                    b.m_sweep.alpha0 = 0.0f;
                }

                for (b2Contact c = m_contactManager.ContactList; c; c = c.Next)
                {
                    // Invalidate TOI
                    c.ContactFlags &= ~(b2ContactType.e_toiFlag | b2ContactType.e_islandFlag);
                    c.m_toiCount    = 0;
                    c.m_toi         = 1.0f;
                }
            }

            // Find TOI events and solve them.
            for (; ;)
            {
                // Find the first TOI.
                b2Contact minContact = null;
                float     minAlpha   = 1.0f;

                for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
                {
                    // Is this contact disabled?
                    if (c.IsEnabled() == false)
                    {
                        continue;
                    }

                    // Prevent excessive sub-stepping.
                    if (c.m_toiCount > b2Settings.b2_maxSubSteps)
                    {
                        continue;
                    }

                    float alpha = 1.0f;
                    if (c.ContactFlags.HasFlag(b2ContactFlags.e_toiFlag))
                    {
                        // This contact has a valid cached TOI.
                        alpha = c.m_toi;
                    }
                    else
                    {
                        b2Fixture fA = c.GetFixtureA();
                        b2Fixture fB = c.GetFixtureB();

                        // Is there a sensor?
                        if (fA.IsSensor || fB.IsSensor)
                        {
                            continue;
                        }

                        b2Body bA = fA.Body;
                        b2Body bB = fB.Body;

                        b2BodyType typeA = bA.BodyType;
                        b2BodyType typeB = bB.BodyType;

                        bool activeA = bA.IsAwake() && typeA != b2BodyType.b2_staticBody;
                        bool activeB = bB.IsAwake() && typeB != b2BodyType.b2_staticBody;

                        // Is at least one body active (awake and dynamic or kinematic)?
                        if (activeA == false && activeB == false)
                        {
                            continue;
                        }

                        bool collideA = bA.IsBullet() || typeA != b2BodyType.b2_dynamicBody;
                        bool collideB = bB.IsBullet() || typeB != b2BodyType.b2_dynamicBody;

                        // Are these two non-bullet dynamic bodies?
                        if (collideA == false && collideB == false)
                        {
                            continue;
                        }

                        // Compute the TOI for this contact.
                        // Put the sweeps onto the same time interval.
                        float alpha0 = bA.Sweep.alpha0;

                        if (bA.Sweep.alpha0 < bB.Sweep.alpha0)
                        {
                            alpha0 = bB.Sweep.alpha0;
                            bA.Sweep.Advance(alpha0);
                        }
                        else if (bB.Sweep.alpha0 < bA.Sweep.alpha0)
                        {
                            alpha0 = bA.Sweep.alpha0;
                            bB.Sweep.Advance(alpha0);
                        }

                        int indexA = c.GetChildIndexA();
                        int indexB = c.GetChildIndexB();

                        // Compute the time of impact in interval [0, minTOI]
                        b2TOIInput input = new b2TOIInput();
                        input.proxyA.Set(fA.Shape, indexA);
                        input.proxyB.Set(fB.Shape, indexB);
                        input.sweepA = bA.Sweep;
                        input.sweepB = bB.Sweep;
                        input.tMax   = 1.0f;

                        b2TOIOutput output = b2TimeOfImpact(input);

                        // Beta is the fraction of the remaining portion of the .
                        float beta = output.t;
                        if (output.state == b2TOIOutputType.e_touching)
                        {
                            alpha = b2Math.b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
                        }
                        else
                        {
                            alpha = 1.0f;
                        }

                        c.m_toi         = alpha;
                        c.ContactFlags |= b2ContactFlags.e_toiFlag;
                    }

                    if (alpha < minAlpha)
                    {
                        // This is the minimum TOI found so far.
                        minContact = c;
                        minAlpha   = alpha;
                    }
                }

                if (minContact == null || 1.0f - 10.0f * b2Settings.b2_epsilon < minAlpha)
                {
                    // No more TOI events. Done!
                    m_stepComplete = true;
                    break;
                }
                {
                    // Advance the bodies to the TOI.
                    b2Fixture fA = minContact.GetFixtureA();
                    b2Fixture fB = minContact.GetFixtureB();
                    b2Body    bA = fA.Body;
                    b2Body    bB = fB.Body;

                    b2Sweep backup1 = bA.Sweep;
                    b2Sweep backup2 = bB.Sweep;

                    bA.Advance(minAlpha);
                    bB.Advance(minAlpha);

                    // The TOI contact likely has some new contact points.
                    minContact.Update(m_contactManager.ContactListener);
                    minContact.ContactFlags &= ~b2ContactFlags.e_toiFlag;
                    ++minContact.m_toiCount;

                    // Is the contact solid?
                    if (minContact.IsEnabled() == false || minContact.IsTouching() == false)
                    {
                        // Restore the sweeps.
                        minContact.SetEnabled(false);
                        bA.Sweep = backup1;
                        bB.Sweep = backup2;
                        bA.SynchronizeTransform();
                        bB.SynchronizeTransform();
                        continue;
                    }

                    bA.SetAwake(true);
                    bB.SetAwake(true);

                    // Build the island
                    island.Clear();
                    island.Add(bA);
                    island.Add(bB);
                    island.Add(minContact);

                    bA.BodyFlags           |= b2BodyFlags.e_islandFlag;
                    bB.BodyFlags           |= b2BodyFlags.e_islandFlag;
                    minContact.ContentType |= b2ContactFlags.e_islandFlag;

                    // Get contacts on bodyA and bodyB.
                    b2Body[] bodies = new b2Body[] { bA, bB };
                    for (int i = 0; i < 2; ++i)
                    {
                        b2Body body = bodies[i];
                        if (body.BodyType == b2BodyType.b2_dynamicBody)
                        {
                            for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
                            {
                                if (island.BodyCount == island.BodyCapacity)
                                {
                                    break;
                                }

                                if (island.ContactCount == island.ContactCapacity)
                                {
                                    break;
                                }

                                b2Contact contact = ce.contact;

                                // Has this contact already been added to the island?
                                if (contact.ContactType & b2ContactType.e_islandFlag)
                                {
                                    continue;
                                }

                                // Only add static, kinematic, or bullet bodies.
                                b2Body other = ce.other;
                                if (other.BodyType == b2BodyType.b2_dynamicBody &&
                                    body.IsBullet() == false && other.IsBullet() == false)
                                {
                                    continue;
                                }

                                // Skip sensors.
                                bool sensorA = contact.m_fixtureA.m_isSensor;
                                bool sensorB = contact.m_fixtureB.m_isSensor;
                                if (sensorA || sensorB)
                                {
                                    continue;
                                }

                                // Tentatively advance the body to the TOI.
                                b2Sweep backup = other.Sweep;
                                if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
                                {
                                    other.Advance(minAlpha);
                                }

                                // Update the contact points
                                contact.Update(m_contactManager.ContactListener);

                                // Was the contact disabled by the user?
                                if (contact.IsEnabled() == false)
                                {
                                    other.Sweep = backup;
                                    other.SynchronizeTransform();
                                    continue;
                                }

                                // Are there contact points?
                                if (contact.IsTouching() == false)
                                {
                                    other.Sweep = backup;
                                    other.SynchronizeTransform();
                                    continue;
                                }

                                // Add the contact to the island
                                contact.ContactFlags |= b2ContactFlags.e_islandFlag;
                                island.Add(contact);

                                // Has the other body already been added to the island?
                                if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
                                {
                                    continue;
                                }

                                // Add the other body to the island.
                                other.BodyFlags |= b2BodyFlags.e_islandFlag;

                                if (other.BodyType != b2BodyType.b2_staticBody)
                                {
                                    other.SetAwake(true);
                                }

                                island.Add(other);
                            }
                        }
                    }

                    b2TimeStep subStep;
                    subStep.dt                 = (1.0f - minAlpha) * step.dt;
                    subStep.inv_dt             = 1.0f / subStep.dt;
                    subStep.dtRatio            = 1.0f;
                    subStep.positionIterations = 20;
                    subStep.velocityIterations = step.velocityIterations;
                    subStep.warmStarting       = false;
                    island.SolveTOI(subStep, bA.m_islandIndex, bB.m_islandIndex);

                    // Reset island flags and synchronize broad-phase proxies.
                    for (int i = 0; i < island.m_bodyCount; ++i)
                    {
                        b2Body body = island.m_bodies[i];
                        body.BodyFlags &= ~b2BodyFlags.e_islandFlag;

                        if (body.BodyType != b2BodyType.b2_dynamicBody)
                        {
                            continue;
                        }

                        body.SynchronizeFixtures();

                        // Invalidate all contact TOIs on this displaced body.
                        for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
                        {
                            ce.Contact.ContactFlags &= ~(b2ContactFlags.e_toiFlag | b2ContactFlags.e_islandFlag);
                        }
                    }

                    // Commit fixture proxy movements to the broad-phase so that new contacts are created.
                    // Also, some contacts can be destroyed.
                    m_contactManager.FindNewContacts();

                    if (m_subStepping)
                    {
                        m_stepComplete = false;
                        break;
                    }
                }
            }
        }
Ejemplo n.º 12
0
        // Find islands, integrate and solveraints, solve positionraints
        public void Solve(b2TimeStep step)
        {
            m_profile.solveInit     = 0.0f;
            m_profile.solveVelocity = 0.0f;
            m_profile.solvePosition = 0.0f;

            // Size the island for the worst case.
            b2Island island = new b2Island(m_bodyCount,
                                           m_contactManager.ContactCount,
                                           m_jointCount,
                                           m_contactManager.ContactListener);

            // Clear all the island flags.
            for (b2Body b = m_bodyList; b != null; b = b.Next)
            {
                b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
            }
            for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
            {
                c.ContactFlags &= ~b2ContactFlags.e_islandFlag;
            }
            for (b2Joint j = m_jointList; j; j = j.Next)
            {
                j.m_islandFlag = false;
            }

            // Build and simulate all awake islands.
            int stackSize = m_bodyCount;

            b2Body[] stack = new b2Body[stackSize];
            for (b2Body seed = m_bodyList; seed != null; seed = seed.Next)
            {
                if (seed.BodyFlags & b2BodyFlags.e_islandFlag)
                {
                    continue;
                }

                if (seed.IsAwake() == false || seed.IsActive() == false)
                {
                    continue;
                }

                // The seed can be dynamic or kinematic.
                if (seed.BodyType == b2BodyType.b2_staticBody)
                {
                    continue;
                }

                // Reset island and stack.
                island.Clear();
                int stackCount = 0;
                stack[stackCount++] = seed;
                seed.BodyFlags     |= b2BodyFlags.e_islandFlag;

                // Perform a depth first search (DFS) on theraint graph.
                while (stackCount > 0)
                {
                    // Grab the next body off the stack and add it to the island.
                    b2Body b = stack[--stackCount];
                    island.Add(b);

                    // Make sure the body is awake.
                    b.SetAwake(true);

                    // To keep islands as small as possible, we don't
                    // propagate islands across static bodies.
                    if (b.BodyType == b2BodyType.b2_staticBody)
                    {
                        continue;
                    }

                    // Search all contacts connected to this body.
                    for (b2ContactEdge ce = b.ContactList; ce != null; ce = ce.next)
                    {
                        b2Contact contact = ce.contact;

                        // Has this contact already been added to an island?
                        if (contact.ContactFlags & b2ContactFlags.e_islandFlag)
                        {
                            continue;
                        }

                        // Is this contact solid and touching?
                        if (contact.IsEnabled() == false ||
                            contact.IsTouching() == false)
                        {
                            continue;
                        }

                        // Skip sensors.
                        bool sensorA = contact.m_fixtureA.m_isSensor;
                        bool sensorB = contact.m_fixtureB.m_isSensor;
                        if (sensorA || sensorB)
                        {
                            continue;
                        }

                        island.Add(contact);
                        contact.ContactFlags |= b2ContactType.e_islandFlag;

                        b2Body other = ce.other;

                        // Was the other body already added to this island?
                        if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
                        {
                            continue;
                        }

                        stack[stackCount++] = other;
                        other.BodyFlags    |= b2BodyFlags.e_islandFlag;
                    }

                    // Search all joints connect to this body.
                    for (b2JointEdge je = b.JointList; je; je = je.next)
                    {
                        if (je.joint.IslandFlag == true)
                        {
                            continue;
                        }

                        b2Body other = je.other;

                        // Don't simulate joints connected to inactive bodies.
                        if (other.IsActive() == false)
                        {
                            continue;
                        }

                        island.Add(je.joint);
                        je.joint.m_islandFlag = true;

                        if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
                        {
                            continue;
                        }

                        stack[stackCount++] = other;
                        other.BodyFlags    |= b2BodyFlags.e_islandFlag;
                    }
                }

                b2Profile profile = island.Solve(step, m_gravity, m_allowSleep);
                m_profile.solveInit     += profile.solveInit;
                m_profile.solveVelocity += profile.solveVelocity;
                m_profile.solvePosition += profile.solvePosition;

                // Post solve cleanup.
                for (int i = 0; i < island.m_bodyCount; ++i)
                {
                    // Allow static bodies to participate in other islands.
                    b2Body b = island.m_bodies[i];
                    if (b.BodyType == b2BodyType.b2_staticBody)
                    {
                        b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
                    }
                }
            }

            {
                b2Timer timer;
                // Synchronize fixtures, check for out of range bodies.
                for (b2Body b = m_bodyList; b != null; b = b.Next)
                {
                    // If a body was not in an island then it did not move.
                    if ((b.BodyFlags & b2BodyType.e_islandFlag) == 0)
                    {
                        continue;
                    }

                    if (b.GetBodyType() == b2BodyType.b2_staticBody)
                    {
                        continue;
                    }

                    // Update fixtures (for broad-phase).
                    b.SynchronizeFixtures();
                }

                // Look for new contacts.
                m_contactManager.FindNewContacts();
                m_profile.broadphase = timer.GetMilliseconds();
            }
        }
Ejemplo n.º 13
0
        public void DestroyJoint(b2Joint j)
        {
            if (IsLocked())
            {
                return;
            }

            bool collideConnected = j.m_collideConnected;

            // Remove from the doubly linked list.
            if (j.Prev)
            {
                j.Prev.Next = j.Next;
            }

            if (j.Next)
            {
                j.Next.Prev = j.Prev;
            }

            if (j == m_jointList)
            {
                m_jointList = j.Next;
            }

            // Disconnect from island graph.
            b2Body bodyA = j.m_bodyA;
            b2Body bodyB = j.m_bodyB;

            // Wake up connected bodies.
            bodyA.SetAwake(true);
            bodyB.SetAwake(true);

            // Remove from body 1.
            if (j.m_edgeA.prev)
            {
                j.m_edgeA.prev.next = j.m_edgeA.next;
            }

            if (j.m_edgeA.next)
            {
                j.m_edgeA.next.prev = j.m_edgeA.prev;
            }

            if (j.m_edgeA == bodyA.JointList)
            {
                bodyA.JointList = j.m_edgeA.next;
            }

            j.m_edgeA.prev = null;
            j.m_edgeA.next = null;

            // Remove from body 2
            if (j.m_edgeB.prev)
            {
                j.m_edgeB.prev.next = j.m_edgeB.next;
            }

            if (j.m_edgeB.next)
            {
                j.m_edgeB.next.prev = j.m_edgeB.prev;
            }

            if (j.m_edgeB == bodyB.JointList)
            {
                bodyB.JointList = j.m_edgeB.next;
            }

            j.m_edgeB.prev = null;
            j.m_edgeB.next = null;

            b2Joint.Destroy(j);

            --m_jointCount;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (collideConnected == false)
            {
                b2ContactEdge edge = bodyB.ContactList;
                while (edge != null)
                {
                    if (edge.other == bodyA)
                    {
                        // Flag the contact for filtering at the next time step (where either
                        // body is awake).
                        edge.contact.FlagForFiltering();
                    }

                    edge = edge.next;
                }
            }
        }
Ejemplo n.º 14
0
        public b2Joint CreateJoint(b2JointDef def)
        {
            if (IsLocked())
            {
                return(null);
            }

            b2Joint j = b2Joint.Create(def);

            // Connect to the world list.
            j.Prev = null;
            j.Next = m_jointList;
            if (m_jointList)
            {
                m_jointList.Prev = j;
            }
            m_jointList = j;
            ++m_jointCount;

            // Connect to the bodies' doubly linked lists.
            j.m_edgeA.joint = j;
            j.m_edgeA.other = j.m_bodyB;
            j.m_edgeA.prev  = null;
            j.m_edgeA.next  = j.m_bodyA.JointList;
            if (j.m_bodyA.JointList)
            {
                j.m_bodyA.JointList.prev = &j.m_edgeA;
            }
            j.m_bodyA.JointList = &j.m_edgeA;

            j.m_edgeB.joint = j;
            j.m_edgeB.other = j.m_bodyA;
            j.m_edgeB.prev  = null;
            j.m_edgeB.next  = j.m_bodyB.JointList;
            if (j.m_bodyB.JointList)
            {
                j.m_bodyB.JointList.prev = &j.m_edgeB;
            }
            j.m_bodyB.JointList = &j.m_edgeB;

            b2Body bodyA = def.bodyA;
            b2Body bodyB = def.bodyB;

            // If the joint prevents collisions, then flag any contacts for filtering.
            if (def.collideConnected == false)
            {
                b2ContactEdge edge = bodyB.ContactList;
                while (edge != null)
                {
                    if (edge.other == bodyA)
                    {
                        // Flag the contact for filtering at the next time step (where either
                        // body is awake).
                        edge.contact.FlagForFiltering();
                    }

                    edge = edge.next;
                }
            }

            // Note: creating a joint doesn't wake the bodies.

            return(j);
        }
Ejemplo n.º 15
0
        public void DestroyBody(b2Body b)
        {
            if (IsLocked())
            {
                return;
            }

            // Delete the attached joints.
            b2JointEdge je = b.JointList;

            while (je)
            {
                b2JointEdge je0 = je;
                je = je.next;

                if (m_destructionListener != null)
                {
                    m_destructionListener.SayGoodbye(je0.joint);
                }

                DestroyJoint(je0.joint);

                b.JointList = je;
            }
            b.JointList = null;

            // Delete the attached contacts.
            b2ContactEdge ce = b.ContactList;

            while (ce)
            {
                b2ContactEdge ce0 = ce;
                ce = ce.next;
                m_contactManager.Destroy(ce0.contact);
            }
            b.ContactList = null;

            // Delete the attached fixtures. This destroys broad-phase proxies.
            b2Fixture f = b.FixtureList;

            while (f != null)
            {
                b2Fixture f0 = f;
                f = f.Next;

                if (m_destructionListener != null)
                {
                    m_destructionListener.SayGoodbye(f0);
                }

                f0.DestroyProxies(m_contactManager.BroadPhase);

                b.FixtureList   = f;
                b.FixtureCount -= 1;
            }
            b.FixtureList  = null;
            b.FixtureCount = 0;

            // Remove world body list.
            if (b.Prev != null)
            {
                b.Prev.Next = b.Next;
            }

            if (b.Next != null)
            {
                b.Next.Prev = b.Prev;
            }

            if (b == m_bodyList)
            {
                m_bodyList = b.Next;
            }

            --m_bodyCount;
        }
Ejemplo n.º 16
0
public virtual void SetActive(bool flag)
{

    if (flag == IsActive())
    {
        return;
    }

    if (flag)
    {
        m_flags |= b2BodyFlags.e_activeFlag;

        // Create all proxies.
        b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
        for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
        {
            f.CreateProxies(broadPhase, m_xf);
        }

        // Contacts are created the next time step.
    }
    else
    {
        m_flags &= ~b2BodyFlags.e_activeFlag;

        // Destroy all proxies.
        b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
        for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
        {
            f.DestroyProxies(broadPhase);
        }

        // Destroy the attached contacts.
        b2ContactEdge ce = m_contactList;
        while (ce != null)
        {
            b2ContactEdge ce0 = ce;
            ce = ce.Next;
            m_world.ContactManager.Destroy(ce0.contact);
        }
        m_contactList = null;
    }
}
Ejemplo n.º 17
0
        public b2Body(b2BodyDef bd, b2World world)
        {
            BodyFlags = 0;

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

            World = world;

            Transform.p = bd.position;
            Transform.q.Set(bd.angle);

            Sweep.localCenter.SetZero();
            Sweep.c0     = Transform.p;
            Sweep.c      = Transform.p;
            Sweep.a0     = bd.angle;
            Sweep.a      = bd.angle;
            Sweep.alpha0 = 0.0f;

            JointList   = null;
            ContactList = null;
            Prev        = null;
            Next        = null;

            m_linearVelocity  = bd.linearVelocity;
            m_angularVelocity = bd.angularVelocity;

            LinearDamping  = bd.linearDamping;
            AngularDamping = bd.angularDamping;
            GravityScale   = bd.gravityScale;

            Force.SetZero();
            Torque = 0.0f;

            SleepTime = 0.0f;

            BodyType = bd.type;

            if (BodyType == b2BodyType.b2_dynamicBody)
            {
                Mass         = 1.0f;
                InvertedMass = 1.0f;
            }
            else
            {
                Mass         = 0.0f;
                InvertedMass = 0.0f;
            }

            m_I       = 0.0f;
            InvertedI = 0.0f;

            UserData = bd.userData;

            FixtureList  = null;
            FixtureCount = 0;
        }
Ejemplo n.º 18
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;
        }
Ejemplo n.º 19
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;
        }
Ejemplo n.º 20
0
        // This is a callback from the broadphase when two AABB proxies begin
        // to overlap. We create a b2Contact to manage the narrow phase.
        public void AddPair(object proxyUserDataA, object proxyUserDataB)
        {
            b2Fixture fixtureA = proxyUserDataA as b2Fixture;
            b2Fixture fixtureB = proxyUserDataB as b2Fixture;

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

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

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

            while (edge != null)
            {
                if (edge.other == bodyA)
                {
                    b2Fixture fA = edge.contact.GetFixtureA();
                    b2Fixture fB = edge.contact.GetFixtureB();
                    if (fA == fixtureA && fB == fixtureB)
                    {
                        return;
                    }
                    if (fA == fixtureB && fB == fixtureA)
                    {
                        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.ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

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

            // Contact creation may swap shapes.
            fixtureA = c.GetFixtureA();
            fixtureB = c.GetFixtureB();
            bodyA    = fixtureA.m_body;
            bodyB    = fixtureB.m_body;

            // Insert into the world.
            c.m_prev = null;
            c.m_next = m_world.m_contactList;
            if (m_world.m_contactList != null)
            {
                m_world.m_contactList.m_prev = c;
            }
            m_world.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 2
            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;

            ++m_world.m_contactCount;
            return;
        }
Ejemplo n.º 21
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2ContactEdge obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }