diff options
74 files changed, 497 insertions, 315 deletions
diff --git a/.gitignore b/.gitignore index e9beb26e7e..17c9a6c95a 100644 --- a/.gitignore +++ b/.gitignore @@ -243,9 +243,6 @@ xcuserdata/ x64/ x86/ -# Do not ignore x86 folders anywhere under thirdparty libraries -!thirdparty/**/x86/ - [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ @@ -255,6 +252,12 @@ bld/ [Ll]og/ [Ll]ogs/ +# Do not ignore arch-specific folders anywhere under thirdparty libraries +!thirdparty/**/x64/ +!thirdparty/**/x86/ +!thirdparty/**/arm/ +!thirdparty/**/arm64/ + # Visual Studio 2015/2017 cache/options directory .vs/ diff --git a/SConstruct b/SConstruct index 845b9be4a6..2763f3f578 100644 --- a/SConstruct +++ b/SConstruct @@ -200,6 +200,7 @@ opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extr opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False)) opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "") opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) +opts.Add("vsproj_name", "Name of the Visual Studio solution", "godot") opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) opts.Add("build_profile", "Path to a file containing a feature build profile", "") @@ -217,7 +218,7 @@ opts.Add(BoolVariable("builtin_msdfgen", "Use the built-in MSDFgen library", Tru opts.Add(BoolVariable("builtin_glslang", "Use the built-in glslang library", True)) opts.Add(BoolVariable("builtin_graphite", "Use the built-in Graphite library", True)) opts.Add(BoolVariable("builtin_harfbuzz", "Use the built-in HarfBuzz library", True)) -opts.Add(BoolVariable("builtin_icu", "Use the built-in ICU library", True)) +opts.Add(BoolVariable("builtin_icu4c", "Use the built-in ICU library", True)) opts.Add(BoolVariable("builtin_libogg", "Use the built-in libogg library", True)) opts.Add(BoolVariable("builtin_libpng", "Use the built-in libpng library", True)) opts.Add(BoolVariable("builtin_libtheora", "Use the built-in libtheora library", True)) @@ -228,7 +229,7 @@ opts.Add(BoolVariable("builtin_mbedtls", "Use the built-in mbedTLS library", Tru opts.Add(BoolVariable("builtin_miniupnpc", "Use the built-in miniupnpc library", True)) opts.Add(BoolVariable("builtin_pcre2", "Use the built-in PCRE2 library", True)) opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-in PCRE2 library", True)) -opts.Add(BoolVariable("builtin_recast", "Use the built-in Recast library", True)) +opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True)) opts.Add(BoolVariable("builtin_rvo2", "Use the built-in RVO2 library", True)) opts.Add(BoolVariable("builtin_squish", "Use the built-in squish library", True)) opts.Add(BoolVariable("builtin_xatlas", "Use the built-in xatlas library", True)) @@ -923,7 +924,7 @@ if selected_platform in platform_list: print("Error: The `vsproj` option is only usable on Windows with Visual Studio.") Exit(255) env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]] - methods.generate_vs_project(env, GetOption("num_jobs")) + methods.generate_vs_project(env, GetOption("num_jobs"), env["vsproj_name"]) methods.generate_cpp_hint_file("cpp.hint") # Check for the existence of headers diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 5a07d44197..b2e6b57eb6 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -344,7 +344,7 @@ static const _BuiltinActionDisplayName _builtin_action_display_names[] = { { "ui_text_add_selection_for_next_occurrence", TTRC("Add Selection for Next Occurrence") }, { "ui_text_clear_carets_and_selection", TTRC("Clear Carets and Selection") }, { "ui_text_toggle_insert_mode", TTRC("Toggle Insert Mode") }, - { "ui_text_submit", TTRC("Text Submitted") }, + { "ui_text_submit", TTRC("Submit Text") }, { "ui_graph_duplicate", TTRC("Duplicate Nodes") }, { "ui_graph_delete", TTRC("Delete Nodes") }, { "ui_filedialog_up_one_level", TTRC("Go Up One Level") }, diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h index c447b5af64..45b90869b9 100644 --- a/core/templates/paged_array.h +++ b/core/templates/paged_array.h @@ -278,10 +278,10 @@ public: count -= remainder; - uint32_t src_pages = p_array._get_pages_in_use(); + uint32_t src_page_index = 0; uint32_t page_size = page_size_mask + 1; - for (uint32_t i = 0; i < src_pages; i++) { + while (p_array.count > 0) { uint32_t page_count = _get_pages_in_use(); uint32_t new_page_count = page_count + 1; @@ -289,16 +289,14 @@ public: _grow_page_array(); //keep out of inline } - page_data[page_count] = p_array.page_data[i]; - page_ids[page_count] = p_array.page_ids[i]; - if (i == src_pages - 1) { - //last page, only increment with remainder - count += p_array.count & page_size_mask; - } else { - count += page_size; - } + page_data[page_count] = p_array.page_data[src_page_index]; + page_ids[page_count] = p_array.page_ids[src_page_index]; + + uint32_t take = MIN(p_array.count, page_size); //pages to take away + p_array.count -= take; + count += take; + src_page_index++; } - p_array.count = 0; //take away the other array pages //handle the remainder page if exists if (remainder_page) { diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index d5280cb548..ed7bdc07fc 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1140,7 +1140,7 @@ <return type="float" /> <param index="0" name="x" type="float" /> <description> - Returns [code]-1.0[/code] if [param x] is negative, [code]1.0[/code] if [param x] is positive, and [code]0.0[/code] if if [param x] is zero. + Returns [code]-1.0[/code] if [param x] is negative, [code]1.0[/code] if [param x] is positive, and [code]0.0[/code] if [param x] is zero. [codeblock] sign(-6.5) # Returns -1.0 sign(0.0) # Returns 0.0 diff --git a/doc/classes/AnimatedTexture.xml b/doc/classes/AnimatedTexture.xml index 57a7f86901..052c55dfb6 100644 --- a/doc/classes/AnimatedTexture.xml +++ b/doc/classes/AnimatedTexture.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="AnimatedTexture" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> +<class name="AnimatedTexture" inherits="Texture2D" is_deprecated="true" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> Proxy texture for simple frame-based animations. </brief_description> @@ -8,6 +8,7 @@ The playback of the animation is controlled by the [member speed_scale] property, as well as each frame's duration (see [method set_frame_duration]). The animation loops, i.e. it will restart at frame 0 automatically after playing the last frame. [AnimatedTexture] currently requires all frame textures to have the same size, otherwise the bigger ones will be cropped to match the smallest one. [b]Note:[/b] AnimatedTexture doesn't support using [AtlasTexture]s. Each frame needs to be a separate [Texture2D]. + [b]Warning:[/b] AnimatedTexture is deprecated, and might be removed in a future release. Its current implementation is not efficient for the modern renderers. </description> <tutorials> </tutorials> @@ -46,7 +47,7 @@ </methods> <members> <member name="current_frame" type="int" setter="set_current_frame" getter="get_current_frame"> - Sets the currently visible frame of the texture. + Sets the currently visible frame of the texture. Setting this frame while playing resets the current frame time, so the newly selected frame plays for its whole configured frame duration. </member> <member name="frames" type="int" setter="set_frames" getter="get_frames" default="1"> Number of frames to use in the animation. While you can create the frames independently with [method set_frame_texture], you need to set this value for the animation to take new frames into account. The maximum number of frames is [constant MAX_FRAMES]. diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml index ddfa64891d..824416e4d4 100644 --- a/doc/classes/Decal.xml +++ b/doc/classes/Decal.xml @@ -96,7 +96,7 @@ [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter]. </member> <member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture"> - [Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object. + [Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_albedo] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object. [b]Note:[/b] Unlike [BaseMaterial3D] whose filter mode can be adjusted on a per-material basis, the filter mode for [Decal] textures is set globally with [member ProjectSettings.rendering/textures/decals/filter]. </member> <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture"> diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index 294fe49408..d2151773da 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -144,13 +144,13 @@ <member name="path_desired_distance" type="float" setter="set_path_desired_distance" getter="get_path_desired_distance" default="1.0"> The distance threshold before a path point is considered to be reached. This will allow an agent to not have to hit a path point on the path exactly, but in the area. If this value is set to high the NavigationAgent will skip points on the path which can lead to leaving the navigation mesh. If this value is set to low the NavigationAgent will be stuck in a repath loop cause it will constantly overshoot or undershoot the distance to the next point on each physics frame update. </member> - <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="3.0"> + <member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="5.0"> The maximum distance the agent is allowed away from the ideal path to the final position. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path. </member> <member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7"> Additional information to return with the navigation path. </member> - <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0"> + <member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5"> The radius of the avoidance agent. This is the "body" of the avoidance agent and not the avoidance maneuver starting radius (which is controlled by [member neighbor_distance]). Does not affect normal pathfinding. To change an actor's pathfinding radius bake [NavigationMesh] resources with a different [member NavigationMesh.agent_radius] property and use different navigation maps for each actor size. </member> @@ -160,7 +160,7 @@ <member name="target_position" type="Vector3" setter="set_target_position" getter="get_target_position" default="Vector3(0, 0, 0)"> The user-defined target position. Setting this property will clear the current navigation path. </member> - <member name="time_horizon" type="float" setter="set_time_horizon" getter="get_time_horizon" default="5.0"> + <member name="time_horizon" type="float" setter="set_time_horizon" getter="get_time_horizon" default="1.0"> The minimal amount of time for which this agent's velocities, that are computed with the collision avoidance algorithm, are safe with respect to other agents. The larger the number, the sooner the agent will respond to other agents, but less freedom in choosing its velocities. Must be positive. </member> </members> diff --git a/doc/classes/OmniLight3D.xml b/doc/classes/OmniLight3D.xml index 1df8c255dd..7c5b9aff46 100644 --- a/doc/classes/OmniLight3D.xml +++ b/doc/classes/OmniLight3D.xml @@ -13,7 +13,8 @@ </tutorials> <members> <member name="omni_attenuation" type="float" setter="set_param" getter="get_param" default="1.0"> - The light's attenuation (drop-off) curve. A number of presets are available in the [b]Inspector[/b] by right-clicking the curve. + The light's attenuation (drop-off) curve. A number of presets are available in the [b]Inspector[/b] by right-clicking the curve. Zero and negative values are allowed but can produce unusual effects. + [b]Note:[/b] Very high [member omni_attenuation] values (typically above 10) can impact performance negatively if the light is made to use a larger [member omni_range] to compensate. This is because culling opportunities will become less common and shading costs will be increased (as the light will cover more pixels on screen while resulting in the same amount of brightness). To improve performance, use the lowest [member omni_attenuation] value possible for the visuals you're trying to achieve. </member> <member name="omni_range" type="float" setter="set_param" getter="get_param" default="5.0"> The light's radius. Note that the effectively lit area may appear to be smaller depending on the [member omni_attenuation] in use. No matter the [member omni_attenuation] in use, the light will never reach anything outside this radius. diff --git a/doc/classes/SpotLight3D.xml b/doc/classes/SpotLight3D.xml index 6bb4ae548c..3b32923872 100644 --- a/doc/classes/SpotLight3D.xml +++ b/doc/classes/SpotLight3D.xml @@ -20,10 +20,11 @@ [b]Note:[/b] [member spot_angle] is not affected by [member Node3D.scale] (the light's scale or its parent's scale). </member> <member name="spot_angle_attenuation" type="float" setter="set_param" getter="get_param" default="1.0"> - The spotlight's angular attenuation curve. + The spotlight's [i]angular[/i] attenuation curve. See also [member spot_attenuation]. </member> <member name="spot_attenuation" type="float" setter="set_param" getter="get_param" default="1.0"> - The spotlight's light energy attenuation curve. + The spotlight's light energy (drop-off) attenuation curve. A number of presets are available in the [b]Inspector[/b] by right-clicking the curve. Zero and negative values are allowed but can produce unusual effects. See also [member spot_angle_attenuation]. + [b]Note:[/b] Very high [member spot_attenuation] values (typically above 10) can impact performance negatively if the light is made to use a larger [member spot_range] to compensate. This is because culling opportunities will become less common and shading costs will be increased (as the light will cover more pixels on screen while resulting in the same amount of brightness). To improve performance, use the lowest [member spot_attenuation] value possible for the visuals you're trying to achieve. </member> <member name="spot_range" type="float" setter="set_param" getter="get_param" default="5.0"> The maximal range that can be reached by the spotlight. Note that the effectively lit area may appear to be smaller depending on the [member spot_attenuation] in use. No matter the [member spot_attenuation] in use, the light will never reach anything outside this range. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 8535dacda7..53b34332d7 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -1052,7 +1052,7 @@ [codeblock] print("I caught %d fishes!" % 2) # Prints "I caught 2 fishes!" - var my_message = "Travelling to %s, at %2.2f per second." + var my_message = "Travelling to %s, at %2.2f km/h." var location = "Deep Valley" var speed = 40.3485 print(my_message % [location, speed]) # Prints "Travelling to Deep Valley, at 40.35 km/h." diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index 96b958a5b9..4ccb93dab3 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -505,7 +505,7 @@ <return type="bool" /> <param index="0" name="expr" type="String" /> <description> - Does a simple expression match, where [code]*[/code] matches zero or more arbitrary characters and [code]?[/code] matches any single character except a period ([code].[/code]). An empty string or empty expression always evaluates to [code]false[/code]. + Does a simple expression match (also called "glob" or "globbing"), where [code]*[/code] matches zero or more arbitrary characters and [code]?[/code] matches any single character except a period ([code].[/code]). An empty string or empty expression always evaluates to [code]false[/code]. </description> </method> <method name="matchn" qualifiers="const"> diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 1a18f35e64..6cc6b8224c 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1895,6 +1895,10 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); glViewport(0, 0, rb->width, rb->height); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; + // Do depth prepass if it's explicitly enabled bool use_depth_prepass = config->use_depth_prepass; @@ -1910,9 +1914,6 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glDisable(GL_SCISSOR_TEST); - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK; glColorMask(0, 0, 0, 0); glClearDepth(1.0f); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 9eabc31621..c27417f037 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -6623,7 +6623,7 @@ AnimationTrackEditor::AnimationTrackEditor() { optimize_dialog = memnew(ConfirmationDialog); add_child(optimize_dialog); - optimize_dialog->set_title(TTR("Anim. Optimizer")); + optimize_dialog->set_title(TTR("Animation Optimizer")); VBoxContainer *optimize_vb = memnew(VBoxContainer); optimize_dialog->add_child(optimize_vb); @@ -6632,19 +6632,19 @@ AnimationTrackEditor::AnimationTrackEditor() { optimize_velocity_error->set_min(0.001); optimize_velocity_error->set_step(0.001); optimize_velocity_error->set_value(0.01); - optimize_vb->add_margin_child(TTR("Max. Velocity Error:"), optimize_velocity_error); + optimize_vb->add_margin_child(TTR("Max Velocity Error:"), optimize_velocity_error); optimize_angular_error = memnew(SpinBox); optimize_angular_error->set_max(1.0); optimize_angular_error->set_min(0.001); optimize_angular_error->set_step(0.001); optimize_angular_error->set_value(0.01); - optimize_vb->add_margin_child(TTR("Max. Angular Error:"), optimize_angular_error); + optimize_vb->add_margin_child(TTR("Max Angular Error:"), optimize_angular_error); optimize_precision_error = memnew(SpinBox); optimize_precision_error->set_max(6); optimize_precision_error->set_min(1); optimize_precision_error->set_step(1); optimize_precision_error->set_value(3); - optimize_vb->add_margin_child(TTR("Max. Precision Error:"), optimize_precision_error); + optimize_vb->add_margin_child(TTR("Max Precision Error:"), optimize_precision_error); optimize_dialog->set_ok_button_text(TTR("Optimize")); optimize_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_OPTIMIZE_ANIMATION_CONFIRM)); @@ -6735,7 +6735,7 @@ AnimationTrackEditor::AnimationTrackEditor() { // bake_dialog = memnew(ConfirmationDialog); - bake_dialog->set_title(TTR("Anim. Baker")); + bake_dialog->set_title(TTR("Animation Baker")); bake_dialog->connect("confirmed", callable_mp(this, &AnimationTrackEditor::_edit_menu_pressed).bind(EDIT_BAKE_ANIMATION_CONFIRM)); add_child(bake_dialog); GridContainer *bake_grid = memnew(GridContainer); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index e4730faf38..b0d6135d52 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -624,7 +624,9 @@ EditorProfiler::EditorProfiler() { hb->add_child(memnew(Label(TTR("Time:")))); display_time = memnew(OptionButton); + // TRANSLATORS: This is an option in the profiler to display the time spent in a function, including the time spent in other functions called by that function. display_time->add_item(TTR("Inclusive")); + // TRANSLATORS: This is an option in the profiler to display the time spent in a function, exincluding the time spent in other functions called by that function. display_time->add_item(TTR("Self")); display_time->set_tooltip_text(TTR("Inclusive: Includes time from other functions called by this function.\nUse this to spot bottlenecks.\n\nSelf: Only count the time spent in the function itself, not in other functions called by that function.\nUse this to find individual functions to optimize.")); display_time->connect("item_selected", callable_mp(this, &EditorProfiler::_combo_changed)); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index f4cefc606b..ed7638414c 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1336,6 +1336,8 @@ EditorAudioBuses::EditorAudioBuses() { add_child(file_dialog); file_dialog->connect("file_selected", callable_mp(this, &EditorAudioBuses::_file_dialog_callback)); + AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &EditorAudioBuses::_update_buses)); + set_process(true); } diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 4a1f0b4c09..80d1e9dcd7 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -472,6 +472,14 @@ void EditorFileDialog::_action_pressed() { } } + // First check we're not having an empty name. + String file_name = file_text.strip_edges().get_file(); + if (file_name.is_empty()) { + error_dialog->set_text(TTR("Cannot save file with an empty filename.")); + error_dialog->popup_centered(Size2(250, 80) * EDSCALE); + return; + } + // Add first extension of filter if no valid extension is found. if (!valid) { int idx = filter->get_selected(); @@ -480,9 +488,15 @@ void EditorFileDialog::_action_pressed() { f += "." + ext; } + if (file_name.begins_with(".")) { // Could still happen if typed manually. + error_dialog->set_text(TTR("Cannot save file with a name starting with a dot.")); + error_dialog->popup_centered(Size2(250, 80) * EDSCALE); + return; + } + if (dir_access->file_exists(f) && !disable_overwrite_warning) { - confirm_save->set_text(TTR("File exists, overwrite?")); - confirm_save->popup_centered(Size2(200, 80)); + confirm_save->set_text(vformat(TTR("File \"%s\" already exists.\nDo you want to overwrite it?"), f)); + confirm_save->popup_centered(Size2(250, 80) * EDSCALE); } else { _save_to_recent(); hide(); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 6410821dcf..304a7acff1 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -509,6 +509,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.35); const Color font_readonly_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.65); const Color font_placeholder_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.6); + const Color font_outline_color = Color(0, 0, 0, 0); const Color selection_color = accent_color * Color(1, 1, 1, 0.4); const Color disabled_color = mono_color.inverted().lerp(base_color, 0.7); const Color disabled_bg_color = mono_color.inverted().lerp(base_color, 0.9); @@ -816,6 +817,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_write_movie_button->set_expand_margin(SIDE_RIGHT, 2 * EDSCALE); theme->set_stylebox("MovieWriterButtonPressed", "EditorStyles", style_write_movie_button); + // MenuButton theme->set_stylebox("normal", "MenuButton", style_menu); theme->set_stylebox("hover", "MenuButton", style_widget_hover); theme->set_stylebox("pressed", "MenuButton", style_menu); @@ -826,6 +828,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_hover_color", "MenuButton", font_hover_color); theme->set_color("font_hover_pressed_color", "MenuButton", font_hover_pressed_color); theme->set_color("font_focus_color", "MenuButton", font_focus_color); + theme->set_color("font_outline_color", "MenuButton", font_outline_color); + + theme->set_constant("outline_size", "MenuButton", 0 * EDSCALE); theme->set_stylebox("MenuHover", "EditorStyles", style_widget_hover); @@ -842,6 +847,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "Button", font_focus_color); theme->set_color("font_pressed_color", "Button", accent_color); theme->set_color("font_disabled_color", "Button", font_disabled_color); + theme->set_color("font_outline_color", "Button", font_outline_color); theme->set_color("icon_normal_color", "Button", icon_normal_color); theme->set_color("icon_hover_color", "Button", icon_hover_color); @@ -849,6 +855,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_pressed_color", "Button", icon_pressed_color); theme->set_color("icon_disabled_color", "Button", icon_disabled_color); + theme->set_constant("outline_size", "Button", 0 * EDSCALE); + const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE; theme->set_type_variation("InspectorActionButton", "Button"); @@ -895,6 +903,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "MenuBar", font_focus_color); theme->set_color("font_pressed_color", "MenuBar", accent_color); theme->set_color("font_disabled_color", "MenuBar", font_disabled_color); + theme->set_color("font_outline_color", "MenuBar", font_outline_color); theme->set_color("icon_normal_color", "MenuBar", icon_normal_color); theme->set_color("icon_hover_color", "MenuBar", icon_hover_color); @@ -902,6 +911,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_pressed_color", "MenuBar", icon_pressed_color); theme->set_color("icon_disabled_color", "MenuBar", icon_disabled_color); + theme->set_constant("outline_size", "MenuBar", 0 * EDSCALE); + // OptionButton Ref<StyleBoxFlat> style_option_button_focus = style_widget_focus->duplicate(); Ref<StyleBoxFlat> style_option_button_normal = style_widget->duplicate(); @@ -932,6 +943,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "OptionButton", font_focus_color); theme->set_color("font_pressed_color", "OptionButton", accent_color); theme->set_color("font_disabled_color", "OptionButton", font_disabled_color); + theme->set_color("font_outline_color", "OptionButton", font_outline_color); theme->set_color("icon_normal_color", "OptionButton", icon_normal_color); theme->set_color("icon_hover_color", "OptionButton", icon_hover_color); @@ -943,6 +955,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("arrow_margin", "OptionButton", widget_default_margin.x - 2 * EDSCALE); theme->set_constant("modulate_arrow", "OptionButton", true); theme->set_constant("h_separation", "OptionButton", 4 * EDSCALE); + theme->set_constant("outline_size", "OptionButton", 0 * EDSCALE); // CheckButton theme->set_stylebox("normal", "CheckButton", style_menu); @@ -967,6 +980,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "CheckButton", font_focus_color); theme->set_color("font_pressed_color", "CheckButton", accent_color); theme->set_color("font_disabled_color", "CheckButton", font_disabled_color); + theme->set_color("font_outline_color", "CheckButton", font_outline_color); theme->set_color("icon_normal_color", "CheckButton", icon_normal_color); theme->set_color("icon_hover_color", "CheckButton", icon_hover_color); @@ -976,6 +990,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_separation", "CheckButton", 8 * EDSCALE); theme->set_constant("check_v_offset", "CheckButton", 0 * EDSCALE); + theme->set_constant("outline_size", "CheckButton", 0 * EDSCALE); // Checkbox Ref<StyleBoxFlat> sb_checkbox = style_menu->duplicate(); @@ -1001,6 +1016,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "CheckBox", font_focus_color); theme->set_color("font_pressed_color", "CheckBox", accent_color); theme->set_color("font_disabled_color", "CheckBox", font_disabled_color); + theme->set_color("font_outline_color", "CheckBox", font_outline_color); theme->set_color("icon_normal_color", "CheckBox", icon_normal_color); theme->set_color("icon_hover_color", "CheckBox", icon_hover_color); @@ -1010,6 +1026,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_separation", "CheckBox", 8 * EDSCALE); theme->set_constant("check_v_offset", "CheckBox", 0 * EDSCALE); + theme->set_constant("outline_size", "CheckBox", 0 * EDSCALE); // PopupDialog theme->set_stylebox("panel", "PopupDialog", style_popup); @@ -1043,6 +1060,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_accelerator_color", "PopupMenu", font_disabled_color); theme->set_color("font_disabled_color", "PopupMenu", font_disabled_color); theme->set_color("font_separator_color", "PopupMenu", font_disabled_color); + theme->set_color("font_outline_color", "PopupMenu", font_outline_color); theme->set_icon("checked", "PopupMenu", theme->get_icon(SNAME("GuiChecked"), SNAME("EditorIcons"))); theme->set_icon("unchecked", "PopupMenu", theme->get_icon(SNAME("GuiUnchecked"), SNAME("EditorIcons"))); theme->set_icon("radio_checked", "PopupMenu", theme->get_icon(SNAME("GuiRadioChecked"), SNAME("EditorIcons"))); @@ -1063,6 +1081,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const int vsep_base = extra_spacing + default_margin_size + 6; const int force_even_vsep = vsep_base + (vsep_base % 2); theme->set_constant("v_separation", "PopupMenu", force_even_vsep * EDSCALE); + theme->set_constant("outline_size", "PopupMenu", 0 * EDSCALE); theme->set_constant("item_start_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); theme->set_constant("item_end_padding", "PopupMenu", default_margin_size * 1.5 * EDSCALE); @@ -1171,6 +1190,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("custom_button_font_highlight", "Tree", font_hover_color); theme->set_color("font_color", "Tree", font_color); theme->set_color("font_selected_color", "Tree", mono_color); + theme->set_color("font_outline_color", "Tree", font_outline_color); theme->set_color("title_button_color", "Tree", font_color); theme->set_color("drop_position_color", "Tree", accent_color); theme->set_constant("v_separation", "Tree", widget_default_margin.y - EDSCALE); @@ -1180,6 +1200,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); theme->set_constant("scroll_speed", "Tree", 12); + theme->set_constant("outline_size", "Tree", 0 * EDSCALE); const Color guide_color = mono_color * Color(1, 1, 1, 0.05); Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); @@ -1269,11 +1290,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("selected", "ItemList", style_tree_selected); theme->set_color("font_color", "ItemList", font_color); theme->set_color("font_selected_color", "ItemList", mono_color); + theme->set_color("font_outline_color", "ItemList", font_outline_color); theme->set_color("guide_color", "ItemList", guide_color); theme->set_constant("v_separation", "ItemList", force_even_vsep * 0.5 * EDSCALE); theme->set_constant("h_separation", "ItemList", 6 * EDSCALE); theme->set_constant("icon_margin", "ItemList", 6 * EDSCALE); theme->set_constant("line_separation", "ItemList", 3 * EDSCALE); + theme->set_constant("outline_size", "ItemList", 0 * EDSCALE); // TabBar & TabContainer Ref<StyleBoxFlat> style_tabbar_background = make_flat_stylebox(dark_color_1, 0, 0, 0, 0, corner_radius * EDSCALE); @@ -1291,8 +1314,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("button_highlight", "TabBar", style_menu); theme->set_color("font_selected_color", "TabContainer", font_color); theme->set_color("font_unselected_color", "TabContainer", font_disabled_color); + theme->set_color("font_outline_color", "TabContainer", font_outline_color); theme->set_color("font_selected_color", "TabBar", font_color); theme->set_color("font_unselected_color", "TabBar", font_disabled_color); + theme->set_color("font_outline_color", "TabBar", font_outline_color); theme->set_color("drop_mark_color", "TabContainer", tab_highlight); theme->set_color("drop_mark_color", "TabBar", tab_highlight); theme->set_icon("menu", "TabContainer", theme->get_icon(SNAME("GuiTabMenu"), SNAME("EditorIcons"))); @@ -1309,7 +1334,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("drop_mark", "TabContainer", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); theme->set_icon("drop_mark", "TabBar", theme->get_icon(SNAME("GuiTabDropMark"), SNAME("EditorIcons"))); theme->set_constant("side_margin", "TabContainer", 0); + theme->set_constant("outline_size", "TabContainer", 0 * EDSCALE); theme->set_constant("h_separation", "TabBar", 4 * EDSCALE); + theme->set_constant("outline_size", "TabBar", 0 * EDSCALE); // Content of each tab. Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); @@ -1400,10 +1427,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_selected_color", "LineEdit", mono_color); theme->set_color("font_uneditable_color", "LineEdit", font_readonly_color); theme->set_color("font_placeholder_color", "LineEdit", font_placeholder_color); + theme->set_color("font_outline_color", "LineEdit", font_outline_color); theme->set_color("caret_color", "LineEdit", font_color); theme->set_color("selection_color", "LineEdit", selection_color); theme->set_color("clear_button_color", "LineEdit", font_color); theme->set_color("clear_button_color_pressed", "LineEdit", accent_color); + theme->set_constant("outline_size", "LineEdit", 0 * EDSCALE); // TextEdit theme->set_stylebox("normal", "TextEdit", style_line_edit); @@ -1414,9 +1443,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "TextEdit", font_color); theme->set_color("font_readonly_color", "TextEdit", font_readonly_color); theme->set_color("font_placeholder_color", "TextEdit", font_placeholder_color); + theme->set_color("font_outline_color", "TextEdit", font_outline_color); theme->set_color("caret_color", "TextEdit", font_color); theme->set_color("selection_color", "TextEdit", selection_color); theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); + theme->set_constant("outline_size", "TextEdit", 0 * EDSCALE); theme->set_icon("h_grabber", "SplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); theme->set_icon("v_grabber", "SplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); @@ -1549,9 +1580,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // RichTextLabel theme->set_color("default_color", "RichTextLabel", font_color); theme->set_color("font_shadow_color", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color("font_outline_color", "RichTextLabel", font_outline_color); theme->set_constant("shadow_offset_x", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_offset_y", "RichTextLabel", 1 * EDSCALE); theme->set_constant("shadow_outline_size", "RichTextLabel", 1 * EDSCALE); + theme->set_constant("outline_size", "RichTextLabel", 0 * EDSCALE); theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); theme->set_stylebox("normal", "RichTextLabel", style_tree_bg); @@ -1590,10 +1623,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("normal", "Label", style_empty); theme->set_color("font_color", "Label", font_color); theme->set_color("font_shadow_color", "Label", Color(0, 0, 0, 0)); + theme->set_color("font_outline_color", "Label", font_outline_color); theme->set_constant("shadow_offset_x", "Label", 1 * EDSCALE); theme->set_constant("shadow_offset_y", "Label", 1 * EDSCALE); theme->set_constant("shadow_outline_size", "Label", 1 * EDSCALE); theme->set_constant("line_spacing", "Label", 3 * EDSCALE); + theme->set_constant("outline_size", "Label", 0 * EDSCALE); // LinkButton theme->set_stylebox("focus", "LinkButton", style_empty); @@ -1603,6 +1638,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_focus_color", "LinkButton", font_focus_color); theme->set_color("font_pressed_color", "LinkButton", accent_color); theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); + theme->set_color("font_outline_color", "LinkButton", font_outline_color); + + theme->set_constant("outline_size", "LinkButton", 0 * EDSCALE); // TooltipPanel + TooltipLabel // TooltipPanel is also used for custom tooltips, while TooltipLabel @@ -1638,6 +1676,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("background", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressBar"), SNAME("EditorIcons")), 4, 4, 4, 4, 0, 0, 0, 0)); theme->set_stylebox("fill", "ProgressBar", make_stylebox(theme->get_icon(SNAME("GuiProgressFill"), SNAME("EditorIcons")), 6, 6, 6, 6, 2, 1, 2, 1)); theme->set_color("font_color", "ProgressBar", font_color); + theme->set_color("font_outline_color", "ProgressBar", font_outline_color); + theme->set_constant("outline_size", "ProgressBar", 0 * EDSCALE); // GraphEdit theme->set_stylebox("bg", "GraphEdit", style_tree_bg); diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 96a8cc8b91..fe3c2333ed 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -247,7 +247,8 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa pd->file_ofs.push_back(sd); - if (pd->ep->step(TTR("Storing File:") + " " + p_path, 2 + p_file * 100 / p_total, false)) { + // TRANSLATORS: This is an editor progress label describing the storing of a file. + if (pd->ep->step(vformat(TTR("Storing File: %s"), p_path), 2 + p_file * 100 / p_total, false)) { return ERR_SKIP; } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index d0f04cb46f..32c16255dd 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -2267,6 +2267,7 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM Ref<EditorSceneFormatImporter> importer; String ext = p_source_file.get_extension().to_lower(); + // TRANSLATORS: This is an editor progress label. EditorProgress progress("pre-import", TTR("Pre-Import Scene"), 0); progress.step(TTR("Importing Scene..."), 0); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 6eebb84216..348aad1162 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -142,24 +142,23 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma String import_id; bool has_import_id = false; - bool created = false; - if (!material_set.has(p_material)) { - material_set.insert(p_material); - created = true; - } - if (p_material->has_meta("import_id")) { import_id = p_material->get_meta("import_id"); has_import_id = true; } else if (!p_material->get_name().is_empty()) { import_id = p_material->get_name(); has_import_id = true; + } else if (unnamed_material_name_map.has(p_material)) { + import_id = unnamed_material_name_map[p_material]; } else { - import_id = "@MATERIAL:" + itos(material_set.size() - 1); + import_id = "@MATERIAL:" + itos(material_map.size()); + unnamed_material_name_map[p_material] = import_id; } + bool created = false; if (!material_map.has(import_id)) { MaterialData md; + created = true; md.has_import_id = has_import_id; md.material = p_material; @@ -169,6 +168,7 @@ void SceneImportSettings::_fill_material(Tree *p_tree, const Ref<Material> &p_ma } MaterialData &material_data = material_map[import_id]; + ERR_FAIL_COND(p_material != material_data.material); Ref<Texture2D> icon = get_theme_icon(SNAME("StandardMaterial3D"), SNAME("EditorIcons")); @@ -564,10 +564,10 @@ void SceneImportSettings::open_settings(const String &p_path, bool p_for_animati base_path = p_path; - material_set.clear(); mesh_set.clear(); animation_map.clear(); material_map.clear(); + unnamed_material_name_map.clear(); mesh_map.clear(); node_map.clear(); defaults.clear(); diff --git a/editor/import/scene_import_settings.h b/editor/import/scene_import_settings.h index 69bf58b627..d65bb1404a 100644 --- a/editor/import/scene_import_settings.h +++ b/editor/import/scene_import_settings.h @@ -107,6 +107,7 @@ class SceneImportSettings : public ConfirmationDialog { HashMap<StringName, Variant> settings; }; HashMap<String, MaterialData> material_map; + HashMap<Ref<Material>, String> unnamed_material_name_map; struct MeshData { bool has_import_id; @@ -141,7 +142,6 @@ class SceneImportSettings : public ConfirmationDialog { void _fill_scene(Node *p_node, TreeItem *p_parent_item); HashSet<Ref<Mesh>> mesh_set; - HashSet<Ref<Material>> material_set; String selected_type; String selected_id; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index b33ad67f23..c5bfd968d7 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1134,6 +1134,7 @@ void AnimationPlayerEditor::_animation_duplicate() { name_dialog_op = TOOL_DUPLICATE_ANIM; name_dialog->set_title(TTR("Duplicate Animation")); + // TRANSLATORS: This is a label for the new name field in the "Duplicate Animation" dialog. name_title->set_text(TTR("Duplicated Animation Name:")); name->set_text(new_name); name_dialog->popup_centered(Size2(300, 90)); diff --git a/editor/plugins/cast_2d_editor_plugin.cpp b/editor/plugins/cast_2d_editor_plugin.cpp index 723082c293..331b4749cc 100644 --- a/editor/plugins/cast_2d_editor_plugin.cpp +++ b/editor/plugins/cast_2d_editor_plugin.cpp @@ -78,7 +78,7 @@ bool Cast2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) { } } else if (pressed) { EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Set target_position")); + undo_redo->create_action(TTR("Set Target Position")); undo_redo->add_do_property(node, "target_position", target_position); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_property(node, "target_position", original_target_position); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index fc1d8936d5..96f5aeedf0 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1666,6 +1666,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } break; case TRANSFORM_Z_AXIS: { _edit.plane = TRANSFORM_VIEW; + // TRANSLATORS: This refers to the transform of the view plane. set_message(TTR("View Plane Transform."), 2); } break; @@ -4956,6 +4957,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_lock_rotation", TTR("Lock View Rotation")), VIEW_LOCK_ROTATION); view_menu->get_popup()->add_separator(); + // TRANSLATORS: "Normal" as in "normal life", not "normal vector". view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL); view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME); view_menu->get_popup()->add_radio_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 073adb467a..2519928ea3 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -3223,6 +3223,7 @@ void ThemeTypeEditor::_update_stylebox_from_leading() { if (!leading_stylebox.pinned || leading_stylebox.stylebox.is_null()) { return; } + ERR_FAIL_COND_MSG(edited_theme.is_null(), "Leading stylebox does not have an edited theme to update"); // Prevent changes from immediately being reported while the operation is still ongoing. edited_theme->_freeze_change_propagation(); @@ -3706,7 +3707,11 @@ void ThemeEditorPlugin::edit(Object *p_node) { if (Object::cast_to<Theme>(p_node)) { theme_editor->edit(Object::cast_to<Theme>(p_node)); } else { - theme_editor->edit(Ref<Theme>()); + // We intentionally keep a reference to the last used theme to work around + // the the editor being hidden while base resources are edited. Uncomment + // the following line again and remove this comment once that bug has been + // fixed (scheduled for Godot 4.1 in PR 73098): + // theme_editor->edit(Ref<Theme>()); } } diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index a43745b70f..374ce98d63 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -412,7 +412,7 @@ void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const Stri Dictionary action = GLOBAL_GET(old_property_name); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Rename Input Action Event")); + undo_redo->create_action(TTR("Rename Input Action")); // Do: clear old, set new undo_redo->add_do_method(ProjectSettings::get_singleton(), "clear", old_property_name); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", new_property_name, action); diff --git a/methods.py b/methods.py index 7ede2592ff..dddac9bd86 100644 --- a/methods.py +++ b/methods.py @@ -732,7 +732,7 @@ def add_to_vs_project(env, sources): env.vs_srcs += [basename + ".cpp"] -def generate_vs_project(env, num_jobs): +def generate_vs_project(env, num_jobs, project_name="godot"): batch_file = find_visual_c_batch_file(env) if batch_file: @@ -873,7 +873,7 @@ def generate_vs_project(env, num_jobs): env["MSVS"]["PROJECTSUFFIX"] = ".vcxproj" env["MSVS"]["SOLUTIONSUFFIX"] = ".sln" env.MSVSProject( - target=["#godot" + env["MSVSPROJECTSUFFIX"]], + target=["#" + project_name + env["MSVSPROJECTSUFFIX"]], incs=env.vs_incs, srcs=env.vs_srcs, auto_build_solution=1, diff --git a/misc/dist/ios_xcode/godot_ios/vulkan/icd.d/MoltenVK_icd.json b/misc/dist/ios_xcode/godot_ios/vulkan/icd.d/MoltenVK_icd.json deleted file mode 100644 index 7501cb548c..0000000000 --- a/misc/dist/ios_xcode/godot_ios/vulkan/icd.d/MoltenVK_icd.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_format_version" : "1.0.0", - "ICD": { - "library_path": "./../../Frameworks/MoltenVK.framework/MoltenVK", - "api_version" : "1.0.0" - } -} diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub index 161b0f3814..14669847bc 100644 --- a/modules/basis_universal/SCsub +++ b/modules/basis_universal/SCsub @@ -40,6 +40,9 @@ if not env.msvc: else: env_basisu.Prepend(CPPPATH=[thirdparty_dir]) +if env["builtin_zstd"]: + env_basisu.Prepend(CPPPATH=["#thirdparty/zstd"]) + if env.dev_build: env_basisu.Append(CPPDEFINES=[("BASISU_DEVEL_MESSAGES", 1), ("BASISD_ENABLE_DEBUG_FLAGS", 1)]) diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 46cd4b0d55..b34be11169 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -254,7 +254,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (codegen.script->member_indices.has(identifier)) { if (codegen.script->member_indices[identifier].getter != StringName() && codegen.script->member_indices[identifier].getter != codegen.function_name) { // Perform getter. - GDScriptCodeGenerator::Address temp = codegen.add_temporary(); + GDScriptCodeGenerator::Address temp = codegen.add_temporary(codegen.script->member_indices[identifier].data_type); Vector<GDScriptCodeGenerator::Address> args; // No argument needed. gen->write_call_self(temp, codegen.script->member_indices[identifier].getter, args); return temp; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 7a11ea52f0..4db41c4dfa 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -1244,7 +1244,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a "' to a variable of type '" + nc->get_name() + "'."; OPCODE_BREAK; } - Object *src_obj = src->operator Object *(); + + bool was_freed = false; + Object *src_obj = src->get_validated_object_with_check(was_freed); + if (!src_obj) { + if (was_freed) { + err_text = "Trying to assign invalid previously freed instance."; + } else { + err_text = "Trying to assign invalid null variable."; + } + OPCODE_BREAK; + } if (src_obj && !ClassDB::is_parent_class(src_obj->get_class_name(), nc->get_name())) { err_text = "Trying to assign value of type '" + src_obj->get_class_name() + @@ -1274,15 +1284,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } - if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) { - ScriptInstance *scr_inst = src->operator Object *()->get_script_instance(); + if (src->get_type() != Variant::NIL) { + bool was_freed = false; + Object *val_obj = src->get_validated_object_with_check(was_freed); + if (!val_obj) { + if (was_freed) { + err_text = "Trying to assign invalid previously freed instance."; + } else { + err_text = "Trying to assign invalid null variable."; + } + OPCODE_BREAK; + } + + ScriptInstance *scr_inst = val_obj->get_script_instance(); if (!scr_inst) { - err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() + + err_text = "Trying to assign value of type '" + val_obj->get_class_name() + "' to a variable of type '" + base_type->get_path().get_file() + "'."; OPCODE_BREAK; } - Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr(); + Script *src_type = val_obj->get_script_instance()->get_script().ptr(); bool valid = false; while (src_type) { @@ -1294,7 +1315,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } if (!valid) { - err_text = "Trying to assign value of type '" + src->operator Object *()->get_script_instance()->get_script()->get_path().get_file() + + err_text = "Trying to assign value of type '" + val_obj->get_script_instance()->get_script()->get_path().get_file() + "' to a variable of type '" + base_type->get_path().get_file() + "'."; OPCODE_BREAK; } diff --git a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd new file mode 100644 index 0000000000..dd2708b21d --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.gd @@ -0,0 +1,7 @@ +func test(): + var x = Node.new() + + x.free() + + var ok = x + var bad : Node = x diff --git a/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out new file mode 100644 index 0000000000..679e51ed81 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/native_freed_instance.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> analyzer/errors/native_freed_instance.gd +>> 7 +>> Trying to assign invalid previously freed instance. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd new file mode 100644 index 0000000000..758fbaccc9 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.gd @@ -0,0 +1,10 @@ +class A extends Node: + pass + +func test(): + var x = A.new() + + x.free() + + var ok = x + var bad : A = x diff --git a/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out new file mode 100644 index 0000000000..dec7090322 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/script_freed_instance.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> analyzer/errors/script_freed_instance.gd +>> 10 +>> Trying to assign invalid previously freed instance. diff --git a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd new file mode 100644 index 0000000000..38bb7f6e9c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.gd @@ -0,0 +1,9 @@ +var Value:int = 8 : + get: + return Value + set(v): + Value = v + +func test(): + var f:float = Value + print(int(f)) diff --git a/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out new file mode 100644 index 0000000000..b0cb63ef59 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/getter_return_type.out @@ -0,0 +1,2 @@ +GDTEST_OK +8 diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 183190460e..9a7b37df21 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -1197,6 +1197,7 @@ GridMapEditor::GridMapEditor() { options->get_popup()->add_item(TTR("Cursor Back Rotate Z"), MENU_OPTION_CURSOR_BACK_ROTATE_Z, KeyModifierMask::SHIFT + Key::D); options->get_popup()->add_item(TTR("Cursor Clear Rotation"), MENU_OPTION_CURSOR_CLEAR_ROTATION, Key::W); options->get_popup()->add_separator(); + // TRANSLATORS: This is a toggle to select after pasting the new content. options->get_popup()->add_check_item(TTR("Paste Selects"), MENU_OPTION_PASTE_SELECTS); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Duplicate Selection"), MENU_OPTION_SELECTION_DUPLICATE, KeyModifierMask::CTRL + Key::C); diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs index ed3a4c6e26..6c5c61acb9 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs @@ -302,7 +302,7 @@ namespace GodotTools.Build public static bool CleanProjectBlocking( [DisallowNull] string configuration, [AllowNull] string platform = null - ) => CleanProjectBlocking(CreateBuildInfo(configuration, platform, rebuild: false)); + ) => CleanProjectBlocking(CreateBuildInfo(configuration, platform, rebuild: false, onlyClean: true)); public static bool PublishProjectBlocking( [DisallowNull] string configuration, diff --git a/modules/navigation/SCsub b/modules/navigation/SCsub index 0b0822db2d..a9277657f4 100644 --- a/modules/navigation/SCsub +++ b/modules/navigation/SCsub @@ -10,7 +10,7 @@ env_navigation = env_modules.Clone() thirdparty_obj = [] # Recast Thirdparty source files -if env["builtin_recast"]: +if env["builtin_recastnavigation"]: thirdparty_dir = "#thirdparty/recastnavigation/Recast/" thirdparty_sources = [ "Source/Recast.cpp", diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h index 4aa5ffa254..7085504500 100644 --- a/modules/ogg/ogg_packet_sequence.h +++ b/modules/ogg/ogg_packet_sequence.h @@ -32,11 +32,10 @@ #define OGG_PACKET_SEQUENCE_H #include "core/io/resource.h" -#include "core/object/gdvirtual.gen.inc" -#include "core/variant/native_ptr.h" #include "core/variant/typed_array.h" #include "core/variant/variant.h" -#include "thirdparty/libogg/ogg/ogg.h" + +#include <ogg/ogg.h> class OggPacketSequencePlayback; diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub index 4a9c7b3567..b7b7dccdb0 100644 --- a/modules/text_server_adv/SCsub +++ b/modules/text_server_adv/SCsub @@ -7,7 +7,6 @@ env_text_server_adv = env_modules.Clone() def make_icu_data(target, source, env): - dst = target[0].srcnode().abspath g = open(dst, "w", encoding="utf-8") @@ -126,7 +125,7 @@ if env["builtin_harfbuzz"]: env_harfbuzz.Prepend(CPPPATH=["#thirdparty/harfbuzz/src"]) env_harfbuzz.Append(CCFLAGS=["-DHAVE_ICU"]) - if env["builtin_icu"]: + if env["builtin_icu4c"]: env_harfbuzz.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"]) env_harfbuzz.Append(CCFLAGS=["-DU_HAVE_LIB_SUFFIX=1", "-DU_LIB_SUFFIX_C_NAME=_godot", "-DHAVE_ICU_BUILTIN"]) @@ -240,7 +239,7 @@ if env["builtin_graphite"] and freetype_enabled and env["graphite"]: env.Append(LIBS=[lib]) -if env["builtin_icu"]: +if env["builtin_icu4c"]: env_icu = env_modules.Clone() env_icu.disable_warnings() diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index f3ae35ce42..fcd717cfec 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -32,7 +32,8 @@ #include "core/io/file_access.h" #include "core/variant/typed_array.h" -#include "thirdparty/libogg/ogg/ogg.h" + +#include <ogg/ogg.h> int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) { ERR_FAIL_COND_V(!ready, 0); diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h index ad6746eae2..c76df7f84d 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.h +++ b/modules/vorbis/audio_stream_ogg_vorbis.h @@ -34,7 +34,8 @@ #include "core/variant/variant.h" #include "modules/ogg/ogg_packet_sequence.h" #include "servers/audio/audio_stream.h" -#include "thirdparty/libvorbis/vorbis/codec.h" + +#include <vorbis/codec.h> class AudioStreamOggVorbis; diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp index b712d63030..9e280de0ca 100644 --- a/modules/vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp @@ -33,8 +33,9 @@ #include "core/io/file_access.h" #include "core/io/resource_saver.h" #include "scene/resources/texture.h" -#include "thirdparty/libogg/ogg/ogg.h" -#include "thirdparty/libvorbis/vorbis/codec.h" + +#include <ogg/ogg.h> +#include <vorbis/codec.h> #ifdef TOOLS_ENABLED #include "editor/import/audio_stream_import_settings.h" diff --git a/platform/ios/joypad_ios.mm b/platform/ios/joypad_ios.mm index 057f439b81..9194b09ef6 100644 --- a/platform/ios/joypad_ios.mm +++ b/platform/ios/joypad_ios.mm @@ -305,6 +305,25 @@ void JoypadIOS::start_processing() { float value = gamepad.rightTrigger.value; Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, value); } + + if (@available(iOS 13, *)) { + // iOS uses 'buttonOptions' and 'buttonMenu' names for BACK and START joy buttons. + if (element == gamepad.buttonOptions) { + Input::get_singleton()->joy_button(joy_id, JoyButton::BACK, + gamepad.buttonOptions.isPressed); + } else if (element == gamepad.buttonMenu) { + Input::get_singleton()->joy_button(joy_id, JoyButton::START, + gamepad.buttonMenu.isPressed); + } + } + + if (@available(iOS 14, *)) { + // iOS uses 'buttonHome' for the GUIDE joy button. + if (element == gamepad.buttonHome) { + Input::get_singleton()->joy_button(joy_id, JoyButton::GUIDE, + gamepad.buttonHome.isPressed); + } + } }; } else if (controller.microGamepad != nil) { // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index af2a271476..3f713d2db3 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -194,19 +194,21 @@ def configure(env: "Environment"): # FIXME: Check for existence of the libs before parsing their flags with pkg-config # freetype depends on libpng and zlib, so bundling one of them while keeping others - # as shared libraries leads to weird issues - if ( - env["builtin_freetype"] - or env["builtin_libpng"] - or env["builtin_zlib"] - or env["builtin_graphite"] - or env["builtin_harfbuzz"] - ): - env["builtin_freetype"] = True - env["builtin_libpng"] = True - env["builtin_zlib"] = True - env["builtin_graphite"] = True - env["builtin_harfbuzz"] = True + # as shared libraries leads to weird issues. And graphite and harfbuzz need freetype. + ft_linked_deps = [ + env["builtin_freetype"], + env["builtin_libpng"], + env["builtin_zlib"], + env["builtin_graphite"], + env["builtin_harfbuzz"], + ] + if (not all(ft_linked_deps)) and any(ft_linked_deps): # All or nothing. + print( + "These libraries should be either all builtin, or all system provided:\n" + "freetype, libpng, zlib, graphite, harfbuzz.\n" + "Please specify `builtin_<name>=no` for all of them, or none." + ) + sys.exit() if not env["builtin_freetype"]: env.ParseConfig("pkg-config freetype2 --cflags --libs") @@ -214,8 +216,8 @@ def configure(env: "Environment"): if not env["builtin_graphite"]: env.ParseConfig("pkg-config graphite2 --cflags --libs") - if not env["builtin_icu"]: - env.ParseConfig("pkg-config icu-uc --cflags --libs") + if not env["builtin_icu4c"]: + env.ParseConfig("pkg-config icu-i18n icu-uc --cflags --libs") if not env["builtin_harfbuzz"]: env.ParseConfig("pkg-config harfbuzz harfbuzz-icu --cflags --libs") @@ -270,6 +272,11 @@ def configure(env: "Environment"): if not env["builtin_pcre2"]: env.ParseConfig("pkg-config libpcre2-32 --cflags --libs") + if not env["builtin_recastnavigation"]: + # No pkgconfig file so far, hardcode default paths. + env.Prepend(CPPPATH=["/usr/include/recastnavigation"]) + env.Append(LIBS=["Recast"]) + if not env["builtin_embree"]: # No pkgconfig file so far, hardcode expected lib name. env.Append(LIBS=["embree3"]) diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 902fba38bf..c175edb6cb 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -234,7 +234,7 @@ float AudioStreamPlayer2D::get_volume_db() const { } void AudioStreamPlayer2D::set_pitch_scale(float p_pitch_scale) { - ERR_FAIL_COND(p_pitch_scale <= 0.0); + ERR_FAIL_COND(!(p_pitch_scale > 0.0)); pitch_scale = p_pitch_scale; for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { AudioServer::get_singleton()->set_playback_pitch_scale(playback, p_pitch_scale); diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 1ee6a0b779..bfe2f6252e 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -95,19 +95,19 @@ void NavigationAgent2D::_bind_methods() { ADD_GROUP("Pathfinding", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,suffix:px"), "set_path_max_distance", "get_path_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_path_desired_distance", "get_path_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:px"), "set_target_desired_distance", "get_target_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,or_greater,suffix:px"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags"); ADD_GROUP("Avoidance", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,suffix:px"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px"), "set_neighbor_distance", "get_neighbor_distance"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,or_greater,suffix:px"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,or_greater,suffix:px"), "set_neighbor_distance", "get_neighbor_distance"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,or_greater,1"), "set_max_neighbors", "get_max_neighbors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,or_greater,suffix:s"), "set_time_horizon", "get_time_horizon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,or_greater,suffix:px/s"), "set_max_speed", "get_max_speed"); ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled); ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled); diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp index 54ed96f585..1c2903fe22 100644 --- a/scene/2d/touch_screen_button.cpp +++ b/scene/2d/touch_screen_button.cpp @@ -194,10 +194,6 @@ void TouchScreenButton::input(const Ref<InputEvent> &p_event) { return; } - if (p_event->get_device() != 0) { - return; - } - const InputEventScreenTouch *st = Object::cast_to<InputEventScreenTouch>(*p_event); if (passby_press) { diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 77bf15125e..ac626d0d2a 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -559,7 +559,7 @@ float AudioStreamPlayer3D::get_max_db() const { } void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) { - ERR_FAIL_COND(p_pitch_scale <= 0.0); + ERR_FAIL_COND(!(p_pitch_scale > 0.0)); pitch_scale = p_pitch_scale; } diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 5b5ad62d64..396e4b72af 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -99,20 +99,20 @@ void NavigationAgent3D::_bind_methods() { ADD_GROUP("Pathfinding", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_position", "get_target_position"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_path_desired_distance", "get_path_desired_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_target_desired_distance", "get_target_desired_distance"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,suffix:m"), "set_agent_height_offset", "get_agent_height_offset"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,suffix:m"), "set_path_max_distance", "get_path_max_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_path_desired_distance", "get_path_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_target_desired_distance", "get_target_desired_distance"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "agent_height_offset", PROPERTY_HINT_RANGE, "-100.0,100,0.01,or_greater,suffix:m"), "set_agent_height_offset", "get_agent_height_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1,or_greater,suffix:m"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigation_layers", "get_navigation_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags"); ADD_GROUP("Avoidance", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:m"), "set_radius", "get_radius"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m"), "set_neighbor_distance", "get_neighbor_distance"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,100,0.01,suffix:s"), "set_time_horizon", "get_time_horizon"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:m/s"), "set_max_speed", "get_max_speed"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater,suffix:m"), "set_radius", "get_radius"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,10000,0.01,or_greater,suffix:m"), "set_neighbor_distance", "get_neighbor_distance"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1,or_greater"), "set_max_neighbors", "get_max_neighbors"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater,suffix:s"), "set_time_horizon", "get_time_horizon"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,1000,0.01,or_greater,suffix:m/s"), "set_max_speed", "get_max_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y"); ADD_SIGNAL(MethodInfo("path_changed")); diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 072ca1d3e8..cde826ed5c 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -52,14 +52,14 @@ class NavigationAgent3D : public Node { real_t path_desired_distance = 1.0; real_t target_desired_distance = 1.0; - real_t radius = 1.0; + real_t radius = 0.5; real_t navigation_height_offset = 0.0; bool ignore_y = true; real_t neighbor_distance = 50.0; int max_neighbors = 10; - real_t time_horizon = 5.0; + real_t time_horizon = 1.0; real_t max_speed = 10.0; - real_t path_max_distance = 3.0; + real_t path_max_distance = 5.0; Vector3 target_position; bool target_position_submitted = false; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index d169999de4..42b0748698 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -346,25 +346,29 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material } else { mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive } + if (mat->get_feature(BaseMaterial3D::FEATURE_EMISSION)) { + Ref<Texture2D> emission_tex = mat->get_texture(BaseMaterial3D::TEXTURE_EMISSION); - Ref<Texture2D> emission_tex = mat->get_texture(BaseMaterial3D::TEXTURE_EMISSION); - - Color emission_col = mat->get_emission(); - float emission_energy = mat->get_emission_energy_multiplier() * exposure_normalization; - if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { - emission_energy *= mat->get_emission_intensity(); - } + Color emission_col = mat->get_emission(); + float emission_energy = mat->get_emission_energy_multiplier() * exposure_normalization; + if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) { + emission_energy *= mat->get_emission_intensity(); + } - Ref<Image> img_emission; + Ref<Image> img_emission; - if (emission_tex.is_valid()) { - img_emission = emission_tex->get_image(); - } + if (emission_tex.is_valid()) { + img_emission = emission_tex->get_image(); + } - if (mat->get_emission_operator() == BaseMaterial3D::EMISSION_OP_ADD) { - mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy); + if (mat->get_emission_operator() == BaseMaterial3D::EMISSION_OP_ADD) { + mc.emission = _get_bake_texture(img_emission, Color(1, 1, 1) * emission_energy, emission_col * emission_energy); + } else { + mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0)); + } } else { - mc.emission = _get_bake_texture(img_emission, emission_col * emission_energy, Color(0, 0, 0)); + Ref<Image> empty; + mc.emission = _get_bake_texture(empty, Color(0, 0, 0), Color(0, 0, 0)); } } else { diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp index 7533a56b59..6c37d6f81d 100644 --- a/scene/audio/audio_stream_player.cpp +++ b/scene/audio/audio_stream_player.cpp @@ -111,7 +111,7 @@ float AudioStreamPlayer::get_volume_db() const { } void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) { - ERR_FAIL_COND(p_pitch_scale <= 0.0); + ERR_FAIL_COND(!(p_pitch_scale > 0.0)); pitch_scale = p_pitch_scale; for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 0b0698188c..48e3759981 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -31,10 +31,12 @@ #include "color_picker.h" #include "core/input/input.h" +#include "core/io/image.h" #include "core/math/color.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "scene/gui/color_mode.h" +#include "servers/display_server.h" #include "thirdparty/misc/ok_color.h" #include "thirdparty/misc/ok_color_shader.h" @@ -90,8 +92,8 @@ void ColorPicker::_notification(int p_what) { } break; case NOTIFICATION_WM_CLOSE_REQUEST: { - if (screen != nullptr && screen->is_visible()) { - screen->hide(); + if (picker_window != nullptr && picker_window->is_visible()) { + picker_window->hide(); } } break; } @@ -1372,30 +1374,26 @@ void ColorPicker::_recent_preset_pressed(const bool p_pressed, ColorPresetButton emit_signal(SNAME("color_changed"), p_preset->get_preset_color()); } -void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) { +void ColorPicker::_picker_texture_input(const Ref<InputEvent> &p_event) { if (!is_inside_tree()) { return; } Ref<InputEventMouseButton> bev = p_event; if (bev.is_valid() && bev->get_button_index() == MouseButton::LEFT && !bev->is_pressed()) { + set_pick_color(picker_color); emit_signal(SNAME("color_changed"), color); - screen->hide(); + picker_window->hide(); } Ref<InputEventMouseMotion> mev = p_event; if (mev.is_valid()) { - Viewport *r = get_tree()->get_root(); - if (!r->get_visible_rect().has_point(mev->get_global_position())) { - return; - } - - Ref<Image> img = r->get_texture()->get_image(); + Ref<Image> img = picker_texture_rect->get_texture()->get_image(); if (img.is_valid() && !img->is_empty()) { - Vector2 ofs = mev->get_global_position(); - Color c = img->get_pixel(ofs.x, ofs.y); - - set_pick_color(c); + Vector2 ofs = mev->get_position(); + picker_color = img->get_pixel(ofs.x, ofs.y); + picker_preview_style_box->set_bg_color(picker_color); + picker_preview_label->set_self_modulate(picker_color.get_luminance() < 0.5 ? Color(1.0f, 1.0f, 1.0f) : Color(0.0f, 0.0f, 0.0f)); } } } @@ -1409,27 +1407,79 @@ void ColorPicker::_add_preset_pressed() { emit_signal(SNAME("preset_added"), color); } -void ColorPicker::_screen_pick_pressed() { +void ColorPicker::_pick_button_pressed() { if (!is_inside_tree()) { return; } - Viewport *r = get_tree()->get_root(); - if (!screen) { - screen = memnew(Control); - r->add_child(screen); - screen->set_as_top_level(true); - screen->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - screen->set_default_cursor_shape(CURSOR_POINTING_HAND); - screen->connect("gui_input", callable_mp(this, &ColorPicker::_screen_input)); - // It immediately toggles off in the first press otherwise. - screen->call_deferred(SNAME("connect"), "hidden", Callable(btn_pick, "set_pressed").bind(false)); + if (!picker_window) { + picker_window = memnew(Popup); + picker_window->hide(); + picker_window->set_transient(true); + add_child(picker_window); + + picker_texture_rect = memnew(TextureRect); + picker_texture_rect->set_anchors_preset(Control::PRESET_FULL_RECT); + picker_window->add_child(picker_texture_rect); + picker_texture_rect->set_default_cursor_shape(CURSOR_POINTING_HAND); + picker_texture_rect->connect(SNAME("gui_input"), callable_mp(this, &ColorPicker::_picker_texture_input)); + + picker_preview = memnew(Panel); + picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP); + picker_preview->set_mouse_filter(MOUSE_FILTER_IGNORE); + picker_window->add_child(picker_preview); + + picker_preview_label = memnew(Label); + picker_preview->set_anchors_preset(Control::PRESET_CENTER_TOP); + picker_preview_label->set_text("Color Picking active"); + picker_preview->add_child(picker_preview_label); + + picker_preview_style_box = (Ref<StyleBoxFlat>)memnew(StyleBoxFlat); + picker_preview_style_box->set_bg_color(Color(1.0, 1.0, 1.0)); + picker_preview->add_theme_style_override("panel", picker_preview_style_box); + } + + Rect2i screen_rect; + if (picker_window->is_embedded()) { + screen_rect = picker_window->get_embedder()->get_visible_rect(); + picker_window->set_position(Point2i()); + picker_texture_rect->set_texture(ImageTexture::create_from_image(picker_window->get_embedder()->get_texture()->get_image())); } else { - screen->show(); + screen_rect = picker_window->get_parent_rect(); + picker_window->set_position(screen_rect.position); + + Ref<Image> target_image = Image::create_empty(screen_rect.size.x, screen_rect.size.y, false, Image::FORMAT_RGB8); + DisplayServer *ds = DisplayServer::get_singleton(); + + // Add the Texture of each Window to the Image. + Vector<DisplayServer::WindowID> wl = ds->get_window_list(); + // FIXME: sort windows by visibility. + for (int index = 0; index < wl.size(); index++) { + DisplayServer::WindowID wid = wl[index]; + if (wid == DisplayServer::INVALID_WINDOW_ID) { + continue; + } + + ObjectID woid = DisplayServer::get_singleton()->window_get_attached_instance_id(wid); + if (woid == ObjectID()) { + continue; + } + + Window *w = Object::cast_to<Window>(ObjectDB::get_instance(woid)); + Ref<Image> img = w->get_texture()->get_image(); + if (!img.is_valid() || img->is_empty()) { + continue; + } + img->convert(Image::FORMAT_RGB8); + target_image->blit_rect(img, Rect2i(Point2i(0, 0), img->get_size()), w->get_position()); + } + + picker_texture_rect->set_texture(ImageTexture::create_from_image(target_image)); } - screen->move_to_front(); - // TODO: show modal no longer works, needs to be converted to a popup. - //screen->show_modal(); + + picker_window->set_size(screen_rect.size); + picker_preview->set_size(screen_rect.size / 10.0); // 10% of size in each axis. + picker_window->popup(); } void ColorPicker::_html_focus_exit() { @@ -1595,9 +1645,8 @@ ColorPicker::ColorPicker() { btn_pick = memnew(Button); sample_hbc->add_child(btn_pick); - btn_pick->set_toggle_mode(true); - btn_pick->set_tooltip_text(RTR("Pick a color from the editor window.")); - btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed)); + btn_pick->set_tooltip_text(RTR("Pick a color from the application window.")); + btn_pick->connect(SNAME("pressed"), callable_mp(this, &ColorPicker::_pick_button_pressed)); sample = memnew(TextureRect); sample_hbc->add_child(sample); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index f7578612cd..d02c3278e6 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -40,6 +40,7 @@ #include "scene/gui/line_edit.h" #include "scene/gui/menu_button.h" #include "scene/gui/option_button.h" +#include "scene/gui/panel.h" #include "scene/gui/popup.h" #include "scene/gui/separator.h" #include "scene/gui/slider.h" @@ -111,7 +112,12 @@ private: Vector<ColorMode *> modes; - Control *screen = nullptr; + Popup *picker_window = nullptr; + TextureRect *picker_texture_rect = nullptr; + Panel *picker_preview = nullptr; + Label *picker_preview_label = nullptr; + Ref<StyleBoxFlat> picker_preview_style_box; + Color picker_color; Control *uv_edit = nullptr; Control *w_edit = nullptr; AspectRatioContainer *wheel_edit = nullptr; @@ -211,10 +217,10 @@ private: void _line_edit_input(const Ref<InputEvent> &p_event); void _preset_input(const Ref<InputEvent> &p_event, const Color &p_color); void _recent_preset_pressed(const bool pressed, ColorPresetButton *p_preset); - void _screen_input(const Ref<InputEvent> &p_event); + void _picker_texture_input(const Ref<InputEvent> &p_event); void _text_changed(const String &p_new_text); void _add_preset_pressed(); - void _screen_pick_pressed(); + void _pick_button_pressed(); void _html_focus_exit(); inline int _get_preset_size(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 5dd8cde342..ee065cccbf 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -347,14 +347,15 @@ void FileDialog::_action_pressed() { } } - if (!valid) { + String file_name = file_text.strip_edges().get_file(); + if (!valid || file_name.is_empty()) { exterr->popup_centered(Size2(250, 80)); return; } if (dir_access->file_exists(f)) { - confirm_save->set_text(RTR("File exists, overwrite?")); - confirm_save->popup_centered(Size2(200, 80)); + confirm_save->set_text(vformat(RTR("File \"%s\" already exists.\nDo you want to overwrite it?"), f)); + confirm_save->popup_centered(Size2(250, 80)); } else { emit_signal(SNAME("file_selected"), f); hide(); @@ -1136,7 +1137,7 @@ FileDialog::FileDialog() { add_child(mkdirerr, false, INTERNAL_MODE_FRONT); exterr = memnew(AcceptDialog); - exterr->set_text(RTR("Must use a valid extension.")); + exterr->set_text(RTR("Invalid extension, or empty filename.")); add_child(exterr, false, INTERNAL_MODE_FRONT); update_filters(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 2c1c44322a..973b02b3a3 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1179,7 +1179,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; - draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2)); } if (_find_strikethrough(it)) { if (!st_started) { @@ -1341,7 +1341,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; - draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2)); } if (st_started) { st_started = false; @@ -1363,7 +1363,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o dot_ul_started = false; float y_off = TS->shaped_text_get_underline_position(rid); float underline_width = TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale; - draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, underline_width * 2); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2)); } if (st_started) { st_started = false; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index e5dcdd2afd..b36353158b 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -513,14 +513,16 @@ bool CanvasItem::is_y_sort_enabled() const { void CanvasItem::draw_dashed_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, real_t p_width, real_t p_dash, bool p_aligned) { ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); + ERR_FAIL_COND(p_dash <= 0.0); float length = (p_to - p_from).length(); - if (length < p_dash) { + Vector2 step = p_dash * (p_to - p_from).normalized(); + + if (length < p_dash || step == Vector2()) { RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width); return; } - Vector2 step = p_dash * (p_to - p_from).normalized(); int steps = (p_aligned) ? Math::ceil(length / p_dash) : Math::floor(length / p_dash); if (steps % 2 == 0) { steps--; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 126b1d54fc..244e0d5b93 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1330,7 +1330,7 @@ void Viewport::_gui_show_tooltip() { Window *window = gui.tooltip_popup->get_parent_visible_window(); Rect2i vr; if (gui.tooltip_popup->is_embedded()) { - vr = gui.tooltip_popup->_get_embedder()->get_visible_rect(); + vr = gui.tooltip_popup->get_embedder()->get_visible_rect(); } else { vr = window->get_usable_parent_rect(); } @@ -1851,7 +1851,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { Window *w = Object::cast_to<Window>(this); if (w) { if (w->is_embedded()) { - embedder = w->_get_embedder(); + embedder = w->get_embedder(); viewport_pos = get_final_transform().xform(mpos) + w->get_position(); // To parent coords. } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index b79a9ba444..59e3d307c6 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -485,7 +485,7 @@ void Window::set_ime_position(const Point2i &p_pos) { bool Window::is_embedded() const { ERR_FAIL_COND_V(!is_inside_tree(), false); - return _get_embedder() != nullptr; + return get_embedder() != nullptr; } bool Window::is_in_edited_scene_root() const { @@ -710,7 +710,7 @@ void Window::set_visible(bool p_visible) { // Stop any queued resizing, as the window will be resized right now. updating_child_controls = false; - Viewport *embedder_vp = _get_embedder(); + Viewport *embedder_vp = get_embedder(); if (!embedder_vp) { if (!p_visible && window_id != DisplayServer::INVALID_WINDOW_ID) { @@ -1053,7 +1053,7 @@ void Window::_update_window_callbacks() { DisplayServer::get_singleton()->window_set_drop_files_callback(callable_mp(this, &Window::_window_drop_files), window_id); } -Viewport *Window::_get_embedder() const { +Viewport *Window::get_embedder() const { Viewport *vp = get_parent_viewport(); while (vp) { @@ -1088,7 +1088,7 @@ void Window::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { bool embedded = false; { - embedder = _get_embedder(); + embedder = get_embedder(); if (embedder) { embedded = true; if (!visible) { @@ -1431,7 +1431,7 @@ void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio Rect2 parent_rect; if (is_embedded()) { - parent_rect = _get_embedder()->get_visible_rect(); + parent_rect = get_embedder()->get_visible_rect(); } else { DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id(); int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id); @@ -1462,7 +1462,7 @@ void Window::popup_centered(const Size2i &p_minsize) { Rect2 parent_rect; if (is_embedded()) { - parent_rect = _get_embedder()->get_visible_rect(); + parent_rect = get_embedder()->get_visible_rect(); } else { DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id(); int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id); @@ -1488,7 +1488,7 @@ void Window::popup_centered_ratio(float p_ratio) { Rect2 parent_rect; if (is_embedded()) { - parent_rect = _get_embedder()->get_visible_rect(); + parent_rect = get_embedder()->get_visible_rect(); } else { DisplayServer::WindowID parent_id = get_parent_visible_window()->get_window_id(); int parent_screen = DisplayServer::get_singleton()->window_get_current_screen(parent_id); @@ -1509,7 +1509,7 @@ void Window::popup_centered_ratio(float p_ratio) { void Window::popup(const Rect2i &p_screen_rect) { emit_signal(SNAME("about_to_popup")); - if (!_get_embedder() && get_flag(FLAG_POPUP)) { + if (!get_embedder() && get_flag(FLAG_POPUP)) { // Send a focus-out notification when opening a Window Manager Popup. SceneTree *scene_tree = get_tree(); if (scene_tree) { @@ -1545,7 +1545,7 @@ void Window::popup(const Rect2i &p_screen_rect) { Rect2i parent_rect; if (is_embedded()) { - parent_rect = _get_embedder()->get_visible_rect(); + parent_rect = get_embedder()->get_visible_rect(); } else { int screen_id = DisplayServer::get_singleton()->window_get_current_screen(get_window_id()); parent_rect = DisplayServer::get_singleton()->screen_get_usable_rect(screen_id); @@ -1587,7 +1587,7 @@ Rect2i Window::get_usable_parent_rect() const { ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); Rect2i parent_rect; if (is_embedded()) { - parent_rect = _get_embedder()->get_visible_rect(); + parent_rect = get_embedder()->get_visible_rect(); } else { const Window *w = is_visible() ? this : get_parent_visible_window(); //find a parent that can contain us @@ -2154,9 +2154,9 @@ Transform2D Window::get_final_transform() const { Transform2D Window::get_screen_transform_internal(bool p_absolute_position) const { Transform2D embedder_transform; - if (_get_embedder()) { + if (get_embedder()) { embedder_transform.translate_local(get_position()); - embedder_transform = _get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform; + embedder_transform = get_embedder()->get_screen_transform_internal(p_absolute_position) * embedder_transform; } else if (p_absolute_position) { embedder_transform.translate_local(get_position()); } @@ -2170,8 +2170,8 @@ Transform2D Window::get_popup_base_transform() const { Transform2D popup_base_transform; popup_base_transform.set_origin(get_position()); popup_base_transform *= get_final_transform(); - if (_get_embedder()) { - return _get_embedder()->get_popup_base_transform() * popup_base_transform; + if (get_embedder()) { + return get_embedder()->get_popup_base_transform() * popup_base_transform; } return popup_base_transform; } diff --git a/scene/main/window.h b/scene/main/window.h index 5359c37e9a..40b629ed11 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -192,7 +192,6 @@ private: Ref<Shortcut> debugger_stop_shortcut; protected: - Viewport *_get_embedder() const; virtual Rect2i _popup_adjust_rect() const { return Rect2i(); } virtual void _update_theme_item_cache(); @@ -278,6 +277,7 @@ public: void set_ime_position(const Point2i &p_pos); bool is_embedded() const; + Viewport *get_embedder() const; void set_content_scale_size(const Size2i &p_size); Size2i get_content_scale_size() const; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 7e3156d2ff..05be40c446 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2566,73 +2566,6 @@ void GradientTexture2D::_bind_methods() { ////////////////////////////////////// -void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) { - ERR_FAIL_COND(p_texture == this); - - base = p_texture; - if (base.is_valid()) { - ERR_FAIL_NULL(RenderingServer::get_singleton()); - if (proxy_ph.is_valid()) { - RS::get_singleton()->texture_proxy_update(proxy, base->get_rid()); - RS::get_singleton()->free(proxy_ph); - proxy_ph = RID(); - } else if (proxy.is_valid()) { - RS::get_singleton()->texture_proxy_update(proxy, base->get_rid()); - } else { - proxy = RS::get_singleton()->texture_proxy_create(base->get_rid()); - } - } -} - -Ref<Texture2D> ProxyTexture::get_base() const { - return base; -} - -int ProxyTexture::get_width() const { - if (base.is_valid()) { - return base->get_width(); - } - return 1; -} - -int ProxyTexture::get_height() const { - if (base.is_valid()) { - return base->get_height(); - } - return 1; -} - -RID ProxyTexture::get_rid() const { - if (proxy.is_null()) { - proxy_ph = RS::get_singleton()->texture_2d_placeholder_create(); - proxy = RS::get_singleton()->texture_proxy_create(proxy_ph); - } - return proxy; -} - -bool ProxyTexture::has_alpha() const { - if (base.is_valid()) { - return base->has_alpha(); - } - return false; -} - -ProxyTexture::ProxyTexture() { - //proxy = RS::get_singleton()->texture_create(); -} - -ProxyTexture::~ProxyTexture() { - ERR_FAIL_NULL(RenderingServer::get_singleton()); - if (proxy_ph.is_valid()) { - RS::get_singleton()->free(proxy_ph); - } - if (proxy.is_valid()) { - RS::get_singleton()->free(proxy); - } -} - -////////////////////////////////////////////// - void AnimatedTexture::_update_proxy() { RWLockRead r(rw_lock); @@ -2704,6 +2637,7 @@ void AnimatedTexture::set_current_frame(int p_frame) { RWLockWrite r(rw_lock); current_frame = p_frame; + time = 0; } int AnimatedTexture::get_current_frame() const { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 7f74ae6941..7c4d479da8 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -892,29 +892,6 @@ public: VARIANT_ENUM_CAST(GradientTexture2D::Fill); VARIANT_ENUM_CAST(GradientTexture2D::Repeat); -class ProxyTexture : public Texture2D { -private: - mutable RID proxy_ph; - mutable RID proxy; - Ref<Texture2D> base; - -protected: - static void _bind_methods(); - -public: - void set_base(const Ref<Texture2D> &p_texture); - Ref<Texture2D> get_base() const; - - virtual int get_width() const override; - virtual int get_height() const override; - virtual RID get_rid() const override; - - virtual bool has_alpha() const override; - - ProxyTexture(); - ~ProxyTexture(); -}; - class AnimatedTexture : public Texture2D { GDCLASS(AnimatedTexture, Texture2D); diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp index 2693b2a56a..11c1d44472 100644 --- a/servers/audio/effects/audio_effect_pitch_shift.cpp +++ b/servers/audio/effects/audio_effect_pitch_shift.cpp @@ -309,7 +309,7 @@ Ref<AudioEffectInstance> AudioEffectPitchShift::instantiate() { } void AudioEffectPitchShift::set_pitch_scale(float p_pitch_scale) { - ERR_FAIL_COND(p_pitch_scale <= 0.0); + ERR_FAIL_COND(!(p_pitch_scale > 0.0)); pitch_scale = p_pitch_scale; } diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp index 300dca4e08..d566d612ce 100644 --- a/servers/physics_3d/godot_shape_3d.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -1092,6 +1092,8 @@ void GodotConvexPolygonShape3D::_setup(const Vector<Vector3> &p_vertices) { if (err != OK) { ERR_PRINT("Failed to build convex hull"); } + extreme_vertices.resize(0); + vertex_neighbors.resize(0); AABB _aabb; diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp index e031e33041..9389f8149e 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.cpp +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -484,7 +484,7 @@ void SSEffects::downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uin downsample_uniform_set = uniform_set_cache->get_cache_vec(shader, 2, u_depths); } - float depth_linearize_mul = -p_projection.columns[3][2]; + float depth_linearize_mul = -p_projection.columns[3][2] * 0.5; float depth_linearize_add = p_projection.columns[2][2]; if (depth_linearize_mul * depth_linearize_add < 0) { depth_linearize_add = -depth_linearize_add; @@ -668,8 +668,14 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; - ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssil_buffers.buffer_width; - ssil.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssil_buffers.buffer_height; + ssil.gather_push_constant.half_screen_pixel_size[0] = 2.0 / p_settings.full_screen_size.x; + ssil.gather_push_constant.half_screen_pixel_size[1] = 2.0 / p_settings.full_screen_size.y; + if (ssil_half_size) { + ssil.gather_push_constant.half_screen_pixel_size[0] *= 2.0; + ssil.gather_push_constant.half_screen_pixel_size[1] *= 2.0; + } + ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.75; + ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.75; float tan_half_fov_x = 1.0 / p_projection.columns[0][0]; float tan_half_fov_y = 1.0 / p_projection.columns[1][1]; ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; @@ -680,9 +686,6 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende ssil.gather_push_constant.z_far = p_projection.get_z_far(); ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); - ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25; - ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25; - ssil.gather_push_constant.radius = p_settings.radius; float radius_near_limit = (p_settings.radius * 1.2f); if (ssil_quality <= RS::ENV_SSIL_QUALITY_LOW) { @@ -733,7 +736,7 @@ void SSEffects::screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_rende RD::Uniform u_depth_texture_view; u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_depth_texture_view.binding = 0; - u_depth_texture_view.append_id(default_sampler); + u_depth_texture_view.append_id(ss_effects.mirror_sampler); u_depth_texture_view.append_id(depth_texture_view); RD::Uniform u_normal_buffer; @@ -1056,8 +1059,14 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe ssao.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x; ssao.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y; - ssao.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_ssao_buffers.buffer_width; - ssao.gather_push_constant.half_screen_pixel_size[1] = 1.0 / p_ssao_buffers.buffer_height; + ssao.gather_push_constant.half_screen_pixel_size[0] = 2.0 / p_settings.full_screen_size.x; + ssao.gather_push_constant.half_screen_pixel_size[1] = 2.0 / p_settings.full_screen_size.y; + if (ssao_half_size) { + ssao.gather_push_constant.half_screen_pixel_size[0] *= 2.0; + ssao.gather_push_constant.half_screen_pixel_size[1] *= 2.0; + } + ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.75; + ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.75; float tan_half_fov_x = 1.0 / p_projection.columns[0][0]; float tan_half_fov_y = 1.0 / p_projection.columns[1][1]; ssao.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0; @@ -1066,9 +1075,6 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe ssao.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y; ssao.gather_push_constant.is_orthogonal = p_projection.is_orthogonal(); - ssao.gather_push_constant.half_screen_pixel_size_x025[0] = ssao.gather_push_constant.half_screen_pixel_size[0] * 0.25; - ssao.gather_push_constant.half_screen_pixel_size_x025[1] = ssao.gather_push_constant.half_screen_pixel_size[1] * 0.25; - ssao.gather_push_constant.radius = p_settings.radius; float radius_near_limit = (p_settings.radius * 1.2f); if (ssao_quality <= RS::ENV_SSAO_QUALITY_LOW) { @@ -1105,7 +1111,7 @@ void SSEffects::generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORe RD::Uniform u_depth_texture_view; u_depth_texture_view.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u_depth_texture_view.binding = 0; - u_depth_texture_view.append_id(default_sampler); + u_depth_texture_view.append_id(ss_effects.mirror_sampler); u_depth_texture_view.append_id(depth_texture_view); RD::Uniform u_normal_buffer; diff --git a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl index b1ff46dd3b..4f81e36c58 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl @@ -161,17 +161,11 @@ void prepare_depths_and_mips(vec4 p_samples, uvec2 p_output_coord, uvec2 p_gtid) still_alive = p_gtid.x % 16 == depth_array_offset.x && depth_array_offset.y % 16 == depth_array_offset.y; p_output_coord /= 2; - groupMemoryBarrier(); - barrier(); if (still_alive) { + // Use the previous average, not ideal, but still not bad. float sample_00 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 0]; - float sample_01 = depth_buffer[depth_array_index][buffer_coord.x + 0][buffer_coord.y + 8]; - float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 0]; - float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 8]; - - float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11)); - imageStore(dest_image4, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg)); + imageStore(dest_image4, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(sample_00)); } #endif } @@ -190,6 +184,7 @@ void prepare_depths(vec4 p_samples, uvec2 p_tid) { void main() { #ifdef USE_HALF_BUFFERS +// Half buffers means that we divide depth into two half res buffers (we only capture 1/4 of pixels). #ifdef USE_HALF_SIZE float sample_00 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 0, 4 * gl_GlobalInvocationID.y + 0), 0).x; float sample_11 = texelFetch(source_depth, ivec2(4 * gl_GlobalInvocationID.x + 2, 4 * gl_GlobalInvocationID.y + 2), 0).x; @@ -219,11 +214,11 @@ void main() { vec2 uv = (vec2(depth_buffer_coord) + 0.5f) * params.pixel_size; vec4 samples = textureGather(source_depth, uv); -#endif +#endif //USE_HALF_SIZE #ifdef GENERATE_MIPS prepare_depths_and_mips(samples, output_coord, gl_LocalInvocationID.xy); #else prepare_depths(samples, gl_GlobalInvocationID.xy); #endif -#endif +#endif //USE_HALF_BUFFERS } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index a727e83513..940363a7e8 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -8780,7 +8780,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f --texture_uniforms; --texture_binding; if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") { - _set_error(RTR("'hint_normal_roughness_texture is not supported in gl_compatibility shaders.")); + _set_error(RTR("'hint_normal_roughness_texture' is not supported in gl_compatibility shaders.")); return ERR_PARSE_ERROR; } } break; diff --git a/tests/core/templates/test_paged_array.h b/tests/core/templates/test_paged_array.h index 37be3080e8..10dc4473ca 100644 --- a/tests/core/templates/test_paged_array.h +++ b/tests/core/templates/test_paged_array.h @@ -148,6 +148,57 @@ TEST_CASE("[PagedArray] Shared pool fill, including merging") { array2.reset(); //reset so pagepool can be reset pool.reset(); } + +TEST_CASE("[PagedArray] Extensive merge_unordered() test") { + for (int page_size = 1; page_size <= 128; page_size *= 2) { + PagedArrayPool<uint32_t> pool(page_size); + PagedArray<uint32_t> array1; + PagedArray<uint32_t> array2; + array1.set_page_pool(&pool); + array2.set_page_pool(&pool); + + const int max_count = 123; + // Test merging arrays of lengths 0+123, 1+122, 2+121, ..., 123+0 + for (uint32_t j = 0; j < max_count; j++) { + CHECK(array1.size() == 0); + CHECK(array2.size() == 0); + + uint32_t sum = 12345; + for (uint32_t i = 0; i < j; i++) { + // Hashing the addend makes it extremely unlikely for any values + // other than the original inputs to produce a matching sum + uint32_t addend = hash_murmur3_one_32(i) + i; + array1.push_back(addend); + sum += addend; + } + for (uint32_t i = j; i < max_count; i++) { + // See above + uint32_t addend = hash_murmur3_one_32(i) + i; + array2.push_back(addend); + sum += addend; + } + + CHECK(array1.size() == j); + CHECK(array2.size() == max_count - j); + + array1.merge_unordered(array2); + CHECK_MESSAGE(array1.size() == max_count, "merge_unordered() added/dropped elements while merging"); + + // If any elements were altered during merging, the sum will not match up. + for (uint32_t i = 0; i < array1.size(); i++) { + sum -= array1[i]; + } + CHECK_MESSAGE(sum == 12345, "merge_unordered() altered elements while merging"); + + array1.clear(); + } + + array1.reset(); + array2.reset(); + pool.reset(); + } +} + } // namespace TestPagedArray #endif // TEST_PAGED_ARRAY_H diff --git a/thirdparty/basis_universal/encoder/basisu_comp.cpp b/thirdparty/basis_universal/encoder/basisu_comp.cpp index 41eae2b78a..4e69e9e2ee 100644 --- a/thirdparty/basis_universal/encoder/basisu_comp.cpp +++ b/thirdparty/basis_universal/encoder/basisu_comp.cpp @@ -28,7 +28,7 @@ #endif #if BASISD_SUPPORT_KTX2_ZSTD -#include "../zstd/zstd.h" +#include <zstd.h> #endif // Set to 1 to disable the mipPadding alignment workaround (which only seems to be needed when no key-values are written at all) diff --git a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp index 3aeba0ee7a..c698861f3b 100644 --- a/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp +++ b/thirdparty/basis_universal/transcoder/basisu_transcoder.cpp @@ -155,7 +155,7 @@ // If BASISD_SUPPORT_KTX2_ZSTD is 0, UASTC files compressed with Zstd cannot be loaded. #if BASISD_SUPPORT_KTX2_ZSTD // We only use two Zstd API's: ZSTD_decompress() and ZSTD_isError() - #include "../zstd/zstd.h" + #include <zstd.h> #endif #endif |