From ed69fd66da1752ccc4da50e66551be0bb2c4c92d Mon Sep 17 00:00:00 2001 From: SaNeOr Date: Fri, 13 Sep 2024 01:50:39 +0800 Subject: [PATCH 001/100] fix: Editor, save script file: Triple quote string: spaces are converted into tabs --- scene/gui/code_edit.cpp | 4 ++++ tests/scene/test_code_edit.h | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index c3287035ff..79eabd0a4b 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1007,6 +1007,10 @@ void CodeEdit::convert_indent(int p_from_line, int p_to_line) { continue; } + if (is_in_string(i) != -1) { + continue; + } + // Check chars in the line. int j = 0; int space_count = 0; diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h index 9ec1b812df..a1da4dec1e 100644 --- a/tests/scene/test_code_edit.h +++ b/tests/scene/test_code_edit.h @@ -2831,6 +2831,16 @@ TEST_CASE("[SceneTree][CodeEdit] indent") { CHECK(code_edit->has_selection()); CHECK(code_edit->get_selection_origin_column() == 2); CHECK(code_edit->get_caret_column() == 3); + + // Multiline blocks. + code_edit->set_text("'''\n test\n test\n'''"); + code_edit->select(1, 0, 1, 8); + code_edit->convert_indent(); + CHECK(code_edit->get_line(1) == " test"); + CHECK(code_edit->get_line(2) == " test"); + CHECK(code_edit->has_selection()); + CHECK(code_edit->get_selection_origin_column() == 0); + CHECK(code_edit->get_caret_column() == 8); } SUBCASE("[CodeEdit] convert indent to spaces") { From 6adcb2085cd5c6a9b7a79dc36f49a1a4f6cbdcd3 Mon Sep 17 00:00:00 2001 From: arkology <43543909+arkology@users.noreply.github.com> Date: Fri, 21 Feb 2025 22:45:11 +0300 Subject: [PATCH 002/100] `EditorResourcePicker`: Add `Quick Load` button --- editor/editor_resource_picker.cpp | 8 ++++++++ editor/editor_resource_picker.h | 1 + 2 files changed, 9 insertions(+) diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 79d033bf03..d8f40dcc99 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -88,6 +88,7 @@ void EditorResourcePicker::_update_resource() { } assign_button->set_disabled(!editable && edited_resource.is_null()); + quick_load_button->set_visible(editable && edited_resource.is_null()); } void EditorResourcePicker::_update_resource_preview(const String &p_path, const Ref &p_preview, const Ref &p_small_preview, ObjectID p_obj) { @@ -855,6 +856,7 @@ void EditorResourcePicker::_notification(int p_what) { edit_menu->add_theme_constant_override("icon_max_width", icon_width); } + quick_load_button->set_button_icon(get_editor_theme_icon(SNAME("Load"))); edit_button->set_button_icon(get_theme_icon(SNAME("select_arrow"), SNAME("Tree"))); } break; @@ -996,6 +998,7 @@ void EditorResourcePicker::set_resource_owner(Object *p_object) { void EditorResourcePicker::set_editable(bool p_editable) { editable = p_editable; assign_button->set_disabled(!editable && edited_resource.is_null()); + quick_load_button->set_visible(editable && edited_resource.is_null()); edit_button->set_visible(editable); } @@ -1120,6 +1123,11 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) { assign_button->add_child(preview_rect); } + quick_load_button = memnew(Button); + quick_load_button->set_tooltip_text(TTRC("Quick Load")); + add_child(quick_load_button); + quick_load_button->connect(SceneStringName(pressed), callable_mp(this, &EditorResourcePicker::_edit_menu_cbk).bind(OBJ_MENU_QUICKLOAD)); + edit_button = memnew(Button); edit_button->set_flat(false); edit_button->set_toggle_mode(true); diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index a91a4dcb58..29c30f7164 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -56,6 +56,7 @@ class EditorResourcePicker : public HBoxContainer { Button *assign_button = nullptr; TextureRect *preview_rect = nullptr; Button *edit_button = nullptr; + Button *quick_load_button = nullptr; EditorFileDialog *file_dialog = nullptr; ConfirmationDialog *duplicate_resources_dialog = nullptr; From ac2179c546b6ec7b6cb58293acd788c97feb2b71 Mon Sep 17 00:00:00 2001 From: kobewi Date: Mon, 14 Apr 2025 10:45:58 +0200 Subject: [PATCH 003/100] Queue hover update when creating TreeItem --- scene/gui/tree.cpp | 14 +++++++++++--- scene/gui/tree.h | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 56bef63304..699ead96e1 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -4126,6 +4126,8 @@ void Tree::gui_input(const Ref &p_event) { } void Tree::_determine_hovered_item() { + hovered_update_queued = false; + Ref bg = theme_cache.panel_style; bool rtl = is_layout_rtl(); @@ -4213,6 +4215,14 @@ void Tree::_determine_hovered_item() { } } +void Tree::_queue_update_hovered_item() { + if (hovered_update_queued) { + return; + } + hovered_update_queued = true; + callable_mp(this, &Tree::_determine_hovered_item).call_deferred(); +} + bool Tree::edit_selected(bool p_force_edit) { TreeItem *s = get_selected(); ERR_FAIL_NULL_V_MSG(s, false, "No item selected."); @@ -5046,9 +5056,7 @@ TreeItem *Tree::create_item(TreeItem *p_parent, int p_index) { ti = create_item(root, p_index); } } - - _determine_hovered_item(); - + _queue_update_hovered_item(); queue_accessibility_update(); return ti; } diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 979b7ac2da..24c79bdaaa 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -733,7 +733,9 @@ private: bool enable_auto_tooltip = true; + bool hovered_update_queued = false; void _determine_hovered_item(); + void _queue_update_hovered_item(); int _count_selected_items(TreeItem *p_from) const; bool _is_branch_selected(TreeItem *p_from) const; From e213737d66acd26d8729d943c109b578c3d3353b Mon Sep 17 00:00:00 2001 From: HolonProduction Date: Sun, 13 Apr 2025 16:18:19 +0200 Subject: [PATCH 004/100] LSP: Account for unicode identifiers --- .../language_server/gdscript_extend_parser.cpp | 12 ++++++++---- modules/gdscript/tests/scripts/lsp/class.gd | 17 ++++++++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index f8df46b256..654e39d1f9 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -712,9 +712,9 @@ String ExtendGDScriptParser::get_identifier_under_position(const LSP::Position & LSP::Position pos = p_position; if ( pos.character >= line.length() // Cursor at end of line. - || (!is_ascii_identifier_char(line[pos.character]) // Not on valid identifier char. + || (!is_unicode_identifier_continue(line[pos.character]) // Not on valid identifier char. && (pos.character > 0 // Not line start -> there is a prev char. - && is_ascii_identifier_char(line[pos.character - 1]) // Prev is valid identifier char. + && is_unicode_identifier_continue(line[pos.character - 1]) // Prev is valid identifier char. ))) { pos.character--; } @@ -723,7 +723,7 @@ String ExtendGDScriptParser::get_identifier_under_position(const LSP::Position & for (int c = pos.character; c >= 0; c--) { start_pos = c; char32_t ch = line[c]; - bool valid_char = is_ascii_identifier_char(ch); + bool valid_char = is_unicode_identifier_continue(ch); if (!valid_char) { break; } @@ -732,13 +732,17 @@ String ExtendGDScriptParser::get_identifier_under_position(const LSP::Position & int end_pos = pos.character; for (int c = pos.character; c < line.length(); c++) { char32_t ch = line[c]; - bool valid_char = is_ascii_identifier_char(ch); + bool valid_char = is_unicode_identifier_continue(ch); if (!valid_char) { break; } end_pos = c; } + if (!is_unicode_identifier_start(line[start_pos + 1])) { + return ""; + } + if (start_pos < end_pos) { r_range.start.line = r_range.end.line = pos.line; r_range.start.character = start_pos + 1; diff --git a/modules/gdscript/tests/scripts/lsp/class.gd b/modules/gdscript/tests/scripts/lsp/class.gd index 53d0b14d72..519497573c 100644 --- a/modules/gdscript/tests/scripts/lsp/class.gd +++ b/modules/gdscript/tests/scripts/lsp/class.gd @@ -58,16 +58,19 @@ class Inner2: # | | ^^^^ -> class2:func:arg2 # ^^^^ -> class2:func:arg1 -class Inner3 extends Inner2: +class Inner三 extends Inner2: # | | ^^^^^^ -> class2 # ^^^^^^ class3 -> class3 var whatever = "foo" # ^^^^^^^^ class3:whatever -> class3:whatever + var ütf8 = "" + # ^^^^ class3:utf8 -> class3:utf8 + func _init(): # ^^^^^ class3:init # Note: no self-ref check here: resolves to `Object._init`. - # usages of `Inner3.new()` DO resolve to this `_init` + # usages of `Inner三.new()` DO resolve to this `_init` pass class NestedInInner3: @@ -97,14 +100,18 @@ func _ready(): # | | ^^^^^^ -> func:class1:value2 # ^^^^^^ -> func:class1:value1 - var inner3 = Inner3.new() + var inner3 = Inner三.new() # | | | | ^^^ -> class3:init # | | ^^^^^^ -> class3 # ^^^^^^ func:class3 -> func:class3 print(inner3) # ^^^^^^ -> func:class3 - var nested1 = Inner3.NestedInInner3.new() + print(inner3.ütf8) + # | | ^^^^ -> class3:utf8 + # ^^^^^^ -> func:class3 + + var nested1 = Inner三.NestedInInner3.new() # | | | | ^^^^^^^^^^^^^^ -> class3:nested1 # | | ^^^^^^ -> class3 # ^^^^^^^ func:class3:nested1 -> func:class3:nested1 @@ -115,7 +122,7 @@ func _ready(): print(value_nested1) # ^^^^^^^^^^^^^ -> func:class3:nested1:value - var nested2 = Inner3.AnotherNestedInInner3.new() + var nested2 = Inner三.AnotherNestedInInner3.new() # | | | | ^^^^^^^^^^^^^^^^^^^^^ -> class3:nested2 # | | ^^^^^^ -> class3 # ^^^^^^^ func:class3:nested2 -> func:class3:nested2 From 4a0e40f6ea0f30e8eaa07414ec9e2642fdac7622 Mon Sep 17 00:00:00 2001 From: HolonProduction Date: Tue, 15 Apr 2025 12:21:32 +0200 Subject: [PATCH 005/100] GDScript: Do phrase level recovery for match --- modules/gdscript/gdscript_parser.cpp | 10 +++++++++- modules/gdscript/gdscript_parser.h | 8 ++++++++ .../completion/enum_values_in_match/in_branch_1.cfg | 4 ++++ .../completion/enum_values_in_match/in_branch_1.gd | 7 +++++++ .../completion/enum_values_in_match/in_branch_2.cfg | 4 ++++ .../completion/enum_values_in_match/in_branch_2.gd | 11 +++++++++++ .../completion/enum_values_in_match/in_branch_3.cfg | 4 ++++ .../completion/enum_values_in_match/in_branch_3.gd | 11 +++++++++++ .../completion/enum_values_in_match/in_test_1.cfg | 4 ++++ .../completion/enum_values_in_match/in_test_1.gd | 4 ++++ .../completion/enum_values_in_match/in_test_2.cfg | 4 ++++ .../completion/enum_values_in_match/in_test_2.gd | 8 ++++++++ .../completion/enum_values_in_match/in_test_3.cfg | 4 ++++ .../completion/enum_values_in_match/in_test_3.gd | 5 +++++ .../completion/enum_values_in_match/in_test_4.cfg | 4 ++++ .../completion/enum_values_in_match/in_test_4.gd | 9 +++++++++ 16 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.gd create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.cfg create mode 100644 modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.gd diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index b6231d06b2..21f7f293c3 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -2359,8 +2359,16 @@ GDScriptParser::MatchBranchNode *GDScriptParser::parse_match_branch() { } if (!consume(GDScriptTokenizer::Token::COLON, vformat(R"(Expected ":"%s after "match" %s.)", has_guard ? "" : R"( or "when")", has_guard ? "pattern guard" : "patterns"))) { + branch->block = alloc_recovery_suite(); complete_extents(branch); - return nullptr; + // Consume the whole line and treat the next one as new match branch. + while (current.type != GDScriptTokenizer::Token::NEWLINE && !is_at_end()) { + advance(); + } + if (!is_at_end()) { + advance(); + } + return branch; } SuiteNode *suite = alloc_node(); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 47eab0c342..2e0c3cbcdd 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1463,6 +1463,14 @@ private: return node; } + SuiteNode *alloc_recovery_suite() { + SuiteNode *suite = alloc_recovery_node(); + suite->parent_block = current_suite; + suite->parent_function = current_function; + suite->is_in_loop = current_suite->is_in_loop; + return suite; + } + void clear(); void push_error(const String &p_message, const Node *p_origin = nullptr); #ifdef DEBUG_ENABLED diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.cfg new file mode 100644 index 0000000000..8f42aad56f --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "AUTO_TRANSLATE_MODE_INHERIT"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.gd new file mode 100644 index 0000000000..57aa7f4b02 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_1.gd @@ -0,0 +1,7 @@ +extends Node + +var t + +func test(): + match t: + AutoTranslateMode.➡ diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.cfg new file mode 100644 index 0000000000..50ef7900f5 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "VALUE"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.gd new file mode 100644 index 0000000000..bb54f146dc --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_2.gd @@ -0,0 +1,11 @@ +extends Node + +enum TestEnum { + VALUE, +} + +var t + +func test(): + match t: + TestEnum.➡ where diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.cfg new file mode 100644 index 0000000000..50ef7900f5 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "VALUE"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.gd new file mode 100644 index 0000000000..b7b24cad5b --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_branch_3.gd @@ -0,0 +1,11 @@ +extends Node + +enum TestEnum { + VALUE, +} + +var t + +func test(): + match t: + TestEnum.➡: diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.cfg new file mode 100644 index 0000000000..8f42aad56f --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "AUTO_TRANSLATE_MODE_INHERIT"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.gd new file mode 100644 index 0000000000..13dbafca1c --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_1.gd @@ -0,0 +1,4 @@ +extends Node + +func test(): + match AutoTranslateMode.➡ diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.cfg new file mode 100644 index 0000000000..50ef7900f5 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "VALUE"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.gd new file mode 100644 index 0000000000..800cd38915 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_2.gd @@ -0,0 +1,8 @@ +extends Node + +enum TestEnum { + VALUE, +} + +func test(): + match TestEnum.➡: diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.cfg new file mode 100644 index 0000000000..8f42aad56f --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "AUTO_TRANSLATE_MODE_INHERIT"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.gd new file mode 100644 index 0000000000..4659c4f38c --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_3.gd @@ -0,0 +1,5 @@ +extends Node + +func test(): + match AutoTranslateMode.➡: + pass diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.cfg b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.cfg new file mode 100644 index 0000000000..50ef7900f5 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.cfg @@ -0,0 +1,4 @@ +[output] +include=[ + {"display": "VALUE"}, +] diff --git a/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.gd b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.gd new file mode 100644 index 0000000000..f5900fc0e7 --- /dev/null +++ b/modules/gdscript/tests/scripts/completion/enum_values_in_match/in_test_4.gd @@ -0,0 +1,9 @@ +extends Node + +enum TestEnum { + VALUE, +} + +func test(): + match TestEnum.➡: + TestEnum From 5ddaaa93e68c633dcacccaecf8e81510ac30567a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Wed, 16 Apr 2025 10:45:43 +0300 Subject: [PATCH 006/100] Fix X11 boot splash scaling. --- platform/linuxbsd/x11/display_server_x11.cpp | 72 +++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 985209bd08..b357a28b80 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1903,7 +1903,7 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, V void DisplayServerX11::show_window(WindowID p_id) { _THREAD_SAFE_METHOD_ - const WindowData &wd = windows[p_id]; + WindowData &wd = windows[p_id]; popup_open(p_id); DEBUG_LOG_X11("show_window: %lu (%u) \n", wd.x11_window, p_id); @@ -1911,6 +1911,76 @@ void DisplayServerX11::show_window(WindowID p_id) { XMapWindow(x11_display, wd.x11_window); XSync(x11_display, False); _validate_mode_on_map(p_id); + + if (p_id == MAIN_WINDOW_ID) { + // Get main window size for boot splash drawing. + bool get_config_event = false; + + // Search the X11 event queue for ConfigureNotify events and process all that are currently queued early. + { + MutexLock mutex_lock(events_mutex); + + for (uint32_t event_index = 0; event_index < polled_events.size(); ++event_index) { + XEvent &config_event = polled_events[event_index]; + if (config_event.type == ConfigureNotify) { + _window_changed(&config_event); + get_config_event = true; + } + } + XEvent config_event; + while (XCheckTypedEvent(x11_display, ConfigureNotify, &config_event)) { + _window_changed(&config_event); + get_config_event = true; + } + } + + // Estimate maximize/full screen window size, ConfigureNotify may arrive only after maximize animation is finished. + if (!get_config_event && (wd.maximized || wd.fullscreen)) { + int screen = window_get_current_screen(p_id); + Size2i sz; + if (wd.maximized) { + sz = screen_get_usable_rect(screen).size; + if (!wd.borderless) { + Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True); + if (prop != None) { + Atom type; + int format; + unsigned long len; + unsigned long remaining; + unsigned char *data = nullptr; + if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) { + if (format == 32 && len == 4 && data) { + long *extents = (long *)data; + sz.width -= extents[0] + extents[1]; // left, right + sz.height -= extents[2] + extents[3]; // top, bottom + } + XFree(data); + } + } + } + } else { + sz = screen_get_size(screen); + } + if (sz == Size2i()) { + return; + } + + wd.size = sz; +#if defined(RD_ENABLED) + if (rendering_context) { + rendering_context->window_set_size(p_id, sz.width, sz.height); + } +#endif +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->window_resize(p_id, sz.width, sz.height); + } + if (gl_manager_egl) { + gl_manager_egl->window_resize(p_id, sz.width, sz.height); + } +#endif + } + } } void DisplayServerX11::delete_sub_window(WindowID p_id) { From 40c05c69f9917b3c1e89821c81e893a87b376e61 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Mon, 3 Mar 2025 11:01:49 +0000 Subject: [PATCH 007/100] Physics Interpolation - Add editor configuration warnings * For physics bodies that are on non-interpolated branches --- scene/2d/physics/physics_body_2d.cpp | 10 ++++++++++ scene/2d/physics/physics_body_2d.h | 2 ++ scene/3d/physics/physics_body_3d.cpp | 10 ++++++++++ scene/3d/physics/physics_body_3d.h | 2 ++ scene/main/node.cpp | 2 ++ 5 files changed, 26 insertions(+) diff --git a/scene/2d/physics/physics_body_2d.cpp b/scene/2d/physics/physics_body_2d.cpp index df6ec65d9c..18a29ee134 100644 --- a/scene/2d/physics/physics_body_2d.cpp +++ b/scene/2d/physics/physics_body_2d.cpp @@ -169,3 +169,13 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) { ERR_FAIL_NULL_MSG(physics_body, "Collision exception only works between two nodes that inherit from PhysicsBody2D."); PhysicsServer2D::get_singleton()->body_remove_collision_exception(get_rid(), physics_body->get_rid()); } + +PackedStringArray PhysicsBody2D::get_configuration_warnings() const { + PackedStringArray warnings = CollisionObject2D::get_configuration_warnings(); + + if (!is_physics_interpolated()) { + warnings.push_back(RTR("PhysicsBody2D will not work correctly on a non-interpolated branch of the SceneTree.\nCheck the node's inherited physics_interpolation_mode.")); + } + + return warnings; +} diff --git a/scene/2d/physics/physics_body_2d.h b/scene/2d/physics/physics_body_2d.h index de69c62393..6646bfd808 100644 --- a/scene/2d/physics/physics_body_2d.h +++ b/scene/2d/physics/physics_body_2d.h @@ -47,6 +47,8 @@ protected: Ref _move(const Vector2 &p_motion, bool p_test_only = false, real_t p_margin = 0.08, bool p_recovery_as_collision = false); public: + PackedStringArray get_configuration_warnings() const override; + bool move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true); bool test_move(const Transform2D &p_from, const Vector2 &p_motion, const Ref &r_collision = Ref(), real_t p_margin = 0.08, bool p_recovery_as_collision = false); Vector2 get_gravity() const; diff --git a/scene/3d/physics/physics_body_3d.cpp b/scene/3d/physics/physics_body_3d.cpp index fa27312dd5..c844e5ddf7 100644 --- a/scene/3d/physics/physics_body_3d.cpp +++ b/scene/3d/physics/physics_body_3d.cpp @@ -210,6 +210,16 @@ real_t PhysicsBody3D::get_inverse_mass() const { return 0; } +PackedStringArray PhysicsBody3D::get_configuration_warnings() const { + PackedStringArray warnings = CollisionObject3D::get_configuration_warnings(); + + if (!is_physics_interpolated()) { + warnings.push_back(RTR("PhysicsBody3D will not work correctly on a non-interpolated branch of the SceneTree.\nCheck the node's inherited physics_interpolation_mode.")); + } + + return warnings; +} + /////////////////////////////////////// //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. diff --git a/scene/3d/physics/physics_body_3d.h b/scene/3d/physics/physics_body_3d.h index e2145e609b..5ad4f99e32 100644 --- a/scene/3d/physics/physics_body_3d.h +++ b/scene/3d/physics/physics_body_3d.h @@ -49,6 +49,8 @@ protected: Ref _move(const Vector3 &p_motion, bool p_test_only = false, real_t p_margin = 0.001, bool p_recovery_as_collision = false, int p_max_collisions = 1); public: + PackedStringArray get_configuration_warnings() const override; + bool move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true); bool test_move(const Transform3D &p_from, const Vector3 &p_motion, const Ref &r_collision = Ref(), real_t p_margin = 0.001, bool p_recovery_as_collision = false, int p_max_collisions = 1); Vector3 get_gravity() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 59062228e7..0094140750 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -520,6 +520,8 @@ void Node::_propagate_physics_interpolated(bool p_interpolated) { // Allow a call to the RenderingServer etc. in derived classes. _physics_interpolated_changed(); + update_configuration_warnings(); + data.blocked++; for (KeyValue &K : data.children) { K.value->_propagate_physics_interpolated(p_interpolated); From 9f38cfe3ca0b774c80a5adfb3c182860d9302a13 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Mon, 1 Jul 2024 15:55:57 -0700 Subject: [PATCH 008/100] Add mid height property to CapsuleShape2D/3D --- doc/classes/CapsuleShape2D.xml | 5 ++- doc/classes/CapsuleShape3D.xml | 5 ++- doc/classes/SpringBoneCollisionCapsule3D.xml | 5 ++- scene/3d/spring_bone_collision_capsule_3d.cpp | 15 ++++++++ scene/3d/spring_bone_collision_capsule_3d.h | 2 ++ scene/resources/2d/capsule_shape_2d.cpp | 36 +++++++++++++------ scene/resources/2d/capsule_shape_2d.h | 3 ++ scene/resources/3d/capsule_shape_3d.cpp | 30 +++++++++++----- scene/resources/3d/capsule_shape_3d.h | 2 ++ 9 files changed, 81 insertions(+), 22 deletions(-) diff --git a/doc/classes/CapsuleShape2D.xml b/doc/classes/CapsuleShape2D.xml index 52ea7af292..c8652e4ec4 100644 --- a/doc/classes/CapsuleShape2D.xml +++ b/doc/classes/CapsuleShape2D.xml @@ -11,7 +11,10 @@ - The capsule's height. + The capsule's full height, including the semicircles. + + + The capsule's height, excluding the semicircles. This is the height of the central rectangular part in the middle of the capsule, and is the distance between the centers of the two semicircles. This is a wrapper for [member height]. The capsule's radius. diff --git a/doc/classes/CapsuleShape3D.xml b/doc/classes/CapsuleShape3D.xml index 4c6b3a870f..4e7c3d2edb 100644 --- a/doc/classes/CapsuleShape3D.xml +++ b/doc/classes/CapsuleShape3D.xml @@ -12,7 +12,10 @@ - The capsule's height. + The capsule's full height, including the hemispheres. + + + The capsule's height, excluding the hemispheres. This is the height of the central cylindrical part in the middle of the capsule, and is the distance between the centers of the two hemispheres. This is a wrapper for [member height]. The capsule's radius. diff --git a/doc/classes/SpringBoneCollisionCapsule3D.xml b/doc/classes/SpringBoneCollisionCapsule3D.xml index 9af9aca331..1e5767cf8c 100644 --- a/doc/classes/SpringBoneCollisionCapsule3D.xml +++ b/doc/classes/SpringBoneCollisionCapsule3D.xml @@ -10,11 +10,14 @@ - The capsule's height. + The capsule's full height, including the hemispheres. If [code]true[/code], the collision acts to trap the joint within the collision. + + The capsule's height, excluding the hemispheres. This is the height of the central cylindrical part in the middle of the capsule, and is the distance between the centers of the two hemispheres. This is a wrapper for [member height]. + The capsule's radius. diff --git a/scene/3d/spring_bone_collision_capsule_3d.cpp b/scene/3d/spring_bone_collision_capsule_3d.cpp index 39acc5aceb..c238eb0962 100644 --- a/scene/3d/spring_bone_collision_capsule_3d.cpp +++ b/scene/3d/spring_bone_collision_capsule_3d.cpp @@ -60,6 +60,18 @@ float SpringBoneCollisionCapsule3D::get_height() const { return height; } +void SpringBoneCollisionCapsule3D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "SpringBoneCollisionCapsule3D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; +#ifdef TOOLS_ENABLED + update_gizmos(); +#endif // TOOLS_ENABLED +} + +real_t SpringBoneCollisionCapsule3D::get_mid_height() const { + return height - radius * 2.0f; +} + void SpringBoneCollisionCapsule3D::set_inside(bool p_enabled) { inside = p_enabled; #ifdef TOOLS_ENABLED @@ -83,11 +95,14 @@ void SpringBoneCollisionCapsule3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_radius"), &SpringBoneCollisionCapsule3D::get_radius); ClassDB::bind_method(D_METHOD("set_height", "height"), &SpringBoneCollisionCapsule3D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &SpringBoneCollisionCapsule3D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &SpringBoneCollisionCapsule3D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &SpringBoneCollisionCapsule3D::get_mid_height); ClassDB::bind_method(D_METHOD("set_inside", "enabled"), &SpringBoneCollisionCapsule3D::set_inside); ClassDB::bind_method(D_METHOD("is_inside"), &SpringBoneCollisionCapsule3D::is_inside); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "inside"), "set_inside", "is_inside"); } diff --git a/scene/3d/spring_bone_collision_capsule_3d.h b/scene/3d/spring_bone_collision_capsule_3d.h index 61ee79cd3b..5ea7bd9b55 100644 --- a/scene/3d/spring_bone_collision_capsule_3d.h +++ b/scene/3d/spring_bone_collision_capsule_3d.h @@ -49,6 +49,8 @@ public: float get_radius() const; void set_height(float p_height); float get_height() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; void set_inside(bool p_enabled); bool is_inside() const; diff --git a/scene/resources/2d/capsule_shape_2d.cpp b/scene/resources/2d/capsule_shape_2d.cpp index 369acf714e..917cd86f19 100644 --- a/scene/resources/2d/capsule_shape_2d.cpp +++ b/scene/resources/2d/capsule_shape_2d.cpp @@ -38,7 +38,7 @@ Vector CapsuleShape2D::_get_points() const { Vector points; const real_t turn_step = Math::TAU / 24.0; for (int i = 0; i < 24; i++) { - Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -height * 0.5 + radius : height * 0.5 - radius); + Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -height * 0.5f + radius : height * 0.5f - radius); points.push_back(Vector2(Math::sin(i * turn_step), Math::cos(i * turn_step)) * radius + ofs); if (i == 6 || i == 18) { @@ -59,13 +59,13 @@ void CapsuleShape2D::_update_shape() { } void CapsuleShape2D::set_radius(real_t p_radius) { - ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape2D radius cannot be negative."); + ERR_FAIL_COND_MSG(p_radius < 0.0f, "CapsuleShape2D radius cannot be negative."); if (radius == p_radius) { return; } radius = p_radius; - if (radius > height * 0.5) { - height = radius * 2.0; + if (height < radius * 2.0f) { + height = radius * 2.0f; } _update_shape(); } @@ -75,13 +75,13 @@ real_t CapsuleShape2D::get_radius() const { } void CapsuleShape2D::set_height(real_t p_height) { - ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape2D height cannot be negative."); + ERR_FAIL_COND_MSG(p_height < 0.0f, "CapsuleShape2D height cannot be negative."); if (height == p_height) { return; } height = p_height; - if (radius > height * 0.5) { - radius = height * 0.5; + if (radius > height * 0.5f) { + radius = height * 0.5f; } _update_shape(); } @@ -90,6 +90,16 @@ real_t CapsuleShape2D::get_height() const { return height; } +void CapsuleShape2D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "CapsuleShape2D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; + _update_shape(); +} + +real_t CapsuleShape2D::get_mid_height() const { + return height - radius * 2.0f; +} + void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) { Vector points = _get_points(); Vector col = { p_color }; @@ -97,18 +107,18 @@ void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) { if (is_collision_outline_enabled()) { points.push_back(points[0]); - col = { Color(p_color, 1.0) }; + col = { Color(p_color, 1.0f) }; RenderingServer::get_singleton()->canvas_item_add_polyline(p_to_rid, points, col); } } Rect2 CapsuleShape2D::get_rect() const { - const Vector2 half_size = Vector2(radius, height * 0.5); - return Rect2(-half_size, half_size * 2.0); + const Vector2 half_size = Vector2(radius, height * 0.5f); + return Rect2(-half_size, half_size * 2.0f); } real_t CapsuleShape2D::get_enclosing_radius() const { - return height * 0.5; + return height * 0.5f; } void CapsuleShape2D::_bind_methods() { @@ -118,8 +128,12 @@ void CapsuleShape2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleShape2D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleShape2D::get_mid_height); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater,suffix:px", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_LINKED_PROPERTY("radius", "height"); ADD_LINKED_PROPERTY("height", "radius"); } diff --git a/scene/resources/2d/capsule_shape_2d.h b/scene/resources/2d/capsule_shape_2d.h index a6f4a92487..b55771f32d 100644 --- a/scene/resources/2d/capsule_shape_2d.h +++ b/scene/resources/2d/capsule_shape_2d.h @@ -53,6 +53,9 @@ public: void set_radius(real_t p_radius); real_t get_radius() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; + virtual void draw(const RID &p_to_rid, const Color &p_color) override; virtual Rect2 get_rect() const override; virtual real_t get_enclosing_radius() const override; diff --git a/scene/resources/3d/capsule_shape_3d.cpp b/scene/resources/3d/capsule_shape_3d.cpp index b63bf69aee..2a7e36cf0f 100644 --- a/scene/resources/3d/capsule_shape_3d.cpp +++ b/scene/resources/3d/capsule_shape_3d.cpp @@ -39,7 +39,7 @@ Vector CapsuleShape3D::get_debug_mesh_lines() const { Vector points; - Vector3 d(0, c_height * 0.5 - c_radius, 0); + Vector3 d(0, c_height * 0.5f - c_radius, 0); for (int i = 0; i < 360; i++) { float ra = Math::deg_to_rad((float)i); float rb = Math::deg_to_rad((float)i + 1); @@ -87,7 +87,7 @@ Ref CapsuleShape3D::get_debug_arraymesh_faces(const Color &p_modulate } real_t CapsuleShape3D::get_enclosing_radius() const { - return height * 0.5; + return height * 0.5f; } void CapsuleShape3D::_update_shape() { @@ -99,10 +99,10 @@ void CapsuleShape3D::_update_shape() { } void CapsuleShape3D::set_radius(float p_radius) { - ERR_FAIL_COND_MSG(p_radius < 0, "CapsuleShape3D radius cannot be negative."); + ERR_FAIL_COND_MSG(p_radius < 0.0f, "CapsuleShape3D radius cannot be negative."); radius = p_radius; - if (radius > height * 0.5) { - height = radius * 2.0; + if (height < radius * 2.0f) { + height = radius * 2.0f; } _update_shape(); emit_changed(); @@ -113,10 +113,10 @@ float CapsuleShape3D::get_radius() const { } void CapsuleShape3D::set_height(float p_height) { - ERR_FAIL_COND_MSG(p_height < 0, "CapsuleShape3D height cannot be negative."); + ERR_FAIL_COND_MSG(p_height < 0.0f, "CapsuleShape3D height cannot be negative."); height = p_height; - if (radius > height * 0.5) { - radius = height * 0.5; + if (radius > height * 0.5f) { + radius = height * 0.5f; } _update_shape(); emit_changed(); @@ -126,14 +126,28 @@ float CapsuleShape3D::get_height() const { return height; } +void CapsuleShape3D::set_mid_height(real_t p_mid_height) { + ERR_FAIL_COND_MSG(p_mid_height < 0.0f, "CapsuleShape3D mid-height cannot be negative."); + height = p_mid_height + radius * 2.0f; + _update_shape(); + emit_changed(); +} + +real_t CapsuleShape3D::get_mid_height() const { + return height - radius * 2.0f; +} + void CapsuleShape3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape3D::set_radius); ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape3D::get_radius); ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape3D::set_height); ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape3D::get_height); + ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleShape3D::set_mid_height); + ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleShape3D::get_mid_height); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_radius", "get_radius"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m"), "set_height", "get_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mid_height", PROPERTY_HINT_RANGE, "0.001,100,0.001,or_greater,suffix:m", PROPERTY_USAGE_NONE), "set_mid_height", "get_mid_height"); ADD_LINKED_PROPERTY("radius", "height"); ADD_LINKED_PROPERTY("height", "radius"); } diff --git a/scene/resources/3d/capsule_shape_3d.h b/scene/resources/3d/capsule_shape_3d.h index 16f58bc95d..56ac5e4c90 100644 --- a/scene/resources/3d/capsule_shape_3d.h +++ b/scene/resources/3d/capsule_shape_3d.h @@ -49,6 +49,8 @@ public: float get_radius() const; void set_height(float p_height); float get_height() const; + void set_mid_height(real_t p_mid_height); + real_t get_mid_height() const; virtual Vector get_debug_mesh_lines() const override; virtual Ref get_debug_arraymesh_faces(const Color &p_modulate) const override; From 1de9789806b626a3eb9b61d37391a5dbe96ae4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 14 May 2025 10:08:06 +0200 Subject: [PATCH 009/100] Linux: Drop `ppc32` (32-bit PowerPC) architecture support This was added together with `ppc64le` in #54490, but seemingly only for the purpose of getting it to compile on a Linux distro that aims at maximizing support for all CPU architectures. I don't think anyone has ever _run_ Godot on a `ppc32` system (do those even support OpenGL ES 3.0?) and so I don't think we should aim to support it. Debian dropped support for its PowerPC (`ppc32`) arch in Debian 9, released in 2017. --- core/config/engine.cpp | 21 ++----------------- core/os/spin_lock.h | 2 +- doc/classes/Engine.xml | 2 +- editor/editor_property_name_processor.cpp | 1 - editor/plugins/gdextension_export_plugin.h | 1 - modules/jolt_physics/config.py | 2 +- platform/linuxbsd/detect.py | 2 +- .../EditorExportPlatformLinuxBSD.xml | 2 +- platform/linuxbsd/export/export_plugin.cpp | 4 +--- platform_methods.py | 4 +--- 10 files changed, 9 insertions(+), 32 deletions(-) diff --git a/core/config/engine.cpp b/core/config/engine.cpp index a4d460ac7e..fa1be2d30d 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -224,40 +224,23 @@ String Engine::get_license_text() const { String Engine::get_architecture_name() const { #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) return "x86_64"; - #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) return "x86_32"; - #elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) return "arm64"; - #elif defined(__arm__) || defined(_M_ARM) return "arm32"; - #elif defined(__riscv) -#if __riscv_xlen == 8 return "rv64"; -#else - return "riscv"; -#endif - -#elif defined(__powerpc__) -#if defined(__powerpc64__) +#elif defined(__powerpc64__) return "ppc64"; -#else - return "ppc"; -#endif - #elif defined(__loongarch64) return "loongarch64"; - -#elif defined(__wasm__) -#if defined(__wasm64__) +#elif defined(__wasm64__) return "wasm64"; #elif defined(__wasm32__) return "wasm32"; #endif -#endif } bool Engine::is_abort_on_gpu_errors_enabled() const { diff --git a/core/os/spin_lock.h b/core/os/spin_lock.h index c5d1a52c46..7a50510353 100644 --- a/core/os/spin_lock.h +++ b/core/os/spin_lock.h @@ -81,7 +81,7 @@ _ALWAYS_INLINE_ static void _cpu_pause() { __builtin_ia32_pause(); #elif defined(__arm__) || defined(__aarch64__) // ARM. asm volatile("yield"); -#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) // PowerPC. +#elif defined(__powerpc__) // PowerPC. asm volatile("or 27,27,27"); #elif defined(__riscv) // RISC-V. asm volatile(".insn i 0x0F, 0, x0, x0, 0x010"); diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 9ca4a02c7b..554f692014 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -22,7 +22,7 @@ - Returns the name of the CPU architecture the Godot binary was built for. Possible return values include [code]"x86_64"[/code], [code]"x86_32"[/code], [code]"arm64"[/code], [code]"arm32"[/code], [code]"rv64"[/code], [code]"riscv"[/code], [code]"ppc64"[/code], [code]"ppc"[/code], [code]"wasm64"[/code], and [code]"wasm32"[/code]. + Returns the name of the CPU architecture the Godot binary was built for. Possible return values include [code]"x86_64"[/code], [code]"x86_32"[/code], [code]"arm64"[/code], [code]"arm32"[/code], [code]"rv64"[/code], [code]"ppc64"[/code], [code]"loongarch64"[/code], [code]"wasm64"[/code], and [code]"wasm32"[/code]. To detect whether the current build is 64-bit, or the type of architecture, don't use the architecture name. Instead, use [method OS.has_feature] to check for the [code]"64"[/code] feature tag, or tags such as [code]"x86"[/code] or [code]"arm"[/code]. See the [url=$DOCS_URL/tutorials/export/feature_tags.html]Feature Tags[/url] documentation for more details. [b]Note:[/b] This method does [i]not[/i] return the name of the system's CPU architecture (like [method OS.get_processor_name]). For example, when running an [code]x86_32[/code] Godot binary on an [code]x86_64[/code] system, the returned value will still be [code]"x86_32"[/code]. diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 1cf180bc17..a2c772d3a7 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -255,7 +255,6 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["pck"] = "PCK"; capitalize_string_remaps["png"] = "PNG"; capitalize_string_remaps["po2"] = "(Power of 2)"; // Unit. - capitalize_string_remaps["ppc32"] = "ppc32"; capitalize_string_remaps["ppc64"] = "ppc64"; capitalize_string_remaps["pvrtc"] = "PVRTC"; capitalize_string_remaps["pvs"] = "PVS"; diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h index 0792400eda..9f8ca0f1b0 100644 --- a/editor/plugins/gdextension_export_plugin.h +++ b/editor/plugins/gdextension_export_plugin.h @@ -69,7 +69,6 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p all_archs.insert("arm32"); all_archs.insert("arm64"); all_archs.insert("rv64"); - all_archs.insert("ppc32"); all_archs.insert("ppc64"); all_archs.insert("wasm32"); all_archs.insert("loongarch64"); diff --git a/modules/jolt_physics/config.py b/modules/jolt_physics/config.py index 64bd1c73d6..79b382a747 100644 --- a/modules/jolt_physics/config.py +++ b/modules/jolt_physics/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return not env["disable_physics_3d"] and not env["arch"] == "ppc32" + return not env["disable_physics_3d"] def configure(env): diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index da0e62af44..144c5b303e 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -73,7 +73,7 @@ def get_flags(): def configure(env: "SConsEnvironment"): # Validate arch. - supported_arches = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "loongarch64"] + supported_arches = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc64", "loongarch64"] validate_arch(env["arch"], get_name(), supported_arches) ## Build type diff --git a/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml index cbd86eca3d..b3c07cebda 100644 --- a/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml +++ b/platform/linuxbsd/doc_classes/EditorExportPlatformLinuxBSD.xml @@ -11,7 +11,7 @@ Application executable architecture. - Supported architectures: [code]x86_32[/code], [code]x86_64[/code], [code]arm64[/code], [code]arm32[/code], [code]rv64[/code], [code]ppc64[/code], [code]ppc32[/code], and [code]loongarch64[/code]. + Supported architectures: [code]x86_32[/code], [code]x86_64[/code], [code]arm64[/code], [code]arm32[/code], [code]rv64[/code], [code]ppc64[/code], and [code]loongarch64[/code]. Official export templates include [code]x86_32[/code], [code]x86_64[/code], [code]arm32[/code], and [code]arm64[/code] binaries only. diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index d3a6d5c6bf..ae6eecf049 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -184,7 +184,7 @@ bool EditorExportPlatformLinuxBSD::get_export_option_visibility(const EditorExpo void EditorExportPlatformLinuxBSD::get_export_options(List *r_options) const { EditorExportPlatformPC::get_export_options(r_options); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64,arm32,rv64,ppc64,ppc32,loongarch64"), "x86_64")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "binary_format/architecture", PROPERTY_HINT_ENUM, "x86_64,x86_32,arm64,arm32,rv64,ppc64,loongarch64"), "x86_64")); String run_script = "#!/usr/bin/env bash\n" "export DISPLAY=:0\n" @@ -276,8 +276,6 @@ String EditorExportPlatformLinuxBSD::_get_exe_arch(const String &p_path) const { return "x86_32"; case 0x003e: return "x86_64"; - case 0x0014: - return "ppc32"; case 0x0015: return "ppc64"; case 0x0028: diff --git a/platform_methods.py b/platform_methods.py index c8646a4022..022c02c8db 100644 --- a/platform_methods.py +++ b/platform_methods.py @@ -16,7 +16,7 @@ compatibility_platform_aliases = { } # CPU architecture options. -architectures = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32", "loongarch64"] +architectures = ["x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc64", "wasm32", "loongarch64"] architecture_aliases = { "x86": "x86_32", "x64": "x86_64", @@ -28,8 +28,6 @@ architecture_aliases = { "rv": "rv64", "riscv": "rv64", "riscv64": "rv64", - "ppcle": "ppc32", - "ppc": "ppc32", "ppc64le": "ppc64", "loong64": "loongarch64", } From 76a65de3ab402c1e3a1c7688fdce755ba2da183a Mon Sep 17 00:00:00 2001 From: Adam Johnston Date: Thu, 1 May 2025 12:33:27 -0700 Subject: [PATCH 010/100] Change fuzzy search to only set case sensitive within set_query --- core/string/fuzzy_search.cpp | 17 ++++++++++++----- core/string/fuzzy_search.h | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/string/fuzzy_search.cpp b/core/string/fuzzy_search.cpp index f67193b252..418518d87e 100644 --- a/core/string/fuzzy_search.cpp +++ b/core/string/fuzzy_search.cpp @@ -265,12 +265,19 @@ void FuzzySearch::sort_and_filter(Vector &p_results) const { } void FuzzySearch::set_query(const String &p_query) { - tokens.clear(); - for (const String &string : p_query.split(" ", false)) { - tokens.append({ static_cast(tokens.size()), string }); - } + set_query(p_query, !p_query.is_lowercase()); +} - case_sensitive = !p_query.is_lowercase(); +void FuzzySearch::set_query(const String &p_query, bool p_case_sensitive) { + tokens.clear(); + case_sensitive = p_case_sensitive; + + for (const String &string : p_query.split(" ", false)) { + tokens.append({ + static_cast(tokens.size()), + p_case_sensitive ? string : string.to_lower(), + }); + } struct TokenComparator { bool operator()(const FuzzySearchToken &A, const FuzzySearchToken &B) const { diff --git a/core/string/fuzzy_search.h b/core/string/fuzzy_search.h index de46d613b9..d1cd1dc257 100644 --- a/core/string/fuzzy_search.h +++ b/core/string/fuzzy_search.h @@ -84,16 +84,17 @@ public: class FuzzySearch { Vector tokens; + bool case_sensitive = false; void sort_and_filter(Vector &p_results) const; public: int start_offset = 0; - bool case_sensitive = false; int max_results = 100; int max_misses = 2; bool allow_subsequences = true; void set_query(const String &p_query); + void set_query(const String &p_query, bool p_case_sensitive); bool search(const String &p_target, FuzzySearchResult &p_result) const; void search_all(const PackedStringArray &p_targets, Vector &p_results) const; }; From 9f67bf96fa16a5eefaff2edaff2ed8430104a3e9 Mon Sep 17 00:00:00 2001 From: Elzewyr <49611994+elzewyr@users.noreply.github.com> Date: Mon, 12 May 2025 19:33:39 +0300 Subject: [PATCH 011/100] SoftBody3D: Add a property for scaling rest lengths of edge constraints --- doc/classes/PhysicsServer3D.xml | 15 +++++++++++++++ doc/classes/PhysicsServer3DExtension.xml | 13 +++++++++++++ doc/classes/SoftBody3D.xml | 4 ++++ .../godot_physics_3d/godot_physics_server_3d.cpp | 14 ++++++++++++++ .../godot_physics_3d/godot_physics_server_3d.h | 3 +++ modules/godot_physics_3d/godot_soft_body_3d.cpp | 7 +++++++ modules/godot_physics_3d/godot_soft_body_3d.h | 4 ++++ modules/jolt_physics/jolt_physics_server_3d.cpp | 14 ++++++++++++++ modules/jolt_physics/jolt_physics_server_3d.h | 3 +++ .../jolt_physics/objects/jolt_soft_body_3d.cpp | 12 ++++++++++++ modules/jolt_physics/objects/jolt_soft_body_3d.h | 4 ++++ scene/3d/physics/soft_body_3d.cpp | 12 ++++++++++++ scene/3d/physics/soft_body_3d.h | 3 +++ .../extensions/physics_server_3d_extension.cpp | 3 +++ servers/extensions/physics_server_3d_extension.h | 3 +++ servers/physics_server_3d.cpp | 3 +++ servers/physics_server_3d.h | 3 +++ servers/physics_server_3d_dummy.h | 3 +++ servers/physics_server_3d_wrap_mt.h | 3 +++ 19 files changed, 126 insertions(+) diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index f87d6342c7..1644675ef5 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -1121,6 +1121,13 @@ Returns the pressure coefficient of the given soft body. + + + + + Returns the shrinking factor of the given soft body. + + @@ -1258,6 +1265,14 @@ Sets whether the given soft body will be pickable when using object picking. + + + + + + Sets the shrinking factor of the given soft body. + + diff --git a/doc/classes/PhysicsServer3DExtension.xml b/doc/classes/PhysicsServer3DExtension.xml index e58a7ff9a8..5598a17f36 100644 --- a/doc/classes/PhysicsServer3DExtension.xml +++ b/doc/classes/PhysicsServer3DExtension.xml @@ -1049,6 +1049,12 @@ + + + + + + @@ -1166,6 +1172,13 @@ + + + + + + + diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml index 4d8791d8c1..e5f6f47c1a 100644 --- a/doc/classes/SoftBody3D.xml +++ b/doc/classes/SoftBody3D.xml @@ -124,6 +124,10 @@ If [code]true[/code], the [SoftBody3D] will respond to [RayCast3D]s. + + Scales the rest lengths of [SoftBody3D]'s edge constraints. Positive values shrink the mesh, while negative values expand it. For example, a value of [code]0.1[/code] shortens the edges of the mesh by 10%, while [code]-0.1[/code] expands the edges by 10%. + [b]Note:[/b] [member shrinking_factor] is best used on surface meshes with pinned points. + Increasing this value will improve the resulting simulation, but can affect performance. Use with care. diff --git a/modules/godot_physics_3d/godot_physics_server_3d.cpp b/modules/godot_physics_3d/godot_physics_server_3d.cpp index 35aa538ef5..ac9337b107 100644 --- a/modules/godot_physics_3d/godot_physics_server_3d.cpp +++ b/modules/godot_physics_3d/godot_physics_server_3d.cpp @@ -1104,6 +1104,20 @@ real_t GodotPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const { return soft_body->get_linear_stiffness(); } +void GodotPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_NULL(soft_body); + + soft_body->set_shrinking_factor(p_shrinking_factor); +} + +real_t GodotPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const { + GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_NULL_V(soft_body, 0.f); + + return soft_body->get_shrinking_factor(); +} + void GodotPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { GodotSoftBody3D *soft_body = soft_body_owner.get_or_null(p_body); ERR_FAIL_NULL(soft_body); diff --git a/modules/godot_physics_3d/godot_physics_server_3d.h b/modules/godot_physics_3d/godot_physics_server_3d.h index b394ab592b..492e6f9ad9 100644 --- a/modules/godot_physics_3d/godot_physics_server_3d.h +++ b/modules/godot_physics_3d/godot_physics_server_3d.h @@ -289,6 +289,9 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override; virtual real_t soft_body_get_linear_stiffness(RID p_body) const override; + virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) override; + virtual real_t soft_body_get_shrinking_factor(RID p_body) const override; + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override; virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override; diff --git a/modules/godot_physics_3d/godot_soft_body_3d.cpp b/modules/godot_physics_3d/godot_soft_body_3d.cpp index a117095648..e62ce4527a 100644 --- a/modules/godot_physics_3d/godot_soft_body_3d.cpp +++ b/modules/godot_physics_3d/godot_soft_body_3d.cpp @@ -272,8 +272,10 @@ void GodotSoftBody3D::update_area() { } void GodotSoftBody3D::reset_link_rest_lengths() { + float multiplier = 1.0 - shrinking_factor; for (Link &link : links) { link.rl = (link.n[0]->x - link.n[1]->x).length(); + link.rl *= multiplier; link.c1 = link.rl * link.rl; } } @@ -837,6 +839,7 @@ void GodotSoftBody3D::append_link(uint32_t p_node1, uint32_t p_node2) { link.n[0] = node1; link.n[1] = node2; link.rl = (node1->x - node2->x).length(); + link.rl *= 1.0 - shrinking_factor; links.push_back(link); } @@ -894,6 +897,10 @@ void GodotSoftBody3D::set_linear_stiffness(real_t p_val) { linear_stiffness = p_val; } +void GodotSoftBody3D::set_shrinking_factor(real_t p_val) { + shrinking_factor = p_val; +} + void GodotSoftBody3D::set_pressure_coefficient(real_t p_val) { pressure_coefficient = p_val; } diff --git a/modules/godot_physics_3d/godot_soft_body_3d.h b/modules/godot_physics_3d/godot_soft_body_3d.h index 1fcf349fb2..45854155c3 100644 --- a/modules/godot_physics_3d/godot_soft_body_3d.h +++ b/modules/godot_physics_3d/godot_soft_body_3d.h @@ -95,6 +95,7 @@ class GodotSoftBody3D : public GodotCollisionObject3D { int iteration_count = 5; real_t linear_stiffness = 0.5; // [0,1] + real_t shrinking_factor = 0.0; // [-1,1] real_t pressure_coefficient = 0.0; // [-inf,+inf] real_t damping_coefficient = 0.01; // [0,1] real_t drag_coefficient = 0.0; // [0,1] @@ -191,6 +192,9 @@ public: void set_linear_stiffness(real_t p_val); _FORCE_INLINE_ real_t get_linear_stiffness() const { return linear_stiffness; } + void set_shrinking_factor(real_t p_val); + _FORCE_INLINE_ real_t get_shrinking_factor() const { return shrinking_factor; } + void set_pressure_coefficient(real_t p_val); _FORCE_INLINE_ real_t get_pressure_coefficient() const { return pressure_coefficient; } diff --git a/modules/jolt_physics/jolt_physics_server_3d.cpp b/modules/jolt_physics/jolt_physics_server_3d.cpp index d126f8bde7..77cf96c911 100644 --- a/modules/jolt_physics/jolt_physics_server_3d.cpp +++ b/modules/jolt_physics/jolt_physics_server_3d.cpp @@ -1126,6 +1126,20 @@ real_t JoltPhysicsServer3D::soft_body_get_linear_stiffness(RID p_body) const { return (real_t)body->get_stiffness_coefficient(); } +void JoltPhysicsServer3D::soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) { + JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_NULL(body); + + return body->set_shrinking_factor((float)p_shrinking_factor); +} + +real_t JoltPhysicsServer3D::soft_body_get_shrinking_factor(RID p_body) const { + JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body); + ERR_FAIL_NULL_V(body, 0.0); + + return (real_t)body->get_shrinking_factor(); +} + void JoltPhysicsServer3D::soft_body_set_pressure_coefficient(RID p_body, real_t p_coefficient) { JoltSoftBody3D *body = soft_body_owner.get_or_null(p_body); ERR_FAIL_NULL(body); diff --git a/modules/jolt_physics/jolt_physics_server_3d.h b/modules/jolt_physics/jolt_physics_server_3d.h index 5ee1439459..b162fff673 100644 --- a/modules/jolt_physics/jolt_physics_server_3d.h +++ b/modules/jolt_physics/jolt_physics_server_3d.h @@ -331,6 +331,9 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_coefficient) override; virtual real_t soft_body_get_linear_stiffness(RID p_body) const override; + virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) override; + virtual real_t soft_body_get_shrinking_factor(RID p_body) const override; + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_coefficient) override; virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override; diff --git a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp index 95e83c8b7e..4fa27084ae 100644 --- a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp +++ b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp @@ -202,6 +202,10 @@ bool JoltSoftBody3D::_ref_shared_data() { vertex_attrib.mCompliance = vertex_attrib.mShearCompliance = inverse_stiffness; settings.CreateConstraints(&vertex_attrib, 1, JPH::SoftBodySharedSettings::EBendType::None); + float multiplier = 1.0f - shrinking_factor; + for (JPH::SoftBodySharedSettings::Edge &e : settings.mEdgeConstraints) { + e.mRestLength *= multiplier; + } settings.Optimize(); } else { iter_shared_data->value.ref_count++; @@ -454,6 +458,14 @@ void JoltSoftBody3D::set_stiffness_coefficient(float p_coefficient) { stiffness_coefficient = CLAMP(p_coefficient, 0.0f, 1.0f); } +float JoltSoftBody3D::get_shrinking_factor() const { + return shrinking_factor; +} + +void JoltSoftBody3D::set_shrinking_factor(float p_shrinking_factor) { + shrinking_factor = p_shrinking_factor; +} + void JoltSoftBody3D::set_pressure(float p_pressure) { if (unlikely(pressure == p_pressure)) { return; diff --git a/modules/jolt_physics/objects/jolt_soft_body_3d.h b/modules/jolt_physics/objects/jolt_soft_body_3d.h index 4ec422e555..53f47271e0 100644 --- a/modules/jolt_physics/objects/jolt_soft_body_3d.h +++ b/modules/jolt_physics/objects/jolt_soft_body_3d.h @@ -64,6 +64,7 @@ class JoltSoftBody3D final : public JoltObject3D { float pressure = 0.0f; float linear_damping = 0.01f; float stiffness_coefficient = 0.5f; + float shrinking_factor = 0.0f; int simulation_precision = 5; @@ -138,6 +139,9 @@ public: float get_stiffness_coefficient() const; void set_stiffness_coefficient(float p_coefficient); + float get_shrinking_factor() const; + void set_shrinking_factor(float p_shrinking_factor); + float get_pressure() const { return pressure; } void set_pressure(float p_pressure); diff --git a/scene/3d/physics/soft_body_3d.cpp b/scene/3d/physics/soft_body_3d.cpp index b0fc94d75f..d906159dc0 100644 --- a/scene/3d/physics/soft_body_3d.cpp +++ b/scene/3d/physics/soft_body_3d.cpp @@ -352,6 +352,9 @@ void SoftBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); + ClassDB::bind_method(D_METHOD("set_shrinking_factor", "shrinking_factor"), &SoftBody3D::set_shrinking_factor); + ClassDB::bind_method(D_METHOD("get_shrinking_factor"), &SoftBody3D::get_shrinking_factor); + ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient); ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient); @@ -377,6 +380,7 @@ void SoftBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shrinking_factor", PROPERTY_HINT_RANGE, "-1,1,0.01,or_less,or_greater"), "set_shrinking_factor", "get_shrinking_factor"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); @@ -643,6 +647,14 @@ real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } +void SoftBody3D::set_shrinking_factor(real_t p_shrinking_factor) { + PhysicsServer3D::get_singleton()->soft_body_set_shrinking_factor(physics_rid, p_shrinking_factor); +} + +real_t SoftBody3D::get_shrinking_factor() { + return PhysicsServer3D::get_singleton()->soft_body_get_shrinking_factor(physics_rid); +} + real_t SoftBody3D::get_pressure_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid); } diff --git a/scene/3d/physics/soft_body_3d.h b/scene/3d/physics/soft_body_3d.h index f136b7ac0b..e517ba7eb1 100644 --- a/scene/3d/physics/soft_body_3d.h +++ b/scene/3d/physics/soft_body_3d.h @@ -164,6 +164,9 @@ public: void set_linear_stiffness(real_t p_linear_stiffness); real_t get_linear_stiffness(); + void set_shrinking_factor(real_t p_shrinking_factor); + real_t get_shrinking_factor(); + void set_pressure_coefficient(real_t p_pressure_coefficient); real_t get_pressure_coefficient(); diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp index 0937021c64..254877445f 100644 --- a/servers/extensions/physics_server_3d_extension.cpp +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -338,6 +338,9 @@ void PhysicsServer3DExtension::_bind_methods() { GDVIRTUAL_BIND(_soft_body_set_linear_stiffness, "body", "linear_stiffness"); GDVIRTUAL_BIND(_soft_body_get_linear_stiffness, "body"); + GDVIRTUAL_BIND(_soft_body_set_shrinking_factor, "body", "shrinking_factor"); + GDVIRTUAL_BIND(_soft_body_get_shrinking_factor, "body"); + GDVIRTUAL_BIND(_soft_body_set_pressure_coefficient, "body", "pressure_coefficient"); GDVIRTUAL_BIND(_soft_body_get_pressure_coefficient, "body"); diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index 4d27efacf7..5e271bbf26 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -445,6 +445,9 @@ public: EXBIND2(soft_body_set_linear_stiffness, RID, real_t) EXBIND1RC(real_t, soft_body_get_linear_stiffness, RID) + EXBIND2(soft_body_set_shrinking_factor, RID, real_t) + EXBIND1RC(real_t, soft_body_get_shrinking_factor, RID) + EXBIND2(soft_body_set_pressure_coefficient, RID, real_t) EXBIND1RC(real_t, soft_body_get_pressure_coefficient, RID) diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index f85ce55d99..be0bdf37c2 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -876,6 +876,9 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("soft_body_set_linear_stiffness", "body", "stiffness"), &PhysicsServer3D::soft_body_set_linear_stiffness); ClassDB::bind_method(D_METHOD("soft_body_get_linear_stiffness", "body"), &PhysicsServer3D::soft_body_get_linear_stiffness); + ClassDB::bind_method(D_METHOD("soft_body_set_shrinking_factor", "body", "shrinking_factor"), &PhysicsServer3D::soft_body_set_shrinking_factor); + ClassDB::bind_method(D_METHOD("soft_body_get_shrinking_factor", "body"), &PhysicsServer3D::soft_body_get_shrinking_factor); + ClassDB::bind_method(D_METHOD("soft_body_set_pressure_coefficient", "body", "pressure_coefficient"), &PhysicsServer3D::soft_body_set_pressure_coefficient); ClassDB::bind_method(D_METHOD("soft_body_get_pressure_coefficient", "body"), &PhysicsServer3D::soft_body_get_pressure_coefficient); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 921b590ce6..7d50825062 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -607,6 +607,9 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) = 0; virtual real_t soft_body_get_linear_stiffness(RID p_body) const = 0; + virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) = 0; + virtual real_t soft_body_get_shrinking_factor(RID p_body) const = 0; + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) = 0; virtual real_t soft_body_get_pressure_coefficient(RID p_body) const = 0; diff --git a/servers/physics_server_3d_dummy.h b/servers/physics_server_3d_dummy.h index 3867ed4065..f8de13f5a6 100644 --- a/servers/physics_server_3d_dummy.h +++ b/servers/physics_server_3d_dummy.h @@ -341,6 +341,9 @@ public: virtual void soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) override {} virtual real_t soft_body_get_linear_stiffness(RID p_body) const override { return 0; } + virtual void soft_body_set_shrinking_factor(RID p_body, real_t p_shrinking_factor) override {} + virtual real_t soft_body_get_shrinking_factor(RID p_body) const override { return 0; } + virtual void soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) override {} virtual real_t soft_body_get_pressure_coefficient(RID p_body) const override { return 0; } diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index 74653dac09..c3a3951061 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -304,6 +304,9 @@ public: FUNC2(soft_body_set_linear_stiffness, RID, real_t); FUNC1RC(real_t, soft_body_get_linear_stiffness, RID); + FUNC2(soft_body_set_shrinking_factor, RID, real_t); + FUNC1RC(real_t, soft_body_get_shrinking_factor, RID); + FUNC2(soft_body_set_pressure_coefficient, RID, real_t); FUNC1RC(real_t, soft_body_get_pressure_coefficient, RID); From 6fe17b264e149169da057a20ffdd585bd837617b Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Sun, 18 May 2025 19:43:07 +0200 Subject: [PATCH 012/100] Use `if` based mod in `HashMap` and `HashSet` in loops (faster than `fastmod`). --- core/templates/hash_map.h | 20 +++++++++++++++----- core/templates/hash_set.h | 26 ++++++++++++++++++-------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h index ef0ca33046..ce77bf2cb1 100644 --- a/core/templates/hash_map.h +++ b/core/templates/hash_map.h @@ -91,9 +91,19 @@ private: return hash; } + _FORCE_INLINE_ static constexpr void _increment_mod(uint32_t &r_pos, const uint32_t p_capacity) { + r_pos++; + // `if` is faster than both fastmod and mod. + if (unlikely(r_pos == p_capacity)) { + r_pos = 0; + } + } + static _FORCE_INLINE_ uint32_t _get_probe_length(const uint32_t p_pos, const uint32_t p_hash, const uint32_t p_capacity, const uint64_t p_capacity_inv) { const uint32_t original_pos = fastmod(p_hash, p_capacity_inv, p_capacity); - return fastmod(p_pos - original_pos + p_capacity, p_capacity_inv, p_capacity); + const uint32_t distance_pos = p_pos - original_pos + p_capacity; + // At most p_capacity over 0, so we can use an if (faster than fastmod). + return distance_pos >= p_capacity ? distance_pos - p_capacity : distance_pos; } bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const { @@ -121,7 +131,7 @@ private: return true; } - pos = fastmod((pos + 1), capacity_inv, capacity); + _increment_mod(pos, capacity); distance++; } } @@ -152,7 +162,7 @@ private: distance = existing_probe_len; } - pos = fastmod((pos + 1), capacity_inv, capacity); + _increment_mod(pos, capacity); distance++; } } @@ -357,7 +367,7 @@ public: SWAP(hashes[next_pos], hashes[pos]); SWAP(elements[next_pos], elements[pos]); pos = next_pos; - next_pos = fastmod((pos + 1), capacity_inv, capacity); + _increment_mod(next_pos, capacity); } hashes[pos] = EMPTY_HASH; @@ -406,7 +416,7 @@ public: SWAP(hashes[next_pos], hashes[pos]); SWAP(elements[next_pos], elements[pos]); pos = next_pos; - next_pos = fastmod((pos + 1), capacity_inv, capacity); + _increment_mod(next_pos, capacity); } hashes[pos] = EMPTY_HASH; elements[pos] = nullptr; diff --git a/core/templates/hash_set.h b/core/templates/hash_set.h index b2982f6860..a87517a286 100644 --- a/core/templates/hash_set.h +++ b/core/templates/hash_set.h @@ -70,9 +70,19 @@ private: return hash; } + _FORCE_INLINE_ static constexpr void _increment_mod(uint32_t &r_pos, const uint32_t p_capacity) { + r_pos++; + // `if` is faster than both fastmod and mod. + if (unlikely(r_pos == p_capacity)) { + r_pos = 0; + } + } + static _FORCE_INLINE_ uint32_t _get_probe_length(const uint32_t p_pos, const uint32_t p_hash, const uint32_t p_capacity, const uint64_t p_capacity_inv) { const uint32_t original_pos = fastmod(p_hash, p_capacity_inv, p_capacity); - return fastmod(p_pos - original_pos + p_capacity, p_capacity_inv, p_capacity); + const uint32_t distance_pos = p_pos - original_pos + p_capacity; + // At most p_capacity over 0, so we can use an if (faster than fastmod). + return distance_pos >= p_capacity ? distance_pos - p_capacity : distance_pos; } bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const { @@ -91,16 +101,16 @@ private: return false; } - if (distance > _get_probe_length(pos, hashes[pos], capacity, capacity_inv)) { - return false; - } - if (hashes[pos] == hash && Comparator::compare(keys[hash_to_key[pos]], p_key)) { r_pos = hash_to_key[pos]; return true; } - pos = fastmod(pos + 1, capacity_inv, capacity); + if (distance > _get_probe_length(pos, hashes[pos], capacity, capacity_inv)) { + return false; + } + + _increment_mod(pos, capacity); distance++; } } @@ -130,7 +140,7 @@ private: distance = existing_probe_len; } - pos = fastmod(pos + 1, capacity_inv, capacity); + _increment_mod(pos, capacity); distance++; } } @@ -274,7 +284,7 @@ public: SWAP(hash_to_key[next_pos], hash_to_key[pos]); pos = next_pos; - next_pos = fastmod(pos + 1, capacity_inv, capacity); + _increment_mod(next_pos, capacity); } hashes[pos] = EMPTY_HASH; From f5383df83b9b4dd279583626132e1679463dd114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Thu, 19 Dec 2024 10:15:02 +0100 Subject: [PATCH 013/100] Overhaul `Resource::duplicate_for_local_scene()` - Serves as a first step for future refactors. - Code is simpler. - Algorithm is more efficient: instead of two passes (dumb copy + resolve copies), it's single-pass. - Now obeys `PROPERTY_USAGE_NEVER_DUPLICATE`. - Now handles deep self-references (the resource to be duplicated being referenced somewhere deep). --- core/io/resource.cpp | 104 +++++++++++++++++++++++++++---------------- core/io/resource.h | 2 +- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 5b76b6a544..e714978d13 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -34,6 +34,7 @@ #include "core/math/math_funcs.h" #include "core/math/random_pcg.h" #include "core/os/os.h" +#include "core/variant/container_type_validate.h" #include "scene/main/node.h" //only so casting works void Resource::emit_changed() { @@ -265,51 +266,62 @@ void Resource::reload_from_file() { copy_from(s); } -void Resource::_dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMap, Ref> &p_remap_cache) { - switch (r_variant.get_type()) { - case Variant::ARRAY: { - Array a = r_variant; - for (int i = 0; i < a.size(); i++) { - _dupe_sub_resources(a[i], p_for_scene, p_remap_cache); - } - } break; - case Variant::DICTIONARY: { - Dictionary d = r_variant; - for (Variant &k : d.get_key_list()) { - if (k.get_type() == Variant::OBJECT) { - // Replace in dictionary key. - Ref sr = k; - if (sr.is_valid() && sr->is_local_to_scene()) { - if (p_remap_cache.has(sr)) { - d[p_remap_cache[sr]] = d[k]; - d.erase(k); - } else { - Ref dupe = sr->duplicate_for_local_scene(p_for_scene, p_remap_cache); - d[dupe] = d[k]; - d.erase(k); - p_remap_cache[sr] = dupe; - } - } - } else { - _dupe_sub_resources(k, p_for_scene, p_remap_cache); - } - - _dupe_sub_resources(d[k], p_for_scene, p_remap_cache); - } - } break; +Variant Resource::_duplicate_recursive_for_local_scene(const Variant &p_variant, Node *p_for_scene, HashMap, Ref> &p_remap_cache) { + switch (p_variant.get_type()) { case Variant::OBJECT: { - Ref sr = r_variant; + const Ref &sr = p_variant; if (sr.is_valid() && sr->is_local_to_scene()) { if (p_remap_cache.has(sr)) { - r_variant = p_remap_cache[sr]; + return p_remap_cache[sr]; } else { - Ref dupe = sr->duplicate_for_local_scene(p_for_scene, p_remap_cache); - r_variant = dupe; + const Ref &dupe = sr->duplicate_for_local_scene(p_for_scene, p_remap_cache); p_remap_cache[sr] = dupe; + return dupe; } + } else { + return p_variant; } } break; + case Variant::ARRAY: { + const Array &src = p_variant; + Array dst; + if (src.is_typed()) { + dst.set_typed(src.get_element_type()); + } + dst.resize(src.size()); + for (int i = 0; i < src.size(); i++) { + dst[i] = _duplicate_recursive_for_local_scene(src[i], p_for_scene, p_remap_cache); + } + return dst; + } break; + case Variant::DICTIONARY: { + const Dictionary &src = p_variant; + Dictionary dst; + if (src.is_typed()) { + dst.set_typed(src.get_key_type(), src.get_value_type()); + } + for (const Variant &k : src.get_key_list()) { + const Variant &v = src[k]; + dst.set( + _duplicate_recursive_for_local_scene(k, p_for_scene, p_remap_cache), + _duplicate_recursive_for_local_scene(v, p_for_scene, p_remap_cache)); + } + return dst; + } break; + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + case Variant::PACKED_VECTOR4_ARRAY: { + return p_variant.duplicate(); + } break; default: { + return p_variant; } } } @@ -321,15 +333,31 @@ Ref Resource::duplicate_for_local_scene(Node *p_for_scene, HashMap r = Object::cast_to(ClassDB::instantiate(get_class())); ERR_FAIL_COND_V(r.is_null(), Ref()); + p_remap_cache[this] = r; + r->local_scene = p_for_scene; + // Duplicate script first, so the scripted properties are considered. + r->set_script(get_script()); + for (const PropertyInfo &E : plist) { if (!(E.usage & PROPERTY_USAGE_STORAGE)) { continue; } - Variant p = get(E.name).duplicate(true); + if (E.name == "script") { + continue; + } - _dupe_sub_resources(p, p_for_scene, p_remap_cache); + Variant p = get(E.name); + + bool should_recurse = true; + if ((E.usage & PROPERTY_USAGE_NEVER_DUPLICATE) && ((Ref)p).is_valid()) { + should_recurse = false; + } + + if (should_recurse) { + p = _duplicate_recursive_for_local_scene(p, p_for_scene, p_remap_cache); + } r->set(E.name, p); } diff --git a/core/io/resource.h b/core/io/resource.h index 14c08629d9..6511f6e1b1 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -83,7 +83,7 @@ private: SelfList remapped_list; - void _dupe_sub_resources(Variant &r_variant, Node *p_for_scene, HashMap, Ref> &p_remap_cache); + Variant _duplicate_recursive_for_local_scene(const Variant &p_variant, Node *p_for_scene, HashMap, Ref> &p_remap_cache); void _find_sub_resources(const Variant &p_variant, HashSet> &p_resources_found); protected: From 93575368b2d43c5273788d73be45f3cc49b7fdbc Mon Sep 17 00:00:00 2001 From: chocola-mint <56677134+chocola-mint@users.noreply.github.com> Date: Sat, 17 May 2025 21:53:13 +0900 Subject: [PATCH 014/100] Implement method lookup for method tracks --- editor/animation_track_editor.cpp | 64 +++++++++++++++++++++++++++++++ editor/animation_track_editor.h | 7 ++++ 2 files changed, 71 insertions(+) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index a6e4625cc0..0e25158535 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -44,6 +44,7 @@ #include "editor/inspector_dock.h" #include "editor/multi_node_edit.h" #include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/plugins/script_editor_plugin.h" #include "editor/themes/editor_scale.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/animation/animation_player.h" @@ -2801,6 +2802,13 @@ Ref AnimationTrackEdit::_get_key_type_icon() const { return type_icons[animation->track_get_type(track)]; } +Control::CursorShape AnimationTrackEdit::get_cursor_shape(const Point2 &p_pos) const { + if (command_or_control_pressed && animation->track_get_type(track) == Animation::TYPE_METHOD && hovering_key_idx != -1) { + return Control::CURSOR_POINTING_HAND; + } + return get_default_cursor_shape(); +} + String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { if (check_rect.has_point(p_pos)) { return TTR("Toggle this track on/off."); @@ -3144,6 +3152,11 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { } } + if (mb->is_command_or_control_pressed() && _lookup_key(hovering_key_idx)) { + accept_event(); + return; + } + if (_try_select_at_ui_pos(pos, mb->is_command_or_control_pressed() || mb->is_shift_pressed(), true)) { accept_event(); } @@ -3164,6 +3177,13 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { bool selected = _try_select_at_ui_pos(pos, mb->is_command_or_control_pressed() || mb->is_shift_pressed(), false); menu->clear(); + if (animation->track_get_type(track) == Animation::TYPE_METHOD) { + if (hovering_key_idx != -1) { + lookup_key_idx = hovering_key_idx; + menu->add_icon_item(get_editor_theme_icon(SNAME("Help")), vformat("%s (%s)", TTR("Go to Definition"), animation->method_track_get_name(track, lookup_key_idx)), MENU_KEY_LOOKUP); + menu->add_separator(); + } + } menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Key..."), MENU_KEY_INSERT); if (selected || editor->is_selection_active()) { menu->add_separator(); @@ -3247,6 +3267,8 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { if (mm.is_valid()) { const int previous_hovering_key_idx = hovering_key_idx; + command_or_control_pressed = mm->is_command_or_control_pressed(); + // Hovering compressed keyframes for editing is not possible. if (!animation->track_is_compressed(track)) { const float scale = timeline->get_zoom_scale(); @@ -3392,6 +3414,45 @@ bool AnimationTrackEdit::_try_select_at_ui_pos(const Point2 &p_pos, bool p_aggre return false; } +bool AnimationTrackEdit::_lookup_key(int p_key_idx) const { + if (p_key_idx < 0 || p_key_idx >= animation->track_get_key_count(track)) { + return false; + } + + if (animation->track_get_type(track) == Animation::TYPE_METHOD) { + Node *target = root->get_node_or_null(animation->track_get_path(track)); + if (target) { + StringName method = animation->method_track_get_name(track, p_key_idx); + // First, check every script in the inheritance chain. + bool found_in_script = false; + Ref