slerp method
Implementation
Quaternion slerp(Quaternion qb, double t) {
if (t == 0) return this;
if (t == 1) return setFrom(qb);
final x = _x, y = _y, z = _z, w = _w;
// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
double cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
if (cosHalfTheta < 0) {
_w = -qb._w;
_x = -qb._x;
_y = -qb._y;
_z = -qb._z;
cosHalfTheta = -cosHalfTheta;
} else {
setFrom(qb);
}
if (cosHalfTheta >= 1.0) {
_w = w;
_x = x;
_y = y;
_z = z;
return this;
}
final sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
if (sqrSinHalfTheta <= MathUtils.epsilon) {
final s = 1 - t;
_w = s * w + t * _w;
_x = s * x + t * _x;
_y = s * y + t * _y;
_z = s * z + t * _z;
normalize();
onChangeCallback();
return this;
}
final sinHalfTheta = math.sqrt(sqrSinHalfTheta);
final halfTheta = math.atan2(sinHalfTheta, cosHalfTheta);
final ratioA = math.sin((1 - t) * halfTheta) / sinHalfTheta,
ratioB = math.sin(t * halfTheta) / sinHalfTheta;
_w = (w * ratioA + _w * ratioB);
_x = (x * ratioA + _x * ratioB);
_y = (y * ratioA + _y * ratioB);
_z = (z * ratioA + _z * ratioB);
onChangeCallback();
return this;
}