From 5dcf234d13ce8ffc61e77eab24d9c50cf2793160 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Thu, 27 Feb 2025 09:03:17 +0000 Subject: [PATCH] Physics Interpolation - reduce xforms in non-interpolated nodes In the specific case of non-interpolated nodes, if ancestor nodes were moved on the physics tick this would lead to unnecessary NOTIFICATION_TRANSFORM_CHANGED and calls to `VisualServer`. This would lower performance and lead to unwanted physics interpolation warnings about movement on physics ticks. Here we remove these unnecessary notifications. --- scene/3d/node_3d.cpp | 21 ++++++++++++++++++++- scene/3d/node_3d.h | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 1efa1d9457b..151b45a249d 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -104,14 +104,33 @@ void Node3D::_propagate_transform_changed_deferred() { } void Node3D::_propagate_transform_changed(Node3D *p_origin) { + // Wrapper function, to do the heavy lifting to decide + // whether we need to check interpolation on / off for each node + // to determine whether to send notifications. + _propagate_transform_changed(p_origin, + Engine::get_singleton()->is_in_physics_frame() && is_inside_tree() && get_tree()->is_physics_interpolation_enabled()); +} + +void Node3D::_propagate_transform_changed(Node3D *p_origin, bool p_check_physics_interpolation_state) { if (!is_inside_tree()) { return; } for (Node3D *&E : data.children) { + // Don't propagate to a top_level. if (E->data.top_level) { - continue; //don't propagate to a top_level + continue; } + + // The first non-interpolated child is responsible for grabbing + // the interpolated xform from the parent / target on each frame. + // If this is not done, there will be judder, because the non-interpolated child + // will be matching the PHYSICS xform of the parent, rather than the interpolated + // xform. + if (p_check_physics_interpolation_state && !E->is_physics_interpolated() && p_origin->is_physics_interpolated()) { + continue; + } + E->_propagate_transform_changed(p_origin); } #ifdef TOOLS_ENABLED diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 20288fad3a6..c0a14d99d3d 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -151,6 +151,7 @@ private: void _update_gizmos(); void _notify_dirty(); void _propagate_transform_changed(Node3D *p_origin); + void _propagate_transform_changed(Node3D *p_origin, bool p_check_physics_interpolation_state); void _propagate_visibility_changed();