circleToCircle static method

bool circleToCircle(
  1. RigidBody aBody,
  2. RigidBody bBody
)

Implementation

static bool circleToCircle(RigidBody aBody, RigidBody bBody) {
  final a = aBody.shape as Circle;
  final b = bBody.shape as Circle;

  // diff = a.position - b.position
  _temp.set(a.position.x - b.position.x, a.position.y - b.position.y);
  final distSq = _temp.magnitudeSquared;
  final rSum = a.radius + b.radius;

  if (distSq >= rSum * rSum) return false;

  final dist = distSq == 0 ? 0.0 : _temp.magnitude;
  if (dist == 0) {
    _temp.set(0, 1);
  } else {
    _temp.scale(1 / dist);
  }

  final penetration = rSum - dist;
  final totalInvMass = aBody.invMass + bBody.invMass;
  if (totalInvMass == 0) return true;

  final correction = penetration / totalInvMass;
  a.position.x += _temp.x * correction * aBody.invMass;
  a.position.y += _temp.y * correction * aBody.invMass;
  b.position.x -= _temp.x * correction * bBody.invMass;
  b.position.y -= _temp.y * correction * bBody.invMass;

  // relVel = aBody.velocity - bBody.velocity
  _temp2.set(aBody.velocity.x - bBody.velocity.x, aBody.velocity.y - bBody.velocity.y);
  final sepVel = _temp2.x * _temp.x + _temp2.y * _temp.y;

  if (sepVel > 0) return true;

  final e = aBody.elasticity < bBody.elasticity ? aBody.elasticity : bBody.elasticity;
  final impulseScalar = -(1 + e) * sepVel / totalInvMass;

  aBody.velocity.x += _temp.x * impulseScalar * aBody.invMass;
  aBody.velocity.y += _temp.y * impulseScalar * aBody.invMass;
  bBody.velocity.x -= _temp.x * impulseScalar * bBody.invMass;
  bBody.velocity.y -= _temp.y * impulseScalar * bBody.invMass;

  return true;
}