diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index e8173c965..77662cfd1 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -387,14 +387,14 @@
- Returns [code]true[/code] if the physics interpolated flag is set for this Node (see [method set_physics_interpolated]).
+ Returns [code]true[/code] if the physics interpolated flag is set for this Node (see [member physics_interpolation_mode]).
[b]Note:[/b] Interpolation will only be active is both the flag is set [b]and[/b] physics interpolation is enabled within the [SceneTree]. This can be tested using [method is_physics_interpolated_and_enabled].
- Returns [code]true[/code] if physics interpolation is enabled (see [method set_physics_interpolated]) [b]and[/b] enabled in the [SceneTree].
+ Returns [code]true[/code] if physics interpolation is enabled (see [member physics_interpolation_mode]) [b]and[/b] enabled in the [SceneTree].
This is a convenience version of [method is_physics_interpolated] that also checks whether physics interpolation is enabled globally.
See [member SceneTree.physics_interpolation] and [member ProjectSettings.physics/common/physics_interpolation].
@@ -643,14 +643,6 @@
Sets the node's network master to the peer with the given peer ID. The network master is the peer that has authority over the node on the network. Useful in conjunction with the [code]master[/code] and [code]puppet[/code] keywords. Inherited from the parent node by default, which ultimately defaults to peer ID 1 (the server). If [code]recursive[/code], the given peer is recursively set as the master for all children of this node.
-
-
-
-
- Enables or disables physics interpolation per node, offering a finer grain of control than turning physics interpolation on and off globally.
- [b]Note:[/b] This can be especially useful for [Camera]s, where custom interpolation can sometimes give superior results.
-
-
@@ -735,6 +727,10 @@
The node owner. A node can have any other node as owner (as long as it is a valid parent, grandparent, etc. ascending in the tree). When saving a node (using [PackedScene]), all the nodes it owns will be saved with it. This allows for the creation of complex [SceneTree]s, with instancing and subinstancing.
[b]Note:[/b] If you want a child to be persisted to a [PackedScene], you must set [member owner] in addition to calling [method add_child]. This is typically relevant for [url=$DOCS_URL/tutorials/plugins/running_code_in_the_editor.html]tool scripts[/url] and [url=$DOCS_URL/tutorials/plugins/editor/index.html]editor plugins[/url]. If [method add_child] is called without setting [member owner], the newly added [Node] will not be visible in the scene tree, though it will be visible in the 2D/3D view.
+
+ Allows enabling or disabling physics interpolation per node, offering a finer grain of control than turning physics interpolation on and off globally.
+ [b]Note:[/b] This can be especially useful for [Camera]s, where custom interpolation can sometimes give superior results.
+
Pause mode. How the node will behave if the [SceneTree] is paused.
@@ -908,6 +904,15 @@
Continue to process regardless of the [SceneTree] pause state.
+
+ Inherits physics interpolation mode from the node's parent. For the root node, it is equivalent to [constant PHYSICS_INTERPOLATION_MODE_ON]. Default.
+
+
+ Turn off physics interpolation in this node and children set to [constant PHYSICS_INTERPOLATION_MODE_INHERIT].
+
+
+ Turn on physics interpolation in this node and children set to [constant PHYSICS_INTERPOLATION_MODE_INHERIT].
+
Duplicate the node's signals.
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 901d67e37..1749affb3 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -49,6 +49,7 @@
#endif
VARIANT_ENUM_CAST(Node::PauseMode);
+VARIANT_ENUM_CAST(Node::PhysicsInterpolationMode);
int Node::orphan_node_count = 0;
@@ -83,6 +84,14 @@ void Node::_notification(int p_notification) {
data.pause_owner = this;
}
+ if (data.physics_interpolation_mode == PHYSICS_INTERPOLATION_MODE_INHERIT) {
+ bool interpolate = true; // Root node default is for interpolation to be on
+ if (data.parent) {
+ interpolate = data.parent->is_physics_interpolated();
+ }
+ _propagate_physics_interpolated(interpolate);
+ }
+
if (data.input) {
add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
}
@@ -187,6 +196,23 @@ void Node::_propagate_ready() {
}
void Node::_propagate_physics_interpolated(bool p_interpolated) {
+ switch (data.physics_interpolation_mode) {
+ case PHYSICS_INTERPOLATION_MODE_INHERIT:
+ // keep the parent p_interpolated
+ break;
+ case PHYSICS_INTERPOLATION_MODE_OFF: {
+ p_interpolated = false;
+ } break;
+ case PHYSICS_INTERPOLATION_MODE_ON: {
+ p_interpolated = true;
+ } break;
+ }
+
+ // no change? no need to propagate further
+ if (data.physics_interpolated == p_interpolated) {
+ return;
+ }
+
data.physics_interpolated = p_interpolated;
// allow a call to the VisualServer etc in derived classes
@@ -804,14 +830,36 @@ bool Node::can_process() const {
return true;
}
-void Node::set_physics_interpolated(bool p_interpolated) {
+void Node::set_physics_interpolation_mode(PhysicsInterpolationMode p_mode) {
+ if (data.physics_interpolation_mode == p_mode) {
+ return;
+ }
+
+ data.physics_interpolation_mode = p_mode;
+
+ bool interpolate = true; // default for root node
+
+ switch (p_mode) {
+ case PHYSICS_INTERPOLATION_MODE_INHERIT: {
+ if (is_inside_tree() && data.parent) {
+ interpolate = data.parent->is_physics_interpolated();
+ }
+ } break;
+ case PHYSICS_INTERPOLATION_MODE_OFF: {
+ interpolate = false;
+ } break;
+ case PHYSICS_INTERPOLATION_MODE_ON: {
+ interpolate = true;
+ } break;
+ }
+
// if swapping from interpolated to non-interpolated, use this as
// an extra means to cause a reset
- if (is_physics_interpolated() && !p_interpolated) {
+ if (is_physics_interpolated() && !interpolate) {
reset_physics_interpolation();
}
- _propagate_physics_interpolated(p_interpolated);
+ _propagate_physics_interpolated(interpolate);
}
void Node::reset_physics_interpolation() {
@@ -2960,7 +3008,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_physics_process_internal", "enable"), &Node::set_physics_process_internal);
ClassDB::bind_method(D_METHOD("is_physics_processing_internal"), &Node::is_physics_processing_internal);
- ClassDB::bind_method(D_METHOD("set_physics_interpolated", "enable"), &Node::set_physics_interpolated);
+ ClassDB::bind_method(D_METHOD("set_physics_interpolation_mode", "mode"), &Node::set_physics_interpolation_mode);
+ ClassDB::bind_method(D_METHOD("get_physics_interpolation_mode"), &Node::get_physics_interpolation_mode);
ClassDB::bind_method(D_METHOD("is_physics_interpolated"), &Node::is_physics_interpolated);
ClassDB::bind_method(D_METHOD("is_physics_interpolated_and_enabled"), &Node::is_physics_interpolated_and_enabled);
ClassDB::bind_method(D_METHOD("reset_physics_interpolation"), &Node::reset_physics_interpolation);
@@ -3069,6 +3118,10 @@ void Node::_bind_methods() {
BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
BIND_ENUM_CONSTANT(PAUSE_MODE_PROCESS);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_INHERIT);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_OFF);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_ON);
+
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS);
@@ -3084,6 +3137,8 @@ void Node::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "pause_mode", PROPERTY_HINT_ENUM, "Inherit,Stop,Process"), "set_pause_mode", "get_pause_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_interpolation_mode", PROPERTY_HINT_ENUM, "Inherit,Off,On"), "set_physics_interpolation_mode", "get_physics_interpolation_mode");
+
#ifdef ENABLE_DEPRECATED
//no longer exists, but remains for compatibility (keep previous scenes folded
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor/display_folded", PROPERTY_HINT_NONE, "", 0), "set_display_folded", "is_displayed_folded");
@@ -3097,9 +3152,6 @@ void Node::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority");
- // Disabled for now
- // ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_interpolated"), "set_physics_interpolated", "is_physics_interpolated");
-
BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta")));
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta")));
BIND_VMETHOD(MethodInfo("_enter_tree"));
@@ -3148,6 +3200,7 @@ Node::Node() {
data.unhandled_input = false;
data.unhandled_key_input = false;
data.pause_mode = PAUSE_MODE_INHERIT;
+ data.physics_interpolation_mode = PHYSICS_INTERPOLATION_MODE_INHERIT;
data.pause_owner = nullptr;
data.network_master = 1; //server by default
data.path_cache = nullptr;
diff --git a/scene/main/node.h b/scene/main/node.h
index 6a8264dde..92f0e27e4 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -52,6 +52,13 @@ public:
PAUSE_MODE_PROCESS
};
+ enum PhysicsInterpolationMode {
+
+ PHYSICS_INTERPOLATION_MODE_INHERIT,
+ PHYSICS_INTERPOLATION_MODE_OFF,
+ PHYSICS_INTERPOLATION_MODE_ON
+ };
+
enum DuplicateFlags {
DUPLICATE_SIGNALS = 1,
@@ -112,7 +119,6 @@ private:
List::Element *OW; // owned element
List owned;
- PauseMode pause_mode;
Node *pause_owner;
int network_master;
@@ -121,6 +127,10 @@ private:
int process_priority;
+ // Keep bitpacked values together to get better packing
+ PauseMode pause_mode : 2;
+ PhysicsInterpolationMode physics_interpolation_mode : 2;
+
// variables used to properly sort the node when processing, ignored otherwise
//should move all the stuff below to bits
bool physics_process : 1;
@@ -232,7 +242,10 @@ protected:
void _add_child_nocheck(Node *p_child, const StringName &p_name);
void _set_owner_nocheck(Node *p_owner);
void _set_name_nocheck(const StringName &p_name);
- void _set_physics_interpolated_client_side(bool p_enable);
+ void set_physics_interpolation_mode(PhysicsInterpolationMode p_mode);
+ PhysicsInterpolationMode get_physics_interpolation_mode() const {
+ return data.physics_interpolation_mode;
+ }
bool _is_physics_interpolated_client_side() const {
return data.physics_interpolated_client_side;
}