To blend quaternions correctly I had to implement weighted quaternions, these are scaled, non-normal quaternions which are contributed into the blend buffer and eventually combine into a regular, near-normalised, quaternion. Getting this working was quite a mean feat, various boundary cases play havoc with the interpolation causing the actor to 'jump' sporadically when extreme blends are performed. The main issue was that a dot product test would change sign, signalling a sign-inversion of the to-be-weighted quaternion, this is important to ensure a shortest-arc blend around the quaternion hypersphere. Unfortunately the sign would change a fraction too early, as a consequence of the discretised sampling and tweening. To solve this I detect when the dot product is close to zero, at which point I begin calculating both the inverted and non-inverted quaternions, contributing them both to copies of the destination buffer. I then blend between the destination buffer alternatives, depending on the actual value of the dot product in the epsilon range around zero. This has the effect of smoothing out the inversion transitions in a range around the boundary case and produces visually pleasing results.
Calculating the positional and rotational velocities is simply a matter of working out the delta from frame to frame, the rotational delta is propagated through the blend-tree but not through the pose structure, rather it is propagated through the blend_info structure. This structure holds various useful infos that travel from node to node, including the destination buffer, blend weight, skeletal structure/bone names and the rotational delta. Rotation is handled separately simply because of the nature of this delta. It's actually the rotational delta around the y-axis, the x and z axis are not stored as deltas and remain in the pose structure to be blended as usual, only the y-axis rotation is converted to a delta since this decides the heading of the character over an essentially 2D terrain system. Naturally, to achieve this, I have to extract the y-rotation from the interpolated root rotation, this proved interesting when combined with my smoothing algorithm and required a couple of attempts to get it right.
All in all the quaternion blending is quite robust, numerically stable and reasonably fast, although there's plenty of room for improvement.
No comments:
Post a Comment