diff options
124 files changed, 1151 insertions, 357 deletions
diff --git a/SConstruct b/SConstruct index 200e8e5984..b64e0bddd8 100644 --- a/SConstruct +++ b/SConstruct @@ -386,6 +386,9 @@ if env_base["target"] == "debug": # DEV_ENABLED enables *engine developer* code which should only be compiled for those # working on the engine itself. env_base.Append(CPPDEFINES=["DEV_ENABLED"]) +else: + # Disable assert() for production targets (only used in thirdparty code). + env_base.Append(CPPDEFINES=["NDEBUG"]) # SCons speed optimization controlled by the `fast_unsafe` option, which provide # more than 10 s speed up for incremental rebuilds. @@ -669,7 +672,6 @@ if selected_platform in platform_list: print(" Use `tools=no target=release` to build a release export template.") Exit(255) suffix += ".opt" - env.Append(CPPDEFINES=["NDEBUG"]) elif env["target"] == "release_debug": if env["tools"]: suffix += ".opt.tools" diff --git a/core/core_bind.h b/core/core_bind.h index 3ca2da0acf..ba22971d78 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -32,9 +32,6 @@ #define CORE_BIND_H #include "core/debugger/engine_profiler.h" -#include "core/io/compression.h" -#include "core/io/dir_access.h" -#include "core/io/file_access.h" #include "core/io/image.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" diff --git a/core/doc_data.h b/core/doc_data.h index 3b7bf149b4..bb356f027e 100644 --- a/core/doc_data.h +++ b/core/doc_data.h @@ -32,7 +32,6 @@ #define DOC_DATA_H #include "core/io/xml_parser.h" -#include "core/templates/rb_map.h" #include "core/variant/variant.h" struct ScriptMemberInfo { diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 596b704732..712fc68c93 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1325,7 +1325,7 @@ bool InputEventAction::is_match(const Ref<InputEvent> &p_event, bool p_exact_mat return false; } - return p_event->is_action(action); + return p_event->is_action(action, p_exact_match); } bool InputEventAction::is_action(const StringName &p_action) const { diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h index bd86fe0eba..cc41a794bd 100644 --- a/core/math/convex_hull.h +++ b/core/math/convex_hull.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef CONVEX_HULL_H +#define CONVEX_HULL_H + /* Copyright (c) 2011 Ole Kniemeyer, MAXON, www.maxon.net This software is provided 'as-is', without any express or implied warranty. @@ -40,9 +43,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifndef CONVEX_HULL_H -#define CONVEX_HULL_H - #include "core/math/geometry_3d.h" #include "core/math/vector3.h" #include "core/templates/local_vector.h" diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index f36b228543..726a2aeb97 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -56,6 +56,15 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::VECTOR2I: { + SETUP_TYPE(Vector2i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + + return target; + } + case Variant::RECT2: { SETUP_TYPE(Rect2) @@ -67,6 +76,17 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::RECT2I: { + SETUP_TYPE(Rect2i) + + /**/ TRY_TRANSFER_FIELD("x", position.x) + else TRY_TRANSFER_FIELD("y", position.y) + else TRY_TRANSFER_FIELD("w", size.x) + else TRY_TRANSFER_FIELD("h", size.y) + + return target; + } + case Variant::VECTOR3: { SETUP_TYPE(Vector3) @@ -192,6 +212,29 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::PROJECTION: { + SETUP_TYPE(Projection) + + /**/ TRY_TRANSFER_FIELD("xx", matrix[0].x) + else TRY_TRANSFER_FIELD("xy", matrix[0].y) + else TRY_TRANSFER_FIELD("xz", matrix[0].z) + else TRY_TRANSFER_FIELD("xw", matrix[0].w) + else TRY_TRANSFER_FIELD("yx", matrix[1].x) + else TRY_TRANSFER_FIELD("yy", matrix[1].y) + else TRY_TRANSFER_FIELD("yz", matrix[1].z) + else TRY_TRANSFER_FIELD("yw", matrix[1].w) + else TRY_TRANSFER_FIELD("zx", matrix[2].x) + else TRY_TRANSFER_FIELD("zy", matrix[2].y) + else TRY_TRANSFER_FIELD("zz", matrix[2].z) + else TRY_TRANSFER_FIELD("zw", matrix[2].w) + else TRY_TRANSFER_FIELD("xo", matrix[3].x) + else TRY_TRANSFER_FIELD("yo", matrix[3].y) + else TRY_TRANSFER_FIELD("zo", matrix[3].z) + else TRY_TRANSFER_FIELD("wo", matrix[3].w) + + return target; + } + default: { ERR_FAIL_V(p_target); } diff --git a/core/os/os.cpp b/core/os/os.cpp index 526b31ae7e..ee8da21751 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -54,10 +54,6 @@ double OS::get_unix_time() const { return 0; } -void OS::debug_break() { - // something -} - void OS::_set_logger(CompositeLogger *p_logger) { if (_logger) { memdelete(_logger); diff --git a/core/os/os.h b/core/os/os.h index 0f79ff1a23..aa45a3b8a8 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -287,8 +287,6 @@ public: virtual Error move_to_trash(const String &p_path) { return FAILED; } - virtual void debug_break(); - virtual int get_exit_code() const; // `set_exit_code` should only be used from `SceneTree` (or from a similar // level, e.g. from the `Main::start` if leaving without creating a `SceneTree`). diff --git a/core/os/pool_allocator.cpp b/core/os/pool_allocator.cpp index f622e2c7c5..e7f2cff7c5 100644 --- a/core/os/pool_allocator.cpp +++ b/core/os/pool_allocator.cpp @@ -35,8 +35,6 @@ #include "core/os/os.h" #include "core/string/print_string.h" -#include <assert.h> - #define COMPACT_CHUNK(m_entry, m_to_pos) \ do { \ void *_dst = &((unsigned char *)pool)[m_to_pos]; \ @@ -169,11 +167,6 @@ bool PoolAllocator::find_entry_index(EntryIndicesPos *p_map_pos, const Entry *p_ PoolAllocator::ID PoolAllocator::alloc(int p_size) { ERR_FAIL_COND_V(p_size < 1, POOL_ALLOCATOR_INVALID_ID); -#ifdef DEBUG_ENABLED - if (p_size > free_mem) { - OS::get_singleton()->debug_break(); - } -#endif ERR_FAIL_COND_V(p_size > free_mem, POOL_ALLOCATOR_INVALID_ID); mt_lock(); @@ -482,7 +475,6 @@ void *PoolAllocator::get(ID p_mem) { ERR_FAIL_COND_V(!e, nullptr); } if (e->lock == 0) { - //assert(0); mt_unlock(); ERR_PRINT("e->lock == 0"); return nullptr; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index bad53ab4e6..2e144a4c9a 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -44,6 +44,7 @@ #include "core/input/input_map.h" #include "core/input/shortcut.h" #include "core/io/config_file.h" +#include "core/io/dir_access.h" #include "core/io/dtls_server.h" #include "core/io/http_client.h" #include "core/io/image_loader.h" diff --git a/core/string/ustring.h b/core/string/ustring.h index b8ae3c2392..4b6568a502 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Note: _GODOT suffix added to avoid conflict with ICU header with the same guard. - #ifndef USTRING_GODOT_H #define USTRING_GODOT_H +// Note: _GODOT suffix added to header guard to avoid conflict with ICU header. + #include "core/string/char_utils.h" #include "core/templates/cowdata.h" #include "core/templates/vector.h" diff --git a/core/templates/pooled_list.h b/core/templates/pooled_list.h index f13156b292..08f53572e7 100644 --- a/core/templates/pooled_list.h +++ b/core/templates/pooled_list.h @@ -28,7 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#pragma once +#ifndef POOLED_LIST_H +#define POOLED_LIST_H // Simple template to provide a pool with O(1) allocate and free. // The freelist could alternatively be a linked list placed within the unused elements @@ -206,3 +207,5 @@ private: LocalVector<U, U> _active_map; LocalVector<U, U> _active_list; }; + +#endif // POOLED_LIST_H diff --git a/doc/classes/NavigationPathQueryParameters2D.xml b/doc/classes/NavigationPathQueryParameters2D.xml index 70455017c4..364f495a72 100644 --- a/doc/classes/NavigationPathQueryParameters2D.xml +++ b/doc/classes/NavigationPathQueryParameters2D.xml @@ -16,6 +16,7 @@ The navigation layers the query will use (as a bitmask). </member> <member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters2D.PathPostProcessing" default="0"> + The path postprocessing applied to the raw path corridor found by the [member pathfinding_algorithm]. </member> <member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters2D.PathfindingAlgorithm" default="0"> The pathfinding algorithm used in the path query. diff --git a/doc/classes/NavigationPathQueryParameters3D.xml b/doc/classes/NavigationPathQueryParameters3D.xml index 4dd54601f5..59c907c5b5 100644 --- a/doc/classes/NavigationPathQueryParameters3D.xml +++ b/doc/classes/NavigationPathQueryParameters3D.xml @@ -16,6 +16,7 @@ The navigation layers the query will use (as a bitmask). </member> <member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters3D.PathPostProcessing" default="0"> + The path postprocessing applied to the raw path corridor found by the [member pathfinding_algorithm]. </member> <member name="pathfinding_algorithm" type="int" setter="set_pathfinding_algorithm" getter="get_pathfinding_algorithm" enum="NavigationPathQueryParameters3D.PathfindingAlgorithm" default="0"> The pathfinding algorithm used in the path query. diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 4b588033c0..18ac8a11df 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -53,6 +53,20 @@ <description> </description> </method> + <method name="area_get_collision_layer" qualifiers="const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + Returns the physics layer or layers an area belongs to. + </description> + </method> + <method name="area_get_collision_mask" qualifiers="const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + Returns the physics layer or layers an area can contact with. + </description> + </method> <method name="area_get_object_instance_id" qualifiers="const"> <return type="int" /> <param index="0" name="area" type="RID" /> diff --git a/doc/classes/PhysicsServer2DExtension.xml b/doc/classes/PhysicsServer2DExtension.xml index 518862bb28..9bb11e0d89 100644 --- a/doc/classes/PhysicsServer2DExtension.xml +++ b/doc/classes/PhysicsServer2DExtension.xml @@ -47,6 +47,18 @@ <description> </description> </method> + <method name="_area_get_collision_layer" qualifiers="virtual const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + </description> + </method> + <method name="_area_get_collision_mask" qualifiers="virtual const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + </description> + </method> <method name="_area_get_object_instance_id" qualifiers="virtual const"> <return type="int" /> <param index="0" name="area" type="RID" /> diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index da9e10c420..95f7fb69a2 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -40,6 +40,20 @@ Creates an [Area3D]. </description> </method> + <method name="area_get_collision_layer" qualifiers="const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + Returns the physics layer or layers an area belongs to. + </description> + </method> + <method name="area_get_collision_mask" qualifiers="const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + Returns the physics layer or layers an area can contact with. + </description> + </method> <method name="area_get_object_instance_id" qualifiers="const"> <return type="int" /> <param index="0" name="area" type="RID" /> diff --git a/doc/classes/PhysicsServer3DExtension.xml b/doc/classes/PhysicsServer3DExtension.xml index ab00f63359..1e9df54de5 100644 --- a/doc/classes/PhysicsServer3DExtension.xml +++ b/doc/classes/PhysicsServer3DExtension.xml @@ -34,6 +34,18 @@ <description> </description> </method> + <method name="_area_get_collision_layer" qualifiers="virtual const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + </description> + </method> + <method name="_area_get_collision_mask" qualifiers="virtual const"> + <return type="int" /> + <param index="0" name="area" type="RID" /> + <description> + </description> + </method> <method name="_area_get_object_instance_id" qualifiers="virtual const"> <return type="int" /> <param index="0" name="area" type="RID" /> diff --git a/doc/classes/QuadMesh.xml b/doc/classes/QuadMesh.xml index 7469338ef9..b869774601 100644 --- a/doc/classes/QuadMesh.xml +++ b/doc/classes/QuadMesh.xml @@ -12,5 +12,6 @@ </tutorials> <members> <member name="orientation" type="int" setter="set_orientation" getter="get_orientation" overrides="PlaneMesh" enum="PlaneMesh.Orientation" default="2" /> + <member name="size" type="Vector2" setter="set_size" getter="get_size" overrides="PlaneMesh" default="Vector2(1, 1)" /> </members> </class> diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml index 68834839f3..a3fcf53228 100644 --- a/doc/classes/ScriptEditorBase.xml +++ b/doc/classes/ScriptEditorBase.xml @@ -35,6 +35,13 @@ Emitted when the user requests a specific documentation page. </description> </signal> + <signal name="go_to_method"> + <param index="0" name="script" type="Object" /> + <param index="1" name="method" type="String" /> + <description> + Emitted when the user requests to view a specific method of a script, similar to [signal request_open_script_at_line]. + </description> + </signal> <signal name="name_changed"> <description> Emitted after script validation or when the edited resource has changed. @@ -56,7 +63,7 @@ <param index="0" name="script" type="Object" /> <param index="1" name="line" type="int" /> <description> - Emitted when the user requests a script. + Emitted when the user requests to view a specific line of a script, similar to [signal go_to_method]. </description> </signal> <signal name="request_save_history"> diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index ab298a0e49..c8a42e925e 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -51,7 +51,6 @@ #include <sys/sysctl.h> #endif -#include <assert.h> #include <dlfcn.h> #include <errno.h> #include <poll.h> @@ -104,10 +103,6 @@ static void _setup_clock() { } #endif -void OS_Unix::debug_break() { - assert(false); -} - static void handle_interrupt(int sig) { if (!EngineDebugger::is_active()) { return; diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 8ef650f28b..b35f161524 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -86,7 +86,6 @@ public: virtual int get_processor_count() const override; - virtual void debug_break() override; virtual void initialize_debugging() override; virtual String get_executable_path() const override; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 236f3d7b08..ddeb8643b8 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -367,6 +367,10 @@ void ConnectDialog::popup_dialog(const String &p_for_signal) { error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root())); } + if (first_popup) { + first_popup = false; + _advanced_pressed(); + } popup_centered(); } @@ -389,6 +393,7 @@ void ConnectDialog::_advanced_pressed() { } _update_ok_enabled(); + EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "use_advanced_connections", advanced->is_pressed()); popup_centered(); } @@ -480,6 +485,7 @@ ConnectDialog::ConnectDialog() { vbc_left->add_child(advanced); advanced->set_text(TTR("Advanced")); advanced->set_h_size_flags(Control::SIZE_SHRINK_BEGIN | Control::SIZE_EXPAND); + advanced->set_pressed(EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "use_advanced_connections", false)); advanced->connect("pressed", callable_mp(this, &ConnectDialog::_advanced_pressed)); HBoxContainer *hbox = memnew(HBoxContainer); diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index e37246e7a0..db2f855617 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -112,6 +112,7 @@ private: LineEdit *dst_method = nullptr; ConnectDialogBinds *cdbinds = nullptr; bool edit_mode = false; + bool first_popup = true; NodePath dst_path; VBoxContainer *vbc_right = nullptr; diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h index 5b2df8abd5..5af3a0d84a 100644 --- a/editor/debugger/editor_debugger_tree.h +++ b/editor/debugger/editor_debugger_tree.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "scene/gui/tree.h" - #ifndef EDITOR_DEBUGGER_TREE_H #define EDITOR_DEBUGGER_TREE_H +#include "scene/gui/tree.h" + class SceneDebuggerTree; class EditorFileDialog; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 673fa3404c..28768b7f34 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6901,23 +6901,24 @@ EditorNode::EditorNode() { play_button->set_toggle_mode(true); play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY)); + play_button->set_tooltip_text(TTR("Run the project's default scene.")); - ED_SHORTCUT_AND_COMMAND("editor/play", TTR("Play"), Key::F5); - ED_SHORTCUT_OVERRIDE("editor/play", "macos", KeyModifierMask::META | Key::B); - play_button->set_shortcut(ED_GET_SHORTCUT("editor/play")); + ED_SHORTCUT_AND_COMMAND("editor/run_project", TTR("Run Project"), Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_project", "macos", KeyModifierMask::META | Key::B); + play_button->set_shortcut(ED_GET_SHORTCUT("editor/run_project")); pause_button = memnew(Button); pause_button->set_flat(true); pause_button->set_toggle_mode(true); pause_button->set_icon(gui_base->get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); pause_button->set_focus_mode(Control::FOCUS_NONE); - pause_button->set_tooltip_text(TTR("Pause the scene execution for debugging.")); + pause_button->set_tooltip_text(TTR("Pause the running project's execution for debugging.")); pause_button->set_disabled(true); launch_pad_hb->add_child(pause_button); - ED_SHORTCUT("editor/pause_scene", TTR("Pause Scene"), Key::F7); - ED_SHORTCUT_OVERRIDE("editor/pause_scene", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); - pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_scene")); + ED_SHORTCUT("editor/pause_running_project", TTR("Pause Running Project"), Key::F7); + ED_SHORTCUT_OVERRIDE("editor/pause_running_project", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); + pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_running_project")); stop_button = memnew(Button); stop_button->set_flat(true); @@ -6925,12 +6926,12 @@ EditorNode::EditorNode() { stop_button->set_focus_mode(Control::FOCUS_NONE); stop_button->set_icon(gui_base->get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_STOP)); - stop_button->set_tooltip_text(TTR("Stop the scene.")); + stop_button->set_tooltip_text(TTR("Stop the currently running project.")); stop_button->set_disabled(true); - ED_SHORTCUT("editor/stop", TTR("Stop"), Key::F8); - ED_SHORTCUT_OVERRIDE("editor/stop", "macos", KeyModifierMask::META | Key::PERIOD); - stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop")); + ED_SHORTCUT("editor/stop_running_project", TTR("Stop Running Project"), Key::F8); + ED_SHORTCUT_OVERRIDE("editor/stop_running_project", "macos", KeyModifierMask::META | Key::PERIOD); + stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); run_native = memnew(EditorRunNative); launch_pad_hb->add_child(run_native); @@ -6942,10 +6943,11 @@ EditorNode::EditorNode() { play_scene_button->set_toggle_mode(true); play_scene_button->set_focus_mode(Control::FOCUS_NONE); play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE)); + play_scene_button->set_tooltip_text(TTR("Run the currently edited scene.")); - ED_SHORTCUT_AND_COMMAND("editor/play_scene", TTR("Play Scene"), Key::F6); - ED_SHORTCUT_OVERRIDE("editor/play_scene", "macos", KeyModifierMask::META | Key::R); - play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_scene")); + ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTR("Run Current Scene"), Key::F6); + ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R); + play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene")); play_custom_scene_button = memnew(Button); play_custom_scene_button->set_flat(true); @@ -6953,12 +6955,11 @@ EditorNode::EditorNode() { play_custom_scene_button->set_toggle_mode(true); play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE); play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_CUSTOM_SCENE)); + play_custom_scene_button->set_tooltip_text(TTR("Run a specific scene.")); - _reset_play_buttons(); - - ED_SHORTCUT_AND_COMMAND("editor/play_custom_scene", TTR("Play Custom Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5); - ED_SHORTCUT_OVERRIDE("editor/play_custom_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); - play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/play_custom_scene")); + ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTR("Run Specific Scene"), KeyModifierMask::META | KeyModifierMask::SHIFT | Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); + play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_specific_scene")); write_movie_panel = memnew(PanelContainer); write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); diff --git a/editor/editor_settings_dialog.cpp b/editor/editor_settings_dialog.cpp index 48e746ac36..2c09543d92 100644 --- a/editor/editor_settings_dialog.cpp +++ b/editor/editor_settings_dialog.cpp @@ -772,6 +772,7 @@ EditorSettingsDialog::EditorSettingsDialog() { shortcut_editor = memnew(InputEventConfigurationDialog); shortcut_editor->connect("confirmed", callable_mp(this, &EditorSettingsDialog::_event_config_confirmed)); shortcut_editor->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY); + shortcut_editor->set_close_on_escape(false); add_child(shortcut_editor); set_hide_on_ok(true); diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index bcc85570ed..13ab5cebf6 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -710,7 +710,7 @@ String EditorExportPlatform::_export_customize(const String &p_path, LocalVector if (type == "PackedScene") { // Its a scene. Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene", ResourceFormatLoader::CACHE_MODE_IGNORE); ERR_FAIL_COND_V(ps.is_null(), p_path); - Node *node = ps->instantiate(); + Node *node = ps->instantiate(PackedScene::GEN_EDIT_STATE_INSTANCE); // Make sure the child scene root gets the correct inheritance chain. ERR_FAIL_COND_V(node == nullptr, p_path); if (customize_scenes_plugins.size()) { for (uint32_t i = 0; i < customize_scenes_plugins.size(); i++) { diff --git a/editor/icons/MemberAnnotation.svg b/editor/icons/MemberAnnotation.svg index c73ebf7b9b..39bef6d9ee 100644 --- a/editor/icons/MemberAnnotation.svg +++ b/editor/icons/MemberAnnotation.svg @@ -1 +1 @@ -<svg width="16" height="16" version="1.0" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><script id="custom-useragent-string-page-script"/><path d="m13.821 12.756c-5.0033 3.9148-12.551 2.248-12.49-4.538 0.67424-11.471 17.312-7.4502 12.446 2.1173-1.0549 1.1955-2.0737 1.4617-3.1983 0.4329-0.21023-0.19282-0.44783-1.1594-0.3819-1.5089 0.35827-1.8946 1.0885-4.0778-0.72151-4.7234-2.4171-0.86457-4.5592 1.6495-4.9697 4.0193-0.47396 2.7343 2.284 3.3749 4.1487 1.9879 0.4553-0.36324 1.6433-1.3796 1.6806-1.9742" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.4928"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.821 12.756c-5.0033 3.9148-12.551 2.248-12.49-4.538.67424-11.471 17.312-7.4502 12.446 2.1173-1.0549 1.1955-2.0737 1.4617-3.1983.4329-.21023-.19282-.44783-1.1594-.3819-1.5089.35827-1.8946 1.0885-4.0778-.72151-4.7234-2.4171-.86457-4.5592 1.6495-4.9697 4.0193-.47396 2.7343 2.284 3.3749 4.1487 1.9879.4553-.36324 1.6433-1.3796 1.6806-1.9742" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.4928"/></svg> diff --git a/editor/icons/MethodOverride.svg b/editor/icons/MethodOverride.svg new file mode 100644 index 0000000000..004b9bf283 --- /dev/null +++ b/editor/icons/MethodOverride.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.2333332 4.2333332" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.49005985 3.3580432.83285685-.0000001v-.7093212c.0027125-.6681099.2054076-1.1321001 1.0021593-1.1328214h.3207573v-.79375l1.3229167 1.0648649-1.3229167 1.0518017v-.79375h-.3364788c-.2888876 0-.4514151.2436282-.4573001.5980603 0 .2833012.0000193.4455045.0000289.7134508h.79375v.4907171l-2.15577345.00147z" fill="#5fb2ff"/></svg> diff --git a/editor/icons/MethodOverrideAndSlot.svg b/editor/icons/MethodOverrideAndSlot.svg new file mode 100644 index 0000000000..d3bd9f0253 --- /dev/null +++ b/editor/icons/MethodOverrideAndSlot.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 4.2333332 4.2333332" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.15761184 3.636193h.37155483l.004252-.7093212c.0027092-.6681099.12999225-1.1321001.92674393-1.1328214h.1273374l.0042585-.7357171 1.3186582 1.006832-1.3229167 1.0700676v-.8531081h-.1260545c-.2888876 0-.3972562.2847204-.4031411.6391525 0 .2833012.0000193.4455045.0000289.7134508h1.2412654v.4907171h-2.14198686z" fill="#5fb2ff"/><path d="m2.38125.79375h1.5875v2.6458333h-1.5875v-.5291666h1.0583333v-1.5875h-1.0583333z" fill="#5fff97"/></svg> diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 77bc06533c..386519bc59 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -35,11 +35,13 @@ #include "core/io/resource_importer.h" #include "core/variant/dictionary.h" #include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/3d/node_3d.h" #include "scene/resources/animation.h" +#include "scene/resources/box_shape_3d.h" +#include "scene/resources/capsule_shape_3d.h" +#include "scene/resources/cylinder_shape_3d.h" #include "scene/resources/mesh.h" #include "scene/resources/shape_3d.h" -#include "scene/resources/skin.h" +#include "scene/resources/sphere_shape_3d.h" class Material; class AnimationPlayer; @@ -311,11 +313,6 @@ public: virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override; }; -#include "scene/resources/box_shape_3d.h" -#include "scene/resources/capsule_shape_3d.h" -#include "scene/resources/cylinder_shape_3d.h" -#include "scene/resources/sphere_shape_3d.h" - template <class M> Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options) { ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX; diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 8791da8245..3679657567 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -227,6 +227,7 @@ void ScriptEditorBase::_bind_methods() { // TODO: This signal is no use for VisualScript. ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text"))); ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text"))); + ADD_SIGNAL(MethodInfo("go_to_method", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::STRING, "method"))); } class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache { @@ -2380,6 +2381,7 @@ bool ScriptEditor::edit(const Ref<Resource> &p_resource, int p_line, int p_col, se->connect("request_save_history", callable_mp(this, &ScriptEditor::_save_history)); se->connect("search_in_files_requested", callable_mp(this, &ScriptEditor::_on_find_in_files_requested)); se->connect("replace_in_files_requested", callable_mp(this, &ScriptEditor::_on_replace_in_files_requested)); + se->connect("go_to_method", callable_mp(this, &ScriptEditor::script_goto_method)); //test for modification, maybe the script was not edited but was loaded @@ -2544,7 +2546,7 @@ void ScriptEditor::apply_scripts() const { } } -void ScriptEditor::reload_scripts() { +void ScriptEditor::reload_scripts(bool p_refresh_only) { for (int i = 0; i < tab_container->get_tab_count(); i++) { ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_tab_control(i)); if (!se) { @@ -2557,30 +2559,33 @@ void ScriptEditor::reload_scripts() { continue; //internal script, who cares } - uint64_t last_date = edited_res->get_last_modified_time(); - uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); + if (!p_refresh_only) { + uint64_t last_date = edited_res->get_last_modified_time(); + uint64_t date = FileAccess::get_modified_time(edited_res->get_path()); - if (last_date == date) { - continue; - } + if (last_date == date) { + continue; + } - Ref<Script> script = edited_res; - if (script != nullptr) { - Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); - ERR_CONTINUE(!rel_script.is_valid()); - script->set_source_code(rel_script->get_source_code()); - script->set_last_modified_time(rel_script->get_last_modified_time()); - script->reload(true); - } + Ref<Script> script = edited_res; + if (script != nullptr) { + Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE); + ERR_CONTINUE(!rel_script.is_valid()); + script->set_source_code(rel_script->get_source_code()); + script->set_last_modified_time(rel_script->get_last_modified_time()); + script->reload(true); + } - Ref<TextFile> text_file = edited_res; - if (text_file != nullptr) { - Error err; - Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); - ERR_CONTINUE(!rel_text_file.is_valid()); - text_file->set_text(rel_text_file->get_text()); - text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); + Ref<TextFile> text_file = edited_res; + if (text_file != nullptr) { + Error err; + Ref<TextFile> rel_text_file = _load_text_file(text_file->get_path(), &err); + ERR_CONTINUE(!rel_text_file.is_valid()); + text_file->set_text(rel_text_file->get_text()); + text_file->set_last_modified_time(rel_text_file->get_last_modified_time()); + } } + se->reload_text(); } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 59191b8891..1e78dc4ec4 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -477,7 +477,7 @@ public: bool toggle_scripts_panel(); bool is_scripts_panel_toggled(); void apply_scripts() const; - void reload_scripts(); + void reload_scripts(bool p_refresh_only = false); void open_script_create_dialog(const String &p_base_name, const String &p_base_path); void open_text_file_create_dialog(const String &p_base_path, const String &p_base_name = ""); Ref<Resource> open_file(const String &p_file); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index ad07ac180b..7a57f8a1e2 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -956,10 +956,7 @@ void ScriptTextEditor::_update_connected_methods() { CodeEdit *text_edit = code_editor->get_text_editor(); text_edit->set_gutter_width(connection_gutter, text_edit->get_line_height()); for (int i = 0; i < text_edit->get_line_count(); i++) { - if (text_edit->get_line_gutter_metadata(i, connection_gutter) == "") { - continue; - } - text_edit->set_line_gutter_metadata(i, connection_gutter, ""); + text_edit->set_line_gutter_metadata(i, connection_gutter, Dictionary()); text_edit->set_line_gutter_icon(i, connection_gutter, nullptr); text_edit->set_line_gutter_clickable(i, connection_gutter, false); } @@ -974,6 +971,7 @@ void ScriptTextEditor::_update_connected_methods() { return; } + // Add connection icons to methods. Vector<Node *> nodes = _find_all_node_for_script(base, base, script); HashSet<StringName> methods_found; for (int i = 0; i < nodes.size(); i++) { @@ -1002,8 +1000,11 @@ void ScriptTextEditor::_update_connected_methods() { for (int j = 0; j < functions.size(); j++) { String name = functions[j].get_slice(":", 0); if (name == method) { + Dictionary line_meta; + line_meta["type"] = "connection"; + line_meta["method"] = method; line = functions[j].get_slice(":", 1).to_int() - 1; - text_edit->set_line_gutter_metadata(line, connection_gutter, method); + text_edit->set_line_gutter_metadata(line, connection_gutter, line_meta); text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); text_edit->set_line_gutter_clickable(line, connection_gutter, true); methods_found.insert(method); @@ -1033,6 +1034,58 @@ void ScriptTextEditor::_update_connected_methods() { } } } + + // Add override icons to methods. + methods_found.clear(); + for (int i = 0; i < functions.size(); i++) { + StringName name = StringName(functions[i].get_slice(":", 0)); + if (methods_found.has(name)) { + continue; + } + + String found_base_class; + StringName base_class = script->get_instance_base_type(); + Ref<Script> inherited_script = script->get_base_script(); + while (!inherited_script.is_null()) { + if (inherited_script->has_method(name)) { + found_base_class = "script:" + inherited_script->get_path(); + break; + } + + base_class = inherited_script->get_instance_base_type(); + inherited_script = inherited_script->get_base_script(); + } + + if (found_base_class.is_empty() && base_class) { + List<MethodInfo> methods; + ClassDB::get_method_list(base_class, &methods); + for (int j = 0; j < methods.size(); j++) { + if (methods[j].name == name) { + found_base_class = "builtin:" + base_class; + break; + } + } + } + + if (!found_base_class.is_empty()) { + int line = functions[i].get_slice(":", 1).to_int() - 1; + + Dictionary line_meta = text_edit->get_line_gutter_metadata(line, connection_gutter); + if (line_meta.is_empty()) { + // Add override icon to gutter. + line_meta["type"] = "inherits"; + line_meta["method"] = name; + line_meta["base_class"] = found_base_class; + text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverride"), SNAME("EditorIcons"))); + text_edit->set_line_gutter_clickable(line, connection_gutter, true); + } else { + // If method is also connected to signal, then merge icons and keep the click behavior of the slot. + text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_theme_icon(SNAME("MethodOverrideAndSlot"), SNAME("EditorIcons"))); + } + + methods_found.insert(name); + } + } } void ScriptTextEditor::_update_gutter_indexes() { @@ -1054,18 +1107,40 @@ void ScriptTextEditor::_gutter_clicked(int p_line, int p_gutter) { return; } - String method = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter); - if (method.is_empty()) { + Dictionary meta = code_editor->get_text_editor()->get_line_gutter_metadata(p_line, p_gutter); + String type = meta.get("type", ""); + if (type.is_empty()) { return; } - Node *base = get_tree()->get_edited_scene_root(); - if (!base) { + // All types currently need a method name. + String method = meta.get("method", ""); + if (method.is_empty()) { return; } - Vector<Node *> nodes = _find_all_node_for_script(base, base, script); - connection_info_dialog->popup_connections(method, nodes); + if (type == "connection") { + Node *base = get_tree()->get_edited_scene_root(); + if (!base) { + return; + } + + Vector<Node *> nodes = _find_all_node_for_script(base, base, script); + connection_info_dialog->popup_connections(method, nodes); + } else if (type == "inherits") { + String base_class_raw = meta["base_class"]; + PackedStringArray base_class_split = base_class_raw.split(":", true, 1); + + if (base_class_split[0] == "script") { + // Go to function declaration. + Ref<Script> base_script = ResourceLoader::load(base_class_split[1]); + ERR_FAIL_COND(!base_script.is_valid()); + emit_signal(SNAME("go_to_method"), base_script, method); + } else if (base_class_split[0] == "builtin") { + // Open method documentation. + emit_signal(SNAME("go_to_help"), "class_method:" + base_class_split[1] + ":" + method); + } + } } void ScriptTextEditor::_edit_option(int p_op) { diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index 253c3062b8..f8ba3f0354 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -217,6 +217,7 @@ static const char *gdscript_function_renames[][2] = { { "_get_configuration_warning", "_get_configuration_warnings" }, // Node { "_set_current", "set_current" }, // Camera2D { "_set_editor_description", "set_editor_description" }, // Node + { "_set_playing", "set_playing" }, // AnimatedSprite3D { "_toplevel_raise_self", "_top_level_raise_self" }, // CanvasItem { "_update_wrap_at", "_update_wrap_at_column" }, // TextEdit { "add_animation", "add_animation_library" }, // AnimationPlayer @@ -231,6 +232,7 @@ static const char *gdscript_function_renames[][2] = { { "add_scene_import_plugin", "add_scene_format_importer_plugin" }, //EditorPlugin { "add_stylebox_override", "add_theme_stylebox_override" }, // Control { "add_torque", "apply_torque" }, //RigidBody2D + { "agent_set_neighbor_dist", "agent_set_neighbor_distance" }, // NavigationServer2D, NavigationServer3D { "apply_changes", "_apply_changes" }, // EditorPlugin { "body_add_force", "body_apply_force" }, // PhysicsServer2D { "body_add_torque", "body_apply_torque" }, // PhysicsServer2D @@ -332,6 +334,7 @@ static const char *gdscript_function_renames[][2] = { { "get_metakey", "is_meta_pressed" }, // InputEventWithModifiers { "get_mid_height", "get_height" }, // CapsuleMesh { "get_motion_remainder", "get_remainder" }, // PhysicsTestMotionResult2D + { "get_neighbor_dist", "get_neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "get_network_connected_peers", "get_peers" }, // Multiplayer API { "get_network_master", "get_multiplayer_authority" }, // Node { "get_network_peer", "get_multiplayer_peer" }, // Multiplayer API @@ -512,6 +515,7 @@ static const char *gdscript_function_renames[][2] = { { "set_max_atlas_size", "set_max_texture_size" }, // LightmapGI { "set_metakey", "set_meta_pressed" }, // InputEventWithModifiers { "set_mid_height", "set_height" }, // CapsuleMesh + { "set_neighbor_dist", "set_neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "set_network_master", "set_multiplayer_authority" }, // Node { "set_network_peer", "set_multiplayer_peer" }, // Multiplayer API { "set_oneshot", "set_one_shot" }, // AnimatedTexture @@ -652,6 +656,7 @@ static const char *csharp_function_renames[][2] = { { "_GetConfigurationWarning", "_GetConfigurationWarnings" }, // Node { "_SetCurrent", "SetCurrent" }, // Camera2D { "_SetEditorDescription", "SetEditorDescription" }, // Node + { "_SetPlaying", "SetPlaying" }, // AnimatedSprite3D { "_ToplevelRaiseSelf", "_TopLevelRaiseSelf" }, // CanvasItem { "_UpdateWrapAt", "_UpdateWrapAtColumn" }, // TextEdit { "AddAnimation", "AddAnimationLibrary" }, // AnimationPlayer @@ -666,6 +671,7 @@ static const char *csharp_function_renames[][2] = { { "AddSceneImportPlugin", "AddSceneFormatImporterPlugin" }, //EditorPlugin { "AddStyleboxOverride", "AddThemeStyleboxOverride" }, // Control { "AddTorque", "AddConstantTorque" }, //RigidBody2D + { "AgentSetNeighborDist", "AgentSetNeighborDistance" }, // NavigationServer2D, NavigationServer3D { "BindChildNodeToBone", "SetBoneChildren" }, // Skeleton3D { "BumpmapToNormalmap", "BumpMapToNormalMap" }, // Image { "CanBeHidden", "_CanBeHidden" }, // EditorNode3DGizmoPlugin @@ -759,6 +765,7 @@ static const char *csharp_function_renames[][2] = { { "GetMetakey", "IsMetaPressed" }, // InputEventWithModifiers { "GetMidHeight", "GetHeight" }, // CapsuleMesh { "GetMotionRemainder", "GetRemainder" }, // PhysicsTestMotionResult2D + { "GetNeighborDist", "GetNeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "GetNetworkConnectedPeers", "GetPeers" }, // Multiplayer API { "GetNetworkMaster", "GetMultiplayerAuthority" }, // Node { "GetNetworkPeer", "GetMultiplayerPeer" }, // Multiplayer API @@ -929,6 +936,7 @@ static const char *csharp_function_renames[][2] = { { "SetMaxAtlasSize", "SetMaxTextureSize" }, // LightmapGI { "SetMetakey", "SetMetaPressed" }, // InputEventWithModifiers { "SetMidHeight", "SetHeight" }, // CapsuleMesh + { "SetNeighborDist", "SetNeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "SetNetworkMaster", "SetMultiplayerAuthority" }, // Node { "SetNetworkPeer", "SetMultiplayerPeer" }, // Multiplayer API { "SetOneshot", "SetOneShot" }, // AnimatedTexture @@ -1064,6 +1072,7 @@ static const char *gdscript_properties_renames[][2] = { { "focus_neighbour_left", "focus_neighbor_left" }, // Control { "focus_neighbour_right", "focus_neighbor_right" }, // Control { "focus_neighbour_top", "focus_neighbor_top" }, // Control + { "follow_viewport_enable", "follow_viewport_enabled" }, // CanvasItem { "file_icon_modulate", "file_icon_color" }, // Theme { "files_disabled", "file_disabled_color" }, // Theme { "folder_icon_modulate", "folder_icon_color" }, // Theme @@ -1079,6 +1088,7 @@ static const char *gdscript_properties_renames[][2] = { { "margin_right", "offset_right" }, // Control broke NinePatchRect, StyleBox { "margin_top", "offset_top" }, // Control broke NinePatchRect, StyleBox { "mid_height", "height" }, // CapsuleMesh + { "neighbor_dist", "neighbor_distance" }, // NavigationAgent2D, NavigationAgent3D { "offset_h", "drag_horizontal_offset" }, // Camera2D { "offset_v", "drag_vertical_offset" }, // Camera2D { "off", "unchecked" }, // Theme @@ -1167,6 +1177,7 @@ static const char *csharp_properties_renames[][2] = { { "FocusNeighbourLeft", "FocusNeighborLeft" }, // Control { "FocusNeighbourRight", "FocusNeighborRight" }, // Control { "FocusNeighbourTop", "FocusNeighborTop" }, // Control + { "FollowViewportEnable", "FollowViewportEnabled" }, // CanvasItem { "GlobalRateScale", "PlaybackSpeedScale" }, // AudioServer { "GravityDistanceScale", "GravityPointDistanceScale" }, // Area2D { "GravityVec", "GravityDirection" }, // Area2D @@ -1179,6 +1190,7 @@ static const char *csharp_properties_renames[][2] = { { "MarginRight", "OffsetRight" }, // Control broke NinePatchRect, StyleBox { "MarginTop", "OffsetTop" }, // Control broke NinePatchRect, StyleBox { "MidHeight", "Height" }, // CapsuleMesh + { "NeighborDist", "NeighborDistance" }, // NavigationAgent2D, NavigationAgent3D { "OffsetH", "DragHorizontalOffset" }, // Camera2D { "OffsetV", "DragVerticalOffset" }, // Camera2D { "Ofs", "Offset" }, // Theme @@ -2339,7 +2351,9 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { valid = valid && test_conversion_gdscript_builtin("OS.get_window_safe_area()", "DisplayServer.get_display_safe_area()", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide( a, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("\tmove_and_slide( a, b, c, d, e, f ) # Roman", "\tset_velocity(a)\n\tset_up_direction(b)\n\tset_floor_stop_on_slope_enabled(c)\n\tset_max_slides(d)\n\tset_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tmove_and_slide() # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("\tvar aa = roman(r.move_and_slide_with_snap( a, g, b, c, d, e, f )) # Roman", "\tr.set_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tr.set_up_direction(b)\n\tr.set_floor_stop_on_slope_enabled(c)\n\tr.set_max_slides(d)\n\tr.set_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tr.move_and_slide()\n\tvar aa = roman(r.velocity) # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); + valid = valid && test_conversion_gdscript_builtin("\tmove_and_slide_with_snap( a, g, b, c, d, e, f ) # Roman", "\tset_velocity(a)\n\t# TODOConverter40 looks that snap in Godot 4.0 is float, not vector like in Godot 3 - previous value `g`\n\tset_up_direction(b)\n\tset_floor_stop_on_slope_enabled(c)\n\tset_max_slides(d)\n\tset_floor_max_angle(e)\n\t# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `f`\n\tmove_and_slide() # Roman", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a , b )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); valid = valid && test_conversion_gdscript_builtin("list_dir_begin( a )", "list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547", &ProjectConverter3To4::rename_gdscript_functions, "custom rename", reg_container, false); @@ -3143,8 +3157,13 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[5] + "`\n"; } - line_new += starting_space + base_obj + "move_and_slide()\n"; - line = line_new + line.substr(0, start) + "velocity" + line.substr(end + start); + line_new += starting_space + base_obj + "move_and_slide()"; + + if (!line.begins_with(starting_space + "move_and_slide")) { + line = line_new + "\n" + line.substr(0, start) + "velocity" + line.substr(end + start); + } else { + line = line_new + line.substr(end + start); + } } } } @@ -3194,8 +3213,13 @@ void ProjectConverter3To4::process_gdscript_line(String &line, const RegExContai line_new += starting_space + "# TODOConverter40 infinite_inertia were removed in Godot 4.0 - previous value `" + parts[6] + "`\n"; } - line_new += starting_space + base_obj + "move_and_slide()\n"; - line = line_new + line.substr(0, start) + "velocity" + line.substr(end + start); // move_and_slide used to return velocity + line_new += starting_space + base_obj + "move_and_slide()"; + + if (!line.begins_with(starting_space + "move_and_slide_with_snap")) { + line = line_new + "\n" + line.substr(0, start) + "velocity" + line.substr(end + start); + } else { + line = line_new + line.substr(end + start); + } } } } diff --git a/main/main.cpp b/main/main.cpp index fa7df8d705..aac77c1625 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -157,6 +157,7 @@ static bool show_help = false; static bool auto_quit = false; static OS::ProcessID editor_pid = 0; #ifdef TOOLS_ENABLED +static bool found_project = false; static bool auto_build_solutions = false; static String debug_server_uri; static int converter_max_kb_file = 4 * 1024; // 4MB @@ -707,9 +708,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Vector<String> breakpoints; bool use_custom_res = true; bool force_res = false; -#ifdef TOOLS_ENABLED - bool found_project = false; -#endif String default_renderer = ""; String renderer_hints = ""; @@ -1938,7 +1936,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { #ifdef TOOLS_ENABLED if (editor || project_manager || cmdline_tool) { EditorPaths::create(); - if (EditorPaths::get_singleton()->is_self_contained()) { + if (found_project && EditorPaths::get_singleton()->is_self_contained()) { if (ProjectSettings::get_singleton()->get_resource_path() == OS::get_singleton()->get_executable_path().get_base_dir()) { ERR_PRINT("You are trying to run a self-contained editor at the same location as a project. This is not allowed, since editor files will mix with project files."); OS::get_singleton()->set_exit_code(EXIT_FAILURE); diff --git a/methods.py b/methods.py index 78ec9b8674..97a1e15e35 100644 --- a/methods.py +++ b/methods.py @@ -105,7 +105,7 @@ def get_version_info(module_version_string="", silent=False): if os.getenv("GODOT_VERSION_STATUS") != None: version_info["status"] = str(os.getenv("GODOT_VERSION_STATUS")) if not silent: - print(f"Using version status '{version_info.status}', overriding the original '{version.status}'.") + print(f"Using version status '{version_info['status']}', overriding the original '{version.status}'.") # Parse Git hash if we're in a Git repo. githash = "" @@ -846,7 +846,8 @@ def generate_vs_project(env, num_jobs): add_to_vs_project(env, env.servers_sources) if env["tests"]: add_to_vs_project(env, env.tests_sources) - add_to_vs_project(env, env.editor_sources) + if env["tools"]: + add_to_vs_project(env, env.editor_sources) for header in glob_recursive("**/*.h"): env.vs_incs.append(str(header)) diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index 467aa3ce83..b58f002f3c 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -249,7 +249,6 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; diff --git a/misc/scripts/header_guards.sh b/misc/scripts/header_guards.sh index 9a830f3ad2..9fdc864f8c 100755 --- a/misc/scripts/header_guards.sh +++ b/misc/scripts/header_guards.sh @@ -5,11 +5,15 @@ if [ ! -f "version.py" ]; then echo "Some of the paths checks may not work as intended from a different folder." fi +files_invalid_guard="" + for file in $(find -name "thirdparty" -prune -o -name "*.h" -print); do # Skip *.gen.h and *-so_wrap.h, they're generated. if [[ "$file" == *".gen.h" || "$file" == *"-so_wrap.h" ]]; then continue; fi # Has important define before normal header guards. if [[ "$file" == *"thread.h" || "$file" == *"platform_config.h" ]]; then continue; fi + # Obj-C files don't use header guards. + if grep -q "#import " "$file"; then continue; fi bname=$(basename $file .h) @@ -43,8 +47,21 @@ for file in $(find -name "thirdparty" -prune -o -name "*.h" -print); do sed -i $file -e "$ s/#endif.*/\n#endif \/\/ $guard/" # Removes redundant \n added before, if they weren't needed. sed -i $file -e "/^$/N;/^\n$/D" + + # Check that first ifndef (should be header guard) is at the expected position. + # If not it can mean we have some code before the guard that should be after. + # "31" is the expected line with the copyright header. + first_ifndef=$(grep -n -m 1 "ifndef" $file | sed 's/\([0-9]*\).*/\1/') + if [[ "$first_ifndef" != "31" ]]; then + files_invalid_guard+="$file\n" + fi done +if [[ ! -z "$files_invalid_guard" ]]; then + echo -e "The following files were found to have potentially invalid header guard:\n" + echo -e "$files_invalid_guard" +fi + diff=$(git diff --color) # If no diff has been generated all is OK, clean up, and exit. diff --git a/modules/csg/csg.h b/modules/csg/csg.h index 738e3d68ea..aae99c52a3 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -39,7 +39,6 @@ #include "core/object/ref_counted.h" #include "core/templates/list.h" #include "core/templates/oa_hash_map.h" -#include "core/templates/rb_map.h" #include "core/templates/vector.h" #include "scene/resources/material.h" diff --git a/modules/denoise/SCsub b/modules/denoise/SCsub index 97feea2b44..779ce165d2 100644 --- a/modules/denoise/SCsub +++ b/modules/denoise/SCsub @@ -103,9 +103,9 @@ env_oidn.Append( "__STDC_LIMIT_MACROS", "DISABLE_VERBOSE", "MKLDNN_ENABLE_CONCURRENT_EXEC", - "NDEBUG", ] ) +env_oidn.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds. env_thirdparty = env_oidn.Clone() env_thirdparty.disable_warnings() diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 1cff2181af..54cadf7df3 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2390,7 +2390,7 @@ Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const Str } Error err; - Ref<GDScript> script = GDScriptCache::get_full_script(p_path, err); + Ref<GDScript> script = GDScriptCache::get_full_script(p_path, err, "", p_cache_mode == CACHE_MODE_IGNORE); // TODO: Reintroduce binary and encrypted scripts. diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index c25f5b58d5..271296c2f9 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -183,20 +183,26 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri return script; } -Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) { +Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner, bool p_update_from_disk) { MutexLock lock(singleton->lock); if (!p_owner.is_empty()) { singleton->dependencies[p_owner].insert(p_path); } + Ref<GDScript> script; r_error = OK; if (singleton->full_gdscript_cache.has(p_path)) { - return singleton->full_gdscript_cache[p_path]; + script = Ref<GDScript>(singleton->full_gdscript_cache[p_path]); + if (!p_update_from_disk) { + return script; + } } - Ref<GDScript> script = get_shallow_script(p_path); - ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>()); + if (script.is_null()) { + script = get_shallow_script(p_path); + ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>()); + } r_error = script->load_source_code(p_path); diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h index b971bdd984..3d111ea229 100644 --- a/modules/gdscript/gdscript_cache.h +++ b/modules/gdscript/gdscript_cache.h @@ -88,7 +88,7 @@ public: static Ref<GDScriptParserRef> get_parser(const String &p_path, GDScriptParserRef::Status status, Error &r_error, const String &p_owner = String()); static String get_source_code(const String &p_path); static Ref<GDScript> get_shallow_script(const String &p_path, const String &p_owner = String()); - static Ref<GDScript> get_full_script(const String &p_path, Error &r_error, const String &p_owner = String()); + static Ref<GDScript> get_full_script(const String &p_path, Error &r_error, const String &p_owner = String(), bool p_update_from_disk = false); static Error finish_compiling(const String &p_owner); GDScriptCache(); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 00e8223b9a..fd418ced47 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2041,7 +2041,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ codegen.generator->write_newline(field->initializer->start_line); // For typed arrays we need to make sure this is already initialized correctly so typed assignment work. - if (field_type.is_hard_type() && field_type.builtin_type == Variant::ARRAY && field_type.has_container_element_type()) { + if (field_type.is_hard_type() && field_type.builtin_type == Variant::ARRAY) { if (field_type.has_container_element_type()) { codegen.generator->write_construct_typed_array(dst_address, _gdtype_from_datatype(field_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>()); } else { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index d8a06a8663..b4da94e448 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4001,7 +4001,7 @@ String GDScriptParser::DataType::to_string() const { if (is_meta_type) { return script_type->get_class_name().operator String(); } - String name = script_type->get_name(); + String name = script_type != nullptr ? script_type->get_name() : ""; if (!name.is_empty()) { return name; } diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 5ad9680ea0..ccde0521f2 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -422,6 +422,7 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin if (error == OK) { if (script->load_source_code(path) == OK) { script->reload(true); + ScriptEditor::get_singleton()->reload_scripts(true); // Refresh scripts opened in the internal editor. } } } diff --git a/modules/gltf/register_types.h b/modules/gltf/register_types.h index 90b9a83c88..bf2730d2ef 100644 --- a/modules/gltf/register_types.h +++ b/modules/gltf/register_types.h @@ -28,7 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GLTF_REGISTER_TYPES_H +#define GLTF_REGISTER_TYPES_H + #include "modules/register_module_types.h" void initialize_gltf_module(ModuleInitializationLevel p_level); void uninitialize_gltf_module(ModuleInitializationLevel p_level); + +#endif // GLTF_REGISTER_TYPES_H diff --git a/modules/mono/utils/macos_utils.h b/modules/mono/utils/macos_utils.h index ca4957f5a7..0b74114685 100644 --- a/modules/mono/utils/macos_utils.h +++ b/modules/mono/utils/macos_utils.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/string/ustring.h" - #ifndef MONO_MACOS_UTILS_H #define MONO_MACOS_UTILS_H #ifdef MACOS_ENABLED +#include "core/string/ustring.h" + bool macos_is_app_bundle_installed(const String &p_bundle_id); #endif diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub index 593d1ff3c1..298977f96d 100644 --- a/modules/openxr/SCsub +++ b/modules/openxr/SCsub @@ -18,38 +18,36 @@ env_openxr.Prepend( thirdparty_dir + "/src", thirdparty_dir + "/src/common", thirdparty_dir + "/src/external/jsoncpp/include", - thirdparty_dir + "/src/loader", ] ) -# may need to check and set: -# - XR_USE_TIMESPEC - -env_thirdparty = env_openxr.Clone() -env_thirdparty.disable_warnings() -env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"]) - if env["platform"] == "android": # may need to set OPENXR_ANDROID_VERSION_SUFFIX - env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"]) + env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"]) + env_openxr.AppendUnique(CPPDEFINES=["JSON_USE_EXCEPTION=0"]) # may need to include java parts of the openxr loader elif env["platform"] == "linuxbsd": - env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX"]) + env_openxr.AppendUnique(CPPDEFINES=["XR_OS_LINUX"]) if env["x11"]: - env_thirdparty.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"]) + env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"]) # FIXME: Review what needs to be set for Android and macOS. - env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"]) + env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"]) elif env["platform"] == "windows": - env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_WINDOWS", "NOMINMAX", "XR_USE_PLATFORM_WIN32"]) + env_openxr.AppendUnique(CPPDEFINES=["XR_OS_WINDOWS", "NOMINMAX", "XR_USE_PLATFORM_WIN32"]) -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c") +# may need to check and set: +# - XR_USE_TIMESPEC -# add in common files (hope these don't clash with us) -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/object_info.cpp") +env_thirdparty = env_openxr.Clone() +env_thirdparty.disable_warnings() +env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"]) + +if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]: + env_thirdparty["CXXFLAGS"].remove("-fno-exceptions") +env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"]) # add in external jsoncpp dependency env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_reader.cpp") @@ -57,17 +55,24 @@ env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/ env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_writer.cpp") # add in load -if env["platform"] == "android": - env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/android_utilities.cpp") - -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_core.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_instance.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/manifest_file.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp") -env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp") +if env["platform"] != "android": + # On Android the openxr_loader is provided by separate plugins for each device + # Build the engine using object files + khrloader_obj = [] + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c") + + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/object_info.cpp") + + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_core.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_instance.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/manifest_file.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp") + env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp") + env.modules_sources += khrloader_obj env.modules_sources += thirdparty_obj diff --git a/modules/openxr/config.py b/modules/openxr/config.py index f91cb1359f..650146fdd3 100644 --- a/modules/openxr/config.py +++ b/modules/openxr/config.py @@ -1,7 +1,5 @@ def can_build(env, platform): - if ( - platform == "linuxbsd" or platform == "windows" - ): # or platform == "android" -- temporarily disabled android support + if platform in ("linuxbsd", "windows", "android"): return env["openxr"] else: # not supported on these platforms diff --git a/modules/openxr/extensions/openxr_android_extension.cpp b/modules/openxr/extensions/openxr_android_extension.cpp index 3bd4db169c..8f6d5c28db 100644 --- a/modules/openxr/extensions/openxr_android_extension.cpp +++ b/modules/openxr/extensions/openxr_android_extension.cpp @@ -29,7 +29,12 @@ /*************************************************************************/ #include "openxr_android_extension.h" +#include "java_godot_wrapper.h" +#include "os_android.h" +#include "thread_jandroid.h" +#include <jni.h> +#include <modules/openxr/openxr_api.h> #include <openxr/openxr.h> #include <openxr/openxr_platform.h> @@ -42,19 +47,16 @@ OpenXRAndroidExtension *OpenXRAndroidExtension::get_singleton() { OpenXRAndroidExtension::OpenXRAndroidExtension(OpenXRAPI *p_openxr_api) : OpenXRExtensionWrapper(p_openxr_api) { singleton = this; - request_extensions[XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME] = nullptr; // must be available +} - // Initialize the loader - PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR; - result = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction *)(&xrInitializeLoaderKHR)); - ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to retrieve pointer to xrInitializeLoaderKHR"); +void OpenXRAndroidExtension::on_before_instance_created() { + EXT_INIT_XR_FUNC(xrInitializeLoaderKHR); - // TODO fix this code, this is still code from GDNative! - JNIEnv *env = android_api->godot_android_get_env(); + JNIEnv *env = get_jni_env(); JavaVM *vm; env->GetJavaVM(&vm); - jobject activity_object = env->NewGlobalRef(android_api->godot_android_get_activity()); + jobject activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity()); XrLoaderInitInfoAndroidKHR loader_init_info_android = { .type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR, @@ -62,7 +64,7 @@ OpenXRAndroidExtension::OpenXRAndroidExtension(OpenXRAPI *p_openxr_api) : .applicationVM = vm, .applicationContext = activity_object }; - xrInitializeLoaderKHR((const XrLoaderInitInfoBaseHeaderKHR *)&loader_init_info_android); + XrResult result = xrInitializeLoaderKHR((const XrLoaderInitInfoBaseHeaderKHR *)&loader_init_info_android); ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to call xrInitializeLoaderKHR"); } diff --git a/modules/openxr/extensions/openxr_android_extension.h b/modules/openxr/extensions/openxr_android_extension.h index 88b0e310e7..eda7022064 100644 --- a/modules/openxr/extensions/openxr_android_extension.h +++ b/modules/openxr/extensions/openxr_android_extension.h @@ -31,6 +31,7 @@ #ifndef OPENXR_ANDROID_EXTENSION_H #define OPENXR_ANDROID_EXTENSION_H +#include "../util.h" #include "openxr_extension_wrapper.h" class OpenXRAndroidExtension : public OpenXRExtensionWrapper { @@ -38,10 +39,16 @@ public: static OpenXRAndroidExtension *get_singleton(); OpenXRAndroidExtension(OpenXRAPI *p_openxr_api); + + virtual void on_before_instance_created() override; + virtual ~OpenXRAndroidExtension() override; private: static OpenXRAndroidExtension *singleton; + + // Initialize the loader + EXT_PROTO_XRRESULT_FUNC1(xrInitializeLoaderKHR, (const XrLoaderInitInfoBaseHeaderKHR *), loaderInitInfo) }; #endif // OPENXR_ANDROID_EXTENSION_H diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index ecc6e0dd4e..0ed0155fc7 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -66,6 +66,7 @@ public: virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; } virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; } + virtual void on_before_instance_created() {} virtual void on_instance_created(const XrInstance p_instance) {} virtual void on_instance_destroyed() {} virtual void on_session_created(const XrSession p_instance) {} diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp index 2608c4ac17..f9e771c934 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp @@ -31,30 +31,12 @@ #include "core/string/print_string.h" #include "../extensions/openxr_vulkan_extension.h" -#include "../openxr_api.h" #include "../openxr_util.h" #include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" #include "servers/rendering/rendering_server_globals.h" #include "servers/rendering_server.h" -// need to include Vulkan so we know of type definitions -#define XR_USE_GRAPHICS_API_VULKAN - -#ifdef WINDOWS_ENABLED -// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform -// however due to the way the openxr headers are put together, we have no choice. -#include <windows.h> -#endif - -// include platform dependent structs -#include <openxr/openxr_platform.h> - -PFN_xrGetVulkanGraphicsRequirements2KHR xrGetVulkanGraphicsRequirements2KHR_ptr = nullptr; -PFN_xrCreateVulkanInstanceKHR xrCreateVulkanInstanceKHR_ptr = nullptr; -PFN_xrGetVulkanGraphicsDevice2KHR xrGetVulkanGraphicsDevice2KHR_ptr = nullptr; -PFN_xrCreateVulkanDeviceKHR xrCreateVulkanDeviceKHR_ptr = nullptr; - OpenXRVulkanExtension::OpenXRVulkanExtension(OpenXRAPI *p_openxr_api) : OpenXRGraphicsExtensionWrapper(p_openxr_api) { VulkanContext::set_vulkan_hooks(this); @@ -69,36 +51,15 @@ OpenXRVulkanExtension::~OpenXRVulkanExtension() { } void OpenXRVulkanExtension::on_instance_created(const XrInstance p_instance) { - XrResult result; - ERR_FAIL_NULL(openxr_api); // Obtain pointers to functions we're accessing here, they are (not yet) part of core. - result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsRequirements2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsRequirements2KHR_ptr); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to xrGetVulkanGraphicsRequirements2KHR entry point [", openxr_api->get_error_string(result), "]"); - } - result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanInstanceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanInstanceKHR_ptr); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to xrCreateVulkanInstanceKHR entry point [", openxr_api->get_error_string(result), "]"); - } - - result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsDevice2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsDevice2KHR_ptr); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to xrGetVulkanGraphicsDevice2KHR entry point [", openxr_api->get_error_string(result), "]"); - } - - result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanDeviceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanDeviceKHR_ptr); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to xrCreateVulkanDeviceKHR entry point [", openxr_api->get_error_string(result), "]"); - } -} - -XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements) { - ERR_FAIL_NULL_V(xrGetVulkanGraphicsRequirements2KHR_ptr, XR_ERROR_HANDLE_INVALID); - - return (*xrGetVulkanGraphicsRequirements2KHR_ptr)(p_instance, p_system_id, p_graphics_requirements); + EXT_INIT_XR_FUNC(xrGetVulkanGraphicsRequirements2KHR); + EXT_INIT_XR_FUNC(xrCreateVulkanInstanceKHR); + EXT_INIT_XR_FUNC(xrGetVulkanGraphicsDevice2KHR); + EXT_INIT_XR_FUNC(xrCreateVulkanDeviceKHR); + EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages); } bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_version) { @@ -141,12 +102,6 @@ bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_versi return true; } -XrResult OpenXRVulkanExtension::xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result) { - ERR_FAIL_NULL_V(xrCreateVulkanInstanceKHR_ptr, XR_ERROR_HANDLE_INVALID); - - return (*xrCreateVulkanInstanceKHR_ptr)(p_instance, p_create_info, r_vulkan_instance, r_vulkan_result); -} - bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) { // get the vulkan version we are creating uint32_t vulkan_version = p_vulkan_create_info->pApplicationInfo->apiVersion; @@ -195,12 +150,6 @@ bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p return true; } -XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device) { - ERR_FAIL_NULL_V(xrGetVulkanGraphicsDevice2KHR_ptr, XR_ERROR_HANDLE_INVALID); - - return (*xrGetVulkanGraphicsDevice2KHR_ptr)(p_instance, p_get_info, r_vulkan_physical_device); -} - bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) { ERR_FAIL_NULL_V(openxr_api, false); @@ -222,12 +171,6 @@ bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) { return true; } -XrResult OpenXRVulkanExtension::xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result) { - ERR_FAIL_NULL_V(xrCreateVulkanDeviceKHR_ptr, XR_ERROR_HANDLE_INVALID); - - return (*xrCreateVulkanDeviceKHR_ptr)(p_instance, p_create_info, r_device, r_result); -} - bool OpenXRVulkanExtension::create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) { ERR_FAIL_NULL_V(openxr_api, false); diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h index 5dddc4b9c9..d6e9917900 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.h +++ b/modules/openxr/extensions/openxr_vulkan_extension.h @@ -36,16 +36,25 @@ #include "drivers/vulkan/vulkan_context.h" -// Forward declare these so we don't need OpenXR headers where-ever this is included -// Including OpenXR at this point gives loads and loads of compile issues especially -// on Windows because windows.h is EVIL and really shouldn't be included outside of platform -// but we really don't have a choice in the matter +#include "../openxr_api.h" +#include "../util.h" -struct XrGraphicsRequirementsVulkanKHR; -struct XrVulkanInstanceCreateInfoKHR; -struct XrVulkanGraphicsDeviceGetInfoKHR; -struct XrVulkanDeviceCreateInfoKHR; -struct XrGraphicsBindingVulkanKHR; +// need to include Vulkan so we know of type definitions +#define XR_USE_GRAPHICS_API_VULKAN + +#ifdef WINDOWS_ENABLED +// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform +// however due to the way the openxr headers are put together, we have no choice. +#include <windows.h> +#endif + +#ifdef ANDROID_ENABLED +// The jobject type from jni.h is used by openxr_platform.h on Android. +#include <jni.h> +#endif + +// include platform dependent structs +#include <openxr/openxr_platform.h> class OpenXRVulkanExtension : public OpenXRGraphicsExtensionWrapper, VulkanHooks { public: @@ -84,10 +93,11 @@ private: uint32_t vulkan_queue_family_index = 0; uint32_t vulkan_queue_index = 0; - XrResult xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements); - XrResult xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result); - XrResult xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device); - XrResult xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result); + EXT_PROTO_XRRESULT_FUNC3(xrGetVulkanGraphicsRequirements2KHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsVulkanKHR *), p_graphics_requirements) + EXT_PROTO_XRRESULT_FUNC4(xrCreateVulkanInstanceKHR, (XrInstance), p_instance, (const XrVulkanInstanceCreateInfoKHR *), p_create_info, (VkInstance *), r_vulkan_instance, (VkResult *), r_vulkan_result) + EXT_PROTO_XRRESULT_FUNC3(xrGetVulkanGraphicsDevice2KHR, (XrInstance), p_instance, (const XrVulkanGraphicsDeviceGetInfoKHR *), p_get_info, (VkPhysicalDevice *), r_vulkan_physical_device) + EXT_PROTO_XRRESULT_FUNC4(xrCreateVulkanDeviceKHR, (XrInstance), p_instance, (const XrVulkanDeviceCreateInfoKHR *), p_create_info, (VkDevice *), r_device, (VkResult *), r_result) + EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images) }; #endif // OPENXR_VULKAN_EXTENSION_H diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 94095eb61c..76f7b2a60a 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -41,6 +41,7 @@ #endif #ifdef ANDROID_ENABLED +#define OPENXR_LOADER_NAME "libopenxr_loader.so" #include "extensions/openxr_android_extension.h" #endif @@ -284,6 +285,9 @@ bool OpenXRAPI::create_instance() { 0, // runtimeVersion, from here will be set by our get call "" // runtimeName }; + + OPENXR_API_INIT_XR_FUNC_V(xrGetInstanceProperties); + result = xrGetInstanceProperties(instance, &instanceProps); if (XR_FAILED(result)) { // not fatal probably @@ -992,9 +996,94 @@ bool OpenXRAPI::is_running() { return running; } +bool OpenXRAPI::openxr_loader_init() { +#ifdef ANDROID_ENABLED + ERR_FAIL_COND_V_MSG(openxr_loader_library_handle != nullptr, false, "OpenXR Loader library is already loaded."); + + { + Error error_code = OS::get_singleton()->open_dynamic_library(OPENXR_LOADER_NAME, openxr_loader_library_handle); + ERR_FAIL_COND_V_MSG(error_code != OK, false, "OpenXR loader not found."); + } + + { + Error error_code = OS::get_singleton()->get_dynamic_library_symbol_handle(openxr_loader_library_handle, "xrGetInstanceProcAddr", (void *&)xrGetInstanceProcAddr); + ERR_FAIL_COND_V_MSG(error_code != OK, false, "Symbol xrGetInstanceProcAddr not found in OpenXR Loader library."); + } +#endif + + // Resolve the symbols that don't require an instance + OPENXR_API_INIT_XR_FUNC_V(xrCreateInstance); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateApiLayerProperties); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateInstanceExtensionProperties); + + return true; +} + +bool OpenXRAPI::resolve_instance_openxr_symbols() { + ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false); + + OPENXR_API_INIT_XR_FUNC_V(xrAcquireSwapchainImage); + OPENXR_API_INIT_XR_FUNC_V(xrApplyHapticFeedback); + OPENXR_API_INIT_XR_FUNC_V(xrAttachSessionActionSets); + OPENXR_API_INIT_XR_FUNC_V(xrBeginFrame); + OPENXR_API_INIT_XR_FUNC_V(xrBeginSession); + OPENXR_API_INIT_XR_FUNC_V(xrCreateAction); + OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSet); + OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSpace); + OPENXR_API_INIT_XR_FUNC_V(xrCreateReferenceSpace); + OPENXR_API_INIT_XR_FUNC_V(xrCreateSession); + OPENXR_API_INIT_XR_FUNC_V(xrCreateSwapchain); + OPENXR_API_INIT_XR_FUNC_V(xrDestroyAction); + OPENXR_API_INIT_XR_FUNC_V(xrDestroyActionSet); + OPENXR_API_INIT_XR_FUNC_V(xrDestroyInstance); + OPENXR_API_INIT_XR_FUNC_V(xrDestroySession); + OPENXR_API_INIT_XR_FUNC_V(xrDestroySpace); + OPENXR_API_INIT_XR_FUNC_V(xrDestroySwapchain); + OPENXR_API_INIT_XR_FUNC_V(xrEndFrame); + OPENXR_API_INIT_XR_FUNC_V(xrEndSession); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateReferenceSpaces); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateSwapchainFormats); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurations); + OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurationViews); + OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateBoolean); + OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateFloat); + OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateVector2f); + OPENXR_API_INIT_XR_FUNC_V(xrGetCurrentInteractionProfile); + OPENXR_API_INIT_XR_FUNC_V(xrGetSystem); + OPENXR_API_INIT_XR_FUNC_V(xrGetSystemProperties); + OPENXR_API_INIT_XR_FUNC_V(xrLocateViews); + OPENXR_API_INIT_XR_FUNC_V(xrLocateSpace); + OPENXR_API_INIT_XR_FUNC_V(xrPathToString); + OPENXR_API_INIT_XR_FUNC_V(xrPollEvent); + OPENXR_API_INIT_XR_FUNC_V(xrReleaseSwapchainImage); + OPENXR_API_INIT_XR_FUNC_V(xrResultToString); + OPENXR_API_INIT_XR_FUNC_V(xrStringToPath); + OPENXR_API_INIT_XR_FUNC_V(xrSuggestInteractionProfileBindings); + OPENXR_API_INIT_XR_FUNC_V(xrSyncActions); + OPENXR_API_INIT_XR_FUNC_V(xrWaitFrame); + OPENXR_API_INIT_XR_FUNC_V(xrWaitSwapchainImage); + + return true; +} + +XrResult OpenXRAPI::get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) { + XrResult result = xrGetInstanceProcAddr(instance, p_name, p_addr); + + if (result != XR_SUCCESS) { + String error_message = String("Symbol ") + p_name + " not found in OpenXR instance."; + ERR_FAIL_COND_V_MSG(true, result, error_message.utf8().get_data()); + } + + return result; +} + bool OpenXRAPI::initialize(const String &p_rendering_driver) { ERR_FAIL_COND_V_MSG(instance != XR_NULL_HANDLE, false, "OpenXR instance was already created"); + if (!openxr_loader_init()) { + return false; + } + if (p_rendering_driver == "vulkan") { #ifdef VULKAN_ENABLED graphics_extension = memnew(OpenXRVulkanExtension(this)); @@ -1017,6 +1106,10 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) { } // initialize + for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { + wrapper->on_before_instance_created(); + } + if (!load_layer_properties()) { destroy_instance(); return false; @@ -1032,6 +1125,11 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) { return false; } + if (!resolve_instance_openxr_symbols()) { + destroy_instance(); + return false; + } + if (!get_system_info()) { destroy_instance(); return false; @@ -1669,6 +1767,13 @@ OpenXRAPI::~OpenXRAPI() { layer_properties = nullptr; } +#ifdef ANDROID_ENABLED + if (openxr_loader_library_handle) { + OS::get_singleton()->close_dynamic_library(openxr_loader_library_handle); + openxr_loader_library_handle = nullptr; + } +#endif + singleton = nullptr; } diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index dc224c4237..4f84cc3b5b 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -50,6 +50,8 @@ #include "extensions/openxr_composition_layer_provider.h" #include "extensions/openxr_extension_wrapper.h" +#include "util.h" + // Note, OpenXR code that we wrote for our plugin makes use of C++20 notation for initialising structs which ensures zeroing out unspecified members. // Godot is currently restricted to C++17 which doesn't allow this notation. Make sure critical fields are set. @@ -134,6 +136,61 @@ private: bool load_supported_extensions(); bool is_extension_supported(const String &p_extension) const; + bool openxr_loader_init(); + bool resolve_instance_openxr_symbols(); + + void *openxr_loader_library_handle = nullptr; + + // function pointers +#ifdef ANDROID_ENABLED + // On non-Android platforms we use the OpenXR symbol linked into the engine binary. + PFN_xrGetInstanceProcAddr xrGetInstanceProcAddr = nullptr; +#endif + EXT_PROTO_XRRESULT_FUNC3(xrAcquireSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageAcquireInfo *), acquireInfo, (uint32_t *), index) + EXT_PROTO_XRRESULT_FUNC3(xrApplyHapticFeedback, (XrSession), session, (const XrHapticActionInfo *), hapticActionInfo, (const XrHapticBaseHeader *), hapticFeedback) + EXT_PROTO_XRRESULT_FUNC2(xrAttachSessionActionSets, (XrSession), session, (const XrSessionActionSetsAttachInfo *), attachInfo) + EXT_PROTO_XRRESULT_FUNC2(xrBeginFrame, (XrSession), session, (const XrFrameBeginInfo *), frameBeginInfo) + EXT_PROTO_XRRESULT_FUNC2(xrBeginSession, (XrSession), session, (const XrSessionBeginInfo *), beginInfo) + EXT_PROTO_XRRESULT_FUNC3(xrCreateAction, (XrActionSet), actionSet, (const XrActionCreateInfo *), createInfo, (XrAction *), action) + EXT_PROTO_XRRESULT_FUNC3(xrCreateActionSet, (XrInstance), instance, (const XrActionSetCreateInfo *), createInfo, (XrActionSet *), actionSet) + EXT_PROTO_XRRESULT_FUNC3(xrCreateActionSpace, (XrSession), session, (const XrActionSpaceCreateInfo *), createInfo, (XrSpace *), space) + EXT_PROTO_XRRESULT_FUNC2(xrCreateInstance, (const XrInstanceCreateInfo *), createInfo, (XrInstance *), instance) + EXT_PROTO_XRRESULT_FUNC3(xrCreateReferenceSpace, (XrSession), session, (const XrReferenceSpaceCreateInfo *), createInfo, (XrSpace *), space) + EXT_PROTO_XRRESULT_FUNC3(xrCreateSession, (XrInstance), instance, (const XrSessionCreateInfo *), createInfo, (XrSession *), session) + EXT_PROTO_XRRESULT_FUNC3(xrCreateSwapchain, (XrSession), session, (const XrSwapchainCreateInfo *), createInfo, (XrSwapchain *), swapchain) + EXT_PROTO_XRRESULT_FUNC1(xrDestroyAction, (XrAction), action) + EXT_PROTO_XRRESULT_FUNC1(xrDestroyActionSet, (XrActionSet), actionSet) + EXT_PROTO_XRRESULT_FUNC1(xrDestroyInstance, (XrInstance), instance) + EXT_PROTO_XRRESULT_FUNC1(xrDestroySession, (XrSession), session) + EXT_PROTO_XRRESULT_FUNC1(xrDestroySpace, (XrSpace), space) + EXT_PROTO_XRRESULT_FUNC1(xrDestroySwapchain, (XrSwapchain), swapchain) + EXT_PROTO_XRRESULT_FUNC2(xrEndFrame, (XrSession), session, (const XrFrameEndInfo *), frameEndInfo) + EXT_PROTO_XRRESULT_FUNC1(xrEndSession, (XrSession), session) + EXT_PROTO_XRRESULT_FUNC3(xrEnumerateApiLayerProperties, (uint32_t), propertyCapacityInput, (uint32_t *), propertyCountOutput, (XrApiLayerProperties *), properties) + EXT_PROTO_XRRESULT_FUNC4(xrEnumerateInstanceExtensionProperties, (const char *), layerName, (uint32_t), propertyCapacityInput, (uint32_t *), propertyCountOutput, (XrExtensionProperties *), properties) + EXT_PROTO_XRRESULT_FUNC4(xrEnumerateReferenceSpaces, (XrSession), session, (uint32_t), spaceCapacityInput, (uint32_t *), spaceCountOutput, (XrReferenceSpaceType *), spaces) + EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainFormats, (XrSession), session, (uint32_t), formatCapacityInput, (uint32_t *), formatCountOutput, (int64_t *), formats) + EXT_PROTO_XRRESULT_FUNC5(xrEnumerateViewConfigurations, (XrInstance), instance, (XrSystemId), systemId, (uint32_t), viewConfigurationTypeCapacityInput, (uint32_t *), viewConfigurationTypeCountOutput, (XrViewConfigurationType *), viewConfigurationTypes) + EXT_PROTO_XRRESULT_FUNC6(xrEnumerateViewConfigurationViews, (XrInstance), instance, (XrSystemId), systemId, (XrViewConfigurationType), viewConfigurationType, (uint32_t), viewCapacityInput, (uint32_t *), viewCountOutput, (XrViewConfigurationView *), views) + EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateBoolean, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateBoolean *), state) + EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateFloat, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateFloat *), state) + EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateVector2f, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateVector2f *), state) + EXT_PROTO_XRRESULT_FUNC3(xrGetCurrentInteractionProfile, (XrSession), session, (XrPath), topLevelUserPath, (XrInteractionProfileState *), interactionProfile) + EXT_PROTO_XRRESULT_FUNC2(xrGetInstanceProperties, (XrInstance), instance, (XrInstanceProperties *), instanceProperties) + EXT_PROTO_XRRESULT_FUNC3(xrGetSystem, (XrInstance), instance, (const XrSystemGetInfo *), getInfo, (XrSystemId *), systemId) + EXT_PROTO_XRRESULT_FUNC3(xrGetSystemProperties, (XrInstance), instance, (XrSystemId), systemId, (XrSystemProperties *), properties) + EXT_PROTO_XRRESULT_FUNC4(xrLocateSpace, (XrSpace), space, (XrSpace), baseSpace, (XrTime), time, (XrSpaceLocation *), location) + EXT_PROTO_XRRESULT_FUNC6(xrLocateViews, (XrSession), session, (const XrViewLocateInfo *), viewLocateInfo, (XrViewState *), viewState, (uint32_t), viewCapacityInput, (uint32_t *), viewCountOutput, (XrView *), views) + EXT_PROTO_XRRESULT_FUNC5(xrPathToString, (XrInstance), instance, (XrPath), path, (uint32_t), bufferCapacityInput, (uint32_t *), bufferCountOutput, (char *), buffer) + EXT_PROTO_XRRESULT_FUNC2(xrPollEvent, (XrInstance), instance, (XrEventDataBuffer *), eventData) + EXT_PROTO_XRRESULT_FUNC2(xrReleaseSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageReleaseInfo *), releaseInfo) + EXT_PROTO_XRRESULT_FUNC3(xrResultToString, (XrInstance), instance, (XrResult), value, (char *), buffer) + EXT_PROTO_XRRESULT_FUNC3(xrStringToPath, (XrInstance), instance, (const char *), pathString, (XrPath *), path) + EXT_PROTO_XRRESULT_FUNC2(xrSuggestInteractionProfileBindings, (XrInstance), instance, (const XrInteractionProfileSuggestedBinding *), suggestedBindings) + EXT_PROTO_XRRESULT_FUNC2(xrSyncActions, (XrSession), session, (const XrActionsSyncInfo *), syncInfo) + EXT_PROTO_XRRESULT_FUNC3(xrWaitFrame, (XrSession), session, (const XrFrameWaitInfo *), frameWaitInfo, (XrFrameState *), frameState) + EXT_PROTO_XRRESULT_FUNC2(xrWaitSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageWaitInfo *), waitInfo) + // instance bool create_instance(); bool get_system_info(); @@ -231,6 +288,7 @@ public: static bool openxr_is_enabled(bool p_check_run_in_editor = true); static OpenXRAPI *get_singleton(); + XrResult get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr); String get_error_string(XrResult result); String get_swapchain_format_name(int64_t p_swapchain_format) const; diff --git a/modules/openxr/util.h b/modules/openxr/util.h new file mode 100644 index 0000000000..5c79890830 --- /dev/null +++ b/modules/openxr/util.h @@ -0,0 +1,110 @@ +/*************************************************************************/ +/* util.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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 UTIL_H +#define UTIL_H + +#define UNPACK(...) __VA_ARGS__ + +#define INIT_XR_FUNC_V(openxr_api, name) \ + do { \ + XrResult get_instance_proc_addr_result; \ + get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \ + ERR_FAIL_COND_V(XR_FAILED(get_instance_proc_addr_result), false); \ + } while (0) + +#define EXT_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(openxr_api, name) +#define OPENXR_API_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(this, name) + +#define INIT_XR_FUNC(openxr_api, name) \ + do { \ + XrResult get_instance_proc_addr_result; \ + get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \ + ERR_FAIL_COND(XR_FAILED(get_instance_proc_addr_result)); \ + } while (0) + +#define EXT_INIT_XR_FUNC(name) INIT_XR_FUNC(openxr_api, name) +#define OPENXR_API_INIT_XR_FUNC(name) INIT_XR_FUNC(this, name) + +#define EXT_PROTO_XRRESULT_FUNC1(func_name, arg1_type, arg1) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1); \ + } + +#define EXT_PROTO_XRRESULT_FUNC2(func_name, arg1_type, arg1, arg2_type, arg2) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1, arg2); \ + } + +#define EXT_PROTO_XRRESULT_FUNC3(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1, arg2, arg3); \ + } + +#define EXT_PROTO_XRRESULT_FUNC4(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1, arg2, arg3, arg4); \ + } + +#define EXT_PROTO_XRRESULT_FUNC5(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4, arg5_type, arg5) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4, UNPACK arg5_type arg5) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1, arg2, arg3, arg4, arg5); \ + } + +#define EXT_PROTO_XRRESULT_FUNC6(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4, arg5_type, arg5, arg6_type, arg6) \ + PFN_##func_name func_name##_ptr = nullptr; \ + XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4, UNPACK arg5_type arg5, UNPACK arg6_type arg6) const { \ + if (!func_name##_ptr) { \ + return XR_ERROR_HANDLE_INVALID; \ + } \ + return (*func_name##_ptr)(arg1, arg2, arg3, arg4, arg5, arg6); \ + } + +#endif // UTIL_H diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub index 074795759a..0670c7f468 100644 --- a/modules/raycast/SCsub +++ b/modules/raycast/SCsub @@ -63,7 +63,8 @@ if env["builtin_embree"]: thirdparty_sources = [thirdparty_dir + file for file in embree_src] env_raycast.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "include"]) - env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"]) + env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL"]) + env_raycast.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds. if not env.msvc: if env["arch"] == "x86_64": diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster_embree.cpp index 9b35b5616e..e6a579bd3a 100644 --- a/modules/raycast/lightmap_raycaster.cpp +++ b/modules/raycast/lightmap_raycaster_embree.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lightmap_raycaster.cpp */ +/* lightmap_raycaster_embree.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,7 +30,7 @@ #ifdef TOOLS_ENABLED -#include "lightmap_raycaster.h" +#include "lightmap_raycaster_embree.h" #ifdef __SSE2__ #include <pmmintrin.h> @@ -193,4 +193,4 @@ LightmapRaycasterEmbree::~LightmapRaycasterEmbree() { } } -#endif +#endif // TOOLS_ENABLED diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster_embree.h index 2e9f59dda4..0c3371f07c 100644 --- a/modules/raycast/lightmap_raycaster.h +++ b/modules/raycast/lightmap_raycaster_embree.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lightmap_raycaster.h */ +/* lightmap_raycaster_embree.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef LIGHTMAP_RAYCASTER_EMBREE_H +#define LIGHTMAP_RAYCASTER_EMBREE_H + #ifdef TOOLS_ENABLED #include "core/io/image.h" @@ -74,4 +77,6 @@ public: ~LightmapRaycasterEmbree(); }; -#endif // LIGHTMAP_RAYCASTER_H +#endif // TOOLS_ENABLED + +#endif // LIGHTMAP_RAYCASTER_EMBREE_H diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp index 42de1d971d..a8380b00ba 100644 --- a/modules/raycast/register_types.cpp +++ b/modules/raycast/register_types.cpp @@ -30,9 +30,9 @@ #include "register_types.h" -#include "lightmap_raycaster.h" +#include "lightmap_raycaster_embree.h" #include "raycast_occlusion_cull.h" -#include "static_raycaster.h" +#include "static_raycaster_embree.h" RaycastOcclusionCull *raycast_occlusion_cull = nullptr; diff --git a/modules/raycast/register_types.h b/modules/raycast/register_types.h index a917285390..25a6c346b9 100644 --- a/modules/raycast/register_types.h +++ b/modules/raycast/register_types.h @@ -28,7 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef RAYCAST_REGISTER_TYPES_H +#define RAYCAST_REGISTER_TYPES_H + #include "modules/register_module_types.h" void initialize_raycast_module(ModuleInitializationLevel p_level); void uninitialize_raycast_module(ModuleInitializationLevel p_level); + +#endif // RAYCAST_REGISTER_TYPES_H diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster_embree.cpp index 7659eea27f..b5a4ab42d4 100644 --- a/modules/raycast/static_raycaster.cpp +++ b/modules/raycast/static_raycaster_embree.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* static_raycaster.cpp */ +/* static_raycaster_embree.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -30,7 +30,7 @@ #ifdef TOOLS_ENABLED -#include "static_raycaster.h" +#include "static_raycaster_embree.h" #ifdef __SSE2__ #include <pmmintrin.h> @@ -134,4 +134,4 @@ StaticRaycasterEmbree::~StaticRaycasterEmbree() { } } -#endif +#endif // TOOLS_ENABLED diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster_embree.h index 607a392683..4d631e3ca0 100644 --- a/modules/raycast/static_raycaster.h +++ b/modules/raycast/static_raycaster_embree.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* static_raycaster.h */ +/* static_raycaster_embree.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef STATIC_RAYCASTER_EMBREE_H +#define STATIC_RAYCASTER_EMBREE_H + #ifdef TOOLS_ENABLED #include "core/math/static_raycaster.h" @@ -61,4 +64,6 @@ public: ~StaticRaycasterEmbree(); }; -#endif // STATIC_RAYCASTER_H +#endif // TOOLS_ENABLED + +#endif // STATIC_RAYCASTER_EMBREE_H diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index c97a6ef289..1a4831857f 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -5430,7 +5430,10 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) { Array fonts_scr_only; Array fonts_no_match; int font_count = span.fonts.size(); - for (int l = 0; l < font_count; l++) { + if (font_count > 0) { + fonts.push_back(sd->spans[k].fonts[0]); + } + for (int l = 1; l < font_count; l++) { if (font_is_script_supported(span.fonts[l], script)) { if (font_is_language_supported(span.fonts[l], span.language)) { fonts.push_back(sd->spans[k].fonts[l]); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 7bed22fbb1..9ef0f0ad82 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -2844,7 +2844,10 @@ bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const Strin // Pre-sort fonts, push fonts with the language support first. Array fonts_no_match; int font_count = p_fonts.size(); - for (int i = 0; i < font_count; i++) { + if (font_count > 0) { + span.fonts.push_back(p_fonts[0]); + } + for (int i = 1; i < font_count; i++) { if (font_is_language_supported(p_fonts[i], p_language)) { span.fonts.push_back(p_fonts[i]); } else { diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 00ba32eae1..aed95294e7 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -100,7 +100,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff uint32_t width = p_header.image_width; uint32_t height = p_header.image_height; tga_origin_e origin = static_cast<tga_origin_e>((p_header.image_descriptor & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT); - + uint8_t alpha_bits = p_header.image_descriptor & TGA_IMAGE_DESCRIPTOR_ALPHA_MASK; uint32_t x_start; int32_t x_step; uint32_t x_end; @@ -184,6 +184,27 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff y += y_step; } } + } else if (p_header.pixel_depth == 16) { + while (y != y_end) { + while (x != x_end) { + if (i + 1 >= p_input_size) { + return ERR_PARSE_ERROR; + } + + // Always stored as RGBA5551 + uint8_t r = (p_buffer[i + 1] & 0x7c) << 1; + uint8_t g = ((p_buffer[i + 1] & 0x03) << 6) | ((p_buffer[i + 0] & 0xe0) >> 2); + uint8_t b = (p_buffer[i + 0] & 0x1f) << 3; + uint8_t a = (p_buffer[i + 1] & 0x80) ? 0xff : 0; + + TGA_PUT_PIXEL(r, g, b, alpha_bits ? a : 0xff); + + x += x_step; + i += 2; + } + x = x_start; + y += y_step; + } } else if (p_header.pixel_depth == 24) { while (y != y_end) { while (x != x_end) { @@ -277,7 +298,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField err = FAILED; } - if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) { + if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 16 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) { err = FAILED; } diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index b257ed110d..de964373ed 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -33,6 +33,8 @@ #include "core/io/image_loader.h" +#define TGA_IMAGE_DESCRIPTOR_ALPHA_MASK 0xf + class ImageLoaderTGA : public ImageFormatLoader { enum tga_type_e { TGA_TYPE_NO_DATA = 0, diff --git a/platform/android/detect.py b/platform/android/detect.py index f36e7e2a7f..2ff9cd3dc5 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -124,12 +124,9 @@ def configure(env): env.Append(CCFLAGS=[opt]) elif env["optimize"] == "size": # optimize for size env.Append(CCFLAGS=["-Oz"]) - env.Append(CPPDEFINES=["NDEBUG"]) elif env["target"] == "debug": env.Append(LINKFLAGS=["-O0"]) - env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"]) - env.Append(CPPDEFINES=["_DEBUG"]) - env.Append(CPPFLAGS=["-UNDEBUG"]) + env.Append(CCFLAGS=["-O0", "-g"]) # LTO diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 9a1a877b6f..24995147d4 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -28,9 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// note, swapped java and godot around in the file name so all the java -// wrappers are together - #ifndef JAVA_GODOT_IO_WRAPPER_H #define JAVA_GODOT_IO_WRAPPER_H diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index a6c7853107..0e96a4e1f3 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -28,9 +28,6 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// note, swapped java and godot around in the file name so all the java -// wrappers are together - #ifndef JAVA_GODOT_WRAPPER_H #define JAVA_GODOT_WRAPPER_H diff --git a/platform/ios/detect.py b/platform/ios/detect.py index cb863e266d..0f277d6b3a 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -55,7 +55,7 @@ def configure(env): ## Build type if env["target"].startswith("release"): - env.Append(CPPDEFINES=["NDEBUG", ("NS_BLOCK_ASSERTIONS", 1)]) + env.Append(CPPDEFINES=[("NS_BLOCK_ASSERTIONS", 1)]) if env["optimize"] == "speed": # optimize for speed (default) # `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces # when using `target=release_debug`. @@ -67,8 +67,7 @@ def configure(env): env.Append(LINKFLAGS=["-Os"]) elif env["target"] == "debug": - env.Append(CCFLAGS=["-gdwarf-2", "-O0"]) - env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1)]) + env.Append(CCFLAGS=["-g", "-O0"]) ## LTO diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h index 00d91da771..400040875f 100644 --- a/platform/ios/os_ios.h +++ b/platform/ios/os_ios.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef IOS_ENABLED - #ifndef OS_IOS_H #define OS_IOS_H +#ifdef IOS_ENABLED + #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" #include "ios.h" @@ -124,6 +124,6 @@ public: void on_focus_in(); }; -#endif // OS_IOS_H +#endif // IOS_ENABLED #endif // OS_IOS_H diff --git a/platform/linuxbsd/detect_prime_x11.h b/platform/linuxbsd/detect_prime_x11.h index 21ebaead32..7eb7064cc5 100644 --- a/platform/linuxbsd/detect_prime_x11.h +++ b/platform/linuxbsd/detect_prime_x11.h @@ -28,11 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef X11_ENABLED -#if defined(GLES3_ENABLED) +#ifndef DETECT_PRIME_X11_H +#define DETECT_PRIME_X11_H + +#if defined(X11_ENABLED) && defined(GLES3_ENABLED) int detect_prime(); -#endif +#endif // X11_ENABLED && GLES3_ENABLED #endif // DETECT_PRIME_X11_H diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index a27e0d5efa..e72273a681 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -179,6 +179,12 @@ private: IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID; + struct MenuCall { + Variant tag; + Callable callback; + }; + Vector<MenuCall> deferred_menu_calls; + const NSMenu *_get_menu_root(const String &p_menu_root) const; NSMenu *_get_menu_root(const String &p_menu_root); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 34723c7d4b..1914c5f35d 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -565,11 +565,11 @@ void DisplayServerMacOS::menu_callback(id p_sender) { } if (value->callback != Callable()) { - Variant tag = value->meta; - Variant *tagp = &tag; - Variant ret; - Callable::CallError ce; - value->callback.callp((const Variant **)&tagp, 1, ret, ce); + MenuCall mc; + mc.tag = value->meta; + mc.callback = value->callback; + deferred_menu_calls.push_back(mc); + // Do not run callback from here! If it is opening a new window or calling process_events, it will corrupt OS event queue and crash. } } } @@ -3280,6 +3280,16 @@ void DisplayServerMacOS::process_events() { [NSApp sendEvent:event]; } + // Process "menu_callback"s. + for (MenuCall &E : deferred_menu_calls) { + Variant tag = E.tag; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + E.callback.callp((const Variant **)&tagp, 1, ret, ce); + } + deferred_menu_calls.clear(); + if (!drop_events) { _process_key_events(); Input::get_singleton()->flush_buffered_events(); diff --git a/platform/macos/export/codesign.h b/platform/macos/export/codesign.h index fea7b117d0..01e97bca81 100644 --- a/platform/macos/export/codesign.h +++ b/platform/macos/export/codesign.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef MACOS_CODESIGN_H +#define MACOS_CODESIGN_H + // macOS code signature creation utility. // // Current implementation has the following limitation: @@ -38,9 +41,6 @@ // - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported). // - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only. -#ifndef MACOS_CODESIGN_H -#define MACOS_CODESIGN_H - #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" diff --git a/platform/macos/export/lipo.h b/platform/macos/export/lipo.h index 516ef99860..6378f9899c 100644 --- a/platform/macos/export/lipo.h +++ b/platform/macos/export/lipo.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Universal / Universal 2 fat binary file creator and extractor. - #ifndef MACOS_LIPO_H #define MACOS_LIPO_H +// Universal / Universal 2 fat binary file creator and extractor. + #include "core/io/file_access.h" #include "core/object/ref_counted.h" #include "modules/modules_enabled.gen.h" // For regex. diff --git a/platform/macos/export/macho.h b/platform/macos/export/macho.h index 7ef0d9067e..0d42a7013f 100644 --- a/platform/macos/export/macho.h +++ b/platform/macos/export/macho.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Mach-O binary object file format parser and editor. - #ifndef MACOS_MACHO_H #define MACOS_MACHO_H +// Mach-O binary object file format parser and editor. + #include "core/crypto/crypto.h" #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" diff --git a/platform/macos/export/plist.h b/platform/macos/export/plist.h index 79cb928d0a..b3c51a9635 100644 --- a/platform/macos/export/plist.h +++ b/platform/macos/export/plist.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Property list file format (application/x-plist) parser, property list ASN-1 serialization. - #ifndef MACOS_PLIST_H #define MACOS_PLIST_H +// Property list file format (application/x-plist) parser, property list ASN-1 serialization. + #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" #include "modules/modules_enabled.gen.h" // For regex. diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 52a959b34a..095d688213 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -350,7 +350,6 @@ def configure_msvc(env, vcvars_msvc_config): elif env["target"] == "debug": env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"]) - # Allow big objects. Only needed for debug, see MinGW branch for rationale. env.Append(LINKFLAGS=["/DEBUG"]) if env["debug_symbols"]: diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 46cb5473da..b9e6f7b843 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3352,7 +3352,7 @@ void DisplayServerWindows::_process_key_events() { k->set_ctrl_pressed(ke.control); k->set_meta_pressed(ke.meta); k->set_pressed(true); - k->set_keycode((Key)KeyMappingWindows::get_keysym(ke.wParam)); + k->set_keycode((Key)KeyMappingWindows::get_keysym(MapVirtualKey((ke.lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK))); k->set_physical_keycode((Key)(KeyMappingWindows::get_scansym((ke.lParam >> 16) & 0xFF, ke.lParam & (1 << 24)))); k->set_unicode(unicode); if (k->get_unicode() && gr_mem) { diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 49a59de9b2..facffb99ee 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "animation_node_state_machine.h" +#include "scene/main/window.h" ///////////////////////////////////////////////// @@ -169,7 +170,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ADD_GROUP("Advance", "advance_"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "advance_expression", PROPERTY_HINT_EXPRESSION, ""), "set_advance_expression", "get_advance_expression"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node"), "set_advance_expression_base_node", "get_advance_expression_base_node"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "advance_expression_base_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node"), "set_advance_expression_base_node", "get_advance_expression_base_node"); ADD_GROUP("Disabling", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); @@ -656,13 +657,15 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima ERR_FAIL_COND_V(tree_base == nullptr, false); NodePath advance_expression_base_node_path; - if (!transition->advance_expression_base_node.is_empty()) { - advance_expression_base_node_path = transition->advance_expression_base_node; + Node *expression_base = nullptr; + if (!transition->get_advance_expression_base_node().is_empty()) { + advance_expression_base_node_path = transition->get_advance_expression_base_node(); + expression_base = tree_base->get_tree()->get_root()->get_child(0)->get_node_or_null(advance_expression_base_node_path); } else { advance_expression_base_node_path = tree_base->get_advance_expression_base_node(); + expression_base = tree_base->get_node_or_null(advance_expression_base_node_path); } - Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path); if (expression_base) { Ref<Expression> exp = transition->expression; bool ret = exp->execute(Array(), expression_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls. diff --git a/scene/animation/easing_equations.h b/scene/animation/easing_equations.h index 094829e406..03d9e16454 100644 --- a/scene/animation/easing_equations.h +++ b/scene/animation/easing_equations.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef EASING_EQUATIONS_H +#define EASING_EQUATIONS_H + /* * Derived from Robert Penner's easing equations: http://robertpenner.com/easing/ * @@ -52,9 +55,6 @@ * SOFTWARE. */ -#ifndef EASING_EQUATIONS_H -#define EASING_EQUATIONS_H - namespace linear { static real_t in(real_t t, real_t b, real_t c, real_t d) { return c * t / d + b; diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index f6e0e4216d..8069ab465b 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -1216,30 +1216,39 @@ bool CodeEdit::is_drawing_executing_lines_gutter() const { } void CodeEdit::_main_gutter_draw_callback(int p_line, int p_gutter, const Rect2 &p_region) { + bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT); + if (draw_breakpoints && breakpoint_icon.is_valid()) { bool hovering = p_region.has_point(get_local_mouse_pos()); bool breakpointed = is_line_breakpointed(p_line); - if (breakpointed || (hovering && !is_dragging_cursor())) { + if (breakpointed || (hovering && !is_dragging_cursor() && !shift_pressed)) { int padding = p_region.size.x / 6; Rect2 icon_region = p_region; icon_region.position += Point2(padding, padding); icon_region.size -= Point2(padding, padding) * 2; - // Darken icon when hovering & not yet breakpointed. - Color use_color = hovering && !breakpointed ? breakpoint_color.darkened(0.4) : breakpoint_color; + // Darken icon when hovering, shift not pressed & not yet breakpointed. + Color use_color = hovering && !breakpointed && !shift_pressed ? breakpoint_color.darkened(0.4) : breakpoint_color; breakpoint_icon->draw_rect(get_canvas_item(), icon_region, false, use_color); } } - if (draw_bookmarks && is_line_bookmarked(p_line) && bookmark_icon.is_valid()) { - int horizontal_padding = p_region.size.x / 2; - int vertical_padding = p_region.size.y / 4; + if (draw_bookmarks && bookmark_icon.is_valid()) { + bool hovering = p_region.has_point(get_local_mouse_pos()); + bool bookmarked = is_line_bookmarked(p_line); - Rect2 bookmark_region = p_region; - bookmark_region.position += Point2(horizontal_padding, 0); - bookmark_region.size -= Point2(horizontal_padding * 1.1, vertical_padding); - bookmark_icon->draw_rect(get_canvas_item(), bookmark_region, false, bookmark_color); + if (bookmarked || (hovering && !is_dragging_cursor() && shift_pressed)) { + int horizontal_padding = p_region.size.x / 2; + int vertical_padding = p_region.size.y / 4; + Rect2 icon_region = p_region; + icon_region.position += Point2(horizontal_padding, 0); + icon_region.size -= Point2(horizontal_padding * 1.1, vertical_padding); + + // Darken icon when hovering, shift pressed & not yet bookmarked. + Color use_color = hovering && !bookmarked && shift_pressed ? bookmark_color.darkened(0.4) : bookmark_color; + bookmark_icon->draw_rect(get_canvas_item(), icon_region, false, use_color); + } } if (draw_executing_lines && is_line_executing(p_line) && executing_line_icon.is_valid()) { @@ -2378,9 +2387,13 @@ int CodeEdit::_get_auto_brace_pair_close_at_pos(int p_line, int p_col) { /* Gutters */ void CodeEdit::_gutter_clicked(int p_line, int p_gutter) { + bool shift_pressed = Input::get_singleton()->is_key_pressed(Key::SHIFT); + if (p_gutter == main_gutter) { - if (draw_breakpoints) { + if (draw_breakpoints && !shift_pressed) { set_line_as_breakpoint(p_line, !is_line_breakpointed(p_line)); + } else if (draw_bookmarks && shift_pressed) { + set_line_as_bookmarked(p_line, !is_line_bookmarked(p_line)); } return; } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 4a1f2ab7c6..5751c54877 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -427,12 +427,15 @@ void ColorPicker::_html_submitted(const String &p_html) { return; } - float last_alpha = color.a; + Color previous_color = color; color = Color::html(p_html); if (!is_editing_alpha()) { - color.a = last_alpha; + color.a = previous_color.a; } + if (color == previous_color) { + return; + } if (!is_inside_tree()) { return; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 318447ecd8..38302136d6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1201,13 +1201,14 @@ void TextEdit::_notification(int p_what) { current_color.a = font_readonly_color.a; } } + Color gl_color = current_color; if (selection.active && line >= selection.from_line && line <= selection.to_line) { // Selection int sel_from = (line > selection.from_line) ? TS->shaped_text_get_range(rid).x : selection.from_column; int sel_to = (line < selection.to_line) ? TS->shaped_text_get_range(rid).y : selection.to_column; if (glyphs[j].start >= sel_from && glyphs[j].end <= sel_to && override_selected_font_color) { - current_color = font_selected_color; + gl_color = font_selected_color; } } @@ -1217,29 +1218,29 @@ void TextEdit::_notification(int p_what) { if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) || (caret.column == glyphs[j].start && caret.line == line && caret_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) { if (brace_open_mismatch) { - current_color = brace_mismatch_color; + gl_color = brace_mismatch_color; } Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1)); - draw_rect(rect, current_color); + draw_rect(rect, gl_color); } if ((brace_close_match_line == line && brace_close_match_column == glyphs[j].start) || (caret.column == glyphs[j].start + 1 && caret.line == line && caret_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) { if (brace_close_mismatch) { - current_color = brace_mismatch_color; + gl_color = brace_mismatch_color; } Rect2 rect = Rect2(char_pos, ofs_y + font->get_underline_position(font_size), glyphs[j].advance * glyphs[j].repeat, MAX(font->get_underline_thickness(font_size) * get_theme_default_base_scale(), 1)); - draw_rect(rect, current_color); + draw_rect(rect, gl_color); } } if (draw_tabs && ((glyphs[j].flags & TextServer::GRAPHEME_IS_TAB) == TextServer::GRAPHEME_IS_TAB)) { int yofs = (text_height - tab_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); - tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), current_color); + tab_icon->draw(ci, Point2(char_pos, ofs_y + yofs), gl_color); } else if (draw_spaces && ((glyphs[j].flags & TextServer::GRAPHEME_IS_SPACE) == TextServer::GRAPHEME_IS_SPACE)) { int yofs = (text_height - space_icon->get_height()) / 2 - ldata->get_line_ascent(line_wrap_index); int xofs = (glyphs[j].advance * glyphs[j].repeat - space_icon->get_width()) / 2; - space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), current_color); + space_icon->draw(ci, Point2(char_pos + xofs, ofs_y + yofs), gl_color); } } @@ -1247,10 +1248,10 @@ void TextEdit::_notification(int p_what) { for (int k = 0; k < glyphs[j].repeat; k++) { if (!clipped && (char_ofs + char_margin) >= xmargin_beg && (char_ofs + glyphs[j].advance + char_margin) <= xmargin_end) { if (glyphs[j].font_rid != RID()) { - TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color); + TS->font_draw_glyph(glyphs[j].font_rid, ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); had_glyphs_drawn = true; } else if ((glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) { - TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, current_color); + TS->draw_hex_code_box(ci, glyphs[j].font_size, Vector2(char_margin + char_ofs + ofs_x + glyphs[j].x_off, ofs_y + glyphs[j].y_off), glyphs[j].index, gl_color); had_glyphs_drawn = true; } } diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h index fe4741d6e5..9430e5797d 100644 --- a/scene/resources/particle_process_material.h +++ b/scene/resources/particle_process_material.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/templates/rid.h" -#include "scene/resources/material.h" - #ifndef PARTICLE_PROCESS_MATERIAL_H #define PARTICLE_PROCESS_MATERIAL_H +#include "core/templates/rid.h" +#include "scene/resources/material.h" + /* TODO: -Path following diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 65823a8f7f..ee61f0ac55 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -271,6 +271,7 @@ class QuadMesh : public PlaneMesh { public: QuadMesh() { set_orientation(FACE_Z); + set_size(Size2(1, 1)); } }; diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index fbb202d8d8..3de1a4b26f 100644 --- a/scene/resources/sky_material.h +++ b/scene/resources/sky_material.h @@ -28,12 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/templates/rid.h" -#include "scene/resources/material.h" - #ifndef SKY_MATERIAL_H #define SKY_MATERIAL_H +#include "core/templates/rid.h" +#include "scene/resources/material.h" + class ProceduralSkyMaterial : public Material { GDCLASS(ProceduralSkyMaterial, Material); diff --git a/servers/extensions/physics_server_2d_extension.cpp b/servers/extensions/physics_server_2d_extension.cpp index 769315daa7..e5920c78d4 100644 --- a/servers/extensions/physics_server_2d_extension.cpp +++ b/servers/extensions/physics_server_2d_extension.cpp @@ -189,7 +189,10 @@ void PhysicsServer2DExtension::_bind_methods() { GDVIRTUAL_BIND(_area_get_transform, "area"); GDVIRTUAL_BIND(_area_set_collision_layer, "area", "layer"); + GDVIRTUAL_BIND(_area_get_collision_layer, "area"); + GDVIRTUAL_BIND(_area_set_collision_mask, "area", "mask"); + GDVIRTUAL_BIND(_area_get_collision_mask, "area"); GDVIRTUAL_BIND(_area_set_monitorable, "area", "monitorable"); GDVIRTUAL_BIND(_area_set_pickable, "area", "pickable"); diff --git a/servers/extensions/physics_server_2d_extension.h b/servers/extensions/physics_server_2d_extension.h index a6dbe35264..573b51ee12 100644 --- a/servers/extensions/physics_server_2d_extension.h +++ b/servers/extensions/physics_server_2d_extension.h @@ -268,8 +268,11 @@ public: EXBIND2RC(Variant, area_get_param, RID, AreaParameter) EXBIND1RC(Transform2D, area_get_transform, RID) - EXBIND2(area_set_collision_mask, RID, uint32_t) EXBIND2(area_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_layer, RID) + + EXBIND2(area_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_mask, RID) EXBIND2(area_set_monitorable, RID, bool) EXBIND2(area_set_pickable, RID, bool) diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp index 4785fa33fb..27f9ed2cb3 100644 --- a/servers/extensions/physics_server_3d_extension.cpp +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -192,7 +192,10 @@ void PhysicsServer3DExtension::_bind_methods() { GDVIRTUAL_BIND(_area_get_transform, "area"); GDVIRTUAL_BIND(_area_set_collision_layer, "area", "layer"); + GDVIRTUAL_BIND(_area_get_collision_layer, "area"); + GDVIRTUAL_BIND(_area_set_collision_mask, "area", "mask"); + GDVIRTUAL_BIND(_area_get_collision_mask, "area"); GDVIRTUAL_BIND(_area_set_monitorable, "area", "monitorable"); GDVIRTUAL_BIND(_area_set_ray_pickable, "area", "enable"); diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index f1e522aca8..57f2a2d790 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -271,8 +271,11 @@ public: EXBIND2RC(Variant, area_get_param, RID, AreaParameter) EXBIND1RC(Transform3D, area_get_transform, RID) - EXBIND2(area_set_collision_mask, RID, uint32_t) EXBIND2(area_set_collision_layer, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_layer, RID) + + EXBIND2(area_set_collision_mask, RID, uint32_t) + EXBIND1RC(uint32_t, area_get_collision_mask, RID) EXBIND2(area_set_monitorable, RID, bool) EXBIND2(area_set_ray_pickable, RID, bool) diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index 11f6bd9c1e..6ce8175e6c 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -485,6 +485,20 @@ void GodotPhysicsServer2D::area_set_monitorable(RID p_area, bool p_monitorable) area->set_monitorable(p_monitorable); } +void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_layer(p_layer); +} + +uint32_t GodotPhysicsServer2D::area_get_collision_layer(RID p_area) const { + GodotArea2D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_layer(); +} + void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) { GodotArea2D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); @@ -492,11 +506,11 @@ void GodotPhysicsServer2D::area_set_collision_mask(RID p_area, uint32_t p_mask) area->set_collision_mask(p_mask); } -void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer) { +uint32_t GodotPhysicsServer2D::area_get_collision_mask(RID p_area) const { GodotArea2D *area = area_owner.get_or_null(p_area); - ERR_FAIL_COND(!area); + ERR_FAIL_COND_V(!area, 0); - area->set_collision_layer(p_layer); + return area->get_collision_mask(); } void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h index c780ef3b66..b96677700c 100644 --- a/servers/physics_2d/godot_physics_server_2d.h +++ b/servers/physics_2d/godot_physics_server_2d.h @@ -151,8 +151,12 @@ public: virtual Variant area_get_param(RID p_area, AreaParameter p_param) const override; virtual Transform2D area_get_transform(RID p_area) const override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; + virtual uint32_t area_get_collision_layer(RID p_area) const override; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual uint32_t area_get_collision_mask(RID p_area) const override; virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 7f2ec72921..f3a589d469 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -387,6 +387,13 @@ void GodotPhysicsServer3D::area_set_collision_layer(RID p_area, uint32_t p_layer area->set_collision_layer(p_layer); } +uint32_t GodotPhysicsServer3D::area_get_collision_layer(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_layer(); +} + void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); @@ -394,6 +401,13 @@ void GodotPhysicsServer3D::area_set_collision_mask(RID p_area, uint32_t p_mask) area->set_collision_mask(p_mask); } +uint32_t GodotPhysicsServer3D::area_get_collision_mask(RID p_area) const { + GodotArea3D *area = area_owner.get_or_null(p_area); + ERR_FAIL_COND_V(!area, 0); + + return area->get_collision_mask(); +} + void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h index 6dc9330caf..e3e649da57 100644 --- a/servers/physics_3d/godot_physics_server_3d.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -148,8 +148,11 @@ public: virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; + virtual uint32_t area_get_collision_layer(RID p_area) const override; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; + virtual uint32_t area_get_collision_mask(RID p_area) const override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h index fdcc2ceea3..1651d34916 100644 --- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h +++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_CONE_TWIST_JOINT_3D_H +#define GODOT_CONE_TWIST_JOINT_3D_H + /* Adapted to Godot from the Bullet library. */ @@ -49,9 +52,6 @@ subject to the following restrictions: Written by: Marcus Hennix */ -#ifndef GODOT_CONE_TWIST_JOINT_3D_H -#define GODOT_CONE_TWIST_JOINT_3D_H - #include "servers/physics_3d/godot_joint_3d.h" #include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h index bcf2d18647..6a0ab81461 100644 --- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h +++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_GENERIC_6DOF_JOINT_3D_H +#define GODOT_GENERIC_6DOF_JOINT_3D_H + /* Adapted to Godot from the Bullet library. */ -#ifndef GODOT_GENERIC_6DOF_JOINT_3D_H -#define GODOT_GENERIC_6DOF_JOINT_3D_H - #include "servers/physics_3d/godot_joint_3d.h" #include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.h b/servers/physics_3d/joints/godot_hinge_joint_3d.h index b934540e8d..f1187771af 100644 --- a/servers/physics_3d/joints/godot_hinge_joint_3d.h +++ b/servers/physics_3d/joints/godot_hinge_joint_3d.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_HINGE_JOINT_3D_H +#define GODOT_HINGE_JOINT_3D_H + /* Adapted to Godot from the Bullet library. */ -#ifndef GODOT_HINGE_JOINT_3D_H -#define GODOT_HINGE_JOINT_3D_H - #include "servers/physics_3d/godot_joint_3d.h" #include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" diff --git a/servers/physics_3d/joints/godot_jacobian_entry_3d.h b/servers/physics_3d/joints/godot_jacobian_entry_3d.h index 0fe15751d5..a46ce830ec 100644 --- a/servers/physics_3d/joints/godot_jacobian_entry_3d.h +++ b/servers/physics_3d/joints/godot_jacobian_entry_3d.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_JACOBIAN_ENTRY_3D_H +#define GODOT_JACOBIAN_ENTRY_3D_H + /* Adapted to Godot from the Bullet library. */ -#ifndef GODOT_JACOBIAN_ENTRY_3D_H -#define GODOT_JACOBIAN_ENTRY_3D_H - /* Bullet Continuous Collision Detection and Physics Library Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.h b/servers/physics_3d/joints/godot_pin_joint_3d.h index eeeaa650bd..b3e2389d5a 100644 --- a/servers/physics_3d/joints/godot_pin_joint_3d.h +++ b/servers/physics_3d/joints/godot_pin_joint_3d.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_PIN_JOINT_3D_H +#define GODOT_PIN_JOINT_3D_H + /* Adapted to Godot from the Bullet library. */ -#ifndef GODOT_PIN_JOINT_3D_H -#define GODOT_PIN_JOINT_3D_H - #include "servers/physics_3d/godot_joint_3d.h" #include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.h b/servers/physics_3d/joints/godot_slider_joint_3d.h index f596c9ff75..29d19be0d7 100644 --- a/servers/physics_3d/joints/godot_slider_joint_3d.h +++ b/servers/physics_3d/joints/godot_slider_joint_3d.h @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef GODOT_SLIDER_JOINT_3D_H +#define GODOT_SLIDER_JOINT_3D_H + /* Adapted to Godot from the Bullet library. */ -#ifndef GODOT_SLIDER_JOINT_3D_H -#define GODOT_SLIDER_JOINT_3D_H - #include "servers/physics_3d/godot_joint_3d.h" #include "servers/physics_3d/joints/godot_jacobian_entry_3d.h" diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index abaa473017..21be311637 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -652,7 +652,10 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer2D::area_clear_shapes); ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer2D::area_set_collision_layer); + ClassDB::bind_method(D_METHOD("area_get_collision_layer", "area"), &PhysicsServer2D::area_get_collision_layer); + ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer2D::area_set_collision_mask); + ClassDB::bind_method(D_METHOD("area_get_collision_mask", "area"), &PhysicsServer2D::area_get_collision_mask); ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer2D::area_set_param); ClassDB::bind_method(D_METHOD("area_set_transform", "area", "transform"), &PhysicsServer2D::area_set_transform); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index bd57a6a375..a3feb97d5d 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -332,8 +332,11 @@ public: virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const = 0; virtual Transform2D area_get_transform(RID p_area) const = 0; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0; + virtual uint32_t area_get_collision_layer(RID p_area) const = 0; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; + virtual uint32_t area_get_collision_mask(RID p_area) const = 0; virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; virtual void area_set_pickable(RID p_area, bool p_pickable) = 0; diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index 1353d8de6d..14a6a5c2a1 100644 --- a/servers/physics_server_2d_wrap_mt.h +++ b/servers/physics_server_2d_wrap_mt.h @@ -156,8 +156,11 @@ public: FUNC2RC(Variant, area_get_param, RID, AreaParameter); FUNC1RC(Transform2D, area_get_transform, RID); - FUNC2(area_set_collision_mask, RID, uint32_t); FUNC2(area_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_layer, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_mask, RID); FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_pickable, RID, bool); diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index b4f30d7649..24cc7e8459 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -720,7 +720,10 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer3D::area_clear_shapes); ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer3D::area_set_collision_layer); + ClassDB::bind_method(D_METHOD("area_get_collision_layer", "area"), &PhysicsServer3D::area_get_collision_layer); + ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer3D::area_set_collision_mask); + ClassDB::bind_method(D_METHOD("area_get_collision_mask", "area"), &PhysicsServer3D::area_get_collision_mask); ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer3D::area_set_param); ClassDB::bind_method(D_METHOD("area_set_transform", "area", "transform"), &PhysicsServer3D::area_set_transform); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 2151d84e40..b21c4e9249 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -364,8 +364,11 @@ public: virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const = 0; virtual Transform3D area_get_transform(RID p_area) const = 0; - virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0; + virtual uint32_t area_get_collision_layer(RID p_area) const = 0; + + virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0; + virtual uint32_t area_get_collision_mask(RID p_area) const = 0; virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index 9b07e19e50..1d5fa95bfb 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -157,8 +157,11 @@ public: FUNC2RC(Variant, area_get_param, RID, AreaParameter); FUNC1RC(Transform3D, area_get_transform, RID); - FUNC2(area_set_collision_mask, RID, uint32_t); FUNC2(area_set_collision_layer, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_layer, RID); + + FUNC2(area_set_collision_mask, RID, uint32_t); + FUNC1RC(uint32_t, area_get_collision_mask, RID); FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_ray_pickable, RID, bool); diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 459d798a80..a3734a7218 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -597,7 +597,7 @@ void main() { #ifdef MODE_LIGHT_ONLY color = vec4(0.0); -#else +#elif !defined(MODE_UNSHADED) color *= canvas_data.canvas_modulation; #endif diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/SCsub +++ b/servers/rendering/renderer_rd/shaders/effects/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/environment/SCsub +++ b/servers/rendering/renderer_rd/shaders/environment/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub index 741da8fe69..f06a2d86e2 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub @@ -4,7 +4,7 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: # find all include files - gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")] # find all shader code(all glsl files excluding our include files) glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files] diff --git a/tests/core/math/test_vector2.h b/tests/core/math/test_vector2.h index 9b7800164a..0d7f1163e4 100644 --- a/tests/core/math/test_vector2.h +++ b/tests/core/math/test_vector2.h @@ -37,6 +37,14 @@ namespace TestVector2 { +TEST_CASE("[Vector2] Constructor methods") { + const Vector2 vector_empty = Vector2(); + const Vector2 vector_zero = Vector2(0.0, 0.0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector2 Constructor with no inputs should return a zero Vector2."); +} + TEST_CASE("[Vector2] Angle methods") { const Vector2 vector_x = Vector2(1, 0); const Vector2 vector_y = Vector2(0, 1); @@ -102,6 +110,9 @@ TEST_CASE("[Vector2] Interpolation methods") { Vector2(1, 1).slerp(Vector2(), 0.5) == Vector2(0.5, 0.5), "Vector2 slerp with one input as zero should behave like a regular lerp."); CHECK_MESSAGE( + Vector2(4, 6).slerp(Vector2(8, 10), 0.5).is_equal_approx(Vector2(5.9076470794008017626, 8.07918879020090480697)), + "Vector2 slerp should work as expected."); + CHECK_MESSAGE( Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)4.31959610746631919), "Vector2 slerp with different length input should return a vector with an interpolated length."); CHECK_MESSAGE( @@ -171,6 +182,15 @@ TEST_CASE("[Vector2] Normalization methods") { CHECK_MESSAGE( Vector2(1, 1).normalized().is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)), "Vector2 normalized should work as expected."); + + Vector2 vector = Vector2(3.2, -5.4); + vector.normalize(); + CHECK_MESSAGE( + vector == Vector2(3.2, -5.4).normalized(), + "Vector2 normalize should convert same way as Vector2 normalized."); + CHECK_MESSAGE( + vector.is_equal_approx(Vector2(0.509802390301732898898, -0.860291533634174266891)), + "Vector2 normalize should work as expected."); } TEST_CASE("[Vector2] Operators") { @@ -276,12 +296,14 @@ TEST_CASE("[Vector2] Other methods") { CHECK_MESSAGE( Math::is_equal_approx(vector.aspect(), (real_t)1.2 / (real_t)3.4), "Vector2 aspect should work as expected."); + CHECK_MESSAGE( vector.direction_to(Vector2()).is_equal_approx(-vector.normalized()), "Vector2 direction_to should work as expected."); CHECK_MESSAGE( Vector2(1, 1).direction_to(Vector2(2, 2)).is_equal_approx(Vector2(Math_SQRT12, Math_SQRT12)), "Vector2 direction_to should work as expected."); + CHECK_MESSAGE( vector.posmod(2).is_equal_approx(Vector2(1.2, 1.4)), "Vector2 posmod should work as expected."); @@ -294,10 +316,21 @@ TEST_CASE("[Vector2] Other methods") { CHECK_MESSAGE( (-vector).posmodv(Vector2(2, 3)).is_equal_approx(Vector2(0.8, 2.6)), "Vector2 posmodv should work as expected."); + + CHECK_MESSAGE( + vector.rotated(Math_TAU).is_equal_approx(Vector2(1.2, 3.4)), + "Vector2 rotated should work as expected."); CHECK_MESSAGE( vector.rotated(Math_TAU / 4).is_equal_approx(Vector2(-3.4, 1.2)), "Vector2 rotated should work as expected."); CHECK_MESSAGE( + vector.rotated(Math_TAU / 3).is_equal_approx(Vector2(-3.544486372867091398996, -0.660769515458673623883)), + "Vector2 rotated should work as expected."); + CHECK_MESSAGE( + vector.rotated(Math_TAU / 2).is_equal_approx(vector.rotated(Math_TAU / -2)), + "Vector2 rotated should work as expected."); + + CHECK_MESSAGE( vector.snapped(Vector2(1, 1)) == Vector2(1, 3), "Vector2 snapped to integers should be the same as rounding."); CHECK_MESSAGE( @@ -306,23 +339,57 @@ TEST_CASE("[Vector2] Other methods") { CHECK_MESSAGE( vector.snapped(Vector2(0.25, 0.25)) == Vector2(1.25, 3.5), "Vector2 snapped to 0.25 should give exact results."); + + CHECK_MESSAGE( + Vector2(1.2, 2.5).is_equal_approx(vector.min(Vector2(3.0, 2.5))), + "Vector2 min should return expected value."); + + CHECK_MESSAGE( + Vector2(5.3, 3.4).is_equal_approx(vector.max(Vector2(5.3, 2.0))), + "Vector2 max should return expected value."); } TEST_CASE("[Vector2] Plane methods") { const Vector2 vector = Vector2(1.2, 3.4); const Vector2 vector_y = Vector2(0, 1); + const Vector2 vector_normal = Vector2(0.95879811270838721622267, 0.2840883296913739899919); + const Vector2 vector_non_normal = Vector2(5.4, 1.6); CHECK_MESSAGE( vector.bounce(vector_y) == Vector2(1.2, -3.4), "Vector2 bounce on a plane with normal of the Y axis should."); CHECK_MESSAGE( + vector.bounce(vector_normal).is_equal_approx(Vector2(-2.85851197982345523329, 2.197477931904161412358)), + "Vector2 bounce with normal should return expected value."); + CHECK_MESSAGE( vector.reflect(vector_y) == Vector2(-1.2, 3.4), "Vector2 reflect on a plane with normal of the Y axis should."); CHECK_MESSAGE( + vector.reflect(vector_normal).is_equal_approx(Vector2(2.85851197982345523329, -2.197477931904161412358)), + "Vector2 reflect with normal should return expected value."); + CHECK_MESSAGE( vector.project(vector_y) == Vector2(0, 3.4), - "Vector2 projected on the X axis should only give the Y component."); + "Vector2 projected on the Y axis should only give the Y component."); + CHECK_MESSAGE( + vector.project(vector_normal).is_equal_approx(Vector2(2.0292559899117276166, 0.60126103404791929382)), + "Vector2 projected on a normal should return expected value."); CHECK_MESSAGE( vector.slide(vector_y) == Vector2(1.2, 0), "Vector2 slide on a plane with normal of the Y axis should set the Y to zero."); + CHECK_MESSAGE( + vector.slide(vector_normal).is_equal_approx(Vector2(-0.8292559899117276166456, 2.798738965952080706179)), + "Vector2 slide with normal should return expected value."); + // There's probably a better way to test these ones? + ERR_PRINT_OFF; + CHECK_MESSAGE( + vector.bounce(vector_non_normal).is_equal_approx(Vector2()), + "Vector2 bounce should return empty Vector2 with non-normalised input."); + CHECK_MESSAGE( + vector.reflect(vector_non_normal).is_equal_approx(Vector2()), + "Vector2 reflect should return empty Vector2 with non-normalised input."); + CHECK_MESSAGE( + vector.slide(vector_non_normal).is_equal_approx(Vector2()), + "Vector2 slide should return empty Vector2 with non-normalised input."); + ERR_PRINT_ON; } TEST_CASE("[Vector2] Rounding methods") { @@ -367,12 +434,20 @@ TEST_CASE("[Vector2] Rounding methods") { TEST_CASE("[Vector2] Linear algebra methods") { const Vector2 vector_x = Vector2(1, 0); const Vector2 vector_y = Vector2(0, 1); + const Vector2 a = Vector2(3.5, 8.5); + const Vector2 b = Vector2(5.2, 4.6); CHECK_MESSAGE( vector_x.cross(vector_y) == 1, "Vector2 cross product of X and Y should give 1."); CHECK_MESSAGE( vector_y.cross(vector_x) == -1, "Vector2 cross product of Y and X should give negative 1."); + CHECK_MESSAGE( + Math::is_equal_approx(a.cross(b), (real_t)-28.1), + "Vector2 cross should return expected value."); + CHECK_MESSAGE( + Math::is_equal_approx(Vector2(-a.x, a.y).cross(Vector2(b.x, -b.y)), (real_t)-28.1), + "Vector2 cross should return expected value."); CHECK_MESSAGE( vector_x.dot(vector_y) == 0.0, @@ -383,6 +458,12 @@ TEST_CASE("[Vector2] Linear algebra methods") { CHECK_MESSAGE( (vector_x * 10).dot(vector_x * 10) == 100.0, "Vector2 dot product of same direction vectors should behave as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(a.dot(b), (real_t)57.3), + "Vector2 dot should return expected value."); + CHECK_MESSAGE( + Math::is_equal_approx(Vector2(-a.x, a.y).dot(Vector2(b.x, -b.y)), (real_t)-57.3), + "Vector2 dot should return expected value."); } } // namespace TestVector2 diff --git a/tests/core/math/test_vector2i.h b/tests/core/math/test_vector2i.h index 841bb793a4..49b0632e3c 100644 --- a/tests/core/math/test_vector2i.h +++ b/tests/core/math/test_vector2i.h @@ -37,6 +37,14 @@ namespace TestVector2i { +TEST_CASE("[Vector2i] Constructor methods") { + const Vector2i vector_empty = Vector2i(); + const Vector2i vector_zero = Vector2i(0, 0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector2i Constructor with no inputs should return a zero Vector2i."); +} + TEST_CASE("[Vector2i] Axis methods") { Vector2i vector = Vector2i(2, 3); CHECK_MESSAGE( @@ -121,6 +129,14 @@ TEST_CASE("[Vector2i] Other methods") { CHECK_MESSAGE( Math::is_equal_approx(vector.aspect(), (real_t)1.0 / (real_t)3.0), "Vector2i aspect should work as expected."); + + CHECK_MESSAGE( + Vector2i(1, 2) == vector.min(Vector2i(3, 2)), + "Vector2i min should return expected value."); + + CHECK_MESSAGE( + Vector2i(5, 3) == vector.max(Vector2i(5, 2)), + "Vector2i max should return expected value."); } TEST_CASE("[Vector2i] Abs and sign methods") { diff --git a/tests/core/math/test_vector3.h b/tests/core/math/test_vector3.h index 6f99fada2b..52118fa943 100644 --- a/tests/core/math/test_vector3.h +++ b/tests/core/math/test_vector3.h @@ -39,6 +39,14 @@ namespace TestVector3 { +TEST_CASE("[Vector3] Constructor methods") { + const Vector3 vector_empty = Vector3(); + const Vector3 vector_zero = Vector3(0.0, 0.0, 0.0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector3 Constructor with no inputs should return a zero Vector3."); +} + TEST_CASE("[Vector3] Angle methods") { const Vector3 vector_x = Vector3(1, 0, 0); const Vector3 vector_y = Vector3(0, 1, 0); @@ -123,6 +131,9 @@ TEST_CASE("[Vector3] Interpolation methods") { Vector3(1, 1, 1).slerp(Vector3(), 0.5) == Vector3(0.5, 0.5, 0.5), "Vector3 slerp with one input as zero should behave like a regular lerp."); CHECK_MESSAGE( + Vector3(4, 6, 2).slerp(Vector3(8, 10, 3), 0.5).is_equal_approx(Vector3(5.90194219811429941053, 8.06758688849378394534, 2.558307894718317120038)), + "Vector3 slerp should work as expected."); + CHECK_MESSAGE( Math::is_equal_approx(vector1.slerp(vector2, 0.5).length(), (real_t)6.25831088708303172), "Vector3 slerp with different length input should return a vector with an interpolated length."); CHECK_MESSAGE( @@ -195,6 +206,15 @@ TEST_CASE("[Vector3] Normalization methods") { CHECK_MESSAGE( Vector3(1, 1, 1).normalized().is_equal_approx(Vector3(Math_SQRT13, Math_SQRT13, Math_SQRT13)), "Vector3 normalized should work as expected."); + + Vector3 vector = Vector3(3.2, -5.4, 6); + vector.normalize(); + CHECK_MESSAGE( + vector == Vector3(3.2, -5.4, 6).normalized(), + "Vector3 normalize should convert same way as Vector3 normalized."); + CHECK_MESSAGE( + vector.is_equal_approx(Vector3(0.368522751763902980457, -0.621882143601586279522, 0.6909801595573180883585)), + "Vector3 normalize should work as expected."); } TEST_CASE("[Vector3] Operators") { @@ -318,10 +338,21 @@ TEST_CASE("[Vector3] Other methods") { CHECK_MESSAGE( (-vector).posmodv(Vector3(2, 3, 4)).is_equal_approx(Vector3(0.8, 2.6, 2.4)), "Vector3 posmodv should work as expected."); + + CHECK_MESSAGE( + vector.rotated(Vector3(0, 1, 0), Math_TAU).is_equal_approx(vector), + "Vector3 rotated should work as expected."); CHECK_MESSAGE( vector.rotated(Vector3(0, 1, 0), Math_TAU / 4).is_equal_approx(Vector3(5.6, 3.4, -1.2)), "Vector3 rotated should work as expected."); CHECK_MESSAGE( + vector.rotated(Vector3(1, 0, 0), Math_TAU / 3).is_equal_approx(Vector3(1.2, -6.54974226119285642, 0.1444863728670914)), + "Vector3 rotated should work as expected."); + CHECK_MESSAGE( + vector.rotated(Vector3(0, 0, 1), Math_TAU / 2).is_equal_approx(vector.rotated(Vector3(0, 0, 1), Math_TAU / -2)), + "Vector3 rotated should work as expected."); + + CHECK_MESSAGE( vector.snapped(Vector3(1, 1, 1)) == Vector3(1, 3, 6), "Vector3 snapped to integers should be the same as rounding."); CHECK_MESSAGE( @@ -332,18 +363,44 @@ TEST_CASE("[Vector3] Other methods") { TEST_CASE("[Vector3] Plane methods") { const Vector3 vector = Vector3(1.2, 3.4, 5.6); const Vector3 vector_y = Vector3(0, 1, 0); + const Vector3 vector_normal = Vector3(0.88763458893247992491, 0.26300284116517923701, 0.37806658417494515320); + const Vector3 vector_non_normal = Vector3(5.4, 1.6, 2.3); CHECK_MESSAGE( vector.bounce(vector_y) == Vector3(1.2, -3.4, 5.6), "Vector3 bounce on a plane with normal of the Y axis should."); CHECK_MESSAGE( + vector.bounce(vector_normal).is_equal_approx(Vector3(-6.0369629829775736287, 1.25571467171034855444, 2.517589840583626047)), + "Vector3 bounce with normal should return expected value."); + CHECK_MESSAGE( vector.reflect(vector_y) == Vector3(-1.2, 3.4, -5.6), "Vector3 reflect on a plane with normal of the Y axis should."); CHECK_MESSAGE( + vector.reflect(vector_normal).is_equal_approx(Vector3(6.0369629829775736287, -1.25571467171034855444, -2.517589840583626047)), + "Vector3 reflect with normal should return expected value."); + CHECK_MESSAGE( vector.project(vector_y) == Vector3(0, 3.4, 0), - "Vector3 projected on the X axis should only give the Y component."); + "Vector3 projected on the Y axis should only give the Y component."); + CHECK_MESSAGE( + vector.project(vector_normal).is_equal_approx(Vector3(3.61848149148878681437, 1.0721426641448257227776, 1.54120507970818697649)), + "Vector3 projected on a normal should return expected value."); CHECK_MESSAGE( vector.slide(vector_y) == Vector3(1.2, 0, 5.6), "Vector3 slide on a plane with normal of the Y axis should set the Y to zero."); + CHECK_MESSAGE( + vector.slide(vector_normal).is_equal_approx(Vector3(-2.41848149148878681437, 2.32785733585517427722237, 4.0587949202918130235)), + "Vector3 slide with normal should return expected value."); + // There's probably a better way to test these ones? + ERR_PRINT_OFF; + CHECK_MESSAGE( + vector.bounce(vector_non_normal).is_equal_approx(Vector3()), + "Vector3 bounce should return empty Vector3 with non-normalised input."); + CHECK_MESSAGE( + vector.reflect(vector_non_normal).is_equal_approx(Vector3()), + "Vector3 reflect should return empty Vector3 with non-normalised input."); + CHECK_MESSAGE( + vector.slide(vector_non_normal).is_equal_approx(Vector3()), + "Vector3 slide should return empty Vector3 with non-normalised input."); + ERR_PRINT_ON; } TEST_CASE("[Vector3] Rounding methods") { @@ -389,6 +446,8 @@ TEST_CASE("[Vector3] Linear algebra methods") { const Vector3 vector_x = Vector3(1, 0, 0); const Vector3 vector_y = Vector3(0, 1, 0); const Vector3 vector_z = Vector3(0, 0, 1); + const Vector3 a = Vector3(3.5, 8.5, 2.3); + const Vector3 b = Vector3(5.2, 4.6, 7.8); CHECK_MESSAGE( vector_x.cross(vector_y) == vector_z, "Vector3 cross product of X and Y should give Z."); @@ -401,6 +460,12 @@ TEST_CASE("[Vector3] Linear algebra methods") { CHECK_MESSAGE( vector_z.cross(vector_x) == vector_y, "Vector3 cross product of Z and X should give Y."); + CHECK_MESSAGE( + a.cross(b).is_equal_approx(Vector3(55.72, -15.34, -28.1)), + "Vector3 cross should return expected value."); + CHECK_MESSAGE( + Vector3(-a.x, a.y, -a.z).cross(Vector3(b.x, -b.y, b.z)).is_equal_approx(Vector3(55.72, 15.34, -28.1)), + "Vector2 cross should return expected value."); CHECK_MESSAGE( vector_x.dot(vector_y) == 0.0, @@ -411,6 +476,12 @@ TEST_CASE("[Vector3] Linear algebra methods") { CHECK_MESSAGE( (vector_x * 10).dot(vector_x * 10) == 100.0, "Vector3 dot product of same direction vectors should behave as expected."); + CHECK_MESSAGE( + Math::is_equal_approx(a.dot(b), (real_t)75.24), + "Vector3 dot should return expected value."); + CHECK_MESSAGE( + Math::is_equal_approx(Vector3(-a.x, a.y, -a.z).dot(Vector3(b.x, -b.y, b.z)), (real_t)-75.24), + "Vector3 dot should return expected value."); } } // namespace TestVector3 diff --git a/tests/core/math/test_vector3i.h b/tests/core/math/test_vector3i.h index b1c6944eba..6c52781556 100644 --- a/tests/core/math/test_vector3i.h +++ b/tests/core/math/test_vector3i.h @@ -36,6 +36,14 @@ namespace TestVector3i { +TEST_CASE("[Vector3i] Constructor methods") { + const Vector3i vector_empty = Vector3i(); + const Vector3i vector_zero = Vector3i(0, 0, 0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector3i Constructor with no inputs should return a zero Vector3i."); +} + TEST_CASE("[Vector3i] Axis methods") { Vector3i vector = Vector3i(1, 2, 3); CHECK_MESSAGE( diff --git a/tests/core/math/test_vector4.h b/tests/core/math/test_vector4.h index ccf991401b..25ec8929b8 100644 --- a/tests/core/math/test_vector4.h +++ b/tests/core/math/test_vector4.h @@ -38,6 +38,14 @@ namespace TestVector4 { +TEST_CASE("[Vector4] Constructor methods") { + const Vector4 vector_empty = Vector4(); + const Vector4 vector_zero = Vector4(0.0, 0.0, 0.0, 0.0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector4 Constructor with no inputs should return a zero Vector4."); +} + TEST_CASE("[Vector4] Axis methods") { Vector4 vector = Vector4(1.2, 3.4, 5.6, -0.9); CHECK_MESSAGE( diff --git a/tests/core/math/test_vector4i.h b/tests/core/math/test_vector4i.h index ac63001b24..e106099914 100644 --- a/tests/core/math/test_vector4i.h +++ b/tests/core/math/test_vector4i.h @@ -36,6 +36,14 @@ namespace TestVector4i { +TEST_CASE("[Vector4i] Constructor methods") { + const Vector4i vector_empty = Vector4i(); + const Vector4i vector_zero = Vector4i(0, 0, 0, 0); + CHECK_MESSAGE( + vector_empty == vector_zero, + "Vector4i Constructor with no inputs should return a zero Vector4i."); +} + TEST_CASE("[Vector4i] Axis methods") { Vector4i vector = Vector4i(1, 2, 3, 4); CHECK_MESSAGE( |