slerpFlat static method
void
slerpFlat()
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;
}