Page MenuHome

Bake Actions causes skewed bones on Rigify armature
Closed, InvalidPublic

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

Event Timeline

Sergey Sharybin (sergey) lowered the priority of this task from 90 to 30.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 30 to 90.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

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.

I can confirm that inherit scale is not needed on def bones. Rigify always constrains the DEF- bones through copytransform. I will make some more tests to verify we can uncheck this by default in next rigify updates to make things easier.

In the while we are working on a script that will sort both parenting and inherit scale, bakes all on DEF- bones and removes all other useless bones before exporting to fbx.

As long as we are talking about rigify the export to game engines problem should be sorted out.

We need some more testing, but form what i’ve seen so far even exremes deformation like the one i showed in the bcon18 panel should work.

@Alexander Gavrilov (angavrilov) thanks for looking into this!

Sebastian Parborg (zeddb) lowered the priority of this task from 90 to Normal.Feb 11 2019, 4:34 PM

I'll put this as normal because it seems @Joshua Leung (aligorith) has already triaged this(?)

the addon by @Paolo Acampora (pkrime) posted in https://developer.blender.org/T57536 seems to address the issue in our tests. As for now it's destructive for the rig itself but can easily be modified to create a non destructive workflow like creating a data block copy of the original rig armature, make the bake on the reparented bones armature created by the script and after the export reassign the original rig data block to the armature object.

Same trouble in 2.81. + there is another issue: when I am exporting in fbx (only deform bones) in fbx file a lot of ORG bones. Have you guys have some idea how I can fix my rig or I need to make everything from scratch?

@Aleksandr (viadvena),
We started some basic approach to this in 2.79. You can check if solution @Paolo Acampora (pkrime) suggested in https://developer.blender.org/T57536 still works in 2.8 or needs some triage.

@Alexander Gavrilov (angavrilov), maybe we can check if inherit scale can be turned off by default (or use your new options) on rigify DEF-bones to make things easier.

@Ivan Cappiello (icappiello) Doesn't work at all :(( Could someone to refresh this addon? I completely rip my brain to try figure this rig out all night and day long... This mystic thing make me crazy: I tried bake everything and reassign parents, manual delete all helper bones etc.... and this damn stretch still there forever only after exporting.

Sybren A. Stüvel (sybren) changed the task status from Confirmed to Needs Information from User.Jan 9 2020, 6:21 PM

The example files are far too complex to analyze. Please trim it down to the bare minimum number of bones that are required to demonstrate the issue, provide steps to reproduce the issue (given the blend file, not from scratch), and make sure there are no errors/warnings about invalid drivers.

Campbell Barton (campbellbarton) changed the subtype of this task from "Report" to "Bug".Jan 13 2020, 9:52 AM
Campbell Barton (campbellbarton) changed the subtype of this task from "Bug" to "Report".Jan 14 2020, 8:08 AM
Sybren A. Stüvel (sybren) claimed this task.

No activity for more than a week. As per the tracker policy we assume the issue is gone and can be closed.

Thanks again for the report. If the problem persists please open a new report with the required information.

This issue definitely isn't gone; in fact it's the opposite, as in a way it can be classified as fundamentally unsolvable (at least, without compromises).

This issue definitely isn't gone; in fact it's the opposite, as in a way it can be classified as fundamentally unsolvable (at least, without compromises).

Should this be an open Known Issue then?
(I am all for tiding up the tracker, but closing will just put up a barrier in finding/referencing this later...)

@Philipp Oeser (lichtwerk) according to the flow diagram on https://code.blender.org/2019/12/tracker-curfew/ reports about current architectural/design limitations should be closed.

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.

@Alexander Gavrilov (angavrilov) correct me if I'm wrong, you'd have to transform the parent's scale vectors into the space of the child --so that the 'scale X' of the parent might become some combination of the child's XYZ, and the same for the Y and Z axes-- and then multiply those transformed components with the corresponding ones from the child's local scale, and disable the child's 'Inherit Scale' property since it's now baked.
So you're not just taking the parent's scale and passing it as the initial scale of the child (before its own keyframes and constraints act on), you're transforming that parent scale first to the space of the child, then doing that. The result is different.
This could be an option in the baking operator, "Transform Inherited Scale" or something like that. It needs to be optional because there might be some rare user cases that actually rely on a shear with no constraints, and want it baked.

Blender has had advanced Inherit Scale modes for a while now, and Aligned is what I meant there: https://docs.blender.org/manual/en/dev/animation/armatures/bones/properties/relations.html#parenting

If the local matrix of the bone is sheared (e.g. due to un-shearing the world matrix with Stretch To after shear was inherited from parent), it can't be baked period, because loc+rot+scale can only produce a non-sheared local matrix.