示例#1
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;
        }