/// <summary>
/// Broad-phase callback.
/// </summary>
/// <param name="proxyUserDataA"></param>
/// <param name="proxyUserDataB"></param>
public void AddPair(object proxyUserDataA, object proxyUserDataB)
{
FixtureProxy proxyA = (FixtureProxy)proxyUserDataA;
FixtureProxy proxyB = (FixtureProxy)proxyUserDataB;
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;
}
// TODO_ERIN use a hash table to remove a potential bottleneck when both
// bodies have a lot of contacts.
// 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 && iA == indexA && fB == fixtureB && iB == indexB)
{
// A contact already exists.
return;
}
if (fA == fixtureB && iA == indexB && fB == fixtureA && 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 user filtering.
if (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false)
{
return;
}
// Call the factory.
Contact c = pool.PopContact(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.
c.Prev = null;
c.Next = ContactList;
if (ContactList != null)
{
ContactList.Prev = c;
}
ContactList = c;
// 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
bodyA.Awake = true;
bodyB.Awake = true;
++ContactCount;
}