johnbakers
johnbakers

Reputation: 24771

Non-linear slerp animation with quaternion

While the popular slerp formula for interpolating between 3D orientations is pretty cool and useful, it occurs to me that this is a linear animation.

Less complicated animation, such as simple tweening between floats, is easily altered to quadratic ease-in and ease-out, but the slerp formula is not so simple (its inventor Shoemake didn't even publish the formula's derivation upon his initial discovery).

So I'm using this:

template <typename T>
inline QuaternionT<T> QuaternionT<T>::Slerp(T t, const QuaternionT<T>& v1) const
{  
const T epsilon = 0.0005f;
T dot = Dot(v1);

if (dot > 1 - epsilon) {
    QuaternionT<T> result = v1 + (*this - v1).Scaled(t);
    result.Normalize();
    return result;
}

if (dot < 0)
    dot = 0;

if (dot > 1)
    dot = 1;

T theta0 = std::acos(dot);
T theta = theta0 * t;

QuaternionT<T> v2 = (v1 - Scaled(dot));
v2.Normalize();

QuaternionT<T> q = Scaled(std::cos(theta)) + v2.Scaled(std::sin(theta));
q.Normalize();
return q;
}

Does anyone know how to make this an easing interpolation based on t (which is the elapsed/duration)?

Upvotes: 3

Views: 911

Answers (1)

Rahul Banerjee
Rahul Banerjee

Reputation: 2363

It is the rate of change of t that controls the "ease" of the lerping, not the lerping itself. I assume that T is a scalar (like float/double).

AFAICT, you're trying to get an ease-in effect, but the path itself is a "straight" rotation between the start and end quaternions. Consequently, as long as t varies from 0 to 1, all you have to do is vary the rate of change of t to get your "easing interpolation".

I usually use the 3*t^2-2*t^3 formula for ease in/out. I'll leave a Wikipedia link here, just in case.

(I feel like I'm missing something here. Let me know if this answered your question).

Upvotes: 2

Related Questions