/// <summary> /// Update the contact manifold and touching status. /// Note: do not assume the fixture AABBs are overlapping or are valid. /// </summary> /// <param name="wake">Whether we should wake the bodies due to touching changing.</param> /// <returns>What current status of the contact is (e.g. start touching, end touching, etc.)</returns> internal ContactStatus Update(IPhysicsManager physicsManager, out bool wake) { PhysicsComponent bodyA = FixtureA !.Body; PhysicsComponent bodyB = FixtureB !.Body; var oldManifold = Manifold; // Re-enable this contact. Enabled = true; bool touching; var wasTouching = IsTouching; wake = false; var sensor = !(FixtureA.Hard && FixtureB.Hard); var bodyATransform = physicsManager.GetTransform(bodyA); var bodyBTransform = physicsManager.GetTransform(bodyB); // Is this contact a sensor? if (sensor) { IPhysShape shapeA = FixtureA.Shape; IPhysShape shapeB = FixtureB.Shape; touching = _manifoldManager.TestOverlap(shapeA, ChildIndexA, shapeB, ChildIndexB, bodyATransform, bodyBTransform); // Sensors don't generate manifolds. Manifold.PointCount = 0; } else { Evaluate(ref Manifold, bodyATransform, bodyBTransform); touching = Manifold.PointCount > 0; // Match old contact ids to new contact ids and copy the // stored impulses to warm start the solver. for (var i = 0; i < Manifold.PointCount; ++i) { var mp2 = Manifold.Points[i]; mp2.NormalImpulse = 0.0f; mp2.TangentImpulse = 0.0f; var id2 = mp2.Id; for (var j = 0; j < oldManifold.PointCount; ++j) { var mp1 = oldManifold.Points[j]; if (mp1.Id.Key == id2.Key) { mp2.NormalImpulse = mp1.NormalImpulse; mp2.TangentImpulse = mp1.TangentImpulse; break; } } Manifold.Points[i] = mp2; } if (touching != wasTouching) { wake = true; } } IsTouching = touching; var status = ContactStatus.NoContact; if (!wasTouching) { if (touching) { status = ContactStatus.StartTouching; } } else { if (!touching) { status = ContactStatus.EndTouching; } } #if DEBUG if (!sensor) { _debugPhysics.HandlePreSolve(this, oldManifold); } #endif return(status); }