// 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; } }
internal void UpdateContacts(ContactEdge contactEdge, bool value) { }
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; } } } } } } } } }
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; }
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(); }
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(); } }