slerp method

Quaternion slerp(
  1. Quaternion toQuat,
  2. double t, [
  3. Quaternion? target
])

Performs a spherical linear interpolation between two quat

@param toQuat second operand @param t interpolation amount between the self quaternion and toQuat @param target A quaternion to store the result in. If not provided, a new one will be created. @returns {Quaternion} The "target" object

Implementation

Quaternion slerp(Quaternion toQuat,double t, [Quaternion? target]){
  target ??= Quaternion();
  final ax = x;
  final ay = y;
  final az = z;
  final aw = w;

  double bx = toQuat.x;
  double by = toQuat.y;
  double bz = toQuat.z;
  double bw = toQuat.w;
  double omega;
  double cosom;
  double sinom;
  double scale0;
  double scale1;

  // calc cosine
  cosom = ax * bx + ay * by + az * bz + aw * bw;

  // adjust signs (if necessary)
  if (cosom < 0.0) {
    cosom = -cosom;
    bx = -bx;
    by = -by;
    bz = -bz;
    bw = -bw;
  }

  // calculate coefficients
  if (1.0 - cosom > 0.000001) {
    // standard case (slerp)
    omega = math.acos(cosom);
    sinom = math.sin(omega);
    scale0 = math.sin((1.0 - t) * omega) / sinom;
    scale1 = math.sin(t * omega) / sinom;
  } else {
    // "from" and "to" quaternions are very close
    //  ... so we can do a linear interpolation
    scale0 = 1.0 - t;
    scale1 = t;
  }

  // calculate final values
  target.x = scale0 * ax + scale1 * bx;
  target.y = scale0 * ay + scale1 * by;
  target.z = scale0 * az + scale1 * bz;
  target.w = scale0 * aw + scale1 * bw;

  return target;
}