Bake Actions causes skewed bones on Rigify armature
Open, Needs TriagePublic

Description

System Information
Win 10 64bits / GTX 1060

Blender Version
Broken: 2.79 up to a6968e8

Short description of error
If you change position of some bones that causes stretching in the rig spine, when baking animation (Bake Actions or FBX export) the DEF bones get bizar skew rotations.

Exact steps for others to reproduce the error

  1. Create a metarig and generate a rigfy rig.
  2. Crate a simple animation. First only rotating CHEST, NECK and HEAD.
  3. Create some keyframe by moving down CHEST (this will stretch DEF spine bones)
  4. Bake Actions for every bones, visual keying, clear constaints, clear parents. (Or just export FBX with baked animations)
  5. Compare DEF bones to ORG bones. You will see DEF bones got skewed.

This problem only occurs when baking or exporting animation. Inside Blender everything is ok.

Sample file:
https://www.dropbox.com/s/d8pffr9uuzcc5go/bake-actions-problem.blend?dl=0

Details

Type
Bug
Sergey Sharybin (sergey) triaged this task as Incomplete priority.Mar 1 2018, 11:46 AM

Please always attach small demo .blend file which demonstrates the issue. This saves a lot of time spent on troubleshooting every issue.

I encounter this bug (?) when exporting an animated character to Unreal. First I thought it was a problem with the FBX export, but it seams a problem with the bake actions function instead.

Please attach the file to this bug report instead of providing a link to 3rd party website, thanks.

I uploaded the file since I have some free time.

Fable Fox (fablefox) raised the priority of this task from Incomplete to Needs Triage.Mar 9 2018, 10:31 AM

Please attach the file to this bug report instead of providing a link to 3rd party website, thanks.

Sorry @Fable Fox (fablefox), didn't find the option to upload.

Yes, this is a general issue with baking. It happens when you scale a parent bone, for some reason the scale affects the transforms of the child bone in a undesired way. I'm attaching a simple example. The armature to the left has constraints, the one to the right is the baked result. This is a really big problem for exporting to game engines.

We should subscribe Aligorith to this bug :)

No Aligorith said he looked into it but couldn't figure it out. Hopefully he can see about it again soon.

So, what's really going on here is that mathematically stacking non-uniform scaling and rotation creates shear, and there obviously are no blender pose channels for shear. Thus in this bone arrangement it is impossible to reproduce the transformation created by constraints using the pose channels, unless parent-child relations are disconnected, or Inherit Scale is unchecked.

P.S. Given that the position, scale and rotation of the bones is completely overridden by constraints, there is no need for inheriting scale (or anything) in the first place in this case.

To elaborate a bit:

  1. Applying non-uniform scale after a rotation (scaled parent with rotated child) fundamentally introduces shear in the local coordinate space of the child. This is how it works mathematically, and impossible to avoid, except by not inheriting scale.
    • Thus when Stretch To scales the parent deform bone, it shears the child. This can be seen by disabling constraints on the child.
  2. The Stretch To constraint works by extracting scale, location and a couple of direction vectors from the transformation of the object, doing some math, and reconstructing the transformation from scratch using location, rotation and scaling.
    • Thus when executed for the child bone, it destroys the shear component of the transformation and restores the bone to the straight state.
    • HOWEVER: this means that the final local transformation of the child effectively includes inverse shear to counteract shear that is induced by the parent.
  3. Blender has no shear pose channels, so it is impossible to replicate this inverse shear with simple posing, and Visual Transform To Pose or baking fails to achieve the desired result.

About the only way I can think of to inherit non-uniform scale in some form without causing shear, is to inherit it locally; i.e. 'scale X' of the parent bone directly stacking onto the 'scale X' of the child even if rotated relative to each other. However I haven't investigated the technical feasibility of such a mode, which would have to be a yet another option next to Inherit Scale etc.

Great to here some news! Thank you, Alexander.

This is a very important matter to game content developers, because it affects characters FBX export.

Regarding FBX, I have no idea whether disabling Inherit Scale would work with export, so the only solution may be what I like to call in my head a 'deform slave armature': a copy of the original armature with only deform bones, which are all unparented, and bound to follow the original deform bones with Copy Transforms constraints. Since Stretch To destroys shear, the final world transform of the bones is good, so if parenting is removed from the picture, it should be bakeable.

I think the problem is not FBX in itself, but the fact that FBX exporter only deals with pre-baked armature animation. So the problem is the bake that occurs before exporting.

I made a very simple addon that creates that 'deform slave armature' I mentioned: https://github.com/angavrilov/blender-scripts/blob/master/slave_armature.py