addPair method

void addPair(
  1. covariant FixtureProxy proxyUserDataA,
  2. covariant FixtureProxy proxyUserDataB
)
override

Broad-phase callback.

Implementation

void addPair(FixtureProxy proxyUserDataA, FixtureProxy proxyUserDataB) {
  FixtureProxy proxyA = proxyUserDataA;
  FixtureProxy proxyB = proxyUserDataB;

  Fixture fixtureA = proxyA.fixture;
  Fixture fixtureB = proxyB.fixture;

  int indexA = proxyA.childIndex;
  int indexB = proxyB.childIndex;

  Body bodyA = fixtureA.getBody();
  Body bodyB = fixtureB.getBody();

  // 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.getContactList();
  while (edge != null) {
    if (edge.other == bodyA) {
      Fixture fA = edge.contact.fixtureA;
      Fixture fB = edge.contact.fixtureB;
      int iA = edge.contact.getChildIndexA();
      int iB = edge.contact.getChildIndexB();

      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;
  indexA = c.getChildIndexA();
  indexB = c.getChildIndexB();
  bodyA = fixtureA.getBody();
  bodyB = fixtureB.getBody();

  // 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
  if (!fixtureA.isSensor() && !fixtureB.isSensor()) {
    bodyA.setAwake(true);
    bodyB.setAwake(true);
  }

  ++contactCount;
}