solveVelocityConstraints method

  1. @override
void solveVelocityConstraints(
  1. SolverData data
)
override

Implementation

@override
void solveVelocityConstraints(SolverData data) {
  final vA = data.velocities[_indexA].v;
  var wA = data.velocities[_indexA].w;
  final vB = data.velocities[_indexB].v;
  var wB = data.velocities[_indexB].w;

  final mA = _invMassA;
  final mB = _invMassB;
  final iA = _invIA;
  final iB = _invIB;

  final fixedRotation = iA + iB == 0.0;

  // Solve motor constraint.
  if (_enableMotor &&
      _limitState != LimitState.equal &&
      fixedRotation == false) {
    final cDot = wB - wA - _motorSpeed;
    var impulse = -_motorMass * cDot;
    final oldImpulse = _motorImpulse;
    final maxImpulse = data.step.dt * _maxMotorTorque;
    _motorImpulse = (_motorImpulse + impulse).clamp(-maxImpulse, maxImpulse);
    impulse = _motorImpulse - oldImpulse;

    wA -= iA * impulse;
    wB += iB * impulse;
  }
  final temp = Vector2.zero();

  // Solve limit constraint.
  if (_enableLimit &&
      _limitState != LimitState.inactive &&
      fixedRotation == false) {
    final cDot1 = Vector2.zero();
    final cDot = Vector3.zero();

    // Solve point-to-point constraint
    _rA.scaleOrthogonalInto(wA, temp);
    _rB.scaleOrthogonalInto(wB, cDot1);
    cDot1
      ..add(vB)
      ..sub(vA)
      ..sub(temp);
    final cDot2 = wB - wA;
    cDot.setValues(cDot1.x, cDot1.y, cDot2);

    final impulse = Vector3.zero();
    Matrix3.solve(_mass, impulse, cDot);
    impulse.negate();

    if (_limitState == LimitState.equal) {
      _impulse.add(impulse);
    } else if (_limitState == LimitState.atLower) {
      final newImpulse = _impulse.z + impulse.z;
      if (newImpulse < 0.0) {
        final rhs = Vector2.zero();
        rhs
          ..setValues(_mass.entry(0, 2), _mass.entry(1, 2))
          ..scale(_impulse.z)
          ..sub(cDot1);
        Matrix3.solve2(_mass, temp, rhs);
        impulse.x = temp.x;
        impulse.y = temp.y;
        impulse.z = -_impulse.z;
        _impulse.x += temp.x;
        _impulse.y += temp.y;
        _impulse.z = 0.0;
      } else {
        _impulse.add(impulse);
      }
    } else if (_limitState == LimitState.atUpper) {
      final newImpulse = _impulse.z + impulse.z;
      if (newImpulse > 0.0) {
        final rhs = Vector2.zero();
        rhs
          ..setValues(_mass.entry(0, 2), _mass.entry(1, 2))
          ..scale(_impulse.z)
          ..sub(cDot1);
        Matrix3.solve2(_mass, temp, rhs);
        impulse.x = temp.x;
        impulse.y = temp.y;
        impulse.z = -_impulse.z;
        _impulse.x += temp.x;
        _impulse.y += temp.y;
        _impulse.z = 0.0;
      } else {
        _impulse.add(impulse);
      }
    }
    final p = Vector2.zero();

    p.setValues(impulse.x, impulse.y);

    vA.x -= mA * p.x;
    vA.y -= mA * p.y;
    wA -= iA * (_rA.cross(p) + impulse.z);

    vB.x += mB * p.x;
    vB.y += mB * p.y;
    wB += iB * (_rB.cross(p) + impulse.z);
  } else {
    // Solve point-to-point constraint
    final cDot = Vector2.zero();
    final impulse = Vector2.zero();

    _rA.scaleOrthogonalInto(wA, temp);
    _rB.scaleOrthogonalInto(wB, cDot);
    cDot
      ..add(vB)
      ..sub(vA)
      ..sub(temp);
    Matrix3.solve2(_mass, impulse, cDot..negate());

    _impulse.x += impulse.x;
    _impulse.y += impulse.y;

    vA.x -= mA * impulse.x;
    vA.y -= mA * impulse.y;
    wA -= iA * _rA.cross(impulse);

    vB.x += mB * impulse.x;
    vB.y += mB * impulse.y;
    wB += iB * _rB.cross(impulse);
  }

  // data.velocities[_indexA].v.set(vA);
  data.velocities[_indexA].w = wA;
  // data.velocities[_indexB].v.set(vB);
  data.velocities[_indexB].w = wB;
}