createFrictionEquationsFromContact method
bool
createFrictionEquationsFromContact(
- ContactEquation contactEquation,
- 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;
}