createFrictionEquationsFromContact method

bool createFrictionEquationsFromContact(
  1. ContactEquation contactEquation,
  2. List<FrictionEquation> outArray
)

Implementation

bool createFrictionEquationsFromContact(ContactEquation contactEquation, List<FrictionEquation>outArray) {
  final bodyA = contactEquation.bi;
  final bodyB = contactEquation.bj;
  final shapeA = contactEquation.si;
  final shapeB = contactEquation.sj;

  final world = this.world;
  final cm = currentContactMaterial;

  // If friction or restitution were specified in the material, use them
  double friction = cm.friction;
  final matA = shapeA.material ?? bodyA.material;
  final matB = shapeB.material ?? bodyB.material;
  if (matA != null && matB != null && matA.friction >= 0 && matB.friction >= 0) {
    friction = matA.friction * matB.friction;
  }

  if (friction > 0) {
    // Create 2 tangent equations
    // Users may provide a force different from global gravity to use when computing contact friction.
    final mug = friction * (world.frictionGravity ?? world.gravity).length();
    double reducedMass = bodyA.invMass + bodyB.invMass;
    if (reducedMass > 0) {
      reducedMass = 1 / reducedMass;
    }
    final pool = frictionEquationPool;
    final c1 = pool.isNotEmpty ? pool.removeLast() : FrictionEquation(bodyA, bodyB, mug * reducedMass);
    final c2 = pool.isNotEmpty ? pool.removeLast() : FrictionEquation(bodyA, bodyB, mug * reducedMass);

    c1.bi = c2.bi = bodyA;
    c1.bj = c2.bj = bodyB;
    c1.minForce = c2.minForce = -mug * reducedMass;
    c1.maxForce = c2.maxForce = mug * reducedMass;

    // Copy over the relative vectors
    c1.ri.copy(contactEquation.ri);
    c1.rj.copy(contactEquation.rj);
    c2.ri.copy(contactEquation.ri);
    c2.rj.copy(contactEquation.rj);

    // Construct tangents
    contactEquation.ni.tangents(c1.t, c2.t);

    // Set spook params
    c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt);
    c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt);

    c1.enabled = contactEquation.enabled;
    c2.enabled = contactEquation.enabled;

    outArray.addAll([c1, c2]);

    return true;
  }

  return false;
}