slerpFlat static method

void slerpFlat(
  1. dynamic dst,
  2. num dstOffset,
  3. dynamic src0,
  4. num srcOffset0,
  5. dynamic src1,
  6. num srcOffset1,
  7. num t,
)

Implementation

static void slerpFlat(
    dst, num dstOffset, src0, num srcOffset0, src1, num srcOffset1, num t) {
  // fuzz-free, array-based Quaternion SLERP operation

  double x0 = src0[srcOffset0 + 0].toDouble(),
      y0 = src0[srcOffset0 + 1].toDouble(),
      z0 = src0[srcOffset0 + 2].toDouble(),
      w0 = src0[srcOffset0 + 3].toDouble();

  double x1 = src1[srcOffset1 + 0].toDouble(),
      y1 = src1[srcOffset1 + 1].toDouble(),
      z1 = src1[srcOffset1 + 2].toDouble(),
      w1 = src1[srcOffset1 + 3].toDouble();

  if (t == 0) {
    dst[dstOffset] = x0;
    dst[dstOffset + 1] = y0;
    dst[dstOffset + 2] = z0;
    dst[dstOffset + 3] = w0;
    return;
  }

  if (t == 1) {
    dst[dstOffset] = x1;
    dst[dstOffset + 1] = y1;
    dst[dstOffset + 2] = z1;
    dst[dstOffset + 3] = w1;
    return;
  }

  if (w0 != w1 || x0 != x1 || y0 != y1 || z0 != z1) {
    var s = 1 - t;
    double cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1;
    var dir = (cos >= 0 ? 1 : -1), sqrSin = 1 - cos * cos;

    // Skip the Slerp for tiny steps to avoid numeric problems:
    if (sqrSin > Math.EPSILON) {
      var sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);

      s = Math.sin(s * len) / sin;
      t = Math.sin(t * len) / sin;
    }

    var tDir = t * dir;

    x0 = x0 * s + x1 * tDir;
    y0 = y0 * s + y1 * tDir;
    z0 = z0 * s + z1 * tDir;
    w0 = w0 * s + w1 * tDir;

    // Normalize in case we just did a lerp:
    if (s == 1 - t) {
      var f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);

      x0 *= f;
      y0 *= f;
      z0 *= f;
      w0 *= f;
    }
  }

  dst[dstOffset] = x0;
  dst[dstOffset + 1] = y0;
  dst[dstOffset + 2] = z0;
  dst[dstOffset + 3] = w0;
}