Unrolling rotations [Fixed]

I’m working on applying JCMs (blendshapes / morphs / shapekeys) to a character mesh.
I have everything working smoothly except in the case where rotations go over 90 degrees.

The problem is that UE will adjust the angles of the original animation, presumably to avoid gimble lock - which works great for animation, but makes applying JCMs at the correct time very difficult!

To illustrate the issue, here are the right hand shoulder curves I’m using for a test animation in Motionbuilder:

Here are the resultant curves that UE produces after applying some sort of gimble lock avoiding filter:

For reference, here is the animation:

ShoulderRotations

I am using the GetDeltaTransformFromRefPose node to get my joint angles.

~ Does anyone know how I can get the original Euler angles instead of the gimble lock adjusted ones?

1 Like

This problem leads down a rabbit hole, but progress has been made. First I tried detecting axis flipping using the algorithm given here:

This worked beautifully. However, when the quaternions were converted back to UE rots, UE applied the anti gimble lock filters again, flipping my data ± 180 degree all over the place - so no dice!

So I created a simple macro that negates the ± 180 flipping:

It ain’t pretty, but it works. It transforms these curves:

Into these:

Naively, I thought I’d solved the problem at this point. However, it seems UE’s anti gimble lock filter has two components. The first is the axis flipping I detected and compensated for above.

The second is more subtle and only kicks in when multiple axes are non-zero and one axis is approaching 90 degrees - which happens a lot in actual mocap data, most notably in shoulder joints.

To demonstrate, here are some shoulder mocap curves in MotionBuilder:

Here are the same curves in UE:

See that little wiggle on the peak of the red curve? That does not look good when driving a JCM!

Note also how the other two curves have been amplified. I am presuming this is another artifact of UE’s anti gimble lock filter and is designed to get the joint to the desired position without any one curve approaching 90 degrees.

So my mission continues. I’m still working on my assumptions about UE’s anti gimble lock filtering - if anyone thinks I’m off track, please let me know and save me some pain!

[Footnote] Note I am using the ‘Preserve Local Transform’ options on animation import - this does help with some of the above issues, but does not remove the wiggle described in my last paragraph.

After much experimentation, I’m finally hitting acceptable results. My system applies JCMs in response to joint angles, which works fine apart from complicated joints like shoulders and thighs. Shoulders and thighs need JCMs applied in response to changes in more than one joint angle (as detailed above).
So for these, I’ve implemented a two-stage Posedriver solution; the first stage applies JCMs and the second drives a twist bone. I am quite pleased with the results:

(For comparison, the Posedriver solution is applied to the left shoulder only)
The Posedriver solution does a pretty good job of maintaining both the shape and volume of the shoulder joint (check the video at around 1:20). Whilst reading up on the subject, I found out Posedrivers use a ‘radial basis function’ which according to wikipedia can be interpreted as a simple kind of neural network. So I’m using a simple neural network on my avatars - sounds kinda cool!