diff options
56 files changed, 383 insertions, 262 deletions
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index d10156c04e..eece270dd9 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -71,3 +71,11 @@ jobs: - name: Style checks via dotnet format (dotnet_format.sh) run: | bash ./misc/scripts/dotnet_format.sh + + - name: Spell checks via codespell + uses: codespell-project/actions-codespell@v1 + with: + skip: ./.*,./**/.*,./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md,./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh,./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json + check_hidden: false + ignore_words_list: curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,nd,numer,ot,te + only_warn: true diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 6a1d802453..39f8ad68e4 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -301,13 +301,13 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { for (int i = 1; i < s.size(); i++) { String feature = s[i].strip_edges(); - Pair<StringName, StringName> fo(feature, p_name); + Pair<StringName, StringName> feature_override(feature, p_name); if (!feature_overrides.has(s[0])) { feature_overrides[s[0]] = LocalVector<Pair<StringName, StringName>>(); } - feature_overrides[s[0]].push_back(fo); + feature_overrides[s[0]].push_back(feature_override); } } } diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 9488c6bcff..4483f61bc4 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -383,15 +383,15 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_ if (O->get().plane.is_equal_approx(f.plane)) { //merge and delete edge and contiguous face, while repointing edges (uuugh!) - int ois = O->get().indices.size(); + int o_index_size = O->get().indices.size(); - for (int j = 0; j < ois; j++) { + for (int j = 0; j < o_index_size; j++) { //search a if (O->get().indices[j] == a) { //append the rest - for (int k = 0; k < ois; k++) { - int idx = O->get().indices[(k + j) % ois]; - int idxn = O->get().indices[(k + j + 1) % ois]; + for (int k = 0; k < o_index_size; k++) { + int idx = O->get().indices[(k + j) % o_index_size]; + int idxn = O->get().indices[(k + j + 1) % o_index_size]; if (idx == b && idxn == a) { //already have b! break; } diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp index 96010b4096..868665cb5c 100644 --- a/core/math/transform_2d.cpp +++ b/core/math/transform_2d.cpp @@ -151,7 +151,7 @@ void Transform2D::orthonormalize() { Vector2 y = columns[1]; x.normalize(); - y = (y - x * (x.dot(y))); + y = y - x * x.dot(y); y.normalize(); columns[0] = x; @@ -159,9 +159,9 @@ void Transform2D::orthonormalize() { } Transform2D Transform2D::orthonormalized() const { - Transform2D on = *this; - on.orthonormalize(); - return on; + Transform2D ortho = *this; + ortho.orthonormalize(); + return ortho; } bool Transform2D::is_equal_approx(const Transform2D &p_transform) const { diff --git a/core/object/worker_thread_pool.h b/core/object/worker_thread_pool.h index cf3f7f0885..c62e05fc28 100644 --- a/core/object/worker_thread_pool.h +++ b/core/object/worker_thread_pool.h @@ -173,8 +173,8 @@ public: template <class C, class M, class U> GroupID add_template_group_task(C *p_instance, M p_method, U p_userdata, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String()) { - typedef GroupUserData<C, M, U> GUD; - GUD *ud = memnew(GUD); + typedef GroupUserData<C, M, U> GroupUD; + GroupUD *ud = memnew(GroupUD); ud->instance = p_instance; ud->method = p_method; ud->userdata = p_userdata; diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index 9ce1c2d4bb..af7c18741d 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -339,7 +339,6 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) { data->refcount.init(); data->absolute = p_absolute; data->path = p_path; - data->has_slashes = true; data->hash_cache_valid = false; } @@ -353,7 +352,6 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p data->absolute = p_absolute; data->path = p_path; data->subpath = p_subpath; - data->has_slashes = true; data->hash_cache_valid = false; } @@ -373,7 +371,6 @@ NodePath::NodePath(const String &p_path) { bool absolute = (path[0] == '/'); bool last_is_slash = true; - bool has_slashes = false; int slices = 0; int subpath_pos = path.find(":"); @@ -402,7 +399,6 @@ NodePath::NodePath(const String &p_path) { for (int i = (int)absolute; i < path.length(); i++) { if (path[i] == '/') { last_is_slash = true; - has_slashes = true; } else { if (last_is_slash) { slices++; @@ -419,7 +415,6 @@ NodePath::NodePath(const String &p_path) { data = memnew(Data); data->refcount.init(); data->absolute = absolute; - data->has_slashes = has_slashes; data->subpath = subpath; data->hash_cache_valid = false; diff --git a/core/string/node_path.h b/core/string/node_path.h index 7053798cb2..876d69924e 100644 --- a/core/string/node_path.h +++ b/core/string/node_path.h @@ -42,7 +42,6 @@ class NodePath { StringName concatenated_path; StringName concatenated_subpath; bool absolute; - bool has_slashes; mutable bool hash_cache_valid; mutable uint32_t hash_cache; }; diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 86562c340d..98256f0a38 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -92,13 +92,6 @@ [/codeblocks] </description> </method> - <method name="rename_parameter"> - <return type="void" /> - <param index="0" name="old_name" type="String" /> - <param index="1" name="new_name" type="String" /> - <description> - </description> - </method> </methods> <members> <member name="active" type="bool" setter="set_active" getter="is_active" default="false"> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 04895c28a8..ca090d596e 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -553,11 +553,11 @@ [b]Note:[/b] If the user has disabled the recycle bin on their system, the file will be permanently deleted instead. [codeblocks] [gdscript] - var file_to_remove = "user://slot1.sav" + var file_to_remove = "user://slot1.save" OS.move_to_trash(ProjectSettings.globalize_path(file_to_remove)) [/gdscript] [csharp] - var fileToRemove = "user://slot1.sav"; + var fileToRemove = "user://slot1.save"; OS.MoveToTrash(ProjectSettings.GlobalizePath(fileToRemove)); [/csharp] [/codeblocks] diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 143e1f23e9..792cd38741 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -529,7 +529,7 @@ <return type="bool" /> <param index="0" name="expr" type="String" /> <description> - Does a simple expression match, where [code]*[/code] matches zero or more arbitrary characters and [code]?[/code] matches any single character except a period ([code].[/code]). An empty string or empty expression always evaluates to [code]false[/code]. + Does a simple expression match (also called "glob" or "globbing"), where [code]*[/code] matches zero or more arbitrary characters and [code]?[/code] matches any single character except a period ([code].[/code]). An empty string or empty expression always evaluates to [code]false[/code]. </description> </method> <method name="matchn" qualifiers="const"> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index c387bd435b..5dedea50d0 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -205,7 +205,7 @@ <param index="2" name="atlas_coords" type="Vector2i" default="Vector2i(-1, -1)" /> <param index="3" name="alternative_tile" type="int" default="-1" /> <description> - Returns a [Vector2i] array with the positions of all cells containing a tile in the given layer. Tiles may be filtered according to their source ([param source_id]), their atlas coordinates ([param atlas_coords]) or alternative id ([param source_id]). + Returns a [Vector2i] array with the positions of all cells containing a tile in the given layer. Tiles may be filtered according to their source ([param source_id]), their atlas coordinates ([param atlas_coords]) or alternative id ([param alternative_tile]). If a parameter has it's value set to the default one, this parameter is not used to filter a cell. Thus, if all parameters have their respective default value, this method returns the same result as [method get_used_cells]. A cell is considered empty if its source identifier equals -1, its atlas coordinates identifiers is [code]Vector2(-1, -1)[/code] and its alternative identifier is -1. </description> @@ -279,8 +279,8 @@ <description> Sets the tile indentifiers for the cell on layer [param layer] at coordinates [param coords]. Each tile of the [TileSet] is identified using three parts: - The source identifier [param source_id] identifies a [TileSetSource] identifier. See [method TileSet.set_source_id], - - The atlas coordinates identifier [param atlas_coords] identifies a tile coordinates in the atlas (if the source is a [TileSetAtlasSource]. For [TileSetScenesCollectionSource] it should always be [code]Vector2i(0, 0)[/code]), - - The alternative tile identifier [param alternative_tile] identifies a tile alternative the source is a [TileSetAtlasSource], and the scene for a [TileSetScenesCollectionSource]. + - The atlas coordinates identifier [param atlas_coords] identifies a tile coordinates in the atlas (if the source is a [TileSetAtlasSource]). For [TileSetScenesCollectionSource] it should always be [code]Vector2i(0, 0)[/code]), + - The alternative tile identifier [param alternative_tile] identifies a tile alternative in the atlas (if the source is a [TileSetAtlasSource]), and the scene for a [TileSetScenesCollectionSource]. If [param source_id] is set to [code]-1[/code], [param atlas_coords] to [code]Vector2i(-1, -1)[/code] or [param alternative_tile] to [code]-1[/code], the cell will be erased. An erased cell gets [b]all[/b] its identifiers automatically set to their respective invalid values, namely [code]-1[/code], [code]Vector2i(-1, -1)[/code] and [code]-1[/code]. </description> </method> diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index aaa07e98c8..f4d293e9f4 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -591,14 +591,12 @@ void ConnectDialog::popup_dialog(const String p_for_signal) { void ConnectDialog::_advanced_pressed() { if (advanced->is_pressed()) { - set_min_size(Size2(900, 500) * EDSCALE); connect_to_label->set_text(TTR("Connect to Node:")); tree->set_connect_to_script_mode(false); vbc_right->show(); error_label->hide(); } else { - set_min_size(Size2(600, 500) * EDSCALE); reset_size(); connect_to_label->set_text(TTR("Connect to Script:")); tree->set_connect_to_script_mode(true); @@ -613,18 +611,15 @@ void ConnectDialog::_advanced_pressed() { } ConnectDialog::ConnectDialog() { - set_min_size(Size2(600, 500) * EDSCALE); - - VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); + set_min_size(Size2(0, 500) * EDSCALE); HBoxContainer *main_hb = memnew(HBoxContainer); - vbc->add_child(main_hb); - main_hb->set_v_size_flags(Control::SIZE_EXPAND_FILL); + add_child(main_hb); VBoxContainer *vbc_left = memnew(VBoxContainer); main_hb->add_child(vbc_left); vbc_left->set_h_size_flags(Control::SIZE_EXPAND_FILL); + vbc_left->set_custom_minimum_size(Vector2(400 * EDSCALE, 0)); from_signal = memnew(LineEdit); vbc_left->add_margin_child(TTR("From Signal:"), from_signal); @@ -685,6 +680,7 @@ ConnectDialog::ConnectDialog() { vbc_right = memnew(VBoxContainer); main_hb->add_child(vbc_right); vbc_right->set_h_size_flags(Control::SIZE_EXPAND_FILL); + vbc_right->set_custom_minimum_size(Vector2(150 * EDSCALE, 0)); vbc_right->hide(); HBoxContainer *add_bind_hb = memnew(HBoxContainer); diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index bbd0a6bd70..4a1f0b4c09 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -620,12 +620,16 @@ void EditorFileDialog::_item_list_item_rmb_clicked(int p_item, const Vector2 &p_ if (allow_delete) { item_menu->add_icon_item(theme_cache.action_delete, TTR("Delete"), ITEM_MENU_DELETE, Key::KEY_DELETE); } + +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + // Opening the system file manager is not supported on the Android and web editors. if (single_item_selected) { item_menu->add_separator(); Dictionary item_meta = item_list->get_item_metadata(p_item); String item_text = item_meta["dir"] ? TTR("Open in File Manager") : TTR("Show in File Manager"); item_menu->add_icon_item(theme_cache.filesystem, item_text, ITEM_MENU_SHOW_IN_EXPLORER); } +#endif if (item_menu->get_item_count() > 0) { item_menu->set_position(item_list->get_screen_position() + p_pos); @@ -655,8 +659,11 @@ void EditorFileDialog::_item_list_empty_clicked(const Vector2 &p_pos, MouseButto item_menu->add_icon_item(theme_cache.folder, TTR("New Folder..."), ITEM_MENU_NEW_FOLDER, KeyModifierMask::CMD_OR_CTRL | Key::N); } item_menu->add_icon_item(theme_cache.reload, TTR("Refresh"), ITEM_MENU_REFRESH, Key::F5); +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + // Opening the system file manager is not supported on the Android and web editors. item_menu->add_separator(); item_menu->add_icon_item(theme_cache.filesystem, TTR("Open in File Manager"), ITEM_MENU_SHOW_IN_EXPLORER); +#endif item_menu->set_position(item_list->get_screen_position() + p_pos); item_menu->reset_size(); diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp index 3f788627f4..57a0a88810 100644 --- a/editor/editor_layouts_dialog.cpp +++ b/editor/editor_layouts_dialog.cpp @@ -65,6 +65,20 @@ void EditorLayoutsDialog::_line_gui_input(const Ref<InputEvent> &p_event) { } } +void EditorLayoutsDialog::_update_ok_disable_state() { + if (layout_names->is_anything_selected()) { + get_ok_button()->set_disabled(false); + } else { + get_ok_button()->set_disabled(!name->is_visible() || name->get_text().is_empty()); + } +} + +void EditorLayoutsDialog::_deselect_layout_names() { + // The deselect method does not emit any signal, therefore we need update the disable state as well. + layout_names->deselect_all(); + _update_ok_disable_state(); +} + void EditorLayoutsDialog::_bind_methods() { ADD_SIGNAL(MethodInfo("name_confirmed", PropertyInfo(Variant::STRING, "name"))); } @@ -82,8 +96,8 @@ void EditorLayoutsDialog::ok_pressed() { void EditorLayoutsDialog::_post_popup() { ConfirmationDialog::_post_popup(); - name->clear(); layout_names->clear(); + name->clear(); Ref<ConfigFile> config; config.instantiate(); @@ -112,9 +126,9 @@ EditorLayoutsDialog::EditorLayoutsDialog() { makevb->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5); layout_names = memnew(ItemList); - layout_names->set_auto_height(true); makevb->add_margin_child(TTR("Select existing layout:"), layout_names); - layout_names->set_custom_minimum_size(Size2(300 * EDSCALE, 1)); + layout_names->set_auto_height(true); + layout_names->set_custom_minimum_size(Size2(300 * EDSCALE, 50 * EDSCALE)); layout_names->set_visible(true); layout_names->set_offset(SIDE_TOP, 5); layout_names->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5); @@ -122,16 +136,17 @@ EditorLayoutsDialog::EditorLayoutsDialog() { layout_names->set_v_size_flags(Control::SIZE_EXPAND_FILL); layout_names->set_select_mode(ItemList::SELECT_MULTI); layout_names->set_allow_rmb_select(true); + layout_names->connect("multi_selected", callable_mp(this, &EditorLayoutsDialog::_update_ok_disable_state).unbind(2)); name = memnew(LineEdit); - name->set_placeholder("Or enter new layout name"); makevb->add_child(name); + name->set_placeholder("Or enter new layout name"); name->set_offset(SIDE_TOP, 5); - name->set_custom_minimum_size(Size2(300 * EDSCALE, 1)); name->set_anchor_and_offset(SIDE_LEFT, Control::ANCHOR_BEGIN, 5); name->set_anchor_and_offset(SIDE_RIGHT, Control::ANCHOR_END, -5); name->connect("gui_input", callable_mp(this, &EditorLayoutsDialog::_line_gui_input)); - name->connect("focus_entered", callable_mp(layout_names, &ItemList::deselect_all)); + name->connect("focus_entered", callable_mp(this, &EditorLayoutsDialog::_deselect_layout_names)); + name->connect("text_changed", callable_mp(this, &EditorLayoutsDialog::_update_ok_disable_state).unbind(1)); } void EditorLayoutsDialog::set_name_line_enabled(bool p_enabled) { diff --git a/editor/editor_layouts_dialog.h b/editor/editor_layouts_dialog.h index 80a7ed0b53..e3557fbe71 100644 --- a/editor/editor_layouts_dialog.h +++ b/editor/editor_layouts_dialog.h @@ -44,6 +44,8 @@ class EditorLayoutsDialog : public ConfirmationDialog { VBoxContainer *makevb = nullptr; void _line_gui_input(const Ref<InputEvent> &p_event); + void _update_ok_disable_state(); + void _deselect_layout_names(); protected: static void _bind_methods(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 378e06b4c9..e1924c7994 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -241,8 +241,8 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo } for (int i = 0; i < favorite_paths.size(); i++) { - String fave = favorite_paths[i]; - if (!fave.begins_with("res://")) { + String favorite = favorite_paths[i]; + if (!favorite.begins_with("res://")) { continue; } @@ -252,18 +252,18 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo String text; Ref<Texture2D> icon; Color color; - if (fave == "res://") { + if (favorite == "res://") { text = "/"; icon = folder_icon; color = folder_color; - } else if (fave.ends_with("/")) { - text = fave.substr(0, fave.length() - 1).get_file(); + } else if (favorite.ends_with("/")) { + text = favorite.substr(0, favorite.length() - 1).get_file(); icon = folder_icon; color = folder_color; } else { - text = fave.get_file(); + text = favorite.get_file(); int index; - EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->find_file(fave, &index); + EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->find_file(favorite, &index); if (dir) { icon = _get_tree_item_icon(dir->get_file_import_is_valid(index), dir->get_file_type(index)); } else { @@ -277,18 +277,18 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo ti->set_text(0, text); ti->set_icon(0, icon); ti->set_icon_modulate(0, color); - ti->set_tooltip_text(0, fave); + ti->set_tooltip_text(0, favorite); ti->set_selectable(0, true); - ti->set_metadata(0, fave); - if (p_select_in_favorites && fave == path) { + ti->set_metadata(0, favorite); + if (p_select_in_favorites && favorite == path) { ti->select(0); ti->set_as_cursor(0); } - if (!fave.ends_with("/")) { + if (!favorite.ends_with("/")) { Array udata; udata.push_back(tree_update_id); udata.push_back(ti); - EditorResourcePreview::get_singleton()->queue_resource_preview(fave, this, "_tree_thumbnail_done", udata); + EditorResourcePreview::get_singleton()->queue_resource_preview(favorite, this, "_tree_thumbnail_done", udata); } } } @@ -2636,24 +2636,31 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str new_menu->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option)); p_popup->add_child(new_menu); - p_popup->add_submenu_item(TTR("New"), "New"); + p_popup->add_submenu_item(TTR("New"), "New", FILE_NEW); new_menu->add_icon_item(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")), TTR("Folder..."), FILE_NEW_FOLDER); new_menu->add_icon_item(get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")), TTR("Scene..."), FILE_NEW_SCENE); new_menu->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("Script..."), FILE_NEW_SCRIPT); new_menu->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("Resource..."), FILE_NEW_RESOURCE); new_menu->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("TextFile..."), FILE_NEW_TEXTFILE); +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) p_popup->add_separator(); +#endif } - String fpath = p_paths[0]; - bool is_directory = fpath.ends_with("/"); - String item_text = is_directory ? TTR("Open in File Manager") : TTR("Show in File Manager"); + const String fpath = p_paths[0]; + +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + // Opening the system file manager is not supported on the Android and web editors. + const bool is_directory = fpath.ends_with("/"); + const String item_text = is_directory ? TTR("Open in File Manager") : TTR("Show in File Manager"); p_popup->add_icon_shortcut(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER); p_popup->set_item_text(p_popup->get_item_index(FILE_SHOW_IN_EXPLORER), item_text); if (!is_directory) { p_popup->add_icon_shortcut(get_theme_icon(SNAME("ExternalLink"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/open_in_external_program"), FILE_OPEN_EXTERNAL); } +#endif + path = fpath; } } @@ -2697,8 +2704,11 @@ void FileSystemDock::_tree_empty_click(const Vector2 &p_pos, MouseButton p_butto tree_popup->add_icon_item(get_theme_icon(SNAME("Script"), SNAME("EditorIcons")), TTR("New Script..."), FILE_NEW_SCRIPT); tree_popup->add_icon_item(get_theme_icon(SNAME("Object"), SNAME("EditorIcons")), TTR("New Resource..."), FILE_NEW_RESOURCE); tree_popup->add_icon_item(get_theme_icon(SNAME("TextFile"), SNAME("EditorIcons")), TTR("New TextFile..."), FILE_NEW_TEXTFILE); +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + // Opening the system file manager is not supported on the Android and web editors. tree_popup->add_separator(); tree_popup->add_icon_shortcut(get_theme_icon(SNAME("Filesystem"), SNAME("EditorIcons")), ED_GET_SHORTCUT("filesystem_dock/show_in_explorer"), FILE_SHOW_IN_EXPLORER); +#endif tree_popup->set_position(tree->get_screen_position() + p_pos); tree_popup->reset_size(); @@ -3120,8 +3130,11 @@ FileSystemDock::FileSystemDock() { ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), Key::KEY_DELETE); ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), Key::F2); ED_SHORTCUT_OVERRIDE("filesystem_dock/rename", "macos", Key::ENTER); +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) + // Opening the system file manager or opening in an external program is not supported on the Android and web editors. ED_SHORTCUT("filesystem_dock/show_in_explorer", TTR("Open in File Manager")); ED_SHORTCUT("filesystem_dock/open_in_external_program", TTR("Open in External Program")); +#endif VBoxContainer *top_vbc = memnew(VBoxContainer); add_child(top_vbc); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index ede6869eea..9060f5c0a4 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -90,17 +90,18 @@ private: FILE_DUPLICATE, FILE_REIMPORT, FILE_INFO, - FILE_NEW_FOLDER, - FILE_NEW_SCRIPT, - FILE_NEW_SCENE, + FILE_NEW, FILE_SHOW_IN_EXPLORER, FILE_OPEN_EXTERNAL, FILE_COPY_PATH, FILE_COPY_UID, - FILE_NEW_RESOURCE, - FILE_NEW_TEXTFILE, FOLDER_EXPAND_ALL, FOLDER_COLLAPSE_ALL, + FILE_NEW_RESOURCE, + FILE_NEW_TEXTFILE, + FILE_NEW_FOLDER, + FILE_NEW_SCRIPT, + FILE_NEW_SCENE, }; FileSortOption file_sort = FILE_SORT_NAME; diff --git a/editor/icons/GizmoBakedLightmap.svg b/editor/icons/GizmoLightmapGI.svg index a7828615fd..a7828615fd 100644 --- a/editor/icons/GizmoBakedLightmap.svg +++ b/editor/icons/GizmoLightmapGI.svg diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 583355833b..77785b15ca 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -985,8 +985,6 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima undo_redo->create_action(TTR("Node Renamed")); undo_redo->add_do_method(blend_tree.ptr(), "rename_node", prev_name, name); undo_redo->add_undo_method(blend_tree.ptr(), "rename_node", name, prev_name); - undo_redo->add_do_method(tree, "rename_parameter", base_path + prev_name, base_path + name); - undo_redo->add_undo_method(tree, "rename_parameter", base_path + name, base_path + prev_name); undo_redo->add_do_method(this, "update_graph"); undo_redo->add_undo_method(this, "update_graph"); undo_redo->commit_action(); diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index d3e16211f7..26f872421e 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -2404,7 +2404,7 @@ Vector<String> ProjectConverter3To4::check_for_files() { directories_to_check.append(current_dir.path_join(file_name) + "/"); } else { bool proper_extension = false; - if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj")) + if (file_name.ends_with(".gd") || file_name.ends_with(".shader") || file_name.ends_with(".gdshader") || file_name.ends_with(".tscn") || file_name.ends_with(".tres") || file_name.ends_with(".godot") || file_name.ends_with(".cs") || file_name.ends_with(".csproj")) proper_extension = true; if (proper_extension) { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index c4f5eb777e..105e3a5d47 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -1503,8 +1503,13 @@ void ProjectList::create_project_item_control(int p_index) { path_hb->add_child(show); if (!item.missing) { +#if !defined(ANDROID_ENABLED) && !defined(WEB_ENABLED) show->connect("pressed", callable_mp(this, &ProjectList::_show_project).bind(item.path)); show->set_tooltip_text(TTR("Show in File Manager")); +#else + // Opening the system file manager is not supported on the Android and web editors. + show->hide(); +#endif } else { show->set_tooltip_text(TTR("Error: Project is missing on the filesystem.")); } diff --git a/misc/scripts/codespell.sh b/misc/scripts/codespell.sh index 0551492420..1268350180 100755 --- a/misc/scripts/codespell.sh +++ b/misc/scripts/codespell.sh @@ -1,8 +1,8 @@ #!/bin/sh -SKIP_LIST="./.*,./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md," -SKIP_LIST+="./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh," +SKIP_LIST="./.*,./**/.*,./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md," +SKIP_LIST+="./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh," SKIP_LIST+="./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json," -IGNORE_LIST="alo,ba,complies,curvelinear,doubleclick,expct,fave,findn,gird,gud,inout,lod,nd,numer,ois,readded,ro,sav,statics,te,varius,varn,wan" +IGNORE_LIST="curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,nd,numer,ot,te" codespell -w -q 3 -S "${SKIP_LIST}" -L "${IGNORE_LIST}" --builtin "clear,rare,en-GB_to_en-US" diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 1c2b743909..cdb4f29854 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -4037,6 +4037,10 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op) Variant GDScriptAnalyzer::make_expression_reduced_value(GDScriptParser::ExpressionNode *p_expression, bool &is_reduced) { Variant value; + if (p_expression == nullptr) { + return value; + } + if (p_expression->is_constant) { is_reduced = true; value = p_expression->reduced_value; @@ -4101,6 +4105,10 @@ Variant GDScriptAnalyzer::make_dictionary_reduced_value(GDScriptParser::Dictiona } Variant GDScriptAnalyzer::make_subscript_reduced_value(GDScriptParser::SubscriptNode *p_subscript, bool &is_reduced) { + if (p_subscript->base == nullptr || p_subscript->index == nullptr) { + return Variant(); + } + bool is_base_value_reduced = false; Variant base_value = make_expression_reduced_value(p_subscript->base, is_base_value_reduced); if (!is_base_value_reduced) { diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index f88ac581ca..12c10642ec 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1953,17 +1953,19 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, case GDScriptParser::DataType::CLASS: if (base_type.class_type->has_function(p_context.current_function->identifier->name)) { GDScriptParser::FunctionNode *parent_function = base_type.class_type->get_member(p_context.current_function->identifier->name).function; - const GDScriptParser::ParameterNode *parameter = parent_function->parameters[parent_function->parameters_indices[p_identifier]]; - if ((!id_type.is_set() || id_type.is_variant()) && parameter->get_datatype().is_hard_type()) { - id_type = parameter->get_datatype(); - } - if (parameter->initializer) { - GDScriptParser::CompletionContext c = p_context; - c.current_function = parent_function; - c.current_class = base_type.class_type; - c.base = nullptr; - if (_guess_expression_type(c, parameter->initializer, r_type)) { - return true; + if (parent_function->parameters_indices.has(p_identifier)) { + const GDScriptParser::ParameterNode *parameter = parent_function->parameters[parent_function->parameters_indices[p_identifier]]; + if ((!id_type.is_set() || id_type.is_variant()) && parameter->get_datatype().is_hard_type()) { + id_type = parameter->get_datatype(); + } + if (parameter->initializer) { + GDScriptParser::CompletionContext c = p_context; + c.current_function = parent_function; + c.current_class = base_type.class_type; + c.base = nullptr; + if (_guess_expression_type(c, parameter->initializer, r_type)) { + return true; + } } } } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 713ad3ed17..ed2dce471f 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3602,6 +3602,7 @@ bool GDScriptParser::tool_annotation(const AnnotationNode *p_annotation, Node *p bool GDScriptParser::icon_annotation(const AnnotationNode *p_annotation, Node *p_node) { ERR_FAIL_COND_V_MSG(p_node->type != Node::CLASS, false, R"("@icon" annotation can only be applied to classes.)"); + ERR_FAIL_COND_V(p_annotation->resolved_arguments.is_empty(), false); ClassNode *p_class = static_cast<ClassNode *>(p_node); p_class->icon_path = p_annotation->resolved_arguments[0]; return true; @@ -3830,6 +3831,10 @@ template <PropertyUsageFlags t_usage> bool GDScriptParser::export_group_annotations(const AnnotationNode *p_annotation, Node *p_node) { AnnotationNode *annotation = const_cast<AnnotationNode *>(p_annotation); + if (annotation->resolved_arguments.is_empty()) { + return false; + } + annotation->export_info.name = annotation->resolved_arguments[0]; switch (t_usage) { @@ -3887,7 +3892,7 @@ bool GDScriptParser::rpc_annotation(const AnnotationNode *p_annotation, Node *p_ Dictionary rpc_config; rpc_config["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY; - if (p_annotation->resolved_arguments.size()) { + if (!p_annotation->resolved_arguments.is_empty()) { int last = p_annotation->resolved_arguments.size() - 1; if (p_annotation->resolved_arguments[last].get_type() == Variant::INT) { rpc_config["channel"] = p_annotation->resolved_arguments[last].operator int(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs index 813bdf1e9f..47a4516948 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs @@ -48,7 +48,7 @@ namespace GodotPlugins.Game } catch (Exception e) { - Console.Error.WriteLine(e); + global::System.Console.Error.WriteLine(e); return false.ToGodotBool(); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 019504ad66..70b48b0e3a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -185,7 +185,9 @@ namespace GodotTools.Export foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories)) { - AddSharedObject(file, tags: null, projectDataDirName); + AddSharedObject(file, tags: null, + Path.Join(projectDataDirName, + Path.GetRelativePath(publishOutputTempDir, Path.GetDirectoryName(file)))); } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 5283dc7ec6..d7392dbda8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -247,19 +247,19 @@ namespace Godot /// <returns>The orthonormalized transform.</returns> public readonly Transform2D Orthonormalized() { - Transform2D on = this; + Transform2D ortho = this; - Vector2 onX = on.X; - Vector2 onY = on.Y; + Vector2 orthoX = ortho.X; + Vector2 orthoY = ortho.Y; - onX.Normalize(); - onY = onY - (onX * onX.Dot(onY)); - onY.Normalize(); + orthoX.Normalize(); + orthoY = orthoY - orthoX * orthoX.Dot(orthoY); + orthoY.Normalize(); - on.X = onX; - on.Y = onY; + ortho.X = orthoX; + ortho.Y = orthoY; - return on; + return ortho; } /// <summary> diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index d546c5d3ba..c3cb1c5f13 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -262,7 +262,7 @@ TypedArray<RID> GodotNavigationServer::map_get_agents(RID p_map) const { const NavMap *map = map_owner.get_or_null(p_map); ERR_FAIL_COND_V(map == nullptr, agents_rids); - const LocalVector<RvoAgent *> agents = map->get_agents(); + const LocalVector<NavAgent *> agents = map->get_agents(); agents_rids.resize(agents.size()); for (uint32_t i = 0; i < agents.size(); i++) { @@ -282,7 +282,7 @@ RID GodotNavigationServer::region_get_map(RID p_region) const { } RID GodotNavigationServer::agent_get_map(RID p_agent) const { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND_V(agent == nullptr, RID()); if (agent->get_map()) { @@ -579,13 +579,13 @@ RID GodotNavigationServer::agent_create() { MutexLock lock(operations_mutex); RID rid = agent_owner.make_rid(); - RvoAgent *agent = agent_owner.get_or_null(rid); + NavAgent *agent = agent_owner.get_or_null(rid); agent->set_self(rid); return rid; } COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); if (agent->get_map()) { @@ -612,77 +612,77 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { } COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->neighborDist_ = p_distance; } COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->maxNeighbors_ = p_count; } COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->timeHorizon_ = p_time; } COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->radius_ = p_radius; } COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->maxSpeed_ = p_max_speed; } COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); } COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); } COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z); } COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->get_agent()->ignore_y_ = p_ignore; } bool GodotNavigationServer::agent_is_map_changed(RID p_agent) const { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND_V(agent == nullptr, false); return agent->is_map_changed(); } COMMAND_2(agent_set_callback, RID, p_agent, Callable, p_callback) { - RvoAgent *agent = agent_owner.get_or_null(p_agent); + NavAgent *agent = agent_owner.get_or_null(p_agent); ERR_FAIL_COND(agent == nullptr); agent->set_callback(p_callback); @@ -713,7 +713,7 @@ COMMAND_1(free, RID, p_object) { } // Remove any assigned agent - for (RvoAgent *agent : map->get_agents()) { + for (NavAgent *agent : map->get_agents()) { map->remove_agent(agent); agent->set_map(nullptr); } @@ -746,7 +746,7 @@ COMMAND_1(free, RID, p_object) { link_owner.free(p_object); } else if (agent_owner.owns(p_object)) { - RvoAgent *agent = agent_owner.get_or_null(p_object); + NavAgent *agent = agent_owner.get_or_null(p_object); // Removes this agent from the map if assigned if (agent->get_map() != nullptr) { diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index eea5713c40..0b113b77d4 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -36,10 +36,10 @@ #include "core/templates/rid_owner.h" #include "servers/navigation_server_3d.h" +#include "nav_agent.h" #include "nav_link.h" #include "nav_map.h" #include "nav_region.h" -#include "rvo_agent.h" /// The commands are functions executed during the `sync` phase. @@ -71,7 +71,7 @@ class GodotNavigationServer : public NavigationServer3D { mutable RID_Owner<NavLink> link_owner; mutable RID_Owner<NavMap> map_owner; mutable RID_Owner<NavRegion> region_owner; - mutable RID_Owner<RvoAgent> agent_owner; + mutable RID_Owner<NavAgent> agent_owner; bool active = true; LocalVector<NavMap *> active_maps; diff --git a/modules/navigation/rvo_agent.cpp b/modules/navigation/nav_agent.cpp index 40f1e925be..293544c0a5 100644 --- a/modules/navigation/rvo_agent.cpp +++ b/modules/navigation/nav_agent.cpp @@ -1,5 +1,5 @@ /**************************************************************************/ -/* rvo_agent.cpp */ +/* nav_agent.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,15 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "rvo_agent.h" +#include "nav_agent.h" #include "nav_map.h" -void RvoAgent::set_map(NavMap *p_map) { +void NavAgent::set_map(NavMap *p_map) { map = p_map; } -bool RvoAgent::is_map_changed() { +bool NavAgent::is_map_changed() { if (map) { bool is_changed = map->get_map_update_id() != map_update_id; map_update_id = map->get_map_update_id(); @@ -46,15 +46,15 @@ bool RvoAgent::is_map_changed() { } } -void RvoAgent::set_callback(Callable p_callback) { +void NavAgent::set_callback(Callable p_callback) { callback = p_callback; } -bool RvoAgent::has_callback() const { +bool NavAgent::has_callback() const { return callback.is_valid(); } -void RvoAgent::dispatch_callback() { +void NavAgent::dispatch_callback() { if (!callback.is_valid()) { return; } diff --git a/modules/navigation/rvo_agent.h b/modules/navigation/nav_agent.h index 5f377b6079..f154ce14d9 100644 --- a/modules/navigation/rvo_agent.h +++ b/modules/navigation/nav_agent.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* rvo_agent.h */ +/* nav_agent.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef RVO_AGENT_H -#define RVO_AGENT_H +#ifndef NAV_AGENT_H +#define NAV_AGENT_H #include "core/object/class_db.h" #include "nav_rid.h" @@ -38,7 +38,7 @@ class NavMap; -class RvoAgent : public NavRid { +class NavAgent : public NavRid { NavMap *map = nullptr; RVO::Agent agent; Callable callback = Callable(); @@ -62,4 +62,4 @@ public: void dispatch_callback(); }; -#endif // RVO_AGENT_H +#endif // NAV_AGENT_H diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index d763b1d3bc..b1674c8fc5 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -31,9 +31,9 @@ #include "nav_map.h" #include "core/object/worker_thread_pool.h" +#include "nav_agent.h" #include "nav_link.h" #include "nav_region.h" -#include "rvo_agent.h" #include <algorithm> #define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a))) @@ -568,18 +568,18 @@ void NavMap::remove_link(NavLink *p_link) { } } -bool NavMap::has_agent(RvoAgent *agent) const { +bool NavMap::has_agent(NavAgent *agent) const { return (agents.find(agent) != -1); } -void NavMap::add_agent(RvoAgent *agent) { +void NavMap::add_agent(NavAgent *agent) { if (!has_agent(agent)) { agents.push_back(agent); agents_dirty = true; } } -void NavMap::remove_agent(RvoAgent *agent) { +void NavMap::remove_agent(NavAgent *agent) { remove_agent_as_controlled(agent); int64_t agent_index = agents.find(agent); if (agent_index != -1) { @@ -588,7 +588,7 @@ void NavMap::remove_agent(RvoAgent *agent) { } } -void NavMap::set_agent_as_controlled(RvoAgent *agent) { +void NavMap::set_agent_as_controlled(NavAgent *agent) { const bool exist = (controlled_agents.find(agent) != -1); if (!exist) { ERR_FAIL_COND(!has_agent(agent)); @@ -596,7 +596,7 @@ void NavMap::set_agent_as_controlled(RvoAgent *agent) { } } -void NavMap::remove_agent_as_controlled(RvoAgent *agent) { +void NavMap::remove_agent_as_controlled(NavAgent *agent) { int64_t active_avoidance_agent_index = controlled_agents.find(agent); if (active_avoidance_agent_index != -1) { controlled_agents.remove_at_unordered(active_avoidance_agent_index); @@ -895,7 +895,7 @@ void NavMap::sync() { // cannot use LocalVector here as RVO library expects std::vector to build KdTree std::vector<RVO::Agent *> raw_agents; raw_agents.reserve(agents.size()); - for (RvoAgent *agent : agents) { + for (NavAgent *agent : agents) { raw_agents.push_back(agent->get_agent()); } rvo.buildAgentTree(raw_agents); @@ -916,7 +916,7 @@ void NavMap::sync() { pm_edge_free_count = _new_pm_edge_free_count; } -void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { +void NavMap::compute_single_step(uint32_t index, NavAgent **agent) { (*(agent + index))->get_agent()->computeNeighbors(&rvo); (*(agent + index))->get_agent()->computeNewVelocity(deltatime); } @@ -930,7 +930,7 @@ void NavMap::step(real_t p_deltatime) { } void NavMap::dispatch_callbacks() { - for (RvoAgent *agent : controlled_agents) { + for (NavAgent *agent : controlled_agents) { agent->dispatch_callback(); } } diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index fce7aff3ba..ab6a48dd70 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -42,7 +42,7 @@ class NavLink; class NavRegion; -class RvoAgent; +class NavAgent; class NavMap : public NavRid { /// Map Up @@ -78,10 +78,10 @@ class NavMap : public NavRid { bool agents_dirty = false; /// All the Agents (even the controlled one) - LocalVector<RvoAgent *> agents; + LocalVector<NavAgent *> agents; /// Controlled agents - LocalVector<RvoAgent *> controlled_agents; + LocalVector<NavAgent *> controlled_agents; /// Physics delta time real_t deltatime = 0.0; @@ -144,15 +144,15 @@ public: return links; } - bool has_agent(RvoAgent *agent) const; - void add_agent(RvoAgent *agent); - void remove_agent(RvoAgent *agent); - const LocalVector<RvoAgent *> &get_agents() const { + bool has_agent(NavAgent *agent) const; + void add_agent(NavAgent *agent); + void remove_agent(NavAgent *agent); + const LocalVector<NavAgent *> &get_agents() const { return agents; } - void set_agent_as_controlled(RvoAgent *agent); - void remove_agent_as_controlled(RvoAgent *agent); + void set_agent_as_controlled(NavAgent *agent); + void remove_agent_as_controlled(NavAgent *agent); uint32_t get_map_update_id() const { return map_update_id; @@ -173,7 +173,7 @@ public: int get_pm_edge_free_count() const { return pm_edge_free_count; } private: - void compute_single_step(uint32_t index, RvoAgent **agent); + void compute_single_step(uint32_t index, NavAgent **agent); void clip_path(const LocalVector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly, Vector<int32_t> *r_path_types, TypedArray<RID> *r_path_rids, Vector<int64_t> *r_path_owners) const; }; diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index 3b39967ba4..0dd41675b6 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -103,6 +103,7 @@ env_openxr.add_source_files(module_obj, "extensions/openxr_fb_passthrough_extens env_openxr.add_source_files(module_obj, "extensions/openxr_fb_display_refresh_rate_extension.cpp") env_openxr.add_source_files(module_obj, "extensions/openxr_pico_controller_extension.cpp") env_openxr.add_source_files(module_obj, "extensions/openxr_wmr_controller_extension.cpp") +env_openxr.add_source_files(module_obj, "extensions/openxr_ml2_controller_extension.cpp") env.modules_sources += module_obj diff --git a/modules/openxr/extensions/openxr_ml2_controller_extension.cpp b/modules/openxr/extensions/openxr_ml2_controller_extension.cpp new file mode 100644 index 0000000000..ae372f69b3 --- /dev/null +++ b/modules/openxr/extensions/openxr_ml2_controller_extension.cpp @@ -0,0 +1,71 @@ +/**************************************************************************/ +/* openxr_ml2_controller_extension.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#include "openxr_ml2_controller_extension.h" +#include "../action_map/openxr_interaction_profile_meta_data.h" + +HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions() { + HashMap<String, bool *> request_extensions; + + request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available; + + return request_extensions; +} + +bool OpenXRML2ControllerExtension::is_available() { + return available; +} + +void OpenXRML2ControllerExtension::on_register_metadata() { + OpenXRInteractionProfileMetaData *metadata = OpenXRInteractionProfileMetaData::get_singleton(); + ERR_FAIL_NULL(metadata); + + // Magic Leap 2 Controller + const String profile_path = "/interaction_profiles/ml/ml2_controller"; + metadata->register_interaction_profile("Magic Leap 2 controller", "/interaction_profiles/ml/ml2_controller", XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME); + for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { + metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + + metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); + metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL); + + metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL); + + metadata->register_io_path(profile_path, "Trackpad click", user_path, user_path + "/input/trackpad/click", "", OpenXRAction::OPENXR_ACTION_BOOL); + metadata->register_io_path(profile_path, "Trackpad force", user_path, user_path + "/input/trackpad/force", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path(profile_path, "Trackpad X", user_path, user_path + "/input/trackpad/x", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path(profile_path, "Trackpad Y", user_path, user_path + "/input/trackpad/y", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path(profile_path, "Trackpad touch", user_path, user_path + "/input/trackpad/touch", "", OpenXRAction::OPENXR_ACTION_VECTOR2); + + metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); + } +} diff --git a/modules/openxr/extensions/openxr_ml2_controller_extension.h b/modules/openxr/extensions/openxr_ml2_controller_extension.h new file mode 100644 index 0000000000..216cd55a2f --- /dev/null +++ b/modules/openxr/extensions/openxr_ml2_controller_extension.h @@ -0,0 +1,48 @@ +/**************************************************************************/ +/* openxr_ml2_controller_extension.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef OPENXR_ML2_CONTROLLER_EXTENSION_H +#define OPENXR_ML2_CONTROLLER_EXTENSION_H + +#include "openxr_extension_wrapper.h" + +class OpenXRML2ControllerExtension : public OpenXRExtensionWrapper { +public: + virtual HashMap<String, bool *> get_requested_extensions() override; + + bool is_available(); + + virtual void on_register_metadata() override; + +private: + bool available = false; +}; + +#endif // OPENXR_ML2_CONTROLLER_EXTENSION_H diff --git a/modules/openxr/register_types.cpp b/modules/openxr/register_types.cpp index 306a2f1bbd..c39e49387a 100644 --- a/modules/openxr/register_types.cpp +++ b/modules/openxr/register_types.cpp @@ -52,6 +52,7 @@ #include "extensions/openxr_htc_controller_extension.h" #include "extensions/openxr_htc_vive_tracker_extension.h" #include "extensions/openxr_huawei_controller_extension.h" +#include "extensions/openxr_ml2_controller_extension.h" #include "extensions/openxr_palm_pose_extension.h" #include "extensions/openxr_pico_controller_extension.h" #include "extensions/openxr_wmr_controller_extension.h" @@ -102,6 +103,7 @@ void initialize_openxr_module(ModuleInitializationLevel p_level) { OpenXRAPI::register_extension_wrapper(memnew(OpenXRFbPassthroughExtensionWrapper)); OpenXRAPI::register_extension_wrapper(memnew(OpenXRDisplayRefreshRateExtension)); OpenXRAPI::register_extension_wrapper(memnew(OpenXRWMRControllerExtension)); + OpenXRAPI::register_extension_wrapper(memnew(OpenXRML2ControllerExtension)); } if (OpenXRAPI::openxr_is_enabled()) { diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 0902be9595..c02acbee83 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -899,10 +899,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p bool screen_support_large = p_preset->get("screen/support_large"); bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); - int xr_mode_index = p_preset->get("xr_features/xr_mode"); - int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); - int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency"); - bool backup_allowed = p_preset->get("user_data_backup/allow"); int app_category = p_preset->get("package/app_category"); bool retain_data_on_uninstall = p_preset->get("package/retain_data_on_uninstall"); @@ -1046,25 +1042,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p } } - // Hand tracking related configurations - if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") { - string_table.write[attr_value] = "com.oculus.handtracking.frequency"; - } - - if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") { - string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH"); - } - - if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_version_name") { - string_table.write[attr_value] = "com.oculus.handtracking.version"; - } - - if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_version_value") { - string_table.write[attr_value] = "V2.0"; - } - } - iofs += 20; } @@ -1079,23 +1056,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p Vector<bool> feature_required_list; Vector<int> feature_versions; - if (xr_mode_index == XR_MODE_OPENXR) { - // Check for hand tracking - if (hand_tracking_index > XR_HAND_TRACKING_NONE) { - feature_names.push_back("oculus.software.handtracking"); - feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED); - feature_versions.push_back(-1); // no version attribute should be added. - } - - // Check for passthrough - int passthrough_mode = p_preset->get("xr_features/passthrough"); - if (passthrough_mode > XR_PASSTHROUGH_NONE) { - feature_names.push_back("com.oculus.feature.PASSTHROUGH"); - feature_required_list.push_back(passthrough_mode == XR_PASSTHROUGH_REQUIRED); - feature_versions.push_back(-1); - } - } - if (feature_names.size() > 0) { ofs += 24; // skip over end tag @@ -2334,6 +2294,12 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit int xr_mode_index = p_preset->get("xr_features/xr_mode"); int hand_tracking = p_preset->get("xr_features/hand_tracking"); int passthrough_mode = p_preset->get("xr_features/passthrough"); + if (xr_mode_index == XR_MODE_OPENXR && !custom_build_enabled) { + valid = false; + err += TTR("OpenXR requires \"Use Custom Build\" to be enabled"); + err += "\n"; + } + if (xr_mode_index != XR_MODE_OPENXR) { if (hand_tracking > XR_HAND_TRACKING_NONE) { valid = false; diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 4fdcca68e9..5e71116c10 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -276,17 +276,39 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) { return manifest_xr_features; } -String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { +String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr) { String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String manifest_activity_text = vformat( " <activity android:name=\"com.godot.game.GodotApp\" " "tools:replace=\"android:screenOrientation,android:excludeFromRecents,android:resizeableActivity\" " + "tools:node=\"mergeOnlyAttributes\" " "android:excludeFromRecents=\"%s\" " "android:screenOrientation=\"%s\" " "android:resizeableActivity=\"%s\">\n", bool_to_string(p_preset->get("package/exclude_from_recents")), orientation, bool_to_string(bool(GLOBAL_GET("display/window/size/resizable")))); + + if (p_uses_xr) { + manifest_activity_text += " <intent-filter>\n" + " <action android:name=\"android.intent.action.MAIN\" />\n" + " <category android:name=\"android.intent.category.LAUNCHER\" />\n" + "\n" + " <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android\n" + " platforms. -->\n" + " <category android:name=\"com.oculus.intent.category.VR\" />\n" + "\n" + " <!-- OpenXR category tag to indicate the activity starts in an immersive OpenXR mode. \n" + " See https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#android-runtime-category. -->\n" + " <category android:name=\"org.khronos.openxr.intent.category.IMMERSIVE_HMD\" />\n" + " </intent-filter>\n"; + } else { + manifest_activity_text += " <intent-filter>\n" + " <action android:name=\"android.intent.action.MAIN\" />\n" + " <category android:name=\"android.intent.category.LAUNCHER\" />\n" + " </intent-filter>\n"; + } + manifest_activity_text += " </activity>\n"; return manifest_activity_text; } @@ -307,9 +329,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ " android:hasFragileUserData=\"%s\"\n" " android:requestLegacyExternalStorage=\"%s\"\n" " tools:replace=\"android:allowBackup,android:appCategory,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" - " tools:ignore=\"GoogleAppIndexingWarning\">\n\n" - " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_version_name\" />\n" - " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n", + " tools:ignore=\"GoogleAppIndexingWarning\">\n\n", bool_to_string(p_preset->get("user_data_backup/allow")), _get_app_category_label(app_category_index), bool_to_string(is_game), @@ -327,7 +347,7 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.version\" android:value=\"V2.0\" />\n"; } } - manifest_application_text += _get_activity_tag(p_preset); + manifest_application_text += _get_activity_tag(p_preset, uses_xr); manifest_application_text += " </application>\n"; return manifest_application_text; } diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 0fa857cb75..fe5888e11c 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -118,7 +118,7 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset); String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset); -String _get_activity_tag(const Ref<EditorExportPreset> &p_preset); +String _get_activity_tag(const Ref<EditorExportPreset> &p_preset, bool p_uses_xr); String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_read_write_storage_permission); diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 1969f9c814..ce4a2ecfe4 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -31,23 +31,6 @@ android:name="org.godotengine.editor.version" android:value="${godotEditorVersion}" /> - <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> - <!-- Do these changes in the export preset. Adding new ones is fine. --> - - <!-- XR hand tracking metadata --> - <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> - <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> - <meta-data - android:name="xr_hand_tracking_metadata_name" - android:value="xr_hand_tracking_metadata_value"/> - - <!-- XR hand tracking version --> - <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> - <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> - <meta-data - android:name="xr_hand_tracking_version_name" - android:value="xr_hand_tracking_version_value"/> - <activity android:name=".GodotApp" android:label="@string/godot_project_name_string" @@ -63,10 +46,6 @@ <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> - - <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android - platforms. --> - <category android:name="com.oculus.intent.category.VR" /> </intent-filter> </activity> diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java index 65032d6a68..677c9d8f13 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -99,7 +99,7 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God // from scratch. Therefore, we need to kill the whole app process and relaunch it. // // Restarting only the activity, wouldn't be enough unless it did proper cleanup (including - // releasing and reloading native libs or resetting their state somehow and clearing statics). + // releasing and reloading native libs or resetting their state somehow and clearing static data). Log.v(TAG, "Restarting Godot instance..."); ProcessPhoenix.triggerRebirth(FullScreenGodotApp.this); } diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index b1880c2fb6..65546392c1 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3920,6 +3920,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM } } show_window(MAIN_WINDOW_ID); + force_process_and_drop_events(); #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3") { diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 49c5501e77..fe6bee0f1b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -250,7 +250,7 @@ void Camera2D::_notification(int p_what) { add_to_group(group_name); add_to_group(canvas_group_name); - if (enabled && !viewport->get_camera_2d()) { + if (!Engine::get_singleton()->is_editor_hint() && enabled && !viewport->get_camera_2d()) { make_current(); } @@ -260,11 +260,11 @@ void Camera2D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { + remove_from_group(group_name); + remove_from_group(canvas_group_name); if (is_current()) { clear_current(); } - remove_from_group(group_name); - remove_from_group(canvas_group_name); viewport = nullptr; } break; diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 380a684c9b..ed6f3b8020 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -140,7 +140,7 @@ void NavigationAgent2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_POST_ENTER_TREE: { // need to use POST_ENTER_TREE cause with normal ENTER_TREE not all required Nodes are ready. - // cannot use READY as ready does not get called if Node is readded to SceneTree + // cannot use READY as ready does not get called if Node is re-added to SceneTree set_agent_parent(get_parent()); set_physics_process_internal(true); diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 5db8611d72..1ffabbb6da 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -143,7 +143,7 @@ void NavigationAgent3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_POST_ENTER_TREE: { // need to use POST_ENTER_TREE cause with normal ENTER_TREE not all required Nodes are ready. - // cannot use READY as ready does not get called if Node is readded to SceneTree + // cannot use READY as ready does not get called if Node is re-added to SceneTree set_agent_parent(get_parent()); set_physics_process_internal(true); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index fa72bbc593..dd5bf31c66 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -2084,20 +2084,6 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const { } } -void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) { - //rename values first - for (const PropertyInfo &E : properties) { - if (E.name.begins_with(p_base)) { - String new_name = E.name.replace_first(p_base, p_new_base); - property_map[new_name] = property_map[E.name]; - } - } - - //update tree second - properties_dirty = true; - _update_properties(); -} - real_t AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const { if (!input_activity_map_get.has(p_path)) { return 0; @@ -2143,8 +2129,6 @@ void AnimationTree::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_properties"), &AnimationTree::_update_properties); - ClassDB::bind_method(D_METHOD("rename_parameter", "old_name", "new_name"), &AnimationTree::rename_parameter); - ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationTree::advance); GDVIRTUAL_BIND(_post_process_key_value, "animation", "track", "value", "object", "object_idx"); diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index a6fb4a8430..c5c2790fae 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -389,8 +389,6 @@ public: real_t get_connection_activity(const StringName &p_path, int p_connection) const; void advance(double p_time); - void rename_parameter(const String &p_base, const String &p_new_base); - uint64_t get_last_process_pass() const; AnimationTree(); ~AnimationTree(); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index dba08e16cb..16a718722c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -84,6 +84,7 @@ void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) { } shift_selection_check_post(p_select); + _reset_caret_blink_timer(); } void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) { @@ -116,6 +117,7 @@ void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) { } shift_selection_check_post(p_select); + _reset_caret_blink_timer(); } void LineEdit::_move_caret_start(bool p_select) { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index ba75c92c85..52c1df8110 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2135,13 +2135,13 @@ Node *Node::_duplicate(int p_flags, HashMap<const Node *, Node *> *r_duplimap) c } else if ((p_flags & DUPLICATE_USE_INSTANTIATION) && !get_scene_file_path().is_empty()) { Ref<PackedScene> res = ResourceLoader::load(get_scene_file_path()); ERR_FAIL_COND_V(res.is_null(), nullptr); - PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; + PackedScene::GenEditState edit_state = PackedScene::GEN_EDIT_STATE_DISABLED; #ifdef TOOLS_ENABLED if (p_flags & DUPLICATE_FROM_EDITOR) { - ges = PackedScene::GEN_EDIT_STATE_INSTANCE; + edit_state = PackedScene::GEN_EDIT_STATE_INSTANCE; } #endif - node = res->instantiate(ges); + node = res->instantiate(edit_state); ERR_FAIL_COND_V(!node, nullptr); node->set_scene_instance_load_placeholder(get_scene_instance_load_placeholder()); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c31155bd5c..b0898e2239 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1061,10 +1061,10 @@ void Viewport::assign_next_enabled_camera_2d(const StringName &p_camera_group) { get_tree()->get_nodes_in_group(p_camera_group, &camera_list); Camera2D *new_camera = nullptr; - for (const Node *E : camera_list) { - const Camera2D *cam = Object::cast_to<Camera2D>(E); + for (Node *E : camera_list) { + Camera2D *cam = Object::cast_to<Camera2D>(E); if (cam->is_enabled()) { - new_camera = const_cast<Camera2D *>(cam); + new_camera = cam; break; } } diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 608d15019e..3006da5309 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -2379,15 +2379,15 @@ Error ResourceFormatSaverText::set_uid(const String &p_path, ResourceUID::ID p_u String local_path = ProjectSettings::get_singleton()->localize_path(p_path); Error err = OK; { - Ref<FileAccess> fo = FileAccess::open(p_path, FileAccess::READ); - if (fo.is_null()) { + Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ); + if (file.is_null()) { ERR_FAIL_V(ERR_CANT_OPEN); } ResourceLoaderText loader; loader.local_path = local_path; loader.res_path = loader.local_path; - err = loader.set_uid(fo, p_uid); + err = loader.set_uid(file, p_uid); } if (err == OK) { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index 0ac5557659..ac217d9a49 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -323,13 +323,13 @@ public: // http://andrewthall.org/papers/df64_qf128.pdf #ifdef REAL_T_IS_DOUBLE - static _FORCE_INLINE_ void split_double(double a, float *ahi, float *alo) { + static _FORCE_INLINE_ void split_double(double a, float *a_hi, float *a_lo) { const double SPLITTER = (1 << 29) + 1; double t = a * SPLITTER; - double thi = t - (t - a); - double tlo = a - thi; - *ahi = (float)thi; - *alo = (float)tlo; + double t_hi = t - (t - a); + double t_lo = a - t_hi; + *a_hi = (float)t_hi; + *a_lo = (float)t_lo; } #endif diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 11a9303f11..44c4ad6e56 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4530,14 +4530,14 @@ bool ShaderLanguage::_check_node_constness(const Node *p_node) const { case Node::TYPE_CONSTANT: break; case Node::TYPE_VARIABLE: { - const VariableNode *varn = static_cast<const VariableNode *>(p_node); - if (!varn->is_const) { + const VariableNode *var_node = static_cast<const VariableNode *>(p_node); + if (!var_node->is_const) { return false; } } break; case Node::TYPE_ARRAY: { - const ArrayNode *arrn = static_cast<const ArrayNode *>(p_node); - if (!arrn->is_const) { + const ArrayNode *arr_node = static_cast<const ArrayNode *>(p_node); + if (!arr_node->is_const) { return false; } } break; diff --git a/tests/scene/test_text_edit.h b/tests/scene/test_text_edit.h index f2663b037d..77312a8604 100644 --- a/tests/scene/test_text_edit.h +++ b/tests/scene/test_text_edit.h @@ -3086,7 +3086,7 @@ TEST_CASE("[SceneTree][TextEdit] context menu") { text_edit->get_viewport()->set_embedding_subwindows(true); // Bypass display server for drop handling. text_edit->set_size(Size2(800, 200)); - text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); MessageQueue::get_singleton()->flush(); text_edit->set_context_menu_enabled(false); @@ -3227,7 +3227,7 @@ TEST_CASE("[SceneTree][TextEdit] mouse") { SceneTree::get_singleton()->get_root()->add_child(text_edit); text_edit->set_size(Size2(800, 200)); - text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); MessageQueue::get_singleton()->flush(); CHECK(text_edit->get_word_at_pos(text_edit->get_pos_at_line_column(0, 1)) == "Lorem"); @@ -3305,9 +3305,9 @@ TEST_CASE("[SceneTree][TextEdit] caret") { SEND_GUI_ACTION(text_edit, "ui_text_caret_left"); CHECK(text_edit->get_caret_column() == 0); - text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); for (int i = 0; i < 3; i++) { - text_edit->insert_line_at(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->insert_line_at(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); } MessageQueue::get_singleton()->flush(); @@ -3519,7 +3519,7 @@ TEST_CASE("[SceneTree][TextEdit] line wrapping") { // Set size for boundary. text_edit->set_size(Size2(800, 200)); - text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->set_line(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); CHECK_FALSE(text_edit->is_line_wrapped(0)); CHECK(text_edit->get_line_wrap_count(0) == 0); CHECK(text_edit->get_line_wrap_index_at_column(0, 130) == 0); @@ -3569,7 +3569,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") { // No subcases here for performance. text_edit->set_size(Size2(800, 600)); for (int i = 0; i < 50; i++) { - text_edit->insert_line_at(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec varius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); + text_edit->insert_line_at(0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vasius mattis leo, sed porta ex lacinia bibendum. Nunc bibendum pellentesque."); } MessageQueue::get_singleton()->flush(); @@ -3897,7 +3897,7 @@ TEST_CASE("[SceneTree][TextEdit] viewport") { CHECK(text_edit->get_h_scroll() == 0); text_edit->set_h_scroll(10000000); - CHECK(text_edit->get_h_scroll() == 313); + CHECK(text_edit->get_h_scroll() == 314); text_edit->set_h_scroll(-100); CHECK(text_edit->get_h_scroll() == 0); |