From 328866ee6a7d1378d42b741ca6b7219cd9d02593 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Fri, 6 May 2022 12:09:06 +0100 Subject: [PATCH] Physics Interpolation - Reset on adding child to SceneTree For convenience, branches added to the SceneTree now have physics interpolation reset after the first update of the transform to the VisualServer. --- scene/3d/visual_instance.cpp | 9 +++++++++ scene/main/node.cpp | 23 +++++++++++++++++++++++ scene/main/node.h | 6 ++++++ 3 files changed, 38 insertions(+) diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index d6d8be962cf..ce4fbca8d0d 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -101,6 +101,15 @@ void VisualInstance::_notification(int p_what) { if (!_is_using_identity_transform()) { Transform gt = get_global_transform(); VisualServer::get_singleton()->instance_set_transform(instance, gt); + + // For instance when first adding to the tree, when the previous transform is + // unset, to prevent streaking from the origin. + if (_is_physics_interpolation_reset_requested()) { + if (_is_vi_visible()) { + _notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION); + } + _set_physics_interpolation_reset_requested(false); + } } } } break; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 58c30564f07..f6f738d602a 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -221,6 +221,18 @@ void Node::_propagate_physics_interpolated(bool p_interpolated) { data.blocked--; } +void Node::_propagate_physics_interpolation_reset_requested() { + if (is_physics_interpolated()) { + data.physics_interpolation_reset_requested = true; + } + + data.blocked++; + for (int i = 0; i < data.children.size(); i++) { + data.children[i]->_propagate_physics_interpolation_reset_requested(); + } + data.blocked--; +} + void Node::_propagate_enter_tree() { // this needs to happen to all children before any enter_tree @@ -1014,6 +1026,10 @@ void Node::_set_physics_interpolated_client_side(bool p_enable) { data.physics_interpolated_client_side = p_enable; } +void Node::_set_physics_interpolation_reset_requested(bool p_enable) { + data.physics_interpolation_reset_requested = p_enable; +} + void Node::_set_use_identity_transform(bool p_enable) { data.use_identity_transform = p_enable; } @@ -1249,6 +1265,12 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) { //recognize children created in this node constructor p_child->data.parent_owned = data.in_constructor; add_child_notify(p_child); + + // Allow physics interpolated nodes to automatically reset when added to the tree + // (this is to save the user doing this manually each time) + if (is_inside_tree() && get_tree()->is_physics_interpolation_enabled()) { + p_child->_propagate_physics_interpolation_reset_requested(); + } } void Node::add_child(Node *p_child, bool p_legible_unique_name) { @@ -3185,6 +3207,7 @@ Node::Node() { data.inside_tree = false; data.ready_notified = false; data.physics_interpolated = true; + data.physics_interpolation_reset_requested = false; data.physics_interpolated_client_side = false; data.use_identity_transform = false; diff --git a/scene/main/node.h b/scene/main/node.h index 133f6e1ac5e..5d20f9e59f9 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -151,6 +151,9 @@ private: // is switched on. bool physics_interpolated : 1; + // We can auto-reset physics interpolation when e.g. adding a node for the first time + bool physics_interpolation_reset_requested : 1; + // Most nodes need not be interpolated in the scene tree, physics interpolation // is normally only needed in the VisualServer. However if we need to read the // interpolated transform of a node in the SceneTree, it is necessary to duplicate @@ -197,6 +200,7 @@ private: void _propagate_exit_tree(); void _propagate_after_exit_branch(bool p_exiting_tree); void _propagate_physics_interpolated(bool p_interpolated); + void _propagate_physics_interpolation_reset_requested(); void _print_stray_nodes(); void _propagate_pause_owner(Node *p_owner); Array _get_node_and_resource(const NodePath &p_path); @@ -243,6 +247,8 @@ protected: void _set_name_nocheck(const StringName &p_name); void _set_physics_interpolated_client_side(bool p_enable); bool _is_physics_interpolated_client_side() const { return data.physics_interpolated_client_side; } + void _set_physics_interpolation_reset_requested(bool p_enable); + bool _is_physics_interpolation_reset_requested() const { return data.physics_interpolation_reset_requested; } void _set_use_identity_transform(bool p_enable); bool _is_using_identity_transform() const { return data.use_identity_transform; }