godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.42k stars 20.24k forks source link

Missing tracks in imported .glb (glTF) animations #59150

Closed bartekd97 closed 1 year ago

bartekd97 commented 2 years ago

Godot version

4.0 alpha 4

System information

Windows 11

Issue description

I use animation from Mixamo. One animation clip per .glb file. Each file has same problem: left-hand fingers nodes have both, rotation and position tracks but right-hand fingers nodes have only position tracks, without rotation. Importing animations to blender or different engines has no such issue.

Changing import options like "Optimizer", "Compression" or "Import Tracks" has no effect. Re-exporting animations to .gltf format instead .glb has no effect too.

Steps to reproduce

  1. Import any of attached animation file
  2. Drag&drop imported asset to a scene
  3. Right click > Editable Children
  4. Select AnimationPlayer
  5. You'll see that e.g. LeftHandPinkyX have both position and rotation tracks, but equivalent RightHandPinkyX only position.
  6. Now import file to Blender - all tracks exists as they should

Minimal reproduction project

anim.zip

fire commented 2 years ago

I noticed there's no mesh. Please review https://github.com/KhronosGroup/glTF-Blender-IO/pull/1582 for exporting pure animations.

Edited: 1582

bartekd97 commented 2 years ago

I noticed there's no mesh. Please review KhronosGroup/glTF-Blender-IO#1582 for exporting pure animations.

Edited: 1582

I store meshes and animations in separate files and reuse them. Had no problems so far until now, when I started working with hand attachements and noticed that something is not right. Files I use (and attached here) comes from project that I've already made in different engine and now slowly porting to Godot.

fire commented 2 years ago

Godot and Blender require an armature structure which is guessed from the gltf file.

The 1582 pr forces the Blender Armature / Godot Skeleton3D through adding the gltf nodes to a skin object. See the issue in the pr for more details.

bartekd97 commented 2 years ago

Godot and Blender require an armature structure which is guessed from the gltf file.

The 1582 pr forces the Blender Armature / Godot Skeleton3D through adding the gltf nodes to a skin object. See the issue in the pr for more details.

Checked PR and and tried re-exporting with skeleton info. It imports structure as skeleton now, but it still doesn't solve the issue and tracks are missing. Actually, regular hierachy instead of Skeleton was not a problem for me - I made a simple tool script to postprocess all imported animations to make them compatible with Skeleton3D. No problems so far, most of controller scripts have already done.

The problem is that some tracks are actually missing although they exist in file.

While exporimentiing with this updated glTF blender addon I've noticed one thing that could be a clue:

Here I attach one of the animations re-exported to .gltf text file (with regular hierachy, no skeleton), so you can manually analyze it that rotation animation track actually exists (e.g. node id 38) but is not imported by Godot. untitled.zip

fire commented 2 years ago

We added a feature several months ago to address this. I forgot.

Screenshot from 2022-03-14 20-13-06

fire commented 2 years ago

I believe we're supposed to blend animation with also the RESET pose. It was discussed at some point that we didn't want to generate placeholder tracks that reset the animation when the RESET track feature exists. Another feature that interacts is because a transform is split into three in the spec the tracks aren't physically there.

Can you describe more about how you use this feature?

I'll be back with a data inspection diagram.

fire commented 2 years ago

I think there's probably an off by one by where constant values different from the RESET pose for one frame are lost.

julienduroure commented 2 years ago

In Blender 3.1, did you try to uncheck "optimize animation size"? image

This option remove constant animation of nodes. Uncheck it will export animation anyway, even if all keyframes are equals

bartekd97 commented 2 years ago

I believe we're supposed to blend animation with also the RESET pose. It was discussed at some point that we didn't want to generate placeholder tracks that reset the animation when the RESET track feature exists. Another feature that interacts is because a transform is split into three in the spec the tracks aren't physically there.

Can you describe more about how you use this feature?

I'll be back with a data inspection diagram.

I store character mesh in a separate .glb file with skeleton in T-Pose as rest pose (those T-Pose transforms i use in RESET track, so they are default if no track is defined for a bone in animation). Every animation clip I store in separate .glb file. Those files are pure Mixamo animation, just reexported to .glb from original .fbx. They all had armature in T-Pose (it's important to note) but actual initial pose of animation is defined in first frame using keyframes, and some of values don't change over time.

Importing mesh to Godot with Skeleton in T-Pose works flawlessy. Importing animation file works fine too, the only problem I had is that imported animation refers to regular node structure instead of Skeleton bone name. I simply made editor PostImport script that renames track paths to refer Skeleton and it works very well, can create and use animation trees on my character with no problem.

The problem is when some track value doesn't change over time (so bone pose is set once in first frame and thats all) - then this track is not imported by Godot and animator uses value from RESET, so T-Pose pose instead of pose defined by first frame of animation clip.

I've just noticed another thing: If I export original animation file (with T-Pose as rest pose) now with updated addon that exports actual Skeleon, then althroguh tracks are still missing, the rest pose of Skeleton3D that comes with importing such file is not T-Pose but pose defined by keyframes from first animation frame! Noticed that same situation is in my current workflow, with converting regular hierarchy to Skeleton3D - nodes are initially set to transform of first animation frame.

I can workaround problem by updating my PostImport script to add missing tracks using those transforms, but still, this is not a valid solution. Initial pose defiend by first frame instead of original T-Pose could be because of glTF exporter, because I was working with those files eralier already. I think that Godot somehow skips importing animation tracks whose keyframes don't differ from original value, even with disabled Optimizer etc. If you try to improt this file again to Blender, then it works fine and imports such tracks, and this is expected behaviour in Godot - so those tracks physically exist in file, I analyzed that in my previous post where I attached sample .gltf text file that contains such tracks that are not imported by Godot.

bartekd97 commented 2 years ago

In Blender 3.1, did you try to uncheck "optimize animation size"? image

This option remove constant animation of nodes. Uncheck it will export animation anyway, even if all keyframes are equals

Yes, but it doesn't change anything. Tracks, that are not imported by Godot, do exist in file - otherwise they wouldn't be imported by Blender.

image

bartekd97 commented 2 years ago

I see in source that glTF importer has hardcoded skipping animation tracks whose all keys are equal to node rest value. And rest pose is always set to first animation frame during exporting from Blender - at least in my cases.

It's definitely going to be even more problematic when resuing more animation clips on more different, but compatible character - rest pose on character node will be usually different than rest pose in animation file, so I think it's better not to have enforced such optimization.

No other scene importer I see in Godot does that - tested exporting to different formats and this problem doesn't occur, everything is fine.

Will make a PR later.

SunnyEX00 commented 2 years ago

For anyone interested in a simple workaround: Add one more animation to the NLA tracks. It should be one keyframe of your model in rest pose. Make this the top track with all tracks muted. This will force blender's exporter to export your intended rest pose as the rest pose for the file. This works for me for now, but I will probably need these constant tracks, including ones that match the rest pose, in order to do layered animations correctly image

julienduroure commented 2 years ago

And rest pose is always set to first animation frame during exporting from Blender - at least in my cases.

This is no more the case since Blender 3.2. Now, by default, rest pose (ie when armature is in edit mode) is used as rest pose at export.

lyuma commented 1 year ago

The usability of glTF animation export has improved greatly in Blender 3.2 and every subsequent version.

As for the original issue, there is an issue that animation tracks with only one keyframe will be removed when identical to the rest pose. The real issue here is the rest pose is identical to the animation keyframe, which means retargeting won't work as expected. Since this issue was reported, we did add a checkbox in Godot 4.0 (see PR #72342 ) to the import settings to workaround this exact issue:

If you encounter this issue and do not intend to use retargeting, you can disable the "Remove Immutable Tracks" option under the Animation section of the Scene, and then optionally change the "Import Tracks" dropdowns in the AnimationPlayer node of the advanced import settings to remove unwanted Scale tracks.

Otherwise, going through newer versions of Blender should be an option and will work better on the latest version of Blender.

Given that there has been no new comments or reports on this issue for most of a year, I think it is reasonable to close this issue at this point.

Edit: adding screenshot showing both settings (Remove Immutable Tracks) that I recommend changing for the originally reported glb files: Remove Immutable Tracks

wilfredjonathanjames commented 1 year ago

I see in source that glTF importer has hardcoded skipping animation tracks whose all keys are equal to node rest value. And rest pose is always set to first animation frame during exporting from Blender - at least in my cases.

This seems to still be the case. I turned off the optimiser, and only moving my bones slightly out of rest position helped.

If it is then this would explain my problem

I switch between equip animations depending on equipped item. Some items don't require me to update the hand position.

Because Godot drops the tracks that match bone rest those bones stay in their last position.

So if my player equips a chocolate bar (pinch movement) and then holds a crate (flat hand, rest pose), the hand is still in a pinched position while holding the crate.

If this is still the case, and it seems to be, this really needs to be an importer option.

@Calinou or someone similar, can we reopen this issue, or shall I make a new one?

levidavidmurray commented 9 months ago

I ran into this as well. I disabled the optimizer in Blender export settings, and everything worked fine. However, after making some changes to the mesh and re-exporting, my animation tracks were once again missing. I had to RE-ENABLE the optimizer to get the tracks to come back...

Definitely something a lil sus going on with Godot's GLTF importer in regards to animations. I'm on 4.2 by the way.

fire commented 9 months ago

Are you familiar with the Remove Immutable tracks feature?

Remove Immutable Tracks: Remove animation tracks that only contain default values. This can reduce output file size and memory usage with certain 3D scenes, depending on the contents of their animation tracks.