mirror of
https://github.com/godotengine/godot.git
synced 2025-12-08 06:09:55 +00:00
Fix get_global_transform_interpolated() with multiple ticks per frame
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.
This commit is contained in:
parent
74b698b817
commit
688dc534e5
6 changed files with 128 additions and 29 deletions
|
|
@ -104,6 +104,27 @@ SceneTreeTimer::SceneTreeTimer() {
|
|||
process_pause = true;
|
||||
}
|
||||
|
||||
// This should be called once per physics tick, to make sure the transform previous and current
|
||||
// is kept up to date on the few spatials that are using client side physics interpolation
|
||||
void SceneTree::ClientPhysicsInterpolation::physics_process() {
|
||||
for (SelfList<Spatial> *E = _spatials_list.first(); E;) {
|
||||
Spatial *spatial = E->self();
|
||||
|
||||
SelfList<Spatial> *current = E;
|
||||
|
||||
// get the next element here BEFORE we potentially delete one
|
||||
E = E->next();
|
||||
|
||||
// This will return false if the spatial has timed out ..
|
||||
// i.e. If get_global_transform_interpolated() has not been called
|
||||
// for a few seconds, we can delete from the list to keep processing
|
||||
// to a minimum.
|
||||
if (!spatial->update_client_physics_interpolation_data()) {
|
||||
_spatials_list.remove(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneTree::tree_changed() {
|
||||
tree_version++;
|
||||
emit_signal(tree_changed_name);
|
||||
|
|
@ -498,6 +519,16 @@ bool SceneTree::is_physics_interpolation_enabled() const {
|
|||
return _physics_interpolation_enabled;
|
||||
}
|
||||
|
||||
void SceneTree::client_physics_interpolation_add_spatial(SelfList<Spatial> *p_elem) {
|
||||
// This ensures that _update_physics_interpolation_data() will be called at least once every
|
||||
// physics tick, to ensure the previous and current transforms are kept up to date.
|
||||
_client_physics_interpolation._spatials_list.add(p_elem);
|
||||
}
|
||||
|
||||
void SceneTree::client_physics_interpolation_remove_spatial(SelfList<Spatial> *p_elem) {
|
||||
_client_physics_interpolation._spatials_list.remove(p_elem);
|
||||
}
|
||||
|
||||
bool SceneTree::iteration(float p_time) {
|
||||
root_lock++;
|
||||
|
||||
|
|
@ -510,6 +541,11 @@ bool SceneTree::iteration(float p_time) {
|
|||
}
|
||||
}
|
||||
|
||||
// Any objects performing client physics interpolation
|
||||
// should be given an opportunity to keep their previous transforms
|
||||
// up to take before each new physics tick.
|
||||
_client_physics_interpolation.physics_process();
|
||||
|
||||
flush_transform_notifications();
|
||||
|
||||
MainLoop::iteration(p_time);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue