getContacts method

void getContacts(
  1. List<Body> p1,
  2. List<Body> p2,
  3. World world,
  4. List<ContactEquation> result,
  5. List<ContactEquation> oldcontacts,
  6. List<FrictionEquation> frictionResult,
  7. List<FrictionEquation> frictionPool,
)

Generate all contacts between a list of body pairs @param p1 Array of body indices @param p2 Array of body indices @param result Array to store generated contacts @param oldcontacts Optional. Array of reusable contact objects

Implementation

void getContacts(
  List<Body> p1,
  List<Body> p2,
  World world,
  List<ContactEquation> result,
  List<ContactEquation> oldcontacts,
  List<FrictionEquation> frictionResult,
  List<FrictionEquation> frictionPool
 ){
  // Save old contact objects
  contactPointPool = oldcontacts;
  frictionEquationPool = frictionPool;
  this.result = result;
  this.frictionResult = frictionResult;

  final qi = _tmpQuat1;
  final qj = _tmpQuat2;
  final xi = _tmpVec1;
  final xj = _tmpVec2;

  for (int k = 0, N = p1.length; k != N; k++) {
    // Get current collision bodies
    final bi = p1[k];
    final bj = p2[k];

    // Get contact material
    ContactMaterial? bodyContactMaterial;
    if (bi.material != null && bj.material != null) {
      bodyContactMaterial = world.getContactMaterial(bi.material!, bj.material!);
    }

    final justTest =
      (bi.type == BodyTypes.kinematic && bj.type == BodyTypes.static) ||
      (bi.type == BodyTypes.static && bj.type == BodyTypes.kinematic) ||
      (bi.type == BodyTypes.kinematic && bj.type == BodyTypes.kinematic);

    for (int i = 0; i < bi.shapes.length; i++) {
      bi.quaternion.mult(bi.shapeOrientations[i], qi);
      bi.quaternion.vmult(bi.shapeOffsets[i], xi);
      xi.vadd(bi.position, xi);
      final si = bi.shapes[i];

      for (int j = 0; j < bj.shapes.length; j++) {
        // Compute world transform of shapes
        bj.quaternion.mult(bj.shapeOrientations[j], qj);
        bj.quaternion.vmult(bj.shapeOffsets[j], xj);
        xj.vadd(bj.position, xj);
        final sj = bj.shapes[j];

        if (!(si.collisionFilterMask & sj.collisionFilterGroup != 0 && sj.collisionFilterMask & si.collisionFilterGroup != 0)) {
          continue;
        }
        if (xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius) {
          continue;
        }
        // Get collision material
        ContactMaterial? shapeContactMaterial;
        if (si.material != null && sj.material != null) {
          shapeContactMaterial = world.getContactMaterial(si.material!, sj.material!);
        }

        currentContactMaterial = shapeContactMaterial ?? bodyContactMaterial ?? world.defaultContactMaterial;

        // Get contacts
        final resolverIndex = getCollisionType(si.type, sj.type);//(si.type | sj.type) as CollisionType;
        final resolver = resolverIndex == null? null:this[resolverIndex];
        if (resolver != null) {
          bool retval = false;

          // TO DO: investigate why sphereParticle and convexParticle
          // resolvers expect si and sj shapes to be in reverse order
          // (i.e. larger integer value type first instead of smaller first)
          if (si.type.index < sj.type.index) {
            retval = resolver.call(si, sj, xi, xj, qi, qj, bi, bj, si, sj, justTest);
          } else {
            retval = resolver.call(sj, si, xj, xi, qj, qi, bj, bi, si, sj, justTest);
          }

          if (retval && justTest) {
            // Register overlap
            world.shapeOverlapKeeper.set(si.id, sj.id);
            world.bodyOverlapKeeper.set(bi.id, bj.id);
          }
        }
      }
    }
  }
}