Ported: 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. - lawnjelly

328866ee6a
This commit is contained in:
Relintai 2022-07-27 17:51:39 +02:00
parent 7ddeae2e23
commit 75606b352f
3 changed files with 41 additions and 0 deletions

View File

@ -103,6 +103,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

@ -225,6 +225,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
@ -1018,6 +1030,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;
}
@ -1254,6 +1270,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) {
@ -3191,6 +3213,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

@ -148,6 +148,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
@ -194,6 +197,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);
@ -253,6 +257,11 @@ protected:
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;