setSlerp method

void setSlerp(
  1. Quaternion a,
  2. Quaternion b,
  3. double t
)

Set to the spherical interpolation from a (t = 0) to b (t = 1), along the shorter arc. Safe when this is a or b.

Implementation

void setSlerp(Quaternion a, Quaternion b, double t) {
  var bx = b.x, by = b.y, bz = b.z, bw = b.w;
  var cosOmega = a.x * bx + a.y * by + a.z * bz + a.w * bw;
  if (cosOmega < 0.0) {
    cosOmega = -cosOmega;
    bx = -bx;
    by = -by;
    bz = -bz;
    bw = -bw;
  }
  double ka, kb;
  if (cosOmega > 0.9995) {
    // Nearly parallel: lerp, then normalise.
    ka = 1.0 - t;
    kb = t;
  } else {
    final omega = math.acos(cosOmega);
    final sinOmega = math.sin(omega);
    ka = math.sin((1.0 - t) * omega) / sinOmega;
    kb = math.sin(t * omega) / sinOmega;
  }
  final ax = a.x, ay = a.y, az = a.z, aw = a.w;
  x = ax * ka + bx * kb;
  y = ay * ka + by * kb;
  z = az * ka + bz * kb;
  w = aw * ka + bw * kb;
  normalize();
}