Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rigidbody3D apply_impulse position ignored when run in _ready or first tick #75934

Open
ZachAR3 opened this issue Apr 11, 2023 · 5 comments
Open

Comments

@ZachAR3
Copy link

ZachAR3 commented Apr 11, 2023

Godot version

4.0.2.stable.mono

System information

Endeavour OS Zen Kernel 6.2.7 Ryzen 5900x Nvidia RTX 2080TI 11GB (proprietary drivers)

Issue description

When using apply_impulse with a position (second) field specified inside of _ready or any subfunction started on the first tick, the position field is ignored. The first (impulse) field seems to work normally on the first tick though.

Steps to reproduce

Create a Rigidbody3D inside of a world with corresponding mesh and colliders. Add a script which runs apply_impulse under _ready using both impulse and location fields. The impulse will disregard the position field and only use the impulse field.

Minimal reproduction project

Under this example project by default the workaround of setting up a timer with an await to skip the first frame is enabled To see the unintended behavior in which the position is ignored comment the await function.
BrokenApplyImpulse.tar.gz

@rburing
Copy link
Member

rburing commented Apr 11, 2023

This is the 3D version of #29888. It is caused by the inverse inertia tensor calculation being deferred (also in 4.0).

It is tricky to solve, because we don't want to re-calculate the inertia tensor every time a single shape is added or removed. Preferably we do it only once in a frame where the shapes have changed (e.g. if 20 shapes have been added). The deferring achieves this, but it has this unfortunate side-effect on the first physics tick.

@ZachAR3
Copy link
Author

ZachAR3 commented Apr 11, 2023

This is the 3D version of #29888. It is caused by the inverse inertia tensor calculation being deferred (also in 4.0).

It is tricky to solve, because we don't want to re-calculate the inertia tensor every time a single shape is added or removed. Preferably we do it only once in a frame where the shapes have changed (e.g. if 20 shapes have been added). The deferring achieves this, but it has this unfortunate side-effect on the first physics tick.

Gotcha. I saw that issue; but I thought it would be worth creating one dedicated for 3D. Especially, since it seems to only effect the position argument. Is there a better way than just adding an await with a super short timer to skip to first frame?

@rburing
Copy link
Member

rburing commented Apr 11, 2023

You can do

await(get_tree().physics_frame)
await(get_tree().physics_frame)

before applying the impulse.

In the meantime, it would be good to add a note like the one that was added to apply_torque and apply_torque_impulse in #68098 to the documentation of apply_impulse as well (for both 2D and 3D).

@ZachAR3
Copy link
Author

ZachAR3 commented Apr 12, 2023

You can do

await(get_tree().physics_frame)
await(get_tree().physics_frame)

before applying the impulse.

In the meantime, it would be good to add a note like the one that was added to apply_torque and apply_torque_impulse in #68098 to the documentation of apply_impulse as well (for both 2D and 3D).

Oh that's a way better method than what I was using (await(get_tree().create_timer(0.00001).timeout)) haha. Thanks!

@jitspoe
Copy link
Contributor

jitspoe commented Feb 4, 2024

Is there some way the angular impulse can be queued up and applied after re-calculating the inertia tensor? This feels like something that should "just work". I should be able to spawn things and impulse them immediately. It's really confusing trying to figure out why things don't work as expected when you have to wait not one, but 2 frames before applying the impulse. I was trying deferring, adding crazy values, etc, until I looked here and found the 2 awaits to fix the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants