initVelocityConstraints method

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

Implementation

@override
void initVelocityConstraints(SolverData data) {
  _indexA = bodyA.islandIndex;
  _indexB = bodyB.islandIndex;
  _localCenterA.setFrom(bodyA.sweep.localCenter);
  _localCenterB.setFrom(bodyB.sweep.localCenter);
  _invMassA = bodyA.inverseMass;
  _invMassB = bodyB.inverseMass;
  _invIA = bodyA.inverseInertia;
  _invIB = bodyB.inverseInertia;

  final cA = data.positions[_indexA].c;
  final aA = data.positions[_indexA].a;
  final vA = data.velocities[_indexA].v;
  var wA = data.velocities[_indexA].w;

  final cB = data.positions[_indexB].c;
  final aB = data.positions[_indexB].a;
  final vB = data.velocities[_indexB].v;
  var wB = data.velocities[_indexB].w;

  final qA = Rot();
  final qB = Rot();
  final d = Vector2.zero();
  final temp = Vector2.zero();
  final rA = Vector2.zero();
  final rB = Vector2.zero();

  qA.setAngle(aA);
  qB.setAngle(aB);

  // Compute the effective masses.
  d
    ..setFrom(localAnchorA)
    ..sub(_localCenterA);
  rA.setFrom(Rot.mulVec2(qA, d));
  d
    ..setFrom(localAnchorB)
    ..sub(_localCenterB);
  rB.setFrom(Rot.mulVec2(qB, d));
  d
    ..setFrom(cB)
    ..sub(cA)
    ..add(rB)
    ..sub(rA);

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

  // Compute motor Jacobian and effective mass.
  {
    _axis.setFrom(Rot.mulVec2(qA, localXAxisA));
    temp
      ..setFrom(d)
      ..add(rA);
    _a1 = temp.cross(_axis);
    _a2 = rB.cross(_axis);

    _motorMass = mA + mB + iA * _a1 * _a1 + iB * _a2 * _a2;
    if (_motorMass > 0.0) {
      _motorMass = 1.0 / _motorMass;
    }
  }

  // Prismatic constraint.
  {
    _perp.setFrom(Rot.mulVec2(qA, _localYAxisA));

    temp
      ..setFrom(d)
      ..add(rA);
    _s1 = temp.cross(_perp);
    _s2 = rB.cross(_perp);

    final k11 = mA + mB + iA * _s1 * _s1 + iB * _s2 * _s2;
    final k12 = iA * _s1 + iB * _s2;
    final k13 = iA * _s1 * _a1 + iB * _s2 * _a2;
    var k22 = iA + iB;
    if (k22 == 0.0) {
      // For bodies with fixed rotation.
      k22 = 1.0;
    }
    final k23 = iA * _a1 + iB * _a2;
    final k33 = mA + mB + iA * _a1 * _a1 + iB * _a2 * _a2;

    _k.setValues(k11, k12, k13, k12, k22, k23, k13, k23, k33);
  }

  // Compute motor and limit terms.
  if (_enableLimit) {
    final jointTranslation = _axis.dot(d);
    if ((_upperTranslation - _lowerTranslation).abs() <
        2.0 * settings.linearSlop) {
      _limitState = LimitState.equal;
    } else if (jointTranslation <= _lowerTranslation) {
      if (_limitState != LimitState.atLower) {
        _limitState = LimitState.atLower;
        _impulse.z = 0.0;
      }
    } else if (jointTranslation >= _upperTranslation) {
      if (_limitState != LimitState.atUpper) {
        _limitState = LimitState.atUpper;
        _impulse.z = 0.0;
      }
    } else {
      _limitState = LimitState.inactive;
      _impulse.z = 0.0;
    }
  } else {
    _limitState = LimitState.inactive;
    _impulse.z = 0.0;
  }

  if (_enableMotor == false) {
    _motorImpulse = 0.0;
  }

  if (data.step.warmStarting) {
    // Account for variable time step.
    _impulse.scale(data.step.dtRatio);
    _motorImpulse *= data.step.dtRatio;

    final p = Vector2.zero();
    temp
      ..setFrom(_axis)
      ..scale(_motorImpulse + _impulse.z);
    p
      ..setFrom(_perp)
      ..scale(_impulse.x)
      ..add(temp);

    final lA =
        _impulse.x * _s1 + _impulse.y + (_motorImpulse + _impulse.z) * _a1;
    final lB =
        _impulse.x * _s2 + _impulse.y + (_motorImpulse + _impulse.z) * _a2;

    vA.x -= mA * p.x;
    vA.y -= mA * p.y;
    wA -= iA * lA;

    vB.x += mB * p.x;
    vB.y += mB * p.y;
    wB += iB * lB;
  } else {
    _impulse.setZero();
    _motorImpulse = 0.0;
  }

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