internal void Collide() { for (int i = 0; i < this.ContactList.Count; i++) { Contact contact = this.ContactList[i]; Fixture fixtureA = contact.FixtureA; Fixture fixtureB = contact.FixtureB; int childIndexA = contact.ChildIndexA; int childIndexB = contact.ChildIndexB; Body body = fixtureA.Body; Body body2 = fixtureB.Body; bool flag = !body.Enabled || !body2.Enabled; if (!flag) { bool filterFlag = contact.FilterFlag; if (filterFlag) { bool flag2 = !body2.ShouldCollide(body); if (flag2) { Contact contact2 = contact; this.Destroy(contact2); goto IL_198; } bool flag3 = !ContactManager.ShouldCollide(fixtureA, fixtureB); if (flag3) { Contact contact3 = contact; this.Destroy(contact3); goto IL_198; } bool flag4 = this.ContactFilter != null && !this.ContactFilter(fixtureA, fixtureB); if (flag4) { Contact contact4 = contact; this.Destroy(contact4); goto IL_198; } contact.FilterFlag = false; } bool flag5 = body.Awake && body.BodyType > BodyType.Static; bool flag6 = body2.Awake && body2.BodyType > BodyType.Static; bool flag7 = !flag5 && !flag6; if (!flag7) { int proxyId = fixtureA.Proxies[childIndexA].ProxyId; int proxyId2 = fixtureB.Proxies[childIndexB].ProxyId; bool flag8 = this.BroadPhase.TestOverlap(proxyId, proxyId2); bool flag9 = !flag8; if (flag9) { Contact contact5 = contact; this.Destroy(contact5); } else { contact.Update(this); } } } IL_198 :; } }
internal void Collide() { // Update awake contacts. #if USE_ACTIVE_CONTACT_SET ActiveList.AddRange(ActiveContacts); foreach (var c in ActiveList) { #else for (int i = 0; i < ContactList.Count; i++) { Contact c = ContactList[i]; #endif Fixture fixtureA = c.FixtureA; Fixture fixtureB = c.FixtureB; int indexA = c.ChildIndexA; int indexB = c.ChildIndexB; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; //Do no try to collide disabled bodies if (!bodyA.Enabled || !bodyB.Enabled) { continue; } // Is this contact flagged for filtering? if (c.FilterFlag) { // Should these bodies collide? if (bodyB.ShouldCollide(bodyA) == false) { Contact cNuke = c; Destroy(cNuke); continue; } // Check default filtering if (ShouldCollide(fixtureA, fixtureB) == false) { Contact cNuke = c; Destroy(cNuke); continue; } // Check user filtering. if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false) { Contact cNuke = c; Destroy(cNuke); continue; } // Clear the filtering flag. c.FilterFlag = false; } bool activeA = bodyA.Awake && bodyA.BodyType != BodyType.Static; bool activeB = bodyB.Awake && bodyB.BodyType != BodyType.Static; // At least one body must be awake and it must be dynamic or kinematic. if (activeA == false && activeB == false) { #if USE_ACTIVE_CONTACT_SET ActiveContacts.Remove(c); #endif continue; } if (fixtureA == null || fixtureA.Proxies == null || fixtureB == null || fixtureB.Proxies == null) { continue; } int proxyIdA = fixtureA.Proxies[indexA].ProxyId; int proxyIdB = fixtureB.Proxies[indexB].ProxyId; bool overlap = BroadPhase.TestOverlap(proxyIdA, proxyIdB); // Here we destroy contacts that cease to overlap in the broad-phase. if (overlap == false) { Contact cNuke = c; Destroy(cNuke); continue; } // The contact persists. c.Update(this); } #if USE_ACTIVE_CONTACT_SET ActiveList.Clear(); #endif }
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; }