1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-24 15:26:15 +00:00

Merge pull request #88424 from rburing/fti_2d

Physics interpolation (2D)
This commit is contained in:
Rémi Verschelde
2024-03-24 01:13:53 +01:00
39 changed files with 1040 additions and 75 deletions

View File

@@ -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() {