Beispiel #1
0
        // Broad-phase callback.
        private void AddPair(ref FixtureProxy proxyA, ref FixtureProxy proxyB)
        {
            Fixture fixtureA = proxyA.Fixture;
            Fixture fixtureB = proxyB.Fixture;

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

            Body bodyA = fixtureA.Body;
            Body bodyB = fixtureB.Body;

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

            // Does a contact already exist?
            ContactEdge edge = bodyB.ContactList;

            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.FixtureA;
                    Fixture fB = edge.Contact.FixtureB;
                    int     iA = edge.Contact.ChildIndexA;
                    int     iB = edge.Contact.ChildIndexB;

                    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 default filter
            if (ShouldCollide(fixtureA, fixtureB) == false)
            {
                return;
            }

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

            //FPE feature: BeforeCollision delegate
            if (fixtureA.BeforeCollision != null && fixtureA.BeforeCollision(fixtureA, fixtureB) == false)
            {
                return;
            }

            if (fixtureB.BeforeCollision != null && fixtureB.BeforeCollision(fixtureB, fixtureA) == false)
            {
                return;
            }

            Body specialSenseBody = null;
            Body otherBody        = null;

            if (bodyA.SpecialSensor != BodySpecialSensor.None)
            {
                specialSenseBody = bodyA;
                otherBody        = bodyB;
            }
            else if (bodyB.SpecialSensor != BodySpecialSensor.None)
            {
                specialSenseBody = bodyB;
                otherBody        = bodyA;
            }

            if (specialSenseBody != null)
            {
                if (Collision.TestOverlap(fixtureA.Shape, indexA, fixtureB.Shape, indexB, ref bodyA._xf, ref bodyB._xf))
                {
                    specialSenseBody._specialSensorResults.Add(otherBody);

                    if (specialSenseBody.SpecialSensor == BodySpecialSensor.ActiveOnce)
                    {
                        specialSenseBody.disabled = true;
                        return;
                    }
                }
                else
                {
                    return;
                }
            }

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

            if (c == null)
            {
                return;
            }

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

            // Insert into the world.
            ContactList.Add(c);

#if USE_ACTIVE_CONTACT_SET
            ActiveContacts.Add(c);
#endif
            // 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
            if (fixtureA.IsSensor == false && fixtureB.IsSensor == false)
            {
                bodyA.Awake = true;
                bodyB.Awake = true;
            }
        }
Beispiel #2
0
 internal void UpdateContacts(ContactEdge contactEdge, bool value)
 {
 }
Beispiel #3
0
        private void AddPair(ref FixtureProxy proxyA, ref FixtureProxy proxyB)
        {
            Fixture fixture     = proxyA.Fixture;
            Fixture fixture2    = proxyB.Fixture;
            int     childIndex  = proxyA.ChildIndex;
            int     childIndex2 = proxyB.ChildIndex;
            Body    body        = fixture.Body;
            Body    body2       = fixture2.Body;
            bool    flag        = body == body2;

            if (!flag)
            {
                for (ContactEdge contactEdge = body2.ContactList; contactEdge != null; contactEdge = contactEdge.Next)
                {
                    bool flag2 = contactEdge.Other == body;
                    if (flag2)
                    {
                        Fixture fixtureA    = contactEdge.Contact.FixtureA;
                        Fixture fixtureB    = contactEdge.Contact.FixtureB;
                        int     childIndexA = contactEdge.Contact.ChildIndexA;
                        int     childIndexB = contactEdge.Contact.ChildIndexB;
                        bool    flag3       = fixtureA == fixture && fixtureB == fixture2 && childIndexA == childIndex && childIndexB == childIndex2;
                        if (flag3)
                        {
                            return;
                        }
                        bool flag4 = fixtureA == fixture2 && fixtureB == fixture && childIndexA == childIndex2 && childIndexB == childIndex;
                        if (flag4)
                        {
                            return;
                        }
                    }
                }
                bool flag5 = !body2.ShouldCollide(body);
                if (!flag5)
                {
                    bool flag6 = !ContactManager.ShouldCollide(fixture, fixture2);
                    if (!flag6)
                    {
                        bool flag7 = this.ContactFilter != null && !this.ContactFilter(fixture, fixture2);
                        if (!flag7)
                        {
                            bool flag8 = fixture.BeforeCollision != null && !fixture.BeforeCollision(fixture, fixture2);
                            if (!flag8)
                            {
                                bool flag9 = fixture2.BeforeCollision != null && !fixture2.BeforeCollision(fixture2, fixture);
                                if (!flag9)
                                {
                                    Body body3  = null;
                                    Body item   = null;
                                    bool flag10 = body.SpecialSensor > BodySpecialSensor.None;
                                    if (flag10)
                                    {
                                        body3 = body;
                                        item  = body2;
                                    }
                                    else
                                    {
                                        bool flag11 = body2.SpecialSensor > BodySpecialSensor.None;
                                        if (flag11)
                                        {
                                            body3 = body2;
                                            item  = body;
                                        }
                                    }
                                    bool flag12 = body3 != null;
                                    if (flag12)
                                    {
                                        bool flag13 = Collision.TestOverlap(body.FixtureList[0].Shape, childIndex, body2.FixtureList[0].Shape, childIndex2, ref body._xf, ref body2._xf);
                                        if (!flag13)
                                        {
                                            return;
                                        }
                                        body3._specialSensorResults.Add(item);
                                        bool flag14 = body3.SpecialSensor == BodySpecialSensor.ActiveOnce;
                                        if (flag14)
                                        {
                                            body3.disabled = true;
                                            return;
                                        }
                                    }
                                    Contact contact = Contact.Create(fixture, childIndex, fixture2, childIndex2);
                                    bool    flag15  = contact == null;
                                    if (!flag15)
                                    {
                                        fixture  = contact.FixtureA;
                                        fixture2 = contact.FixtureB;
                                        body     = fixture.Body;
                                        body2    = fixture2.Body;
                                        this.ContactList.Add(contact);
                                        contact._nodeA.Contact = contact;
                                        contact._nodeA.Other   = body2;
                                        contact._nodeA.Prev    = null;
                                        contact._nodeA.Next    = body.ContactList;
                                        bool flag16 = body.ContactList != null;
                                        if (flag16)
                                        {
                                            body.ContactList.Prev = contact._nodeA;
                                        }
                                        body.ContactList       = contact._nodeA;
                                        contact._nodeB.Contact = contact;
                                        contact._nodeB.Other   = body;
                                        contact._nodeB.Prev    = null;
                                        contact._nodeB.Next    = body2.ContactList;
                                        bool flag17 = body2.ContactList != null;
                                        if (flag17)
                                        {
                                            body2.ContactList.Prev = contact._nodeB;
                                        }
                                        body2.ContactList = contact._nodeB;
                                        bool flag18 = !fixture.IsSensor && !fixture2.IsSensor;
                                        if (flag18)
                                        {
                                            body.Awake  = true;
                                            body2.Awake = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #4
0
        private void SolveTOI(ref TimeStep step)
        {
            this.Island.Reset(64, 32, 0, this.ContactManager);
            bool stepComplete = this._stepComplete;

            if (stepComplete)
            {
                for (int i = 0; i < this.BodyList.Count; i++)
                {
                    this.BodyList[i]._island       = false;
                    this.BodyList[i]._sweep.Alpha0 = 0f;
                }
                for (int j = 0; j < this.ContactManager.ContactList.Count; j++)
                {
                    Contact contact = this.ContactManager.ContactList[j];
                    contact.IslandFlag = false;
                    contact.TOIFlag    = false;
                    contact._toiCount  = 0;
                    contact._toi       = 1f;
                }
            }
            while (true)
            {
                Contact contact2 = null;
                FP      fP       = 1f;
                for (int k = 0; k < this.ContactManager.ContactList.Count; k++)
                {
                    Contact contact3 = this.ContactManager.ContactList[k];
                    bool    flag     = !contact3.Enabled;
                    if (!flag)
                    {
                        bool flag2 = contact3._toiCount > 8;
                        if (!flag2)
                        {
                            bool tOIFlag = contact3.TOIFlag;
                            FP   fP2;
                            if (tOIFlag)
                            {
                                fP2 = contact3._toi;
                            }
                            else
                            {
                                Fixture fixtureA = contact3.FixtureA;
                                Fixture fixtureB = contact3.FixtureB;
                                bool    flag3    = fixtureA.IsSensor || fixtureB.IsSensor;
                                if (flag3)
                                {
                                    goto IL_424;
                                }
                                Body     body      = fixtureA.Body;
                                Body     body2     = fixtureB.Body;
                                BodyType bodyType  = body.BodyType;
                                BodyType bodyType2 = body2.BodyType;
                                Debug.Assert(bodyType == BodyType.Dynamic || bodyType2 == BodyType.Dynamic);
                                bool flag4 = body.Awake && bodyType > BodyType.Static;
                                bool flag5 = body2.Awake && bodyType2 > BodyType.Static;
                                bool flag6 = !flag4 && !flag5;
                                if (flag6)
                                {
                                    goto IL_424;
                                }
                                bool flag7 = (body.IsBullet || bodyType != BodyType.Dynamic) && (fixtureA.IgnoreCCDWith & fixtureB.CollisionCategories) == Category.None && !body.IgnoreCCD;
                                bool flag8 = (body2.IsBullet || bodyType2 != BodyType.Dynamic) && (fixtureB.IgnoreCCDWith & fixtureA.CollisionCategories) == Category.None && !body2.IgnoreCCD;
                                bool flag9 = !flag7 && !flag8;
                                if (flag9)
                                {
                                    goto IL_424;
                                }
                                FP   alpha  = body._sweep.Alpha0;
                                bool flag10 = body._sweep.Alpha0 < body2._sweep.Alpha0;
                                if (flag10)
                                {
                                    alpha = body2._sweep.Alpha0;
                                    body._sweep.Advance(alpha);
                                }
                                else
                                {
                                    bool flag11 = body2._sweep.Alpha0 < body._sweep.Alpha0;
                                    if (flag11)
                                    {
                                        alpha = body._sweep.Alpha0;
                                        body2._sweep.Advance(alpha);
                                    }
                                }
                                Debug.Assert(alpha < 1f);
                                this._input.ProxyA.Set(fixtureA.Shape, contact3.ChildIndexA);
                                this._input.ProxyB.Set(fixtureB.Shape, contact3.ChildIndexB);
                                this._input.SweepA = body._sweep;
                                this._input.SweepB = body2._sweep;
                                this._input.TMax   = 1f;
                                TOIOutput tOIOutput;
                                TimeOfImpact.CalculateTimeOfImpact(out tOIOutput, this._input);
                                FP   t      = tOIOutput.T;
                                bool flag12 = tOIOutput.State == TOIOutputState.Touching;
                                if (flag12)
                                {
                                    fP2 = TSMath.Min(alpha + (1f - alpha) * t, 1f);
                                }
                                else
                                {
                                    fP2 = 1f;
                                }
                                contact3._toi    = fP2;
                                contact3.TOIFlag = true;
                            }
                            bool flag13 = fP2 < fP;
                            if (flag13)
                            {
                                contact2 = contact3;
                                fP       = fP2;
                            }
                        }
                    }
                    IL_424 :;
                }
                bool flag14 = contact2 == null || 1f - 10f * Settings.Epsilon < fP;
                if (flag14)
                {
                    break;
                }
                Fixture fixtureA2 = contact2.FixtureA;
                Fixture fixtureB2 = contact2.FixtureB;
                Body    body3     = fixtureA2.Body;
                Body    body4     = fixtureB2.Body;
                Sweep   sweep     = body3._sweep;
                Sweep   sweep2    = body4._sweep;
                body3.Advance(fP);
                body4.Advance(fP);
                contact2.Update(this.ContactManager);
                contact2.TOIFlag = false;
                contact2._toiCount++;
                bool flag15 = !contact2.Enabled || !contact2.IsTouching;
                if (flag15)
                {
                    contact2.Enabled = false;
                    body3._sweep     = sweep;
                    body4._sweep     = sweep2;
                    body3.SynchronizeTransform();
                    body4.SynchronizeTransform();
                }
                else
                {
                    body3.Awake = true;
                    body4.Awake = true;
                    this.Island.Clear();
                    this.Island.Add(body3);
                    this.Island.Add(body4);
                    this.Island.Add(contact2);
                    body3._island       = true;
                    body4._island       = true;
                    contact2.IslandFlag = true;
                    Body[] array = new Body[]
                    {
                        body3,
                        body4
                    };
                    for (int l = 0; l < 2; l++)
                    {
                        Body body5  = array[l];
                        bool flag16 = body5.BodyType == BodyType.Dynamic;
                        if (flag16)
                        {
                            for (ContactEdge contactEdge = body5.ContactList; contactEdge != null; contactEdge = contactEdge.Next)
                            {
                                Contact contact4 = contactEdge.Contact;
                                bool    flag17   = this.Island.BodyCount == this.Island.BodyCapacity;
                                if (flag17)
                                {
                                    break;
                                }
                                bool flag18 = this.Island.ContactCount == this.Island.ContactCapacity;
                                if (flag18)
                                {
                                    break;
                                }
                                bool islandFlag = contact4.IslandFlag;
                                if (!islandFlag)
                                {
                                    Body other  = contactEdge.Other;
                                    bool flag19 = other.BodyType == BodyType.Dynamic && !body5.IsBullet && !other.IsBullet;
                                    if (!flag19)
                                    {
                                        bool flag20 = contact4.FixtureA.IsSensor || contact4.FixtureB.IsSensor;
                                        if (!flag20)
                                        {
                                            Sweep sweep3 = other._sweep;
                                            bool  flag21 = !other._island;
                                            if (flag21)
                                            {
                                                other.Advance(fP);
                                            }
                                            contact4.Update(this.ContactManager);
                                            bool flag22 = !contact4.Enabled;
                                            if (flag22)
                                            {
                                                other._sweep = sweep3;
                                                other.SynchronizeTransform();
                                            }
                                            else
                                            {
                                                bool flag23 = !contact4.IsTouching;
                                                if (flag23)
                                                {
                                                    other._sweep = sweep3;
                                                    other.SynchronizeTransform();
                                                }
                                                else
                                                {
                                                    contact4.IslandFlag = true;
                                                    this.Island.Add(contact4);
                                                    bool island = other._island;
                                                    if (!island)
                                                    {
                                                        other._island = true;
                                                        bool flag24 = other.BodyType > BodyType.Static;
                                                        if (flag24)
                                                        {
                                                            other.Awake = true;
                                                        }
                                                        this.Island.Add(other);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    TimeStep timeStep;
                    timeStep.dt      = (1f - fP) * step.dt;
                    timeStep.inv_dt  = 1f / timeStep.dt;
                    timeStep.dtRatio = 1f;
                    this.Island.SolveTOI(ref timeStep, body3.IslandIndex, body4.IslandIndex, false);
                    for (int m = 0; m < this.Island.BodyCount; m++)
                    {
                        Body body6 = this.Island.Bodies[m];
                        body6._island = false;
                        bool flag25 = body6.BodyType != BodyType.Dynamic;
                        if (!flag25)
                        {
                            body6.SynchronizeFixtures();
                            for (ContactEdge contactEdge2 = body6.ContactList; contactEdge2 != null; contactEdge2 = contactEdge2.Next)
                            {
                                contactEdge2.Contact.TOIFlag    = false;
                                contactEdge2.Contact.IslandFlag = false;
                            }
                        }
                    }
                    this.ContactManager.FindNewContacts();
                }
            }
            this._stepComplete = true;
        }
Beispiel #5
0
        private void Solve(ref TimeStep step)
        {
            this.Island.Reset(this.BodyList.Count, this.ContactManager.ContactList.Count, this.JointList.Count, this.ContactManager);
            foreach (Body current in this.BodyList)
            {
                current._island = false;
            }
            foreach (Contact current2 in this.ContactManager.ContactList)
            {
                current2.IslandFlag = false;
            }
            foreach (Joint current3 in this.JointList)
            {
                current3.IslandFlag = false;
            }
            int  count = this.BodyList.Count;
            bool flag  = count > this._stack.Length;

            if (flag)
            {
                this._stack = new Body[Math.Max(this._stack.Length * 2, count)];
            }
            for (int i = this.BodyList.Count - 1; i >= 0; i--)
            {
                Body body   = this.BodyList[i];
                bool island = body._island;
                if (!island)
                {
                    bool flag2 = !body.Awake || !body.Enabled;
                    if (!flag2)
                    {
                        bool flag3 = body.BodyType == BodyType.Static;
                        if (!flag3)
                        {
                            this.Island.Clear();
                            int j = 0;
                            this._stack[j++] = body;
                            body._island     = true;
                            while (j > 0)
                            {
                                Body body2 = this._stack[--j];
                                Debug.Assert(body2.Enabled);
                                this.Island.Add(body2);
                                body2.Awake = true;
                                bool flag4 = body2.BodyType == BodyType.Static;
                                if (!flag4)
                                {
                                    for (ContactEdge contactEdge = body2.ContactList; contactEdge != null; contactEdge = contactEdge.Next)
                                    {
                                        Contact contact    = contactEdge.Contact;
                                        bool    islandFlag = contact.IslandFlag;
                                        if (!islandFlag)
                                        {
                                            bool flag5 = !contactEdge.Contact.Enabled || !contactEdge.Contact.IsTouching;
                                            if (!flag5)
                                            {
                                                bool isSensor  = contact.FixtureA.IsSensor;
                                                bool isSensor2 = contact.FixtureB.IsSensor;
                                                bool flag6     = isSensor | isSensor2;
                                                if (!flag6)
                                                {
                                                    this.Island.Add(contact);
                                                    contact.IslandFlag = true;
                                                    Body other   = contactEdge.Other;
                                                    bool island2 = other._island;
                                                    if (!island2)
                                                    {
                                                        Debug.Assert(j < count);
                                                        this._stack[j++] = other;
                                                        other._island    = true;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    for (JointEdge jointEdge = body2.JointList; jointEdge != null; jointEdge = jointEdge.Next)
                                    {
                                        bool islandFlag2 = jointEdge.Joint.IslandFlag;
                                        if (!islandFlag2)
                                        {
                                            Body other2 = jointEdge.Other;
                                            bool flag7  = other2 != null;
                                            if (flag7)
                                            {
                                                bool flag8 = !other2.Enabled;
                                                if (!flag8)
                                                {
                                                    this.Island.Add(jointEdge.Joint);
                                                    jointEdge.Joint.IslandFlag = true;
                                                    bool island3 = other2._island;
                                                    if (!island3)
                                                    {
                                                        Debug.Assert(j < count);
                                                        this._stack[j++] = other2;
                                                        other2._island   = true;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                this.Island.Add(jointEdge.Joint);
                                                jointEdge.Joint.IslandFlag = true;
                                            }
                                        }
                                    }
                                }
                            }
                            this.Island.Solve(ref step, ref this.Gravity);
                            for (int k = 0; k < this.Island.BodyCount; k++)
                            {
                                Body body3 = this.Island.Bodies[k];
                                bool flag9 = body3.BodyType == BodyType.Static;
                                if (flag9)
                                {
                                    body3._island = false;
                                }
                            }
                        }
                    }
                }
            }
            foreach (Body current4 in this.BodyList)
            {
                bool flag10 = !current4._island;
                if (!flag10)
                {
                    bool flag11 = current4.BodyType == BodyType.Static;
                    if (!flag11)
                    {
                        current4.SynchronizeFixtures();
                    }
                }
            }
            this.ContactManager.FindNewContacts();
        }
Beispiel #6
0
        private void ProcessRemovedJoints()
        {
            bool flag = this._jointRemoveList.Count > 0;

            if (flag)
            {
                foreach (Joint current in this._jointRemoveList)
                {
                    bool collideConnected = current.CollideConnected;
                    this.JointList.Remove(current);
                    Body bodyA = current.BodyA;
                    Body bodyB = current.BodyB;
                    bodyA.Awake = true;
                    bool flag2 = !current.IsFixedType();
                    if (flag2)
                    {
                        bodyB.Awake = true;
                    }
                    bool flag3 = current.EdgeA.Prev != null;
                    if (flag3)
                    {
                        current.EdgeA.Prev.Next = current.EdgeA.Next;
                    }
                    bool flag4 = current.EdgeA.Next != null;
                    if (flag4)
                    {
                        current.EdgeA.Next.Prev = current.EdgeA.Prev;
                    }
                    bool flag5 = current.EdgeA == bodyA.JointList;
                    if (flag5)
                    {
                        bodyA.JointList = current.EdgeA.Next;
                    }
                    current.EdgeA.Prev = null;
                    current.EdgeA.Next = null;
                    bool flag6 = !current.IsFixedType();
                    if (flag6)
                    {
                        bool flag7 = current.EdgeB.Prev != null;
                        if (flag7)
                        {
                            current.EdgeB.Prev.Next = current.EdgeB.Next;
                        }
                        bool flag8 = current.EdgeB.Next != null;
                        if (flag8)
                        {
                            current.EdgeB.Next.Prev = current.EdgeB.Prev;
                        }
                        bool flag9 = current.EdgeB == bodyB.JointList;
                        if (flag9)
                        {
                            bodyB.JointList = current.EdgeB.Next;
                        }
                        current.EdgeB.Prev = null;
                        current.EdgeB.Next = null;
                    }
                    bool flag10 = !current.IsFixedType();
                    if (flag10)
                    {
                        bool flag11 = !collideConnected;
                        if (flag11)
                        {
                            for (ContactEdge contactEdge = bodyB.ContactList; contactEdge != null; contactEdge = contactEdge.Next)
                            {
                                bool flag12 = contactEdge.Other == bodyA;
                                if (flag12)
                                {
                                    contactEdge.Contact.FilterFlag = true;
                                }
                            }
                        }
                    }
                    bool flag13 = this.JointRemoved != null;
                    if (flag13)
                    {
                        this.JointRemoved(current);
                    }
                }
                this._jointRemoveList.Clear();
            }
        }