summaryrefslogtreecommitdiffstats
path: root/scene/main/node.cpp
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-03-24 01:13:53 +0100
committerRémi Verschelde <rverschelde@gmail.com>2024-03-24 01:13:53 +0100
commite92806c7e7451ff2a8c6d0a27a95bdadaeb2a3be (patch)
treef1be133cfc5dc131e65e276d1f6af2821c19dd99 /scene/main/node.cpp
parent075c171f800f5ee81c2970a3973b506540814872 (diff)
parent2ed2ccc2d8ff17b97d8ac0fd80fc0190ea47ed00 (diff)
downloadredot-engine-e92806c7e7451ff2a8c6d0a27a95bdadaeb2a3be.tar.gz
Merge pull request #88424 from rburing/fti_2d
Physics interpolation (2D)
Diffstat (limited to 'scene/main/node.cpp')
-rw-r--r--scene/main/node.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 604a322a8b..142736e388 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -99,6 +99,14 @@ void Node::_notification(int p_notification) {
}
}
+ 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);
+ }
+
// Update auto translate mode.
if (data.auto_translate_mode == AUTO_TRANSLATE_MODE_INHERIT && !data.parent) {
ERR_PRINT("The root node can't be set to Inherit auto translate mode, reverting to Always instead.");
@@ -395,6 +403,36 @@ void Node::_propagate_exit_tree() {
data.depth = -1;
}
+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 RenderingServer etc. in derived classes.
+ _physics_interpolated_changed();
+
+ data.blocked++;
+ for (KeyValue<StringName, Node *> &K : data.children) {
+ K.value->_propagate_physics_interpolated(p_interpolated);
+ }
+ data.blocked--;
+}
+
void Node::move_child(Node *p_child, int p_index) {
ERR_FAIL_COND_MSG(data.inside_tree && !Thread::is_main_thread(), "Moving child node positions inside the SceneTree is only allowed from the main thread. Use call_deferred(\"move_child\",child,index).");
ERR_FAIL_NULL(p_child);
@@ -507,6 +545,8 @@ void Node::move_child_notify(Node *p_child) {
void Node::owner_changed_notify() {
}
+void Node::_physics_interpolated_changed() {}
+
void Node::set_physics_process(bool p_process) {
ERR_THREAD_GUARD
if (data.physics_process == p_process) {
@@ -821,6 +861,42 @@ bool Node::_can_process(bool p_paused) const {
}
}
+void Node::set_physics_interpolation_mode(PhysicsInterpolationMode p_mode) {
+ ERR_THREAD_GUARD
+ 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() && !interpolate) {
+ reset_physics_interpolation();
+ }
+
+ _propagate_physics_interpolated(interpolate);
+}
+
+void Node::reset_physics_interpolation() {
+ propagate_notification(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
+}
+
bool Node::_is_enabled() const {
ProcessMode process_mode;
@@ -3515,6 +3591,12 @@ 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_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);
+
ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
@@ -3620,6 +3702,7 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE);
BIND_CONSTANT(NOTIFICATION_DISABLED);
BIND_CONSTANT(NOTIFICATION_ENABLED);
+ BIND_CONSTANT(NOTIFICATION_RESET_PHYSICS_INTERPOLATION);
BIND_CONSTANT(NOTIFICATION_EDITOR_PRE_SAVE);
BIND_CONSTANT(NOTIFICATION_EDITOR_POST_SAVE);
@@ -3659,6 +3742,10 @@ void Node::_bind_methods() {
BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_PHYSICS);
BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_ALL);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_INHERIT);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_ON);
+ BIND_ENUM_CONSTANT(PHYSICS_INTERPOLATION_MODE_OFF);
+
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
BIND_ENUM_CONSTANT(DUPLICATE_SCRIPTS);
@@ -3700,6 +3787,9 @@ void Node::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_group_order"), "set_process_thread_group_order", "get_process_thread_group_order");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_messages", PROPERTY_HINT_FLAGS, "Process,Physics Process"), "set_process_thread_messages", "get_process_thread_messages");
+ ADD_GROUP("Physics Interpolation", "physics_interpolation_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_interpolation_mode", PROPERTY_HINT_ENUM, "Inherit,Off,On"), "set_physics_interpolation_mode", "get_physics_interpolation_mode");
+
ADD_GROUP("Auto Translate", "auto_translate_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "auto_translate_mode", PROPERTY_HINT_ENUM, "Inherit,Always,Disabled"), "set_auto_translate_mode", "get_auto_translate_mode");
@@ -3734,6 +3824,35 @@ String Node::_get_name_num_separator() {
Node::Node() {
orphan_node_count++;
+
+ // Default member initializer for bitfield is a C++20 extension, so:
+
+ data.process_mode = PROCESS_MODE_INHERIT;
+ data.physics_interpolation_mode = PHYSICS_INTERPOLATION_MODE_INHERIT;
+
+ data.physics_process = false;
+ data.process = false;
+
+ data.physics_process_internal = false;
+ data.process_internal = false;
+
+ data.input = false;
+ data.shortcut_input = false;
+ data.unhandled_input = false;
+ data.unhandled_key_input = false;
+
+ data.physics_interpolated = false;
+
+ data.parent_owned = false;
+ data.in_constructor = true;
+ data.use_placeholder = false;
+
+ data.display_folded = false;
+ data.editable_instance = false;
+
+ data.inside_tree = false;
+ data.ready_notified = false; // This is a small hack, so if a node is added during _ready() to the tree, it correctly gets the _ready() notification.
+ data.ready_first = true;
}
Node::~Node() {