AmbientRun / Ambient

The multiplayer game engine
https://ambient.run
Apache License 2.0
3.79k stars 122 forks source link

Blender Animation transforms are off on Ambient import #419

Closed kevzettler closed 1 year ago

kevzettler commented 1 year ago

I have a rigged and animated character in Blender. I'm exporting as gltf/glb. The pose keyframes are getting transformed weirdly when the get to ambient.

Here's an example of the 'idle' pose. Which is one keyframe

Idle

You can notice the shoulders and knee joints are kinked and off and the hitbox is not bound to the hand.

Walk

How can I further troubleshoot this? I just redid the rig and animations and maybe missed baking some transforms.

you can find the code at https://github.com/kevzettler/ambient-test-project/tree/new_animations on the new_animations branch

FredrikNoren commented 1 year ago

Hm can you try opening the glb in another program to verify it works? I’ve used this before : https://gltf-viewer.donmccurdy.com/ (you can just drop the model on the website there to verify it)

kevzettler commented 1 year ago

gltf-viewer

idle image walk walkdon

The poses in glTF Viewer match the poses in Blender.

There appears to be some warnings related to skinned mesh nodes

image

For sanity I also tried BabylonJS gltf viewer at: https://sandbox.babylonjs.com/

Babylonjs

walkbab

Babylon also matches the Blender animations...

FredrikNoren commented 1 year ago

Hm might be related to the warnings; could be that ambient applies the transform of the skinmesh entity differently. Not entirely sure.

kevzettler commented 1 year ago

possibly related: https://github.com/KhronosGroup/glTF-Blender-IO/issues/1626 https://github.com/KhronosGroup/glTF-Blender-IO/issues/1538#issuecomment-1015403354

Leaving as breadcrumbs for my debugging.

kevzettler commented 1 year ago

@FredrikNoren I resolved the warnings and made a totally new rig+animations the issue persisted. Further information. It seems like this issue is non deterministic. I can wipe the build directory in my project and run again and it produces different animation transformations each time.

I can run a bunch of these commands in succession and get different animations

rm -rf ./build && ~/code/Ambient/target/release/ambient run

I've attached a video demonstrating:

It actually does get the correct animation data here on the 2nd try.

https://github.com/AmbientRun/Ambient/assets/126209/65d1c924-e416-426e-84bf-5b479eb973de

This makes me feel like it is maybe and issue with the asset pipeline?

FredrikNoren commented 1 year ago

@kevzettler Hm that's interesting. Could you save the build/assets/MODEL.glb/models/main.json and build/assets/MODEL.glb/animations/* somewhere, re-run the build and use a diff tool to see if they are different between builds?

kevzettler commented 1 year ago

There are no differences between the build directories and I can reproduce the issue just by repeating ~/code/Ambient/target/release/ambient run a few times.

One thought I have is that my animation code is in the server.rs, and examples I've seen are in client.rs. Wondering if that is an issue. It seems like there is a delay upon loading the character model and animations. The animations then render correctly, broken, or sometimes not at all. Let me know your thoughts @FredrikNoren

FredrikNoren commented 1 year ago

@kevzettler Can you try this with the new animation api; there's an apply_base_pose function on the PlayClipFromUrlNode which you can set to true.

kevzettler commented 1 year ago

Ok @FredrikNoren I have updated my project to use the latest animation system. I added the new apply_base_pose invocations in:

https://github.com/kevzettler/ambient-test-project/commit/5e3d98c4102a303c46eafd89ad04716a187bc50e

Unfortunately, i'm still seeing the non-deterministic animation transformations every time I execute ambient run

I'm quite confused by this comment and what this function is actually supposed to do:

https://github.com/AmbientRun/Ambient/blob/7b1a4305f7aae139912c997ae8601706f05473a8/guest/rust/api_core/src/animation.rs#L124-L140

What is a "base pose" and why this special case for handling?

In my model I have 3 animation clips: neutral, idle, walk

The neutral pose is considered the "rest pose" is that the same as the base pose? Sadly I'm really blocked on this. Happy to share the Blender source file and all code is on my public repo at: https://github.com/kevzettler/ambient-test-project

kevzettler commented 1 year ago

For a sanity test I tried exporting an FBX file from Blender instead of glb. I'm seeing the same behavior. Every-time I run ambient run the pose and animation transforms are non deterministically mutated

Fbx branch is: https://github.com/kevzettler/ambient-test-project/tree/fbx_animations

FredrikNoren commented 1 year ago

@kevzettler Ok I think I've figured out what's going on; there are two entities with the same name for a lot of entities. For instance, I see two forearm.L. The bind_id's are the components that decide which entity gets updated by which animation; the animation might have an output like bind_id: forearm.L, but since there are two of those, it becomes random which one is selected.

FredrikNoren commented 1 year ago

(Though, I think this is a bug with ambient; since other programs can handle it, we should be able to too)

kevzettler commented 1 year ago

@FredrikNoren ok good find. I do have multiple corresponding things named the same. like : Bone: forearm.L Mesh: forearm.L Vertex Group: forearm.L

I agree I'd assume the nodes bind_ids are looked up by unique identifier or index instead of node name

FredrikNoren commented 1 year ago

@kevzettler Alright the fix is merged now, please re-open if it's still not working for some reason.

Nice model btw!

FredrikNoren commented 1 year ago

Oh an re the bind_id's looked up by unique identifier; yeah that would be more robust in this case, but it doesn't work when you want to do retargeting (using an animation from one character for another character), which is why it's using the "semantic" names.