Description
I believe this was previously noticed by @djeedai in the review of the Animatable
trait rollout.
I am not an expert in this subject, but here is my understanding.
Context
In additive animation blending, a sample from an animation clip represents a relative displacement rather than an absolute quantity; this is applied on top of other animations by combining the displacement with the absolute quantity "underneath". Like non-additive animation blending (which interpolates between two absolute quantities instead), this can be used in concert with a weight which indicates the strength of the sample's influence in the blend. For additive blending, this means that, as the weight tends to zero, the displacement also attenuates; with a weight of zero, the blend should have no effect on the existing quantity.
For example, additive blending of translational components works something like this:
let (displacement, weight): (Vec3, f32) = incoming_sample;
translation += displacement * weight
The right-hand side of this is perhaps best conceptualized as:
Vec3::lerp(Vec3::ZERO, displacement, weight)
In other words, the additively blended sample is interpolated with zero and then composed with the existing value.
The mismatch
Now, currently additive blending for Quat works like this:
let (rot_displacement, weight): (Quat, f32) = incoming_sample;
rotation = rotation.slerp(rot_displacement, weight);
What I would expect based on my understanding of additive blending is instead something like this:
let (rot_displacement, weight): (Quat, f32) = incoming_sample;
rotation = Quat::slerp(Quat::IDENTITY, rot_displacement, weight) * rotation;
Note that these are definitely not equivalent — when the incoming sample is Quat::IDENTITY
, the latter never has any effect, while the former (with positive weight) will slerp the current rotation state towards the default orientation.
Of course, it's possible this was an intentional decision and I'm missing something; this is just my understanding of things.