// This is the top level collision call for the time step. Here
// all the narrow phase collision is processed for the world
// contact list.
public void Collide()
{
// Update awake contacts.
Contact c = _contactList;
while (c != null)
{
Fixture fixtureA = c.GetFixtureA();
Fixture fixtureB = c.GetFixtureB();
Body bodyA = fixtureA.GetBody();
Body bodyB = fixtureB.GetBody();
if (bodyA.IsSleeping() && bodyB.IsSleeping())
{
c = c.GetNext();
continue;
}
// Is this contact flagged for filtering?
if ((c.Flags & ContactFlag.FilterFlag) == ContactFlag.FilterFlag)
{
//TODO: The following code (next 4 if blocks) use a class and thus copy by ref. It might expect to copy by value
// Are both bodies static?
if (bodyA.IsStatic() && bodyB.IsStatic())
{
Contact cNuke = c;
c = cNuke.GetNext();
Destroy(cNuke);
continue;
}
// Does a joint override collision?
if (bodyB.IsConnected(bodyA))
{
Contact cNuke = c;
c = cNuke.GetNext();
Destroy(cNuke);
continue;
}
// Check user filtering.
if (_contactFilter.ShouldCollide(fixtureA, fixtureB) == false)
{
Contact cNuke = c;
c = cNuke.GetNext();
Destroy(cNuke);
continue;
}
// Clear the filtering flag.
c.Flags &= ~ContactFlag.FilterFlag;
}
int proxyIdA = fixtureA.ProxyId;
int proxyIdB = fixtureB.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;
c = cNuke.GetNext();
Destroy(cNuke);
continue;
}
// The contact persists.
c.Update(_contactListener);
c = c.GetNext();
}
}