idanarye / bevy-tnua

A floating character controller for Bevy

Home Page:https://crates.io/crates/bevy-tnua

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

3D XPBD example has buggy animations

janhohenheim opened this issue · comments

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.

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)

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

Update: Also happens in Chrome Version 121.0.6167.86

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:

Peek.2024-01-31.22-45.mp4

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.

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

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.

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

@idanarye works perfectly now, good work :D