idanarye / bevy-tnua

A floating character controller for Bevy
https://crates.io/crates/bevy-tnua
Apache License 2.0
214 stars 14 forks source link

3D XPBD example has buggy animations #39

Closed janhohenheim closed 8 months ago

janhohenheim commented 8 months ago

When comparing the XPBD demo with the rapier version, the former looks strange when the character has stopped on my Firefox.

Standing still with rapier: image

Standing still with XPBD: image

There's also some stuttering going on with XPBD. Seems like the model is switching rapidly between having a leg lowered and raised.

idanarye commented 8 months ago

Sounds like it is caused by a performance issue. What framerate does it say you get the Rapier and in the XPBD demos? (the framerate is displayed in the egui window at the top-left)

janhohenheim commented 8 months ago

Both have around 165 FPS with occasional dips to 145. I might have phrased that confusingly. By "stuttering" I meant that the animation stutters, not the framerate. In XPBD, after I walk and then stand still, the keyframes switch very quickly (10+ per second) between standing and walking. Sometimes it just stays in walking position. It never stays in standing position.

For the record, I use Firefox 122.0 on Windows 11

janhohenheim commented 8 months ago

Update: Also happens in Chrome Version 121.0.6167.86

idanarye commented 8 months ago

It really is about framerate - but not like I thought. My framerate was always capped at 60 because of vsync, but when I disable vsync and do a release build, I can replicate the problem:

https://github.com/idanarye/bevy-tnua/assets/1149255/d6ddd9bf-6217-49de-9c07-300b91ab140b

idanarye commented 8 months ago

The problem is my fix to #34. When I revert it the problem is solved. I think this is the same issue as this problem reported in the Discord. Accelerations are less precise than impulses because:

  1. I can't reliably predict the frame time the physics engine will use (at least I think that's an issue. I'm not 100% sure)
  2. When the frame rate is high, I hit f32 rounding errors.

At any rate, I want to implement an FPS example before I fix this, to make sure the fix does not create #34 again.

janhohenheim commented 8 months ago

I'm impressed you found the problem this quickly! I didn't look into your codebase much, so ignore me if this is irrelevant, but a very naive fix could entail just ignoring any movement of a magnitude that is smaller than some epsilon, say 1e-7

idanarye commented 8 months ago

Could be, but that's not something that's done by Tnua. Tnua does not touch the translation (it only reads it), and works by touching the acceleration and/or the velocity. The actual change of the position is handled by the physics backend - that's why it only happens in XPBD and not in Rapier.

The solution I want to do is to have small changes to the velocity done using impulses instead of acceleration. I fear it create #34 again, which is why I wanted to implement a FPS example and see if I can replicate it, but now that I think of it if I only do this when I want to stop the character then it shouldn't be a problem. Maybe in the future, when I can properly test it, I'll expand it so that it'll happen when the character is moving, too.

idanarye commented 8 months ago

@janhohenheim Please verify that the demo works properly for you now.

janhohenheim commented 8 months ago

@idanarye works perfectly now, good work :D