Page MenuHome

2.80 FBX export simplify key not working as expected
Open, Confirmed, MediumPublic

Description

The 'Simplify' keys option doesn't appear to work correctly

Goal

  • to export all channels with keys.
  • keep keys that are the same value (flat curves).
  • not add keys to channels that don't have keys.

With 'simplify' set to 0.01 up to 1 - all keys that have a flat curve are removed, even rotations that are not 0,0,0.
With 'simplify' set to 0 (disabled) - all animate-able channels are keyed, even if there are no curves/keys on them.

This means there is no way to export with keys on only the channels I animated.

Should this be fixed???
Simplify shouldn't remove curves that are flat (especially if the values are not default) - or it should be a check box.
Disabling 'simplify' shouldn't add keys to un-keyed channels - we have 'Force Start/End keying' for that.

Current workaround
I can get what I want by ensuring all bones with currently flat curves have some small tweak to make them not flat. Bit of a PITA as you might expect.

If these can't be fixed or aren't considered bugs then we don't have full control over animation exported from Blender in FBX files :(

Details

Type
Bug

Event Timeline

Bastien Montagne (mont29) lowered the priority of this task from Needs Triage by Developer to Needs Information from User.

That sounds like at least an important TODO yes… Can you please upload a (very simple ;) file demonstrating the issue? Would be simpler for me than having to create one, and would be sure of what you expect exactly here.

Sure thing, I'll whip one up shortly.

I've attached a simple test scene.

  • You'll notice the Right arm has flat keys but not 0,0,0
  • The mesh has Shapes but they aren't keyed.

If it can be exported without the Shapes being keyed and keeping the flat curves, that would be amazing!

As mentioned before I believe disabling 'simplify' by setting it to 0 should do this. Otherwise it's doing the opposite and is essentially a 'complexify' setting!

As an aside, I'm very happy to put time into testing any changes to the FBX exporter, happy to be notified and grab builds for testing, is there a list to get put on? Plenty of experience to offer :)

Hey Bastien,
I've attached a new scene with the exported FBX examples imported back in :)

I know this isn't currently classed as a bug. However after fighting it most of today I'm convinced it is (Desperately trying to escalate) hehe
If you try to use it in anger (which people will do very soon)! it's simply broken.

Say you are exporting to unity and you want to leave some channels un-keyed because they will be controlled via script/code/animator. You also have a lot of animations, like idles where the feet don't move - So flat animation curves.

Bit of Extra info from testing today...

  • Simplify removes flat curves completely - (That's a horrid assumption, surely pin em with a key at the start. Un-keyed channels, leave them un-keyed)
  • If you use 'Key All Bones' check box to force a key, simplify then removes it!
  • If you turn simplify off it keys all the params, those with keys and those without! - (We have Force Start/End keying for that).
  • So to get what I need, I have to either nobble anims to make curves not flat

OR

  • In unity make duplicate animations and remove all the unwanted keys.

If you have a large number of animations neither route is workable and leads to moments of deep frustration and or heavy drinking.

Bastien Montagne (mont29) raised the priority of this task from Needs Information from User to Confirmed, Medium.Jun 3 2019, 9:09 PM

Thanks, see what’s happening here now. Thing is, we never actually export anim curves, but rather results of baked animation (which includes anim curves, but also constraints, drivers, and possibly other things affecting object transformations). Taking actually existing anim curves into account in the FBX-keying process is definitively possible, but not a small change, so at that point it will have to wait for after 2.80 release.

Hey Bastein,

*EDIT Hmm just dawned on me that this proposal would only work on directly keyed channels (as in the example scenes), but not those with drivers, constraints, simulations etc, the obfuscation scuppers it :( Will look for a workaround pre-export. *

Thanks for the reply, really appreciated. Understanding how it works may help me find a work around. Sounds like...

  • When simplify is on (and above 0), it bakes all animate-able channels (keyed or un-keyed)
  • Then it simplifies curves and removes all flat curves

BUT

  • When simplify is set to 0 it just bakes all animate-able channels.

If the above is correct some improvements could be made, without adding support for un-plotted curves.
For example perhaps...
If the exporter could make list of channels categorised as...

  • all the animate-able channels
  • all the un-keyed animate-able channels
  • all the keyed channels with values of 0 (Flat keys), with perhaps a tolerance option.

Then after the initial simplify bake we can run another evaluation on the channels stored above to provide a comparison. This would help us get what we want.

  • If un-keyed channels are now keyed we can remove they keys.
    • Then (if selected) apply the options 'Key all Bones' and 'Force Start/End Keying'
  • If the curves were removed from channels with flat curves (by Simplify).
    • Have a new option of 'Keep Flat Curves' (This only runs on channels that were keyed with 0 values.) This then acts like 'Force Start/End Keying' on these channels.

With a new 'Keep Flat Curves' option you can leave 'Key all Bones' and 'Force Start/End Keying' unchecked and still get keys for flat curves but importantly not on un-keyed channels.

This assumes that my understanding of how the exporter works is correct. If it is I think we'd get all the functionality (options do what they say they do) without doing any heavy lifting to pass Curves as they are without baking.

Be interesting to see what you think and if this is even a plausible solution! :)

Cheers.

Hi there, Hijacking this thread for a microsecond with something rather related

we never actually export anim curves, but rather results of baked animation (which includes anim curves, but also constraints, drivers, and possibly other things affecting object transformations).

As far as I'm seeing the data is all packaged, but only a few items are being kept track of namely these

kinds = {
        'LCL_TRANSLATION': ("Lcl Translation", "T", ("X", "Y", "Z")),
        'LCL_ROTATION': ("Lcl Rotation", "R", ("X", "Y", "Z")),
        'LCL_SCALING': ("Lcl Scaling", "S", ("X", "Y", "Z")),
        'SHAPE_KEY': ("DeformPercent", "DeformPercent", ("DeformPercent",)),
        'CAMERA_FOCAL': ("FocalLength", "FocalLength", ("FocalLength",)),
}

Would it be possible to create a CurveNode kind or a Number kind in here or am I looking in the wrong spot?

Turns out I wasn't looking in the wrong spot afterall. Figure I'd mention it. It's not perfect to be sure, but it looks to be almost doing what I need. I'll have to open a merge ticket or something once it's ready.

`
    kinds = {
        'LCL_TRANSLATION': ("Lcl Translation", "T", ("X", "Y", "Z")),
        'LCL_ROTATION': ("Lcl Rotation", "R", ("X", "Y", "Z")),
        'LCL_SCALING': ("Lcl Scaling", "S", ("X", "Y", "Z")),
        'SHAPE_KEY': ("DeformPercent", "DeformPercent", ("DeformPercent",)),
        'CAMERA_FOCAL': ("FocalLength", "FocalLength", ("FocalLength",)),
        'CUSTOM': ("Value", "Value", ("Value",)),
    }

    def __init__(self, elem_key, kind, force_keying, force_startend_keying, default_values=...):
        self.elem_keys = [elem_key]
        assert(kind in self.kinds)
        if kind != 'CUSTOM':
            self.fbx_group = [self.kinds[kind][0]]
            self.fbx_gname = [self.kinds[kind][1]]
            self.fbx_props = [self.kinds[kind][2]]
        else:
            self.fbx_group = [elem_key]
            self.fbx_gname = [elem_key]
            self.fbx_props = [(elem_key,)]
`

Also, Relating to this bug report and a possible temporary fix for Malcom,

if val == p_val:
                    # Never write keyframe when value is exactly the same as prev one!
                    continue

fbx_utils.py line 797
remove the block, reload scripts and just maybe you won't need to slightly alter any bone since it won't be skipped over in the first place, this will also create a bunch of needless key-frames though and it might not even solve the issue. idk, as I thought I said but didn't, I just had the open file.