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.
This commit is contained in:
lawnjelly 2022-05-06 12:09:06 +01:00
parent 2f21644230
commit 328866ee6a
3 changed files with 38 additions and 0 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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; }