-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Fix get_global_transform_interpolated() with multiple ticks per frame #58381
Conversation
9c3637b
to
770f93a
Compare
770f93a
to
fd5067a
Compare
fd5067a
to
e20e0e0
Compare
e20e0e0
to
1907325
Compare
889c887
to
d8a95f0
Compare
14fc02c
to
180cf04
Compare
72160b5
to
d4dc702
Compare
The previous and current transforms in the interpolation data were not being correctly updated in cases where two or more physics ticks occurred on a frame. This PR introduces a simple mechanism to ensure updates on interpolated spatials.
d4dc702
to
688dc53
Compare
@@ -2240,6 +2240,7 @@ bool Main::iteration() { | |||
|
|||
if (OS::get_singleton()->get_main_loop()->iteration(frame_slice * time_scale)) { | |||
exit = true; | |||
Engine::get_singleton()->_in_physics = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think since this is a SceneTree related variable, it may be better to just put it SceneTree rather than here or in engine. Nodes have access to it via get_tree()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I'll take a look at this, could be better in a second PR maybe? (as is only side related to the interpolation, just used as a fallback for if get_global_transform_interpolated()
was called from e.g. _process()
)
And it is a compatibility breaking change, so would benefit from some separate scrutiny.
EDIT - Yes it looks a little more involved than it may appear, because the Input depends on checking this, and due to timing of Input it may not be a good idea just to set it on and off at the beginning and end of SceneTree::iteration
.
This line was a simple fix for an existing bug incidentally - the situation when exiting the app, the in_physics
flag was never set to false (I picked this up when debug outputting error messages if get_global_transform_interpolated()
was called from inside the physics.
I think this looks good, it remains to be seen how well it works when users test it, but I am positive. |
Thanks! |
The previous and current transforms in the interpolation data were not being correctly updated in cases where two or more physics ticks occurred on a frame. This PR introduces a simple mechanism to ensure updates on interpolated spatials.
On suggestion from reduz this now uses a
SelfList
to store the list ofSpatial
s to update, and this list is stored in theSceneTree
. Members of this update list have atimeout
value in order to reduce processing - ifget_global_transform_interpolated()
has not been called in a certain number of physics ticks, it is removed from the update list until the next timeget_global_transform_interpolated()
is called.Note that the update list ONLY copies the current transform to the previous transform and updates the global transform. It does not perform any interpolation, that is performed on request within the
get_global_transform_interpolated()
function.Explanation
Previously, if there were 2 or more physics ticks in a frame (for instance setting physics tick rate to 90tps, at a frame rate of 60fps), then the previous transform would only be set once, and would end up being a stale previous transform, which would result in the the interpolated value being further back in time than it should be, giving a visual effect of jitter.
Notes
get_global_transform_interpolated()
function (e.g. for a Camera).