Just *ported* a spherical cubic (quadrangle) interpolation method to be used with Ardor3D‘s quaternions. I shamelessly ripped it, so I might as well share it:

Quaternion store) {

Quaternion c = Quaternion.fetchTempInstance();

Quaternion d = Quaternion.fetchTempInstance();

q1.multiply(1 - t, c);

q2.multiply(t, d);

q1.add(q2, store);

store.normalizeLocal();

Quaternion.releaseTempInstance(c);

Quaternion.releaseTempInstance(d);

return store;

}

public static Quaternion slerpNoInvert(Quaternion q1, Quaternion q2,

double t, Quaternion store) {

Quaternion c = Quaternion.fetchTempInstance();

Quaternion d = Quaternion.fetchTempInstance();

double dot = q1.dot(q2);

if (dot > -0.95f && dot < 0.95f) {

double angle = MathUtils.acos(dot);

q1.multiply(MathUtils.sin(angle * (1 - t)), c);

q2.multiply(MathUtils.sin(angle * t), d);

c.add(d, store);

divide(store, MathUtils.sin(angle), store);

store.normalizeLocal();

} else {

lerp(q1, q2, t, store);

}

Quaternion.releaseTempInstance(c);

Quaternion.releaseTempInstance(d);

return store;

}

public static Quaternion divide(Quaternion a, double n, Quaternion store) {

if (0 == n)

throw new ArithmeticException("Divide by zero!");

return store.set(store.getX() / n, store.getY() / n, store.getZ() / n,

store.getW() / n);

}

public static Quaternion squad(Quaternion q1, Quaternion q2, Quaternion a,

Quaternion b, double t, Quaternion store) {

Quaternion c = Quaternion.fetchTempInstance();

Quaternion d = Quaternion.fetchTempInstance();

slerpNoInvert(q1, q2, t, c);

slerpNoInvert(a, b, t, d);

slerpNoInvert(c, d, 2 * t * (1 - t), store);

Quaternion.releaseTempInstance(c);

Quaternion.releaseTempInstance(d);

return store;

}

Will Perone, thanks!

EDIT: The previous version had a divide-by-zero problem, which should be fixed in the code above.