diff options
30 files changed, 155 insertions, 130 deletions
diff --git a/core/math/delaunay.h b/core/math/delaunay.h index ed52c506db..3f8013a3e6 100644 --- a/core/math/delaunay.h +++ b/core/math/delaunay.h @@ -80,11 +80,11 @@ public: } static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) { - if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[0]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[1]]))) { + if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) { return true; } - if (Math::is_zero_approx(p_vertices[p_a.edge[0]].distance_to(p_vertices[p_b.edge[1]])) && Math::is_zero_approx(p_vertices[p_a.edge[1]].distance_to(p_vertices[p_b.edge[0]]))) { + if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[1]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[0]]) { return true; } diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index b4c44fe8eb..e510603281 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -165,6 +165,7 @@ </argument> <description> Queues an animation for playback once the current one is done. + [b]Note:[/b] If a looped animation is currently playing, the queued animation will never play unless the looped animation is stopped somehow. </description> </method> <method name="remove_animation"> diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml index b7b77bc02a..fd08643dd5 100644 --- a/doc/classes/ClassDB.xml +++ b/doc/classes/ClassDB.xml @@ -134,7 +134,7 @@ <argument index="2" name="no_inheritance" type="bool" default="false"> </argument> <description> - Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is false) has a method called [code]method[/code] or not. + Returns whether [code]class[/code] (or its ancestry if [code]no_inheritance[/code] is [code]false[/code]) has a method called [code]method[/code] or not. </description> </method> <method name="class_has_signal" qualifiers="const"> @@ -201,7 +201,7 @@ <argument index="0" name="class" type="String"> </argument> <description> - Returns whether this class is enabled or not. + Returns whether this [code]class[/code] is enabled or not. </description> </method> <method name="is_parent_class" qualifiers="const"> diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml index 9294a515d2..8aae85563a 100644 --- a/doc/classes/Directory.xml +++ b/doc/classes/Directory.xml @@ -127,8 +127,8 @@ </argument> <description> Initializes the stream used to list all files and directories using the [method get_next] function, closing the current opened stream if needed. Once the stream has been processed, it should typically be closed with [method list_dir_end]. - If you pass [code]skip_navigational[/code], then [code].[/code] and [code]..[/code] would be filtered out. - If you pass [code]skip_hidden[/code], then hidden files would be filtered out. + If [code]skip_navigational[/code] is [code]true[/code], [code].[/code] and [code]..[/code] are filtered out. + If [code]skip_hidden[/code] is [code]true[/code], hidden files are filtered out. </description> </method> <method name="list_dir_end"> diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml index f5bf12a876..fedf77bfd2 100644 --- a/doc/classes/MainLoop.xml +++ b/doc/classes/MainLoop.xml @@ -4,7 +4,7 @@ Abstract base class for the game's main loop. </brief_description> <description> - [MainLoop] is the abstract base class for a Godot project's game loop. It in inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree. + [MainLoop] is the abstract base class for a Godot project's game loop. It is inherited by [SceneTree], which is the default game loop implementation used in Godot projects, though it is also possible to write and use one's own [MainLoop] subclass instead of the scene tree. Upon the application start, a [MainLoop] implementation must be provided to the OS; otherwise, the application will exit. This happens automatically (and a [SceneTree] is created) unless a main [Script] is provided from the command line (with e.g. [code]godot -s my_loop.gd[/code], which should then be a [MainLoop] implementation. Here is an example script implementing a simple [MainLoop]: [codeblock] diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index 232b9ce7c0..1952e201aa 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -165,11 +165,11 @@ void main() { #elif defined(USE_ASYM_PANO) // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result. - // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1. + // Asymmetrical projection means the center of projection is no longer in the center of the screen but shifted. // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image. vec3 cube_normal; - cube_normal.z = -1000000.0; + cube_normal.z = -1.0; cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y; cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a; cube_normal = mat3(sky_transform) * mat3(pano_transform) * cube_normal; diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 1f43740858..8c9aedc7b7 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -257,6 +257,7 @@ void EditorFileDialog::_post_popup() { if (is_visible_in_tree()) { Ref<Texture> folder = get_icon("folder", "FileDialog"); + const Color folder_color = get_color("folder", "FileDialog"); recent->clear(); bool res = access == ACCESS_RESOURCES; @@ -274,6 +275,7 @@ void EditorFileDialog::_post_popup() { recent->add_item(name, folder); recent->set_item_metadata(recent->get_item_count() - 1, recentd[i]); + recent->set_item_icon_modulate(recent->get_item_count() - 1, folder_color); } local_history.clear(); @@ -734,6 +736,7 @@ void EditorFileDialog::update_file_list() { dir_access->list_dir_begin(); Ref<Texture> folder = get_icon("folder", "FileDialog"); + const Color folder_color = get_color("folder", "FileDialog"); List<String> files; List<String> dirs; @@ -774,6 +777,7 @@ void EditorFileDialog::update_file_list() { d["dir"] = true; item_list->set_item_metadata(item_list->get_item_count() - 1, d); + item_list->set_item_icon_modulate(item_list->get_item_count() - 1, folder_color); dirs.pop_front(); } @@ -1200,6 +1204,7 @@ void EditorFileDialog::_update_favorites() { String current = get_current_dir(); Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); + const Color folder_color = get_color("folder", "FileDialog"); favorites->clear(); favorite->set_pressed(false); @@ -1230,6 +1235,7 @@ void EditorFileDialog::_update_favorites() { } favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]); + favorites->set_item_icon_modulate(favorites->get_item_count() - 1, folder_color); if (setthis) { favorite->set_pressed(true); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index fbfc999dbf..af79c21f85 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -354,7 +354,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i])); if (search_flags & SEARCH_PROPERTIES) for (int i = 0; i < class_doc.properties.size(); i++) - if (_match_string(term, class_doc.properties[i].name)) + if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter)) match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i])); if (search_flags & SEARCH_THEME_ITEMS) for (int i = 0; i < class_doc.theme_properties.size(); i++) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 311f8b295b..5ec071d71a 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5512,6 +5512,9 @@ EditorNode::EditorNode() { } } + // Define a minimum window size to prevent UI elements from overlapping or being cut off + OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE); + ResourceLoader::set_abort_on_missing_resources(false); FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 9c1e919824..d962001b38 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -1066,6 +1066,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // FileDialog theme->set_icon("folder", "FileDialog", theme->get_icon("Folder", "EditorIcons")); + // Use a different color for folder icons to make them easier to distinguish from files. + // On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color. + theme->set_color("folder", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(5, 5, 5)).linear_interpolate(accent_color, 0.7)); theme->set_color("files_disabled", "FileDialog", font_color_disabled); // color picker diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index e4823c7745..83904800e9 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -64,6 +64,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory subdirectory_item->set_text(0, dname); subdirectory_item->set_icon(0, get_icon("Folder", "EditorIcons")); + subdirectory_item->set_icon_color(0, get_color("folder", "FileDialog")); subdirectory_item->set_selectable(0, true); String lpath = p_dir->get_path(); subdirectory_item->set_metadata(0, lpath); @@ -186,15 +187,19 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo continue; Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); + const Color folder_color = get_color("folder", "FileDialog"); String text; Ref<Texture> icon; + Color color; if (fave == "res://") { text = "/"; icon = folder_icon; + color = folder_color; } else if (fave.ends_with("/")) { text = fave.substr(0, fave.length() - 1).get_file(); icon = folder_icon; + color = folder_color; } else { text = fave.get_file(); int index; @@ -204,12 +209,14 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo } else { icon = get_icon("File", "EditorIcons"); } + color = Color(1, 1, 1); } if (searched_string.length() == 0 || text.to_lower().find(searched_string) >= 0) { TreeItem *ti = tree->create_item(favorites); ti->set_text(0, text); ti->set_icon(0, icon); + ti->set_icon_color(0, color); ti->set_tooltip(0, fave); ti->set_selectable(0, true); ti->set_metadata(0, fave); @@ -639,6 +646,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); + const Color folder_color = get_color("folder", "FileDialog"); // Build the FileInfo list List<FileInfo> filelist; @@ -716,6 +724,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_item_metadata(files->get_item_count() - 1, bd); files->set_item_selectable(files->get_item_count() - 1, false); + files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); } for (int i = 0; i < efd->get_subdir_count(); i++) { @@ -724,6 +733,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->add_item(dname, folder_icon, true); files->set_item_metadata(files->get_item_count() - 1, directory.plus_file(dname) + "/"); + files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); if (cselection.has(dname)) { files->select(files->get_item_count() - 1, false); diff --git a/editor/icons/icon_editor_curve_handle.svg b/editor/icons/icon_editor_curve_handle.svg new file mode 100644 index 0000000000..c405ceab9d --- /dev/null +++ b/editor/icons/icon_editor_curve_handle.svg @@ -0,0 +1 @@ +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><circle cx="5" cy="5" fill="#fefefe" r="2.75" stroke="#000" stroke-linecap="square"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_editor_path_sharp_handle.svg b/editor/icons/icon_editor_path_sharp_handle.svg new file mode 100644 index 0000000000..db160dfeae --- /dev/null +++ b/editor/icons/icon_editor_path_sharp_handle.svg @@ -0,0 +1 @@ +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m-3.035534-10.106602h6.071068v6.071068h-6.071068z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="matrix(-.70710678 .70710678 -.70710678 -.70710678 0 0)"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_editor_path_smooth_handle.svg b/editor/icons/icon_editor_path_smooth_handle.svg new file mode 100644 index 0000000000..34f3d290bd --- /dev/null +++ b/editor/icons/icon_editor_path_smooth_handle.svg @@ -0,0 +1 @@ +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><path d="m1.5-8.5h7v7h-7z" fill="#fefefe" stroke="#000" stroke-linecap="square" transform="rotate(90)"/></svg>
\ No newline at end of file diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 574b47d770..7f023af848 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -571,7 +571,8 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl return; Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform(); - const Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); + // All polygon points are sharp, so use the sharp handle icon + const Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons"); const Vertex active_point = get_active_point(); const int n_polygons = _get_polygon_count(); diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index b87bd29cbd..f02dc0bd6d 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -367,18 +367,18 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { - if (!node) + if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid()) return; - if (!node->is_visible_in_tree()) - return; + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - if (!node->get_curve().is_valid()) - return; + const Ref<Texture> path_sharp_handle = get_icon("EditorPathSharpHandle", "EditorIcons"); + const Ref<Texture> path_smooth_handle = get_icon("EditorPathSmoothHandle", "EditorIcons"); + // Both handle icons must be of the same size + const Size2 handle_size = path_sharp_handle->get_size(); - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); - Size2 handle_size = handle->get_size(); + const Ref<Texture> curve_handle = get_icon("EditorCurveHandle", "EditorIcons"); + const Size2 curve_handle_size = curve_handle->get_size(); Ref<Curve2D> curve = node->get_curve(); @@ -387,19 +387,35 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { for (int i = 0; i < len; i++) { Vector2 point = xform.xform(curve->get_point_position(i)); - vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false, Color(1, 1, 1, 1)); + // Determines the point icon to be used + bool smooth = false; if (i < len - 1) { Vector2 pointout = xform.xform(curve->get_point_position(i) + curve->get_point_out(i)); - vpc->draw_line(point, pointout, Color(0.5, 0.5, 1.0, 0.8), 1.0); - vpc->draw_texture_rect(handle, Rect2(pointout - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3)); + if (point != pointout) { + smooth = true; + // Draw the line with a dark and light color to be visible on all backgrounds + vpc->draw_line(point, pointout, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true); + vpc->draw_line(point, pointout, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true); + vpc->draw_texture_rect(curve_handle, Rect2(pointout - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75)); + } } if (i > 0) { Vector2 pointin = xform.xform(curve->get_point_position(i) + curve->get_point_in(i)); - vpc->draw_line(point, pointin, Color(0.5, 0.5, 1.0, 0.8), 1.0); - vpc->draw_texture_rect(handle, Rect2(pointin - handle_size * 0.5, handle_size), false, Color(1, 0.5, 1, 0.3)); + if (point != pointin) { + smooth = true; + // Draw the line with a dark and light color to be visible on all backgrounds + vpc->draw_line(point, pointin, Color(0, 0, 0, 0.5), Math::round(EDSCALE), true); + vpc->draw_line(point, pointin, Color(1, 1, 1, 0.5), Math::round(EDSCALE), true); + vpc->draw_texture_rect(curve_handle, Rect2(pointin - curve_handle_size * 0.5, curve_handle_size), false, Color(1, 1, 1, 0.75)); + } } + + vpc->draw_texture_rect( + smooth ? path_smooth_handle : path_sharp_handle, + Rect2(point - handle_size * 0.5, handle_size), + false); } if (on_edge) { diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index 1ae5acc5ff..2493380585 100644 --- a/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp @@ -652,7 +652,6 @@ PathSpatialGizmoPlugin::PathSpatialGizmoPlugin() { Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8)); create_material("path_material", path_color); - path_color.a = 0.4; - create_material("path_thin_material", path_color); + create_material("path_thin_material", Color(0.5, 0.5, 0.5)); create_handle_material("handles"); } diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 59004a08c0..bd532a6418 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -1045,8 +1045,8 @@ void Polygon2DEditor::_uv_draw() { } } - Ref<Texture> handle = get_icon("EditorHandle", "EditorIcons"); - Ref<Texture> internal_handle = get_icon("EditorInternalHandle", "EditorIcons"); + // All UV points are sharp, so use the sharp handle icon + Ref<Texture> handle = get_icon("EditorPathSharpHandle", "EditorIcons"); Color poly_line_color = Color(0.9, 0.5, 0.5); if (polygons.size() || polygon_create.size()) { @@ -1120,7 +1120,8 @@ void Polygon2DEditor::_uv_draw() { if (i < uv_draw_max) { uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5); } else { - uv_edit_draw->draw_texture(internal_handle, mtx.xform(uvs[i]) - internal_handle->get_size() * 0.5); + // Internal vertex + uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5, Color(0.6, 0.8, 1)); } } } diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index b2f06ca41f..b4cce9745e 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -2006,7 +2006,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { // Tools paint_button = memnew(ToolButton); paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P)); - paint_button->set_tooltip(TTR("Shift+RMB: Line Draw\nShift+Ctrl+RMB: Rectangle Paint")); + paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint")); paint_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_NONE)); paint_button->set_toggle_mode(true); toolbar->add_child(paint_button); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 619fb15a68..589964f620 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -2487,8 +2487,8 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -2581,10 +2581,10 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeVectorSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeVectorScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeVectorOp::OP_STEP, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeVectorScalarStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR)); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 0f3c4c924a..a418773131 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -997,7 +997,6 @@ public: void load_projects(); void set_search_term(String p_search_term); - void set_filter_option(ProjectListFilter::FilterOption p_option); void set_order_option(ProjectListFilter::FilterOption p_option); void sort_projects(); int get_project_count() const; @@ -1030,7 +1029,6 @@ private: static void load_project_data(const String &p_property_key, Item &p_item, bool p_favorite); String _search_term; - ProjectListFilter::FilterOption _filter_option; ProjectListFilter::FilterOption _order_option; Set<String> _selected_project_keys; String _last_clicked; // Project key @@ -1063,7 +1061,6 @@ struct ProjectListComparator { }; ProjectList::ProjectList() { - _filter_option = ProjectListFilter::FILTER_NAME; _order_option = ProjectListFilter::FILTER_MODIFIED; _scroll_children = memnew(VBoxContainer); @@ -1303,12 +1300,6 @@ void ProjectList::set_search_term(String p_search_term) { _search_term = p_search_term; } -void ProjectList::set_filter_option(ProjectListFilter::FilterOption p_option) { - if (_filter_option != p_option) { - _filter_option = p_option; - } -} - void ProjectList::set_order_option(ProjectListFilter::FilterOption p_option) { if (_order_option != p_option) { _order_option = p_option; @@ -1328,11 +1319,18 @@ void ProjectList::sort_projects() { bool visible = true; if (_search_term != "") { - if (_filter_option == ProjectListFilter::FILTER_PATH) { - visible = item.path.findn(_search_term) != -1; - } else if (_filter_option == ProjectListFilter::FILTER_NAME) { - visible = item.project_name.findn(_search_term) != -1; + + String search_path; + if (_search_term.find("/") != -1) { + // Search path will match the whole path + search_path = item.path; + } else { + // Search path will only match the last path component to make searching more strict + search_path = item.path.get_file(); } + + // When searching, display projects whose name or path contain the search term + visible = item.project_name.findn(_search_term) != -1 || search_path.findn(_search_term) != -1; } item.control->set_visible(visible); @@ -1694,7 +1692,6 @@ void ProjectList::_bind_methods() { ClassDB::bind_method("_panel_input", &ProjectList::_panel_input); ClassDB::bind_method("_favorite_pressed", &ProjectList::_favorite_pressed); ClassDB::bind_method("_show_project", &ProjectList::_show_project); - //ClassDB::bind_method("_unhandled_input", &ProjectList::_unhandled_input); ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED)); ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN)); @@ -1754,8 +1751,19 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) { if (k.is_valid()) { - if (!k->is_pressed()) + if (!k->is_pressed()) { return; + } + + // Pressing Command + Q quits the Project Manager + // This is handled by the platform implementation on macOS, + // so only define the shortcut on other platforms +#ifndef OSX_ENABLED + if (k->get_scancode_with_modifiers() == (KEY_MASK_CMD | KEY_Q)) { + _dim_window(); + get_tree()->quit(); + } +#endif if (tabs->get_current_tab() != 0) return; @@ -1834,7 +1842,6 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) { void ProjectManager::_load_recent_projects() { - _project_list->set_filter_option(project_filter->get_filter_option()); _project_list->set_order_option(project_order_filter->get_filter_option()); _project_list->set_search_term(project_filter->get_search_term()); _project_list->load_projects(); @@ -2198,7 +2205,6 @@ void ProjectManager::_on_order_option_changed() { } void ProjectManager::_on_filter_option_changed() { - _project_list->set_filter_option(project_filter->get_filter_option()); _project_list->set_search_term(project_filter->get_search_term()); _project_list->sort_projects(); } @@ -2270,6 +2276,9 @@ ProjectManager::ProjectManager() { } break; } + // Define a minimum window size to prevent UI elements from overlapping or being cut off + OS::get_singleton()->set_min_window_size(Size2(750, 420) * EDSCALE); + #ifndef OSX_ENABLED // The macOS platform implementation uses its own hiDPI window resizing code // TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below @@ -2295,26 +2304,11 @@ ProjectManager::ProjectManager() { VBoxContainer *vb = memnew(VBoxContainer); panel->add_child(vb); vb->set_anchors_and_margins_preset(Control::PRESET_WIDE, Control::PRESET_MODE_MINSIZE, 8 * EDSCALE); - vb->add_constant_override("separation", 8 * EDSCALE); String cp; cp += 0xA9; OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2007-2019 Juan Linietsky, Ariel Manzur & Godot Contributors"); - HBoxContainer *top_hb = memnew(HBoxContainer); - vb->add_child(top_hb); - Label *l = memnew(Label); - l->set_text(VERSION_NAME + String(" - ") + TTR("Project Manager")); - top_hb->add_child(l); - top_hb->add_spacer(); - l = memnew(Label); - String hash = String(VERSION_HASH); - if (hash.length() != 0) - hash = "." + hash.left(9); - l->set_text("v" VERSION_FULL_BUILD "" + hash); - l->set_align(Label::ALIGN_CENTER); - top_hb->add_child(l); - Control *center_box = memnew(Control); center_box->set_v_size_flags(SIZE_EXPAND_FILL); vb->add_child(center_box); @@ -2322,11 +2316,12 @@ ProjectManager::ProjectManager() { tabs = memnew(TabContainer); center_box->add_child(tabs); tabs->set_anchors_and_margins_preset(Control::PRESET_WIDE); + tabs->set_tab_align(TabContainer::ALIGN_LEFT); HBoxContainer *tree_hb = memnew(HBoxContainer); projects_hb = tree_hb; - projects_hb->set_name(TTR("Project List")); + projects_hb->set_name(TTR("Projects")); tabs->add_child(tree_hb); @@ -2343,6 +2338,7 @@ ProjectManager::ProjectManager() { sort_filter_titles.push_back("Path"); sort_filter_titles.push_back("Last Modified"); project_order_filter = memnew(ProjectListFilter); + project_order_filter->add_filter_option(); project_order_filter->_setup_filters(sort_filter_titles); project_order_filter->set_filter_size(150); sort_filters->add_child(project_order_filter); @@ -2353,21 +2349,12 @@ ProjectManager::ProjectManager() { project_order_filter->set_filter_option((ProjectListFilter::FilterOption)projects_sorting_order); sort_filters->add_spacer(true); - Label *search_label = memnew(Label); - search_label->set_text(TTR("Search:")); - sort_filters->add_child(search_label); - - HBoxContainer *search_filters = memnew(HBoxContainer); - Vector<String> vec2; - vec2.push_back("Name"); - vec2.push_back("Path"); + project_filter = memnew(ProjectListFilter); - project_filter->_setup_filters(vec2); project_filter->add_search_box(); - search_filters->add_child(project_filter); project_filter->connect("filter_changed", this, "_on_filter_option_changed"); project_filter->set_custom_minimum_size(Size2(280, 10) * EDSCALE); - sort_filters->add_child(search_filters); + sort_filters->add_child(project_filter); search_tree_vb->add_child(sort_filters); @@ -2457,6 +2444,17 @@ ProjectManager::ProjectManager() { settings_hb->set_alignment(BoxContainer::ALIGN_END); settings_hb->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN); + Label *version_label = memnew(Label); + String hash = String(VERSION_HASH); + if (hash.length() != 0) { + hash = "." + hash.left(9); + } + version_label->set_text("v" VERSION_FULL_BUILD "" + hash); + // Fade out the version label to be less prominent, but still readable + version_label->set_self_modulate(Color(1, 1, 1, 0.6)); + version_label->set_align(Label::ALIGN_CENTER); + settings_hb->add_child(version_label); + language_btn = memnew(OptionButton); language_btn->set_flat(true); language_btn->set_focus_mode(Control::FOCUS_NONE); @@ -2489,27 +2487,6 @@ ProjectManager::ProjectManager() { center_box->add_child(settings_hb); settings_hb->set_anchors_and_margins_preset(Control::PRESET_TOP_RIGHT); - CenterContainer *cc = memnew(CenterContainer); - Button *cancel = memnew(Button); - cancel->set_text(TTR("Exit")); - cancel->set_custom_minimum_size(Size2(100, 1) * EDSCALE); - -#ifndef OSX_ENABLED - // Pressing Command + Q quits the Project Manager - // This is handled by the platform implementation on macOS, - // so only define the shortcut on other platforms - InputEventKey *quit_key = memnew(InputEventKey); - quit_key->set_command(true); - quit_key->set_scancode(KEY_Q); - ShortCut *quit_shortcut = memnew(ShortCut); - quit_shortcut->set_shortcut(quit_key); - cancel->set_shortcut(quit_shortcut); -#endif - - cc->add_child(cancel); - cancel->connect("pressed", this, "_exit_dialog"); - vb->add_child(cc); - ////////////////////////////////////////////////////////////// language_restart_ask = memnew(ConfirmationDialog); @@ -2630,11 +2607,20 @@ void ProjectListFilter::_bind_methods() { ADD_SIGNAL(MethodInfo("filter_changed")); } +void ProjectListFilter::add_filter_option() { + filter_option = memnew(OptionButton); + filter_option->set_clip_text(true); + filter_option->connect("item_selected", this, "_filter_option_selected"); + add_child(filter_option); +} + void ProjectListFilter::add_search_box() { search_box = memnew(LineEdit); + search_box->set_placeholder(TTR("Search")); search_box->connect("text_changed", this, "_search_text_changed"); search_box->set_h_size_flags(SIZE_EXPAND_FILL); add_child(search_box); + has_search_box = true; } @@ -2645,13 +2631,6 @@ void ProjectListFilter::set_filter_size(int h_size) { ProjectListFilter::ProjectListFilter() { _current_filter = FILTER_NAME; - - filter_option = memnew(OptionButton); - set_filter_size(80); - filter_option->set_clip_text(true); - filter_option->connect("item_selected", this, "_filter_option_selected"); - add_child(filter_option); - has_search_box = false; } diff --git a/editor/project_manager.h b/editor/project_manager.h index 4ccb99d6bd..2a5fd02892 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -152,6 +152,7 @@ protected: public: void _setup_filters(Vector<String> options); + void add_filter_option(); void add_search_box(); void set_filter_size(int h_size); String get_search_term(); diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index fd0d36eddf..f1b3fa2ac6 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_ //check if edge and poly share a vertex, of so, assign it to segment_idx for (int i = 0; i < points.size(); i++) { for (int j = 0; j < 2; j++) { - if (Math::is_zero_approx(segment[j].distance_to(points[i].point))) { + if (segment[j] == points[i].point) { segment_idx[j] = i; inserted_points.push_back(i); break; @@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_ Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point }; Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg); - if (Math::is_zero_approx(closest.distance_to(segment[j]))) { + if (closest == segment[j]) { //point rest of this edge res = closest; found = true; @@ -439,7 +439,7 @@ void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, Mes //transform A points to 2D - if (Math::is_zero_approx(segment[0].distance_to(segment[1]))) + if (segment[0] == segment[1]) return; //too small _clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B); @@ -461,10 +461,10 @@ void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map { //check if either is a degenerate - if (Math::is_zero_approx(va[0].distance_to(va[1])) || Math::is_zero_approx(va[0].distance_to(va[2])) || Math::is_zero_approx(va[1].distance_to(va[2]))) + if (va[0] == va[1] || va[0] == va[2] || va[1] == va[2]) return; - if (Math::is_zero_approx(vb[0].distance_to(vb[1])) || Math::is_zero_approx(vb[0].distance_to(vb[2])) || Math::is_zero_approx(vb[1].distance_to(vb[2]))) + if (vb[0] == vb[1] || vb[0] == vb[2] || vb[1] == vb[2]) return; } diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index 62f09bfbf9..dd86c758bf 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -265,7 +265,10 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons ERR_FAIL_COND_V(p_to == p_from, FAILED); - return get_peer(p_to)->put_packet(p_buffer, p_buffer_size); // Sending to specific peer + Ref<WebSocketPeer> peer_to = get_peer(p_to); + ERR_FAIL_COND_V(peer_to.is_null(), FAILED); + + return peer_to->put_packet(p_buffer, p_buffer_size); // Sending to specific peer } } @@ -296,8 +299,6 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u ERR_FAIL_COND(type != SYS_NONE); // Only server sends sys messages ERR_FAIL_COND(from != p_peer_id); // Someone is cheating - _server_relay(from, to, in_buffer, size); // Relay if needed - if (to == 1) { // This is for the server _store_pkt(from, to, in_buffer, data_size); @@ -312,13 +313,9 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u // All but one, for us if not excluded if (_peer_id != -(int32_t)p_peer_id) _store_pkt(from, to, in_buffer, data_size); - - } else { - - // Send to specific peer - ERR_FAIL_COND(!_peer_map.has(to)); - get_peer(to)->put_packet(in_buffer, size); } + // Relay if needed (i.e. "to" includes a peer that is not the server) + _server_relay(from, to, in_buffer, size); } else { diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index f644db462b..5cf28d6c89 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -551,7 +551,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect left_poly = p; portal_left = apex_point; portal_right = apex_point; - if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point))) + if (!path.size() || path[path.size() - 1] != apex_point) path.push_back(apex_point); skip = true; } @@ -569,7 +569,7 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2 &p_start, const Vect right_poly = p; portal_right = apex_point; portal_left = apex_point; - if (!path.size() || !Math::is_zero_approx(path[path.size() - 1].distance_to(apex_point))) + if (!path.size() || path[path.size() - 1] != apex_point) path.push_back(apex_point); } } diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index f2f53d4354..55c8c7f229 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -110,7 +110,7 @@ void Path2D::_notification(int p_what) { real_t frac = j / 8.0; Vector2 p = curve->interpolate(i, frac); - draw_line(prev_p, p, color, line_width); + draw_line(prev_p, p, color, line_width, true); prev_p = p; } } diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 30aeebfdac..051f832882 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1200,7 +1200,9 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float } } - _stop_playing_caches(); + if (get_current_animation() != p_name) { + _stop_playing_caches(); + } c.current.from = &animation_set[name]; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index f1bdbb5ff5..7305d7459c 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -400,6 +400,7 @@ void FileDialog::update_file_list() { TreeItem *root = tree->create_item(); Ref<Texture> folder = get_icon("folder"); + const Color folder_color = get_color("folder"); List<String> files; List<String> dirs; @@ -429,6 +430,7 @@ void FileDialog::update_file_list() { TreeItem *ti = tree->create_item(root); ti->set_text(0, dir_name); ti->set_icon(0, folder); + ti->set_icon_color(0, folder_color); Dictionary d; d["name"] = dir_name; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 8c8552ac54..985b38f913 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2870,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.loc; const Vector3 &v2 = t2.value.loc; - if (Math::is_zero_approx(v0.distance_to(v2))) { + if (v0 == v2) { //0 and 2 are close, let's see if 1 is close - if (!Math::is_zero_approx(v0.distance_to(v1))) { + if (v0 != v1) { //not close, not optimizable return false; } @@ -2959,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.scale; const Vector3 &v2 = t2.value.scale; - if (Math::is_zero_approx(v0.distance_to(v2))) { + if (v0 == v2) { //0 and 2 are close, let's see if 1 is close - if (!Math::is_zero_approx(v0.distance_to(v1))) { + if (v0 != v1) { //not close, not optimizable return false; } diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index fb0fb4f8e3..90787780d3 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -760,6 +760,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // FileDialog theme->set_icon("folder", "FileDialog", make_icon(icon_folder_png)); + theme->set_color("folder", "FileDialog", Color(1, 1, 1)); theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7)); // colorPicker |