initVelocityConstraints method
void
initVelocityConstraints(
- 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;
}