From 23e08b0fad2b69912ac70c1b645305148290cb51 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 1 Feb 2020 00:19:24 +0100 Subject: [PATCH 01/64] Improve the `doc_status.py` console output - Duplicate the header when the `-a` flag is enabled. Since lots of items are displayed in this case, this helps the user remember which column is which without having to scroll back to the top. - Bolden the overall percentages for easier visual grepping. (cherry picked from commit 7c3f6b2870c5108e781a5e691f96d0a6889fa2de) --- doc/tools/doc_status.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py index 352b292be20..e6e6d5f6066 100755 --- a/doc/tools/doc_status.py +++ b/doc/tools/doc_status.py @@ -81,6 +81,7 @@ colors = { 'section': [1, 4], # bold, underline 'state_off': [36], # cyan 'state_on': [1, 35], # bold, magenta/plum + 'bold': [1], # bold } overall_progress_description_weigth = 10 @@ -227,7 +228,7 @@ class ClassStatus: output['items'] = items_progress.to_configured_colored_string() - output['overall'] = (description_progress + items_progress).to_colored_string('{percent}%', '{pad_percent}{s}') + output['overall'] = (description_progress + items_progress).to_colored_string(color('bold', '{percent}%'), '{pad_percent}{s}') if self.name.startswith('Total'): output['url'] = color('url', 'https://docs.godotengine.org/en/latest/classes/') @@ -309,7 +310,7 @@ if flags['i']: table_columns.append('items') if flags['o'] == (not flags['i']): - table_column_names.append('Overall') + table_column_names.append(color('bold', 'Overall')) table_columns.append('overall') if flags['u']: @@ -435,6 +436,11 @@ if len(table) > 2 or not flags['a']: row.append('') table.append(row) +if flags['a']: + # Duplicate the headers at the bottom of the table so they can be viewed + # without having to scroll back to the top. + table.append(table_column_names) + table_column_sizes = [] for row in table: for cell_i, cell in enumerate(row): @@ -460,7 +466,10 @@ for row_i, row in enumerate(table): print(row_string) - if row_i == 0 or row_i == len(table) - 2: + # Account for the possible double header (if the `a` flag is enabled). + # No need to have a condition for the flag, as this will behave correctly + # if the flag is disabled. + if row_i == 0 or row_i == len(table) - 3 or row_i == len(table) - 2: print(divider_string) print(divider_string) From 4657daff055ecb61e83549954b27203d35ff66f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 12 Feb 2020 15:04:19 +0100 Subject: [PATCH 02/64] doc: Add description for EditorInspector (cherry-picked from #35858) --- doc/classes/EditorInspector.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml index c91cbabb9e7..3ed642a6a65 100644 --- a/doc/classes/EditorInspector.xml +++ b/doc/classes/EditorInspector.xml @@ -1,8 +1,10 @@ + A tab used to edit properties of the selected node. + The editor inspector is by default located on the right-hand side of the editor. It's used to edit the properties of the selected node. For example, you can select a node such as Sprite2D then edit its transform through the inspector tool. The editor inspector is an essential tool in the game development workflow. From 20d003403923d271ff5c93f492779becce025d3f Mon Sep 17 00:00:00 2001 From: seenloitering <55366994+seenloitering@users.noreply.github.com> Date: Wed, 5 Feb 2020 07:19:27 -0500 Subject: [PATCH 03/64] Add documentation for Skeleton2D Signal bone_setup_changed remains undocumented. I took a quick look at the cpp code, but its purpose remained unclear to me. If anyone can steer me in the right direction, I'm happy to flesh this out. (cherry picked from commit 915199243235db8d380ee6eaa3b0d177aec7589c) --- doc/classes/Skeleton2D.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/classes/Skeleton2D.xml b/doc/classes/Skeleton2D.xml index a76b3b5d12f..3dc00a5e859 100644 --- a/doc/classes/Skeleton2D.xml +++ b/doc/classes/Skeleton2D.xml @@ -4,6 +4,7 @@ Skeleton for 2D characters and animated objects. + Skeleton2D parents a hierarchy of [Bone2D] objects. It is a requirement of [Bone2D]. Skeleton2D holds a reference to the rest pose of its children and acts as a single point of access to its bones. https://docs.godotengine.org/en/latest/tutorials/animation/2d_skeletons.html @@ -15,19 +16,21 @@ + Returns a [Bone2D] from the node hierarchy parented by Skeleton2D. The object to return is identified by the parameter [code]idx[/code]. Bones are indexed by descending the node hierarchy from top to bottom, adding the children of each branch before moving to the next sibling. - Returns the amount of bones in the skeleton. + Returns the number of [Bone2D] nodes in the node hierarchy parented by Skeleton2D. + Returns the [RID] of a Skeleton2D instance. From 7cfcf1824b5f1f510aa4b0027db0fb334b3271db Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Fri, 7 Feb 2020 10:01:42 +0800 Subject: [PATCH 04/64] Completes doc for ItemList and Tree (cherry picked from commit 7a41c44be2993b21260f4e1f6b9f99949b92dce7) --- doc/classes/ItemList.xml | 14 +++++++ doc/classes/Tree.xml | 40 +++++++++++++++++-- .../resources/default_theme/default_theme.cpp | 2 - 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 13aa181dced..d916d1e0817 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -513,32 +513,46 @@ + Default [StyleBox] for the [ItemList], i.e. used when the control is not being focused. + [StyleBox] used when the [ItemList] is being focused. + [StyleBox] used for the cursor, when the [ItemList] is being focused. + [StyleBox] used for the cursor, when the [ItemList] is not being focused. + [Font] of the item's text. + Default text [Color] of the item. + Text [Color] used when the item is selected. + [Color] of the guideline. The guideline is a line drawn between each row of items. + The horizontal spacing between items. + The spacing between item's icon and text. + The vertical spacing between each line of text. + [StyleBox] for the selected items, used when the [ItemList] is not being focused. + [StyleBox] for the selected items, used when the [ItemList] is being focused. + The vertical spacing between items. diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index f920ae5a060..a2bac812b38 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -387,80 +387,112 @@ + The arrow icon used when a foldable item is not collapsed. + The arrow icon used when a foldable item is collapsed. + Default [StyleBox] for the [Tree], i.e. used when the control is not being focused. + [StyleBox] used when the [Tree] is being focused. + The horizontal space between each button in a cell. + [StyleBox] used when a button in the tree is pressed. + The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is checked. - - + [StyleBox] used for the cursor, when the [Tree] is being focused. + [StyleBox] used for the cursor, when the [Tree] is not being focused. + Default [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell. + Text [Color] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered. + [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's hovered. + [StyleBox] for a [constant TreeItem.CELL_MODE_CUSTOM] mode cell when it's pressed. + Draws the guidelines if not zero, this acts as a boolean. The guideline is a horizontal line drawn at the bottom of each item. + Draws the relationship lines if not zero, this acts as a boolean. Relationship lines are drawn at the start of child items to show hierarchy. + [Color] used to draw possible drop locations. See [enum DropModeFlags] constants for further description of drop locations. + [Font] of the item's text. + Default text [Color] of the item. + Text [Color] used when the item is selected. + [Color] of the guideline. + The horizontal space between item cells. This is also used as the margin at the start of an item when folding is disabled. + The horizontal margin at the start of an item. This is used when folding is enabled for the item. + [Color] of the relationship lines. + The maximum distance between the mouse cursor and the control's border to trigger border scrolling when dragging. + The speed of border scrolling. + The arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell. + [StyleBox] for the selected items, used when the [Tree] is not being focused. - - + [StyleBox] for the selected items, used when the [Tree] is being focused. + Default text [Color] of the title button. + [Font] of the title button's text. + [StyleBox] used when the title button is being hovered. + Default [StyleBox] for the title button. + [StyleBox] used when the title button is being pressed. + The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is unchecked. + The updown arrow icon to display for the [constant TreeItem.CELL_MODE_RANGE] mode cell. + The vertical padding inside each item, i.e. the distance between the item's content and top/bottom border. diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index cc76df62e59..00c56e5eb22 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -647,8 +647,6 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_color("title_button_color", "Tree", control_font_color); theme->set_color("font_color", "Tree", control_font_color_low); theme->set_color("font_color_selected", "Tree", control_font_color_pressed); - theme->set_color("selection_color", "Tree", Color(0.1, 0.1, 1, 0.8)); - theme->set_color("cursor_color", "Tree", Color(0, 0, 0)); theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1)); theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); From f433c3656bbd00d8d96f0dadfcf097a39e63ba6a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 8 Feb 2020 21:35:43 +0100 Subject: [PATCH 05/64] Update EditorSceneImporterAssimp description to reflect current status (cherry picked from commit 95f6be365aef0c2fb489b1ac852f4ead11567712) --- doc/classes/EditorSceneImporterAssimp.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/EditorSceneImporterAssimp.xml b/doc/classes/EditorSceneImporterAssimp.xml index 8fb7347ae8b..27915ba910f 100644 --- a/doc/classes/EditorSceneImporterAssimp.xml +++ b/doc/classes/EditorSceneImporterAssimp.xml @@ -1,10 +1,10 @@ - Multi-format 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. + FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. - This is a multi-format 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. See [url=https://assimp-docs.readthedocs.io/en/latest/about/intoduction.html#installation]this page[/url] for a full list of supported formats. + This is an FBX 3D asset importer based on [url=http://assimp.org/]Assimp[/url]. It currently has many known limitations and works best with static meshes. Most animated meshes won't import correctly. If exporting a FBX scene from Autodesk Maya, use these FBX export settings: [codeblock] - Smoothing Groups From 31506ebe8585e92e8c293d5aea2fb874905998e4 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Mon, 10 Feb 2020 14:09:41 -0800 Subject: [PATCH 06/64] updated description of metallic in SpatialMaterial --- doc/classes/SpatialMaterial.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml index 6eeb10b6605..5ead992e9fb 100644 --- a/doc/classes/SpatialMaterial.xml +++ b/doc/classes/SpatialMaterial.xml @@ -221,7 +221,7 @@ If [code]true[/code], triplanar mapping is calculated in world space rather than object local space. See also [member uv1_triplanar]. - The reflectivity of the object's surface. The higher the value, the more light is reflected. + A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness]. Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources. From e2ac4195b66783f9021ffbebdede5fb7c8719659 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Thu, 24 Oct 2019 21:56:05 +0200 Subject: [PATCH 07/64] Improved search in settings dialogs Settings search used to work only on properties, so if a searchbox text was a substring of a category but not of a property the whole category would be filtered out and no property would be shown. Now the behaviour is changed so that when the searchbox text is a substring of a category all its properties are shown too. The previous behaviour is still present so that in case the searchbox text is both a substring of a category and a property of another category, all properties of the first category are shown and only the property of the second category is shown. (cherry picked from commit 84410f937e6504f72e8a35becf237049b640b39f) --- editor/editor_inspector.cpp | 2 +- editor/editor_sectioned_inspector.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 56da7d93fa6..7c1e58862ea 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1596,7 +1596,7 @@ void EditorInspector::update_tree() { if (capitalize_paths) cat = cat.capitalize(); - if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name)) + if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name) && property_prefix.to_lower().find(filter.to_lower()) == -1) continue; } diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 28825b45e1a..2090c12c91b 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -245,6 +245,9 @@ void SectionedInspector::update_category_list() { if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) continue; + if (!filter.empty() && !filter.is_subsequence_ofi(pi.name) && !filter.is_subsequence_ofi(pi.name.replace("/", " ").capitalize())) + continue; + int sp = pi.name.find("/"); if (sp == -1) pi.name = "global/" + pi.name; @@ -252,9 +255,6 @@ void SectionedInspector::update_category_list() { Vector sectionarr = pi.name.split("/"); String metasection; - if (!filter.empty() && !filter.is_subsequence_ofi(sectionarr[sectionarr.size() - 1].capitalize())) - continue; - int sc = MIN(2, sectionarr.size() - 1); for (int i = 0; i < sc; i++) { From 68f013317bd1bf6b5184a604913f8dd91ec628e2 Mon Sep 17 00:00:00 2001 From: gururise Date: Mon, 25 Nov 2019 12:30:10 -0800 Subject: [PATCH 08/64] change step size of animation length EditSpinSlider to match minimum animation length (cherry picked from commit caab6603d187aaa1bd7e70d4fba5aace28642e0a) --- editor/animation_track_editor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index e9719f8618b..2edfcced602 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1727,7 +1727,7 @@ void AnimationTimelineEdit::update_values() { time_icon->set_tooltip(TTR("Animation length (frames)")); } else { length->set_value(animation->get_length()); - length->set_step(0.01); + length->set_step(0.001); length->set_tooltip(TTR("Animation length (seconds)")); time_icon->set_tooltip(TTR("Animation length (seconds)")); } @@ -1890,7 +1890,7 @@ AnimationTimelineEdit::AnimationTimelineEdit() { length = memnew(EditorSpinSlider); length->set_min(0.001); length->set_max(36000); - length->set_step(0.01); + length->set_step(0.001); length->set_allow_greater(true); length->set_custom_minimum_size(Vector2(70 * EDSCALE, 0)); length->set_hide_slider(true); From a45aa3a46f2c278e4e64993b11dba9fe9c5fa615 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Wed, 27 Nov 2019 20:06:06 +0100 Subject: [PATCH 09/64] Implement zooming using Ctrl + Mouse wheel in the GridMap editor The minimum value of the slider was changed to 0.2 as zooming works in increments of 0.2. This way, the value can go back to 1 after you've reached the slider's minimum value. (cherry picked from commit 4c1b2171b0d2ebff568460a06a24287c0b994dc2) --- modules/gridmap/grid_map_editor_plugin.cpp | 24 ++++++++++++++++++++-- modules/gridmap/grid_map_editor_plugin.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 4aa407f9665..28d301ada10 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -840,15 +840,33 @@ void GridMapEditor::_text_changed(const String &p_text) { void GridMapEditor::_sbox_input(const Ref &p_ie) { - Ref k = p_ie; + const Ref k = p_ie; if (k.is_valid() && (k->get_scancode() == KEY_UP || k->get_scancode() == KEY_DOWN || k->get_scancode() == KEY_PAGEUP || k->get_scancode() == KEY_PAGEDOWN)) { + // Forward the key input to the ItemList so it can be scrolled mesh_library_palette->call("_gui_input", k); search_box->accept_event(); } } +void GridMapEditor::_mesh_library_palette_input(const Ref &p_ie) { + + const Ref mb = p_ie; + + // Zoom in/out using Ctrl + mouse wheel + if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { + + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + size_slider->set_value(size_slider->get_value() + 0.2); + } + + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + size_slider->set_value(size_slider->get_value() - 0.2); + } + } +} + void GridMapEditor::_icon_size_changed(float p_value) { mesh_library_palette->set_icon_scale(p_value); update_palette(); @@ -1183,6 +1201,7 @@ void GridMapEditor::_bind_methods() { ClassDB::bind_method("_text_changed", &GridMapEditor::_text_changed); ClassDB::bind_method("_sbox_input", &GridMapEditor::_sbox_input); + ClassDB::bind_method("_mesh_library_palette_input", &GridMapEditor::_mesh_library_palette_input); ClassDB::bind_method("_icon_size_changed", &GridMapEditor::_icon_size_changed); ClassDB::bind_method("_menu_option", &GridMapEditor::_menu_option); ClassDB::bind_method("_configure", &GridMapEditor::_configure); @@ -1311,7 +1330,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { size_slider = memnew(HSlider); size_slider->set_h_size_flags(SIZE_EXPAND_FILL); - size_slider->set_min(0.1f); + size_slider->set_min(0.2f); size_slider->set_max(4.0f); size_slider->set_step(0.1f); size_slider->set_value(1.0f); @@ -1325,6 +1344,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { mesh_library_palette = memnew(ItemList); add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); + mesh_library_palette->connect("gui_input", this, "_mesh_library_palette_input"); info_message = memnew(Label); info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes.")); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 404e95b74cf..5e6221b4f01 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -214,6 +214,7 @@ class GridMapEditor : public VBoxContainer { void _text_changed(const String &p_text); void _sbox_input(const Ref &p_ie); + void _mesh_library_palette_input(const Ref &p_ie); void _icon_size_changed(float p_value); From 725ff19636e729c57073a3af2ded2ff988e01caa Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 28 Nov 2019 00:07:01 +0100 Subject: [PATCH 10/64] Improve the AutoLoad editor UX - Convert the default AutoLoad name to PascalCase when selecting a file. - Disable the "Add" button if the path is empty or the name is invalid. - Prefix the automatically-chosen name with "Global" if it would conflict with a built-in class. - Replace the FileList icon with the Load icon as it better represents the action. (cherry picked from commit 352be7dbcc1aa782a34381325e89404aad06a6b9) --- editor/editor_autoload_settings.cpp | 41 ++++++++++++++++++++++++++--- editor/editor_autoload_settings.h | 5 +++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 46a54969e02..dba8c2ec8c6 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -120,6 +120,7 @@ void EditorAutoloadSettings::_autoload_add() { autoload_add_path->get_line_edit()->set_text(""); autoload_add_name->set_text(""); + add_autoload->set_disabled(true); } void EditorAutoloadSettings::_autoload_selected() { @@ -312,7 +313,34 @@ void EditorAutoloadSettings::_autoload_open(const String &fpath) { void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) { - autoload_add_name->set_text(p_path.get_file().get_basename()); + // Convert the file name to PascalCase, which is the convention for classes in GDScript. + const String class_name = p_path.get_file().get_basename().capitalize().replace(" ", ""); + + // If the name collides with a built-in class, prefix the name to make it possible to add without having to edit the name. + // The prefix is subjective, but it provides better UX than leaving the Add button disabled :) + const String prefix = ClassDB::class_exists(class_name) ? "Global" : ""; + + autoload_add_name->set_text(prefix + class_name); + add_autoload->set_disabled(false); +} + +void EditorAutoloadSettings::_autoload_text_entered(const String p_name) { + + if (autoload_add_path->get_line_edit()->get_text() != "" && _autoload_name_is_valid(p_name, NULL)) { + _autoload_add(); + } +} + +void EditorAutoloadSettings::_autoload_path_text_changed(const String p_path) { + + add_autoload->set_disabled( + p_path == "" || !_autoload_name_is_valid(autoload_add_name->get_text(), NULL)); +} + +void EditorAutoloadSettings::_autoload_text_changed(const String p_name) { + + add_autoload->set_disabled( + autoload_add_path->get_line_edit()->get_text() == "" || !_autoload_name_is_valid(p_name, NULL)); } Node *EditorAutoloadSettings::_create_autoload(const String &p_path) { @@ -424,7 +452,7 @@ void EditorAutoloadSettings::update_autoload() { item->set_editable(2, true); item->set_text(2, TTR("Enable")); item->set_checked(2, info.is_singleton); - item->add_button(3, get_icon("FileList", "EditorIcons"), BUTTON_OPEN); + item->add_button(3, get_icon("Load", "EditorIcons"), BUTTON_OPEN); item->add_button(3, get_icon("MoveUp", "EditorIcons"), BUTTON_MOVE_UP); item->add_button(3, get_icon("MoveDown", "EditorIcons"), BUTTON_MOVE_DOWN); item->add_button(3, get_icon("Remove", "EditorIcons"), BUTTON_DELETE); @@ -713,7 +741,9 @@ void EditorAutoloadSettings::_bind_methods() { ClassDB::bind_method("_autoload_edited", &EditorAutoloadSettings::_autoload_edited); ClassDB::bind_method("_autoload_button_pressed", &EditorAutoloadSettings::_autoload_button_pressed); ClassDB::bind_method("_autoload_activated", &EditorAutoloadSettings::_autoload_activated); + ClassDB::bind_method("_autoload_path_text_changed", &EditorAutoloadSettings::_autoload_path_text_changed); ClassDB::bind_method("_autoload_text_entered", &EditorAutoloadSettings::_autoload_text_entered); + ClassDB::bind_method("_autoload_text_changed", &EditorAutoloadSettings::_autoload_text_changed); ClassDB::bind_method("_autoload_open", &EditorAutoloadSettings::_autoload_open); ClassDB::bind_method("_autoload_file_callback", &EditorAutoloadSettings::_autoload_file_callback); @@ -806,6 +836,8 @@ EditorAutoloadSettings::EditorAutoloadSettings() { autoload_add_path->set_h_size_flags(SIZE_EXPAND_FILL); autoload_add_path->get_file_dialog()->set_mode(EditorFileDialog::MODE_OPEN_FILE); autoload_add_path->get_file_dialog()->connect("file_selected", this, "_autoload_file_callback"); + autoload_add_path->get_line_edit()->connect("text_changed", this, "_autoload_path_text_changed"); + hbc->add_child(autoload_add_path); l = memnew(Label); @@ -815,11 +847,14 @@ EditorAutoloadSettings::EditorAutoloadSettings() { autoload_add_name = memnew(LineEdit); autoload_add_name->set_h_size_flags(SIZE_EXPAND_FILL); autoload_add_name->connect("text_entered", this, "_autoload_text_entered"); + autoload_add_name->connect("text_changed", this, "_autoload_text_changed"); hbc->add_child(autoload_add_name); - Button *add_autoload = memnew(Button); + add_autoload = memnew(Button); add_autoload->set_text(TTR("Add")); add_autoload->connect("pressed", this, "_autoload_add"); + // The button will be enabled once a valid name is entered (either automatically or manually). + add_autoload->set_disabled(true); hbc->add_child(add_autoload); tree = memnew(Tree); diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h index e1a04644aaa..653a1b0a78f 100644 --- a/editor/editor_autoload_settings.h +++ b/editor/editor_autoload_settings.h @@ -76,6 +76,7 @@ class EditorAutoloadSettings : public VBoxContainer { Tree *tree; EditorLineEditFileChooser *autoload_add_path; LineEdit *autoload_add_name; + Button *add_autoload; bool _autoload_name_is_valid(const String &p_name, String *r_error = NULL); @@ -84,7 +85,9 @@ class EditorAutoloadSettings : public VBoxContainer { void _autoload_edited(); void _autoload_button_pressed(Object *p_item, int p_column, int p_button); void _autoload_activated(); - void _autoload_text_entered(String) { _autoload_add(); } + void _autoload_path_text_changed(const String p_path); + void _autoload_text_entered(const String p_name); + void _autoload_text_changed(const String p_name); void _autoload_open(const String &fpath); void _autoload_file_callback(const String &p_path); Node *_create_autoload(const String &p_path); From ca6ac71cdf8dba5d9d8150589b4618880d33109a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 28 Nov 2019 16:37:15 +0100 Subject: [PATCH 11/64] Improve the Video RAM debugger UX - Refresh tha tab automatically when switching to it. - Disable the Refresh button if no project is currently being debugged. - Scale the column widths on hiDPI displays. - Rename the tab from "Video Mem" to "Video RAM" for consistency. (cherry picked from commit 8f838f33b7a2ec2ee952b428cf4aa48707f3a59e) --- editor/script_editor_debugger.cpp | 27 ++++++++++++++++++++------- editor/script_editor_debugger.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 004c7a68014..ab4501bb8a7 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -484,8 +484,10 @@ int ScriptEditorDebugger::_update_scene_tree(TreeItem *parent, const Array &node void ScriptEditorDebugger::_video_mem_request() { - ERR_FAIL_COND(connection.is_null()); - ERR_FAIL_COND(!connection->is_connected_to_host()); + if (connection.is_null() || !connection->is_connected_to_host()) { + // Video RAM usage is only available while a project is being debugged. + return; + } Array msg; msg.push_back("request_video_mem"); @@ -1323,6 +1325,7 @@ void ScriptEditorDebugger::_notification(int p_what) { inspect_scene_tree->clear(); le_set->set_disabled(true); le_clear->set_disabled(false); + vmem_refresh->set_disabled(false); error_tree->clear(); error_count = 0; warning_count = 0; @@ -1523,6 +1526,7 @@ void ScriptEditorDebugger::stop() { le_clear->set_disabled(false); le_set->set_disabled(true); profiler->set_enabled(true); + vmem_refresh->set_disabled(true); inspect_scene_tree->clear(); inspector->edit(NULL); @@ -2188,6 +2192,13 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { } } +void ScriptEditorDebugger::_tab_changed(int p_tab) { + if (tabs->get_tab_title(p_tab) == TTR("Video RAM")) { + // "Video RAM" tab was clicked, refresh the data it's dislaying when entering the tab. + _video_mem_request(); + } +} + void ScriptEditorDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("_stack_dump_frame_selected"), &ScriptEditorDebugger::_stack_dump_frame_selected); @@ -2219,6 +2230,7 @@ void ScriptEditorDebugger::_bind_methods() { ClassDB::bind_method(D_METHOD("_error_tree_item_rmb_selected"), &ScriptEditorDebugger::_error_tree_item_rmb_selected); ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &ScriptEditorDebugger::_item_menu_id_pressed); + ClassDB::bind_method(D_METHOD("_tab_changed"), &ScriptEditorDebugger::_tab_changed); ClassDB::bind_method(D_METHOD("_paused"), &ScriptEditorDebugger::_paused); @@ -2259,13 +2271,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles")); tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles")); tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles")); + tabs->connect("tab_changed", this, "_tab_changed"); add_child(tabs); { //debugger VBoxContainer *vbc = memnew(VBoxContainer); vbc->set_name(TTR("Debugger")); - //tabs->add_child(vbc); Control *dbg = vbc; HBoxContainer *hbc = memnew(HBoxContainer); @@ -2523,6 +2535,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { vmem_total->set_custom_minimum_size(Size2(100, 0) * EDSCALE); vmem_hb->add_child(vmem_total); vmem_refresh = memnew(ToolButton); + vmem_refresh->set_disabled(true); vmem_hb->add_child(vmem_refresh); vmem_vb->add_child(vmem_hb); vmem_refresh->connect("pressed", this, "_video_mem_request"); @@ -2535,20 +2548,20 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { vmmc->set_v_size_flags(SIZE_EXPAND_FILL); vmem_vb->add_child(vmmc); - vmem_vb->set_name(TTR("Video Mem")); + vmem_vb->set_name(TTR("Video RAM")); vmem_tree->set_columns(4); vmem_tree->set_column_titles_visible(true); vmem_tree->set_column_title(0, TTR("Resource Path")); vmem_tree->set_column_expand(0, true); vmem_tree->set_column_expand(1, false); vmem_tree->set_column_title(1, TTR("Type")); - vmem_tree->set_column_min_width(1, 100); + vmem_tree->set_column_min_width(1, 100 * EDSCALE); vmem_tree->set_column_expand(2, false); vmem_tree->set_column_title(2, TTR("Format")); - vmem_tree->set_column_min_width(2, 150); + vmem_tree->set_column_min_width(2, 150 * EDSCALE); vmem_tree->set_column_expand(3, false); vmem_tree->set_column_title(3, TTR("Usage")); - vmem_tree->set_column_min_width(3, 80); + vmem_tree->set_column_min_width(3, 80 * EDSCALE); vmem_tree->set_hide_root(true); tabs->add_child(vmem_vb); diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index 7d91e247b64..589a011bffe 100644 --- a/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h @@ -226,6 +226,7 @@ private: void _error_tree_item_rmb_selected(const Vector2 &p_pos); void _item_menu_id_pressed(int p_option); + void _tab_changed(int p_tab); void _export_csv(); From 9a396a4e07e1566eec7c179b592a8e0e2907c3f1 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 29 Nov 2019 02:20:31 -0500 Subject: [PATCH 12/64] [Mono] Basis/Transforms Array operator comments and improvements The behavior for Basis and Transform2D is unchanged, and Transform gets new behavior. All of the behavior is identical to GDScript's behavior. (cherry picked from commit 0a39c7b3546e85eb3221c2ec892d2302bf14c51c) --- .../glue/GodotSharp/GodotSharp/Core/Basis.cs | 58 +++++---------- .../glue/GodotSharp/GodotSharp/Core/Mathf.cs | 6 +- .../GodotSharp/Core/StringExtensions.cs | 3 +- .../GodotSharp/GodotSharp/Core/Transform.cs | 70 +++++++++++++++++++ .../GodotSharp/GodotSharp/Core/Transform2D.cs | 46 +++++------- 5 files changed, 109 insertions(+), 74 deletions(-) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index d38589013ec..55408fecb8a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -93,11 +93,15 @@ namespace Godot } } - public Vector3 this[int columnIndex] + /// + /// Access whole columns in the form of Vector3. + /// + /// Which column vector. + public Vector3 this[int column] { get { - switch (columnIndex) + switch (column) { case 0: return Column0; @@ -111,7 +115,7 @@ namespace Godot } set { - switch (columnIndex) + switch (column) { case 0: Column0 = value; @@ -128,50 +132,22 @@ namespace Godot } } - public real_t this[int columnIndex, int rowIndex] + /// + /// Access matrix elements in column-major order. + /// + /// Which column, the matrix horizontal position. + /// Which row, the matrix vertical position. + public real_t this[int column, int row] { get { - switch (columnIndex) - { - case 0: - return Column0[rowIndex]; - case 1: - return Column1[rowIndex]; - case 2: - return Column2[rowIndex]; - default: - throw new IndexOutOfRangeException(); - } + return this[column][row]; } set { - switch (columnIndex) - { - case 0: - { - var column0 = Column0; - column0[rowIndex] = value; - Column0 = column0; - return; - } - case 1: - { - var column1 = Column1; - column1[rowIndex] = value; - Column1 = column1; - return; - } - case 2: - { - var column2 = Column2; - column2[rowIndex] = value; - Column2 = column2; - return; - } - default: - throw new IndexOutOfRangeException(); - } + Vector3 columnVector = this[column]; + columnVector[row] = value; + this[column] = columnVector; } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index ddfed180b50..4f7aa99df86 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -130,7 +130,7 @@ namespace Godot public static real_t InverseLerp(real_t from, real_t to, real_t weight) { - return (weight - from) / (to - from); + return (weight - from) / (to - from); } public static bool IsEqualApprox(real_t a, real_t b) @@ -151,12 +151,12 @@ namespace Godot public static bool IsInf(real_t s) { - return real_t.IsInfinity(s); + return real_t.IsInfinity(s); } public static bool IsNaN(real_t s) { - return real_t.IsNaN(s); + return real_t.IsNaN(s); } public static bool IsZeroApprox(real_t s) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index b926037e5a7..ffef50cc185 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -264,7 +264,8 @@ namespace Godot instanceIndex++; toIndex++; } - } else + } + else { while (true) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs index 0b84050f072..aa8815d1aa4 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs @@ -15,6 +15,76 @@ namespace Godot public Basis basis; public Vector3 origin; + /// + /// Access whole columns in the form of Vector3. The fourth column is the origin vector. + /// + /// Which column vector. + public Vector3 this[int column] + { + get + { + switch (column) + { + case 0: + return basis.Column0; + case 1: + return basis.Column1; + case 2: + return basis.Column2; + case 3: + return origin; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (column) + { + case 0: + basis.Column0 = value; + return; + case 1: + basis.Column1 = value; + return; + case 2: + basis.Column2 = value; + return; + case 3: + origin = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// + /// Access matrix elements in column-major order. The fourth column is the origin vector. + /// + /// Which column, the matrix horizontal position. + /// Which row, the matrix vertical position. + public real_t this[int column, int row] + { + get + { + if (column == 3) + { + return origin[row]; + } + return basis[column, row]; + } + set + { + if (column == 3) + { + origin[row] = value; + return; + } + basis[column, row] = value; + } + } + public Transform AffineInverse() { Basis basisInv = basis.Inverse(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 77ea3e58302..e72a44809a7 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -54,11 +54,15 @@ namespace Godot } } - public Vector2 this[int rowIndex] + /// + /// Access whole columns in the form of Vector2. The third column is the origin vector. + /// + /// Which column vector. + public Vector2 this[int column] { get { - switch (rowIndex) + switch (column) { case 0: return x; @@ -72,7 +76,7 @@ namespace Godot } set { - switch (rowIndex) + switch (column) { case 0: x = value; @@ -89,38 +93,22 @@ namespace Godot } } - public real_t this[int rowIndex, int columnIndex] + /// + /// Access matrix elements in column-major order. The third column is the origin vector. + /// + /// Which column, the matrix horizontal position. + /// Which row, the matrix vertical position. + public real_t this[int column, int row] { get { - switch (rowIndex) - { - case 0: - return x[columnIndex]; - case 1: - return y[columnIndex]; - case 2: - return origin[columnIndex]; - default: - throw new IndexOutOfRangeException(); - } + return this[column][row]; } set { - switch (rowIndex) - { - case 0: - x[columnIndex] = value; - return; - case 1: - y[columnIndex] = value; - return; - case 2: - origin[columnIndex] = value; - return; - default: - throw new IndexOutOfRangeException(); - } + Vector2 columnVector = this[column]; + columnVector[row] = value; + this[column] = columnVector; } } From 56336b4e24e5b96a3136f40866405fb979a5a9eb Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 19 Jan 2020 21:22:16 +0100 Subject: [PATCH 13/64] Improve the batch rename dialog - Use the editor-defined error, warning and success colors for preview texts. - Make the "Regular Expressions" option into a CheckButton (as it does something as soon as it's toggled) and move it out of the Advanced Options submenu. - Make it clearer that the error message originates from an invalid regular expression. - Clarify what the number means in the regex error message. - Tweak some strings' casing for consistency. (cherry picked from commit ff135065f401c34dc485543e1416495d50f29aae) --- editor/rename_dialog.cpp | 51 ++++++++++++++++++---------------------- editor/rename_dialog.h | 2 +- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 32fcdab4c63..7586f6eac19 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -109,9 +109,13 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und const int feature_min_height = 160 * EDSCALE; - CheckButton *chk_collapse_features = memnew(CheckButton); - chk_collapse_features->set_text(TTR("Advanced Options")); - vbc->add_child(chk_collapse_features); + cbut_regex = memnew(CheckButton); + cbut_regex->set_text(TTR("Use Regular Expressions")); + vbc->add_child(cbut_regex); + + CheckButton *cbut_collapse_features = memnew(CheckButton); + cbut_collapse_features->set_text(TTR("Advanced Options")); + vbc->add_child(cbut_collapse_features); tabc_features = memnew(TabContainer); tabc_features->set_tab_align(TabContainer::ALIGN_LEFT); @@ -195,7 +199,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und grd_substitute->add_child(but_insert_count); chk_per_level_counter = memnew(CheckBox); - chk_per_level_counter->set_text(TTR("Per Level counter")); + chk_per_level_counter->set_text(TTR("Per-level Counter")); chk_per_level_counter->set_tooltip(TTR("If set the counter restarts for each group of child nodes")); vbc_substitute->add_child(chk_per_level_counter); @@ -233,18 +237,6 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und spn_count_padding->set_step(1); hbc_count_options->add_child(spn_count_padding); - // ---- Tab RegEx - - VBoxContainer *vbc_regex = memnew(VBoxContainer); - vbc_regex->set_h_size_flags(SIZE_EXPAND_FILL); - vbc_regex->set_name(TTR("Regular Expressions")); - vbc_regex->set_custom_minimum_size(Size2(0, feature_min_height)); - tabc_features->add_child(vbc_regex); - - cbut_regex = memnew(CheckBox); - cbut_regex->set_text(TTR("Regular Expressions")); - vbc_regex->add_child(cbut_regex); - // ---- Tab Process VBoxContainer *vbc_process = memnew(VBoxContainer); @@ -268,8 +260,8 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und opt_style = memnew(OptionButton); opt_style->add_item(TTR("Keep")); - opt_style->add_item(TTR("CamelCase to under_scored")); - opt_style->add_item(TTR("under_scored to CamelCase")); + opt_style->add_item(TTR("PascalCase to snake_case")); + opt_style->add_item(TTR("snake_case to PascalCase")); hbc_style->add_child(opt_style); // ------ Case @@ -299,7 +291,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und lbl_preview = memnew(Label); lbl_preview->set_text(""); - lbl_preview->add_color_override("font_color", Color(1, 0.5f, 0, 1)); + lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor")); vbc->add_child(lbl_preview); // ---- Dialog related @@ -314,7 +306,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und // ---- Connections - chk_collapse_features->connect("toggled", this, "_features_toggled"); + cbut_collapse_features->connect("toggled", this, "_features_toggled"); // Substitite Buttons @@ -414,9 +406,12 @@ void RenameDialog::_update_preview(String new_text) { lbl_preview->set_text(new_name); if (new_name == preview_node->get_name()) { - lbl_preview->add_color_override("font_color", Color(0, 0.5f, 0.25f, 1)); + // New name is identical to the old one. Don't color it as much to avoid distracting the user. + const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_color("accent_color", "Editor"); + const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_color("default_color", "RichTextLabel"); + lbl_preview->add_color_override("font_color", accent_color.linear_interpolate(text_color, 0.5)); } else { - lbl_preview->add_color_override("font_color", Color(0, 1, 0.5f, 1)); + lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("success_color", "Editor")); } } @@ -501,9 +496,9 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char * } self->has_errors = true; - self->lbl_preview_title->set_text(TTR("Error")); - self->lbl_preview->add_color_override("font_color", Color(1, 0.25f, 0, 1)); - self->lbl_preview->set_text(err_str); + self->lbl_preview_title->set_text(TTR("Regular Expression Error")); + self->lbl_preview->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor")); + self->lbl_preview->set_text(vformat(TTR("At character %s"), err_str)); } String RenameDialog::_regex(const String &pattern, const String &subject, const String &replacement) { @@ -520,18 +515,18 @@ String RenameDialog::_postprocess(const String &subject) { String result = subject; if (style_id == 1) { + // PascalCase to snake_case - // CamelCase to Under_Line result = result.camelcase_to_underscore(true); result = _regex("_+", result, "_"); } else if (style_id == 2) { + // snake_case to PascalCase - // Under_Line to CamelCase RegEx pattern("_+(.?)"); Array matches = pattern.search_all(result); - // _ name would become empty. Ignore + // The name `_` would become empty; ignore it. if (matches.size() && result != "_") { String buffer; int start = 0; diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 692e56f1a47..2825cb2cd2b 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -75,7 +75,7 @@ class RenameDialog : public ConfirmationDialog { TabContainer *tabc_features; CheckBox *cbut_substitute; - CheckBox *cbut_regex; + CheckButton *cbut_regex; CheckBox *cbut_process; CheckBox *chk_per_level_counter; From 63daa19538d92a18ac04147386aa1ee7c61e4f4e Mon Sep 17 00:00:00 2001 From: Eric Rybicki Date: Sat, 25 Jan 2020 10:06:14 +0100 Subject: [PATCH 14/64] Use a new approach to fix bone pose override not being reset when IK animation is stopped. This reverts PR #35460 & commit 551c37167b0428b1489a8a6f6233624c5f4aa628. (cherry picked from commit bb0358dd8d3ed99c9fb3545efdf821d28e73b68b) --- editor/plugins/skeleton_ik_editor_plugin.cpp | 11 +---------- editor/plugins/skeleton_ik_editor_plugin.h | 1 - scene/animation/skeleton_ik.cpp | 13 ------------- scene/animation/skeleton_ik.h | 1 - 4 files changed, 1 insertion(+), 25 deletions(-) diff --git a/editor/plugins/skeleton_ik_editor_plugin.cpp b/editor/plugins/skeleton_ik_editor_plugin.cpp index 43dc13b2706..eb6ad9498dd 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.cpp +++ b/editor/plugins/skeleton_ik_editor_plugin.cpp @@ -41,21 +41,12 @@ void SkeletonIKEditorPlugin::_play() { return; if (play_btn->is_pressed()) { - - initial_bone_poses.resize(skeleton_ik->get_parent_skeleton()->get_bone_count()); - for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) { - initial_bone_poses.write[i] = skeleton_ik->get_parent_skeleton()->get_bone_pose(i); - } - skeleton_ik->start(); } else { skeleton_ik->stop(); - if (initial_bone_poses.size() != skeleton_ik->get_parent_skeleton()->get_bone_count()) - return; - for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) { - skeleton_ik->get_parent_skeleton()->set_bone_pose(i, initial_bone_poses[i]); + skeleton_ik->get_parent_skeleton()->set_bone_global_pose_override(i, Transform(), 0); } } } diff --git a/editor/plugins/skeleton_ik_editor_plugin.h b/editor/plugins/skeleton_ik_editor_plugin.h index 06c07031f65..814eb8ff5b9 100644 --- a/editor/plugins/skeleton_ik_editor_plugin.h +++ b/editor/plugins/skeleton_ik_editor_plugin.h @@ -44,7 +44,6 @@ class SkeletonIKEditorPlugin : public EditorPlugin { Button *play_btn; EditorNode *editor; - Vector initial_bone_poses; void _play(); diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 46028a9ce2d..518c243dd0e 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -329,17 +329,6 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove } } -void FabrikInverseKinematic::reset(Task *p_task) { - ChainItem *ci(&p_task->chain.chain_root); - while (ci) { - p_task->skeleton->set_bone_global_pose_override(ci->bone, Transform(), 0); - if (!ci->children.empty()) - ci = &ci->children.write[0]; - else - ci = NULL; - } -} - void SkeletonIK::_validate_property(PropertyInfo &property) const { if (property.name == "root_bone" || property.name == "tip_bone") { @@ -542,8 +531,6 @@ void SkeletonIK::start(bool p_one_time) { void SkeletonIK::stop() { set_process_internal(false); - if (task) - FabrikInverseKinematic::reset(task); } Transform SkeletonIK::_get_target_transform() { diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h index 8fc8a58b998..9ae010dc4e4 100644 --- a/scene/animation/skeleton_ik.h +++ b/scene/animation/skeleton_ik.h @@ -139,7 +139,6 @@ public: static void set_goal(Task *p_task, const Transform &p_goal); static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); - static void reset(Task *p_task); }; class SkeletonIK : public Node { From 2d8289579a4214dae318e9e500c952a9ed43edc6 Mon Sep 17 00:00:00 2001 From: nathanwfranke Date: Fri, 7 Feb 2020 14:43:27 -0600 Subject: [PATCH 15/64] Fix bug where Control at origin with 0 size not rendered Make a new method instead to make the code more elegant Move Function down a bit (cherry picked from commit e5cb557b73d804b59a5eda30b4b09d3d18ea91ad) --- core/math/rect2.h | 13 +++++++++++++ servers/visual/visual_server_canvas.cpp | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/core/math/rect2.h b/core/math/rect2.h index 90173777702..0d2e7eb6e58 100644 --- a/core/math/rect2.h +++ b/core/math/rect2.h @@ -60,6 +60,19 @@ struct Rect2 { return true; } + inline bool intersects_touch(const Rect2 &p_rect) const { + if (position.x > (p_rect.position.x + p_rect.size.width)) + return false; + if ((position.x + size.width) < p_rect.position.x) + return false; + if (position.y > (p_rect.position.y + p_rect.size.height)) + return false; + if ((position.y + size.height) < p_rect.position.y) + return false; + + return true; + } + inline real_t distance_to(const Vector2 &p_point) const { real_t dist = 0.0; diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index e07e188ec6d..c90e061eb72 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -168,7 +168,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor VisualServerRaster::redraw_request(); } - if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) { + if ((!ci->commands.empty() && p_clip_rect.intersects_touch(global_rect)) || ci->vp_render || ci->copy_back_buffer) { //something to draw? ci->final_transform = xform; ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a); From 489b3c2949836d4a419073ac367ab519a14a9e17 Mon Sep 17 00:00:00 2001 From: Alexander Holland Date: Wed, 29 Jan 2020 16:24:40 +0100 Subject: [PATCH 16/64] Fix double tap pressed event regression (cherry picked from commit d2a5b7367b17d4390e582a748ff47bf65f5d1ea3) --- platform/android/os_android.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 44c5b5d6b4b..e5d9bdc60c1 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -507,9 +507,8 @@ void OS_Android::process_double_tap(Point2 p_pos) { ev.instance(); ev->set_position(p_pos); ev->set_global_position(p_pos); - ev->set_pressed(true); + ev->set_pressed(false); ev->set_doubleclick(true); - ev->set_button_index(1); input->parse_input_event(ev); } From 58a940e5aa465bfe33663342b3c2c315e2061da0 Mon Sep 17 00:00:00 2001 From: sumit0190 Date: Wed, 29 Jan 2020 14:46:49 -0500 Subject: [PATCH 17/64] Update cached_width of the line_edit element when setting it to be secret (cherry picked from commit 2e08578985689857271a2c554d524f3eee6cc08d) --- scene/gui/line_edit.cpp | 33 +++++++++++++++------------------ scene/gui/line_edit.h | 1 + 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 7afc3b0d007..7cc47d351e3 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -240,15 +240,7 @@ void LineEdit::_gui_input(Ref p_event) { deselect(); text = text.substr(cursor_pos, text.length() - cursor_pos); - - Ref font = get_font("font"); - - cached_width = 0; - if (font != NULL) { - for (int i = 0; i < text.length(); i++) - cached_width += font->get_char_size(text[i]).width; - } - + update_cached_width(); set_cursor_position(0); _text_changed(); } @@ -1358,18 +1350,10 @@ void LineEdit::set_window_pos(int p_pos) { void LineEdit::append_at_cursor(String p_text) { if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { - - Ref font = get_font("font"); - if (font != NULL) { - for (int i = 0; i < p_text.length(); i++) - cached_width += font->get_char_size(p_text[i]).width; - } else { - cached_width = 0; - } - String pre = text.substr(0, cursor_pos); String post = text.substr(cursor_pos, text.length() - cursor_pos); text = pre + p_text + post; + update_cached_width(); set_cursor_position(cursor_pos + p_text.length()); } else { emit_signal("text_change_rejected"); @@ -1499,6 +1483,7 @@ bool LineEdit::is_editable() const { void LineEdit::set_secret(bool p_secret) { pass = p_secret; + update_cached_width(); update(); } @@ -1514,6 +1499,7 @@ void LineEdit::set_secret_character(const String &p_string) { ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given)."); secret_character = p_string; + update_cached_width(); update(); } @@ -1685,6 +1671,17 @@ void LineEdit::_emit_text_change() { text_changed_dirty = false; } +void LineEdit::update_cached_width() { + Ref font = get_font("font"); + cached_width = 0; + if (font != NULL) { + String text = get_text(); + for (int i = 0; i < text.length(); i++) { + cached_width += font->get_char_size(pass ? secret_character[0] : text[i]).width; + } + } +} + void LineEdit::update_placeholder_width() { if ((max_length <= 0) || (placeholder_translated.length() <= max_length)) { Ref font = get_font("font"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index cf597d11b6f..037238d6827 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -132,6 +132,7 @@ private: void _emit_text_change(); bool expand_to_text_length; + void update_cached_width(); void update_placeholder_width(); bool caret_blink_enabled; From 3c7a013d8d220f5398594df324151b5630896d7f Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Thu, 30 Jan 2020 11:39:13 +0800 Subject: [PATCH 18/64] Adds pan and zoom gestures to TextureRegion editor (cherry picked from commit d1b1edba84a76614368fa9e7eb2459ed0dc95da5) --- editor/plugins/texture_region_editor_plugin.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 507ea0b83d8..94aef60f1ff 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -546,6 +546,17 @@ void TextureRegionEditor::_region_input(const Ref &p_input) { edit_draw->update(); } } + + Ref magnify_gesture = p_input; + if (magnify_gesture.is_valid()) { + _zoom_on_position(draw_zoom * magnify_gesture->get_factor(), magnify_gesture->get_position()); + } + + Ref pan_gesture = p_input; + if (pan_gesture.is_valid()) { + hscroll->set_value(hscroll->get_value() + hscroll->get_page() * pan_gesture->get_delta().x / 8); + vscroll->set_value(vscroll->get_value() + vscroll->get_page() * pan_gesture->get_delta().y / 8); + } } void TextureRegionEditor::_scroll_changed(float) { From 0dedc0a1a3ab0e6021aa1aeb15f9d53133ccaccf Mon Sep 17 00:00:00 2001 From: Eoin O'Neill Date: Thu, 30 Jan 2020 21:05:52 -0800 Subject: [PATCH 19/64] Fix RichTextEffect `visibility` to Account for Skipped Characters. A picture is easier to describe this issue than words. Basically, rich text effects allowed for character visibility changes. While doing so would work properly, the rich text label would render the next `word` in an offset accounting for the hidden characters (leaving a huge space.) This patch fixes this issue by keeping track of the amount of `backtrack` necessary per line. (cherry picked from commit b3fd4884d7dd2e1c5f5d5dadd8af6ed13ab131ac) --- scene/gui/rich_text_label.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 6c2928c65c2..a9b9aa4a4ad 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -199,6 +199,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int line_ascent = cfont->get_ascent(); int line_descent = cfont->get_descent(); + int backtrack = 0; // for dynamic hidden content. + int nonblank_line_count = 0; //number of nonblank lines as counted during PROCESS_DRAW Variant meta; @@ -209,6 +211,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & { \ if (p_mode != PROCESS_CACHE) { \ line++; \ + backtrack = 0; \ if (!line_is_blank) { \ nonblank_line_count++; \ } \ @@ -258,7 +261,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \ l.minimum_width = MAX(l.minimum_width, m_width); \ } \ - if (wofs + m_width > p_width) { \ + if (wofs - backtrack + m_width > p_width) { \ line_wrapped = true; \ if (p_mode == PROCESS_CACHE) { \ if (spaces > 0) \ @@ -385,6 +388,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & int fw = 0; lh = 0; + if (p_mode != PROCESS_CACHE) { lh = line < l.height_caches.size() ? l.height_caches[line] : 1; line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; @@ -427,13 +431,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & { - int ofs = 0; + int ofs = 0 - backtrack; for (int i = 0; i < end; i++) { int pofs = wofs + ofs; if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) { - //int o = (wofs+w)-p_click_pos.x; int cw = font->get_char_size(c[i], c[i + 1]).x; @@ -476,7 +479,10 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & bool visible = visible_characters < 0 || ((p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - line_descent - line_ascent, line_ascent + line_descent)) && faded_visibility > 0.0f); + const bool previously_visible = visible; + for (int j = 0; j < fx_stack.size(); j++) { + ItemFX *item_fx = fx_stack[j]; if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) { @@ -570,6 +576,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & } else { cw = drawer.draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - line_descent) + fx_offset, fx_char, c[i + 1], fx_color); } + } else if (previously_visible) { + backtrack += font->get_char_size(fx_char, c[i + 1]).x; } p_char_count++; @@ -643,6 +651,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & case ITEM_NEWLINE: { lh = 0; + if (p_mode != PROCESS_CACHE) { lh = line < l.height_caches.size() ? l.height_caches[line] : 1; line_is_blank = true; From 3eb978017977043270f3a739bc79ee4b95e519ec Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 31 Jan 2020 16:30:27 +0100 Subject: [PATCH 20/64] Re-add a way to generate a single convex shape from the editor It was removed after the implementation of VHACD. Generating a single shape can lead to better performance, so it may still be desired. This also adds tooltips for several options in the Mesh menu. This closes #35692. (cherry picked from commit 90af009f2ea637e5944a12b85c58018187c0de16) --- .../plugins/mesh_instance_editor_plugin.cpp | 70 ++++++++++++++----- editor/plugins/mesh_instance_editor_plugin.h | 4 +- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 25329906a92..6e5307cebe8 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -60,10 +60,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { } switch (p_option) { - case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: - case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: { - - bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); + case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: { EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); @@ -71,9 +68,12 @@ void MeshInstanceEditor::_menu_option(int p_option) { List selection = editor_selection->get_selected_node_list(); if (selection.empty()) { - Ref shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape(); - if (shape.is_null()) + Ref shape = mesh->create_trimesh_shape(); + if (shape.is_null()) { + err_dialog->set_text(TTR("Couldn't create a Trimesh collision shape.")); + err_dialog->popup_centered_minsize(); return; + } CollisionShape *cshape = memnew(CollisionShape); cshape->set_shape(shape); @@ -82,11 +82,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); - if (trimesh_shape) - ur->create_action(TTR("Create Static Trimesh Body")); - else - ur->create_action(TTR("Create Static Convex Body")); - + ur->create_action(TTR("Create Static Trimesh Body")); ur->add_do_method(node, "add_child", body); ur->add_do_method(body, "set_owner", owner); ur->add_do_method(cshape, "set_owner", owner); @@ -108,7 +104,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { if (m.is_null()) continue; - Ref shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape(); + Ref shape = m->create_trimesh_shape(); if (shape.is_null()) continue; @@ -158,10 +154,44 @@ void MeshInstanceEditor::_menu_option(int p_option) { ur->add_undo_method(node->get_parent(), "remove_child", cshape); ur->commit_action(); } break; - case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: { + case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE: { if (node == get_tree()->get_edited_scene_root()) { - err_dialog->set_text(TTR("This doesn't work on scene root!")); + err_dialog->set_text(TTR("Can't create a single convex collision shape for the scene root.")); + err_dialog->popup_centered_minsize(); + return; + } + + Ref shape = mesh->create_convex_shape(); + + if (shape.is_null()) { + err_dialog->set_text(TTR("Couldn't create a single convex collision shape.")); + err_dialog->popup_centered_minsize(); + return; + } + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + + ur->create_action(TTR("Create Single Convex Shape")); + + CollisionShape *cshape = memnew(CollisionShape); + cshape->set_shape(shape); + cshape->set_transform(node->get_transform()); + + Node *owner = node->get_owner(); + + ur->add_do_method(node->get_parent(), "add_child", cshape); + ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1); + ur->add_do_method(cshape, "set_owner", owner); + ur->add_do_reference(cshape); + ur->add_undo_method(node->get_parent(), "remove_child", cshape); + + ur->commit_action(); + + } break; + case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES: { + + if (node == get_tree()->get_edited_scene_root()) { + err_dialog->set_text(TTR("Can't create multiple convex collision shapes for the scene root.")); err_dialog->popup_centered_minsize(); return; } @@ -169,13 +199,13 @@ void MeshInstanceEditor::_menu_option(int p_option) { Vector > shapes = mesh->convex_decompose(); if (!shapes.size()) { - err_dialog->set_text(TTR("Failed creating shapes!")); + err_dialog->set_text(TTR("Couldn't create any collision shapes.")); err_dialog->popup_centered_minsize(); return; } UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Create Convex Shape(s)")); + ur->create_action(TTR("Create Multiple Convex Shapes")); for (int i = 0; i < shapes.size(); i++) { @@ -421,13 +451,19 @@ MeshInstanceEditor::MeshInstanceEditor() { options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance", "EditorIcons")); options->get_popup()->add_item(TTR("Create Trimesh Static Body"), MENU_OPTION_CREATE_STATIC_TRIMESH_BODY); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a StaticBody and assigns a polygon-based collision shape to it automatically.\nThis is the most accurate (but slowest) option for collision detection.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"), MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); - options->get_popup()->add_item(TTR("Create Convex Collision Sibling(s)"), MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection.")); + options->get_popup()->add_item(TTR("Create Single Convex Collision Siblings"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection.")); + options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between the two above options.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Navigation Mesh"), MENU_OPTION_CREATE_NAVMESH); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Outline Mesh..."), MENU_OPTION_CREATE_OUTLINE_MESH); + options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a static outline mesh. The outline mesh will have its normals flipped automatically.\nThis can be used instead of the SpatialMaterial Grow property when using that property isn't possible.")); options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("View UV1"), MENU_OPTION_DEBUG_UV1); options->get_popup()->add_item(TTR("View UV2"), MENU_OPTION_DEBUG_UV2); diff --git a/editor/plugins/mesh_instance_editor_plugin.h b/editor/plugins/mesh_instance_editor_plugin.h index 5c95676fc43..5ca9aa3fec4 100644 --- a/editor/plugins/mesh_instance_editor_plugin.h +++ b/editor/plugins/mesh_instance_editor_plugin.h @@ -43,9 +43,9 @@ class MeshInstanceEditor : public Control { enum Menu { MENU_OPTION_CREATE_STATIC_TRIMESH_BODY, - MENU_OPTION_CREATE_STATIC_CONVEX_BODY, MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE, - MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE, + MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES, MENU_OPTION_CREATE_NAVMESH, MENU_OPTION_CREATE_OUTLINE_MESH, MENU_OPTION_CREATE_UV2, From a7ff22ea6d3d6bd6601f8017ece1d44851f5592b Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 31 Jan 2020 22:40:14 +0200 Subject: [PATCH 21/64] Fix pressure / tilt ranges on Linux. (cherry picked from commit d552f93f8b79b0e99d912470c3362700d75c4984) --- platform/x11/os_x11.cpp | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index e40aa867f88..229efffe9fc 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -669,14 +669,8 @@ bool OS_X11::refresh_device_info() { int range_max_x = 0; int range_max_y = 0; int pressure_resolution = 0; - int pressure_min = 0; - int pressure_max = 0; int tilt_resolution_x = 0; int tilt_resolution_y = 0; - int tilt_range_min_x = 0; - int tilt_range_min_y = 0; - int tilt_range_max_x = 0; - int tilt_range_max_y = 0; for (int j = 0; j < dev->num_classes; j++) { #ifdef TOUCH_ENABLED if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) { @@ -697,17 +691,14 @@ bool OS_X11::refresh_device_info() { range_max_y = class_info->max; absolute_mode = true; } else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) { - pressure_resolution = class_info->resolution; - pressure_min = class_info->min; - pressure_max = class_info->max; + pressure_resolution = (class_info->max - class_info->min); + if (pressure_resolution == 0) pressure_resolution = 1; } else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) { - tilt_resolution_x = class_info->resolution; - tilt_range_min_x = class_info->min; - tilt_range_max_x = class_info->max; + tilt_resolution_x = (class_info->max - class_info->min); + if (tilt_resolution_x == 0) tilt_resolution_x = 1; } else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) { - tilt_resolution_y = class_info->resolution; - tilt_range_min_y = class_info->min; - tilt_range_max_y = class_info->max; + tilt_resolution_y = (class_info->max - class_info->min); + if (tilt_resolution_y == 0) tilt_resolution_y = 1; } } } @@ -728,15 +719,6 @@ bool OS_X11::refresh_device_info() { print_verbose("XInput: Absolute pointing device: " + String(dev->name)); } - if (pressure_resolution <= 0) { - pressure_resolution = (pressure_max - pressure_min); - } - if (tilt_resolution_x <= 0) { - tilt_resolution_x = (tilt_range_max_x - tilt_range_min_x); - } - if (tilt_resolution_y <= 0) { - tilt_resolution_y = (tilt_range_max_y - tilt_range_min_y); - } xi.pressure = 0; xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y); } From 0a3bf2b62729713e40afbb1b9251c8cc8005857a Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sun, 2 Feb 2020 11:07:01 +0800 Subject: [PATCH 22/64] Fixes add group in Group Editor dialog Before this fix, new group can't be created if any existing group starts with the new name. (cherry picked from commit 421ea09195d7d8dcd904eed764d62e956233e7cd) --- editor/groups_editor.cpp | 2 +- scene/gui/tree.cpp | 11 +++++++++++ scene/gui/tree.h | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp index 83259afb359..c76ff9d6790 100644 --- a/editor/groups_editor.cpp +++ b/editor/groups_editor.cpp @@ -197,7 +197,7 @@ void GroupDialog::_add_group(String p_name) { } String name = p_name.strip_edges(); - if (name == "" || groups->search_item_text(name)) { + if (name.empty() || groups->get_item_with_text(name)) { return; } diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 964f376dbd3..da431d2a787 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3630,6 +3630,17 @@ TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_select return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable); } +TreeItem *Tree::get_item_with_text(const String &p_find) const { + for (TreeItem *current = root; current; current = current->get_next_visible()) { + for (int i = 0; i < columns.size(); i++) { + if (current->get_text(i) == p_find) { + return current; + } + } + } + return NULL; +} + void Tree::_do_incr_search(const String &p_add) { uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec diff --git a/scene/gui/tree.h b/scene/gui/tree.h index d87de6e7738..f3c88eb5acd 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -577,7 +577,10 @@ public: Rect2 get_item_rect(TreeItem *p_item, int p_column = -1) const; bool edit_selected(); + // First item that starts with the text, from the current focused item down and wraps around. TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false); + // First item that matches the whole text, from the first item down. + TreeItem *get_item_with_text(const String &p_find) const; Point2 get_scroll() const; void scroll_to_item(TreeItem *p_item); From 8030178e4881b444e584ced3decdb00ef8fc3e6a Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Sun, 2 Feb 2020 14:08:22 -0300 Subject: [PATCH 23/64] Fix built-in script creation loading existing scripts by mistake (cherry picked from commit f7374cef8459ed34707cc3db2a9b077162e821c0) --- editor/script_create_dialog.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index a982724d4cb..c4627e66273 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -84,7 +84,9 @@ void ScriptCreateDialog::_path_hbox_sorted() { int filename_start_pos = initial_bp.find_last("/") + 1; int filename_end_pos = initial_bp.length(); - file_path->select(filename_start_pos, filename_end_pos); + if (!is_built_in) { + file_path->select(filename_start_pos, filename_end_pos); + } // First set cursor to the end of line to scroll LineEdit view // to the right and then set the actual cursor position. @@ -575,6 +577,10 @@ void ScriptCreateDialog::_browse_class_in_tree() { void ScriptCreateDialog::_path_changed(const String &p_path) { + if (is_built_in) { + return; + } + is_path_valid = false; is_new_script_created = true; From 7ccfbd61a47663854852cb05756cff550d0dd4aa Mon Sep 17 00:00:00 2001 From: dankan1890 Date: Mon, 3 Feb 2020 17:59:24 +0100 Subject: [PATCH 24/64] Fixed String::humanize_size crash. Close #35872 (cherry picked from commit ca0ee767cb5f93420b456fa47422ae2b3e266b4f) --- core/ustring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ustring.cpp b/core/ustring.cpp index 8a1fbfd3836..08418463a0a 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3324,7 +3324,7 @@ String String::humanize_size(uint64_t p_size) { int prefix_idx = 0; - while (prefix_idx < prefixes.size() && p_size > (_div * 1024)) { + while (prefix_idx < prefixes.size() - 1 && p_size > (_div * 1024)) { _div *= 1024; prefix_idx++; } From 262aff67dbf6517cecd77a2af9c116d21a2cee6a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 3 Feb 2020 21:35:00 +0100 Subject: [PATCH 25/64] Allow existing hidden files/directories when creating a new project For instance, this lets users initialize a Git repository and still be able to create a project in the directory afterwards. This closes https://github.com/godotengine/godot-proposals/issues/291. (cherry picked from commit 34b747bac0c07cad64b0615664488f68f01c0d62) --- editor/project_manager.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 1d2e57aefad..ee434aaac2b 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -163,7 +163,7 @@ private: } if (valid_path == "") { - set_message(TTR("The path does not exist."), MESSAGE_ERROR); + set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR); memdelete(d); get_ok()->set_disabled(true); return ""; @@ -177,7 +177,7 @@ private: } if (valid_install_path == "") { - set_message(TTR("The path does not exist."), MESSAGE_ERROR, INSTALL_PATH); + set_message(TTR("The path specified doesn't exist."), MESSAGE_ERROR, INSTALL_PATH); memdelete(d); get_ok()->set_disabled(true); return ""; @@ -195,7 +195,7 @@ private: unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io); if (!pkg) { - set_message(TTR("Error opening package file, not in ZIP format."), MESSAGE_ERROR); + set_message(TTR("Error opening package file (it's not in ZIP format)."), MESSAGE_ERROR); memdelete(d); get_ok()->set_disabled(true); unzClose(pkg); @@ -216,7 +216,7 @@ private: } if (ret == UNZ_END_OF_LIST_OF_FILE) { - set_message(TTR("Invalid '.zip' project file, does not contain a 'project.godot' file."), MESSAGE_ERROR); + set_message(TTR("Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."), MESSAGE_ERROR); memdelete(d); get_ok()->set_disabled(true); unzClose(pkg); @@ -230,7 +230,11 @@ private: bool is_empty = true; String n = d->get_next(); while (n != String()) { - if (n != "." && n != "..") { + if (!n.begins_with(".")) { + // Allow `.`, `..` (reserved current/parent folder names) + // and hidden files/folders to be present. + // For instance, this lets users initialize a Git repository + // and still be able to create a project in the directory afterwards. is_empty = false; break; } @@ -247,7 +251,7 @@ private: } } else { - set_message(TTR("Please choose a 'project.godot' or '.zip' file."), MESSAGE_ERROR); + set_message(TTR("Please choose a \"project.godot\" or \".zip\" file."), MESSAGE_ERROR); memdelete(d); install_path_container->hide(); get_ok()->set_disabled(true); @@ -256,7 +260,7 @@ private: } else if (valid_path.ends_with("zip")) { - set_message(TTR("Directory already contains a Godot project."), MESSAGE_ERROR, INSTALL_PATH); + set_message(TTR("This directory already contains a Godot project."), MESSAGE_ERROR, INSTALL_PATH); memdelete(d); get_ok()->set_disabled(true); return ""; @@ -269,7 +273,11 @@ private: bool is_empty = true; String n = d->get_next(); while (n != String()) { - if (n != "." && n != "..") { // i don't know if this is enough to guarantee an empty dir + if (!n.begins_with(".")) { + // Allow `.`, `..` (reserved current/parent folder names) + // and hidden files/folders to be present. + // For instance, this lets users initialize a Git repository + // and still be able to create a project in the directory afterwards. is_empty = false; break; } @@ -332,7 +340,7 @@ private: install_path_container->show(); get_ok()->set_disabled(false); } else { - set_message(TTR("Please choose a 'project.godot' or '.zip' file."), MESSAGE_ERROR); + set_message(TTR("Please choose a \"project.godot\" or \".zip\" file."), MESSAGE_ERROR); get_ok()->set_disabled(true); return; } From 1b5996c95d4b5cee1b47fa9ba51c30b160e208d6 Mon Sep 17 00:00:00 2001 From: muiroc Date: Tue, 4 Feb 2020 17:45:48 +0100 Subject: [PATCH 26/64] pass missing args in AnimationNode script calls (cherry picked from commit ed3a8cc83dccc0385ce92ef52f18d6bcbbd4b4af) --- scene/animation/animation_tree.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 8b2d8861e79..7efe6f998db 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -49,7 +49,7 @@ void AnimationNode::get_parameter_list(List *r_list) const { Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const { if (get_script_instance()) { - return get_script_instance()->call("get_parameter_default_value"); + return get_script_instance()->call("get_parameter_default_value", p_parameter); } return Variant(); } @@ -397,7 +397,7 @@ void AnimationNode::_validate_property(PropertyInfo &property) const { Ref AnimationNode::get_child_by_name(const StringName &p_name) { if (get_script_instance()) { - return get_script_instance()->call("get_child_by_name"); + return get_script_instance()->call("get_child_by_name", p_name); } return Ref(); } From 1414a189162beb571712021786f97e61c6dd2a0a Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Tue, 4 Feb 2020 19:20:01 -0300 Subject: [PATCH 27/64] Make some QOL improvements to move operations in the FileSystem dock (cherry picked from commit 07a23e75fcf3e02d390d7f6e7d6c86975701befe) --- editor/filesystem_dock.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 62effb406d2..5041441ac32 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1413,17 +1413,13 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw if (!can_move) { // Ask to do something. overwrite_dialog->popup_centered_minsize(); - overwrite_dialog->grab_focus(); return; } } // Check groups. for (int i = 0; i < to_move.size(); i++) { - - print_line("is group: " + to_move[i].path + ": " + itos(EditorFileSystem::get_singleton()->is_group_file(to_move[i].path))); if (to_move[i].is_file && EditorFileSystem::get_singleton()->is_group_file(to_move[i].path)) { - print_line("move to: " + p_to_path.plus_file(to_move[i].path.get_file())); EditorFileSystem::get_singleton()->move_group_file(to_move[i].path, p_to_path.plus_file(to_move[i].path.get_file())); } } @@ -1442,7 +1438,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw if (is_moved) { int current_tab = editor->get_current_tab(); - _save_scenes_after_move(file_renames); //save scenes before updating + _save_scenes_after_move(file_renames); // Save scenes before updating. _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); @@ -1948,7 +1944,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da return false; // Attempting to move a folder into itself will fail later, - // rather than bring up a message don't try to do it in the first place + // rather than bring up a message don't try to do it in the first place. to_dir = to_dir.ends_with("/") ? to_dir : (to_dir + "/"); Vector fnames = drag_data["files"]; for (int i = 0; i < fnames.size(); ++i) { @@ -2050,11 +2046,15 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Vector fnames = drag_data["files"]; to_move.clear(); for (int i = 0; i < fnames.size(); i++) { - to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/"))); + if (fnames[i].get_base_dir() != to_dir) { + to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/"))); + } + } + if (!to_move.empty()) { + _move_operation_confirm(to_dir); } - _move_operation_confirm(to_dir); } else if (favorite) { - // Add the files from favorites + // Add the files from favorites. Vector fnames = drag_data["files"]; Vector favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < fnames.size(); i++) { @@ -2103,6 +2103,10 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori // We drop on a folder. target = fpath; return; + } else { + // We drop on the folder that the target file is in. + target = fpath.get_base_dir(); + return; } } else { if (ti->get_parent() != tree->get_root()->get_children()) { From 77deae41fbd8b9949fc58772757898aa62750577 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Thu, 6 Feb 2020 17:50:12 +0300 Subject: [PATCH 28/64] Few enchancements for shader editor (cherry picked from commit 24368206ca37406a375c78067b3575c0c5a6cf3f) --- editor/plugins/shader_editor_plugin.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index c24a666c553..a19f0b4975e 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -369,6 +369,7 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->set_indent_using_spaces(EditorSettings::get_singleton()->get("text_editor/indent/type")); shader_editor->get_text_edit()->set_auto_indent(EditorSettings::get_singleton()->get("text_editor/indent/auto_indent")); shader_editor->get_text_edit()->set_draw_tabs(EditorSettings::get_singleton()->get("text_editor/indent/draw_tabs")); + shader_editor->get_text_edit()->set_draw_spaces(EditorSettings::get_singleton()->get("text_editor/indent/draw_spaces")); shader_editor->get_text_edit()->set_show_line_numbers(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_numbers")); shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting")); shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences")); @@ -381,6 +382,9 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/navigation/v_scroll_speed")); shader_editor->get_text_edit()->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/navigation/show_minimap")); shader_editor->get_text_edit()->set_minimap_width((int)EditorSettings::get_singleton()->get("text_editor/navigation/minimap_width") * EDSCALE); + shader_editor->get_text_edit()->set_show_line_length_guideline(EditorSettings::get_singleton()->get("text_editor/appearance/show_line_length_guideline")); + shader_editor->get_text_edit()->set_line_length_guideline_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_column")); + shader_editor->get_text_edit()->set_breakpoint_gutter_enabled(false); } void ShaderEditor::_bind_methods() { From 388adac94714d7bbae212d4df9a16221d697d6f8 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 6 Feb 2020 16:00:32 +0100 Subject: [PATCH 29/64] Fix UPNP on windows after #30205. The problem could be related to different byte ordering when copying the interface address over the binding address. (cherry picked from commit e85330231c729a88d5a478de2bbe4a61e5edeae3) --- thirdparty/README.md | 1 + thirdparty/miniupnpc/miniupnpc/minissdpc.c | 4 ---- thirdparty/miniupnpc/windows_fix.diff | 16 ++++++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 thirdparty/miniupnpc/windows_fix.diff diff --git a/thirdparty/README.md b/thirdparty/README.md index 9b6f6709729..7c3378dec36 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -281,6 +281,7 @@ Files extracted from upstream source: - All `*.c` and `*.h` files from `miniupnpc` to `thirdparty/miniupnpc/miniupnpc` - Remove `test*`, `minihttptestserver.c` and `wingenminiupnpcstrings.c` +The patch `windows_fix.diff` is applied to `minissdpc.c` to fix an upstream issue. The only modified file is miniupnpcstrings.h, which was created for Godot (it is usually autogenerated by cmake). diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c index 29f8110155e..ea9af02e1fe 100644 --- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c +++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c @@ -683,11 +683,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif } else { struct in_addr mc_if; -#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) - InetPtonA(AF_INET, multicastif, &mc_if); -#else mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ -#endif if(mc_if.s_addr != INADDR_NONE) { ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; diff --git a/thirdparty/miniupnpc/windows_fix.diff b/thirdparty/miniupnpc/windows_fix.diff new file mode 100644 index 00000000000..460b596888e --- /dev/null +++ b/thirdparty/miniupnpc/windows_fix.diff @@ -0,0 +1,16 @@ +diff --git a/thirdparty/miniupnpc/miniupnpc/minissdpc.c b/thirdparty/miniupnpc/miniupnpc/minissdpc.c +index 29f8110155..ea9af02e1f 100644 +--- a/thirdparty/miniupnpc/miniupnpc/minissdpc.c ++++ b/thirdparty/miniupnpc/miniupnpc/minissdpc.c +@@ -683,11 +683,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], + #endif + } else { + struct in_addr mc_if; +-#if defined(_WIN32) && (_WIN32_WINNT >= _WIN32_WINNT_VISTA) +- InetPtonA(AF_INET, multicastif, &mc_if); +-#else + mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ +-#endif + if(mc_if.s_addr != INADDR_NONE) + { + ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; From 3b2490f19c42332bbc3dd9d30ffd1161bf3a56b7 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Fri, 7 Feb 2020 14:50:11 +0300 Subject: [PATCH 30/64] Prevent shader crash if invalid builtin used after array member accessor (cherry picked from commit 3a70566b15c094241f0df1731f8ad1b3e0d5dc0e) --- servers/visual/shader_language.cpp | 34 ++++++++++++++++++++++++------ servers/visual/shader_language.h | 12 ++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 14d2f6d0862..c144523a36f 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -2986,14 +2986,32 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons bool is_const = false; int array_size = 0; - if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size)) { - _set_error("Unknown identifier in expression: " + String(identifier)); - return NULL; - } + if (p_block && p_block->block_tag != SubClassTag::TAG_GLOBAL) { + int idx = 0; + bool found = false; - if (ident_type == IDENTIFIER_FUNCTION) { - _set_error("Can't use function as identifier: " + String(identifier)); - return NULL; + while (builtin_func_defs[idx].name) { + if (builtin_func_defs[idx].tag == p_block->block_tag && builtin_func_defs[idx].name == identifier) { + found = true; + break; + } + idx++; + } + if (!found) { + _set_error("Unknown identifier in expression: " + String(identifier)); + return NULL; + } + } else { + + if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size)) { + _set_error("Unknown identifier in expression: " + String(identifier)); + return NULL; + } + + if (ident_type == IDENTIFIER_FUNCTION) { + _set_error("Can't use function as identifier: " + String(identifier)); + return NULL; + } } Node *index_expression = NULL; @@ -3009,7 +3027,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_PERIOD) { completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; call_expression = _parse_and_reduce_expression(p_block, p_builtin_types); + p_block->block_tag = SubClassTag::TAG_GLOBAL; if (!call_expression) return NULL; data_type = call_expression->get_datatype(); diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index e5c3c6852c9..f7b02ab70b2 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -279,6 +279,11 @@ public: ARGUMENT_QUALIFIER_INOUT, }; + enum SubClassTag { + TAG_GLOBAL, + TAG_ARRAY, + }; + struct Node { Node *next; @@ -431,6 +436,7 @@ public: }; int block_type; + SubClassTag block_tag; struct Variable { DataType type; @@ -449,6 +455,7 @@ public: parent_function(NULL), parent_block(NULL), block_type(BLOCK_TYPE_STANDART), + block_tag(SubClassTag::TAG_GLOBAL), single_statement(false) {} }; @@ -713,11 +720,6 @@ private: bool _validate_assign(Node *p_node, const Map &p_builtin_types, String *r_message = NULL); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); - enum SubClassTag { - TAG_GLOBAL, - TAG_ARRAY, - }; - struct BuiltinFuncDef { enum { MAX_ARGS = 5 }; const char *name; From ac63e5d6136c40412bebf97487f69aba32c69305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 7 Feb 2020 21:01:03 +0100 Subject: [PATCH 31/64] Workaround WebM playback bug after AudioServer latency fixes af9bb0ea15dfd3dfe8950fcfcce364485dadd92a fixed AudioServer's `get_output_delay()` (which used to always return 0) while renaming it to `get_output_latency()`. It now returns the latency from the AudioDriver, which can be non-0. While this was a clear bugfix, it broke playback for WebM files without audio track. It seems like the playback code, even though it queried the output delay to calculate a time compensation, was designed to work even though the delay value was actually bogus. Now that it's correct, it's not working. As a workaround we comment out uses of the output latency, restoring the behavior of Godot 3.1. This code should still be reviewed by someone more versed in video playback and fixed to properly account for the non-0 driver latency. Fixes #35760. (cherry picked from commit da411d1625a92e4c100bcda2c29709014e261ec9) --- modules/theora/video_stream_theora.cpp | 6 ++++-- modules/webm/video_stream_webm.cpp | 15 ++++++++++----- servers/audio_server.cpp | 8 ++------ servers/audio_server.h | 3 --- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index cf1fc3f175a..00c7e875688 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -363,8 +363,10 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { }; float VideoStreamPlaybackTheora::get_time() const { - - return time - AudioServer::get_singleton()->get_output_latency() - delay_compensation; //-((get_total())/(float)vi.rate); + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + return time - /* AudioServer::get_singleton()->get_output_latency() - */ delay_compensation; }; Ref VideoStreamPlaybackTheora::get_texture() const { diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 41f9e676724..2763d30bb5a 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -393,17 +393,22 @@ int VideoStreamPlaybackWebm::get_mix_rate() const { inline bool VideoStreamPlaybackWebm::has_enough_video_frames() const { if (video_frames_pos > 0) { - - const double audio_delay = AudioServer::get_singleton()->get_output_latency(); + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); const double video_time = video_frames[video_frames_pos - 1]->time; - return video_time >= time + audio_delay + delay_compensation; + return video_time >= time + /* audio_delay + */ delay_compensation; } return false; } bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) { - const double audio_delay = AudioServer::get_singleton()->get_output_latency(); - return video_frame.time >= time + audio_delay + delay_compensation; + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); + return video_frame.time >= time + /* audio_delay + */ delay_compensation; } void VideoStreamPlaybackWebm::delete_pointers() { diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 6ce07fb7b82..232a2f72d6f 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "audio_server.h" + #include "core/io/resource_loader.h" #include "core/os/file_access.h" #include "core/os/os.h" @@ -36,14 +37,11 @@ #include "scene/resources/audio_stream_sample.h" #include "servers/audio/audio_driver_dummy.h" #include "servers/audio/effects/audio_effect_compressor.h" + #ifdef TOOLS_ENABLED - #define MARK_EDITED set_edited(true); - #else - #define MARK_EDITED - #endif AudioDriver *AudioDriver::singleton = NULL; @@ -1405,8 +1403,6 @@ AudioServer::AudioServer() { mix_frames = 0; channel_count = 0; to_mix = 0; - output_latency = 0; - output_latency_ticks = 0; #ifdef DEBUG_ENABLED prof_time = 0; #endif diff --git a/servers/audio_server.h b/servers/audio_server.h index 815200c811f..eff66d4008f 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -240,9 +240,6 @@ private: Mutex *audio_data_lock; - float output_latency; - uint64_t output_latency_ticks; - void init_channels_and_buffers(); void _mix_step(); From be34e452331de54f7ce8ecf92aee195665505001 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sat, 8 Feb 2020 09:23:38 +0800 Subject: [PATCH 32/64] Uses split cursor for SplitContainer (cherry picked from commit 206b9f2d23ba1380de4c5b1c175b7ee5eadfd298) --- scene/gui/split_container.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index bb5260b15e3..079907db07f 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -266,7 +266,7 @@ void SplitContainer::_gui_input(const Ref &p_event) { Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const { if (dragging) - return (vertical ? CURSOR_VSIZE : CURSOR_HSIZE); + return (vertical ? CURSOR_VSPLIT : CURSOR_HSPLIT); if (!collapsed && _getch(0) && _getch(1) && dragger_visibility == DRAGGER_VISIBLE) { @@ -275,11 +275,11 @@ Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const if (vertical) { if (p_pos.y > middle_sep && p_pos.y < middle_sep + sep) - return CURSOR_VSIZE; + return CURSOR_VSPLIT; } else { if (p_pos.x > middle_sep && p_pos.x < middle_sep + sep) - return CURSOR_HSIZE; + return CURSOR_HSPLIT; } } From 0fb35401d4de13926172e18de8dd1014e66b583d Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Sat, 8 Feb 2020 12:07:41 +0100 Subject: [PATCH 33/64] Avoid going out of bounds in IsSubsequenceOf Closes #35598 (cherry picked from commit 4b79ef5ebe2faa4b3690d90dc36ab6ead5ff1315) --- .../mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index ffef50cc185..b85a00d869c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -475,7 +475,7 @@ namespace Godot int source = 0; int target = 0; - while (instance[source] != 0 && text[target] != 0) + while (source < len && target < text.Length) { bool match; @@ -492,7 +492,7 @@ namespace Godot if (match) { source++; - if (instance[source] == 0) + if (source >= len) return true; } From 93b99f2c890d0e8361d4f39ee02a00b18a4117f4 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 8 Feb 2020 18:29:28 +0100 Subject: [PATCH 34/64] Update the zoom percentage when using Frame Selection in the 2D editor This closes #36019. (cherry picked from commit 3e95b79b65ac88ad4df59dc4ba5eb05f9c8b68af) --- editor/plugins/canvas_item_editor_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 1d8f3a2bbd7..a0e5b1c6ea3 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4967,6 +4967,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { zoom = scale_x < scale_y ? scale_x : scale_y; zoom *= 0.90; viewport->update(); + _update_zoom_label(); call_deferred("_popup_callback", VIEW_CENTER_TO_SELECTION); } } From 63809438311fbdc32925fc12f324ec590905f772 Mon Sep 17 00:00:00 2001 From: zxcvdev Date: Sat, 8 Feb 2020 21:32:01 +0100 Subject: [PATCH 35/64] Fix GPU Particles The special case atan(y,0) of the built-in shader function atan(y,x) returns different results on different devices. So this commit will add checks when the atan(y,x) function is used in ParticlesMaterial to set the direction of GPU Particles to make sure the desired values are returned (act as atan2(y,x)). (cherry picked from commit 3580ad6005500abaf9bbb12db73adcfa762bd2e5) --- scene/resources/particles_material.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 412b5c259c2..baeb88400e9 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -316,14 +316,17 @@ void ParticlesMaterial::_update_shader() { if (flags[FLAG_DISABLE_Z]) { - code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n"; + code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n"; code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; From c018d02cdac5d571105fa8bedfcc41b692611ec5 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Sun, 9 Feb 2020 14:21:10 +0800 Subject: [PATCH 36/64] Fixes broken scene created via New Resource (cherry picked from commit 9cff286de1d56577dc8f6979d2b0d41c397ca7c7) --- editor/filesystem_dock.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 5041441ac32..684942dbade 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1782,6 +1782,14 @@ void FileSystemDock::_resource_created() const { Resource *r = Object::cast_to(c); ERR_FAIL_COND(!r); + PackedScene *scene = Object::cast_to(r); + if (scene) { + Node *node = memnew(Node); + node->set_name("Node"); + scene->pack(node); + memdelete(node); + } + REF res(r); editor->push_item(c); From e834e35ea819b60dd3e41ec6e2192eb3e037d2c7 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 9 Feb 2020 17:43:56 +0100 Subject: [PATCH 37/64] Change the Pick Tile and Select default shortcuts in the TileMap editor The new default keys were chosen to match common graphics editing software. A modifier is no longer required to use the Select tool, making it faster to use. This closes #34170. (cherry picked from commit 88213b54bae4accd83028d1a33294c75bc540478) --- editor/plugins/tile_map_editor_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index f889228f873..0c3e29028c2 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -2026,13 +2026,13 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { toolbar->add_child(bucket_fill_button); picker_button = memnew(ToolButton); - picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_CONTROL)); + picker_button->set_shortcut(ED_SHORTCUT("tile_map_editor/pick_tile", TTR("Pick Tile"), KEY_I)); picker_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_PICKING)); picker_button->set_toggle_mode(true); toolbar->add_child(picker_button); select_button = memnew(ToolButton); - select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_MASK_CMD + KEY_B)); + select_button->set_shortcut(ED_SHORTCUT("tile_map_editor/select", TTR("Select"), KEY_M)); select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SELECTING)); select_button->set_toggle_mode(true); toolbar->add_child(select_button); From 59b8f9b2da4c260761ae810dc01b0fbae4241096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 10 Feb 2020 09:19:10 +0100 Subject: [PATCH 38/64] Make file system scan more robust Previously, a change was missed if it happened while the scan was in progress and already past the affected location. Also: - Consider the scan changes thread on termination, in addition to the full scan one - Add FS-reported hidden to the check for hidden by the editor file system (cherry picked from commit 3017bdb7ce2ffcbeb83583c03cfe83353aab165f) --- editor/editor_file_system.cpp | 32 +++++++++++++++++++++++++------- editor/editor_file_system.h | 1 + 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 5abb3c4ec26..3237ae40104 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -675,9 +675,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess if (f == "") break; + if (da->current_is_hidden()) + continue; + if (da->current_is_dir()) { - if (f.begins_with(".")) //ignore hidden and . / .. + if (f.begins_with(".")) // Ignore special and . / .. continue; if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this @@ -871,9 +874,12 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const if (f == "") break; + if (da->current_is_hidden()) + continue; + if (da->current_is_dir()) { - if (f.begins_with(".")) //ignore hidden and . / .. + if (f.begins_with(".")) // Ignore special and . / .. continue; int idx = p_dir->find_dir_index(f); @@ -1059,8 +1065,12 @@ void EditorFileSystem::get_changed_sources(List *r_changed) { void EditorFileSystem::scan_changes() { - if (scanning || scanning_changes || thread) + if (first_scan || // Prevent a premature changes scan from inhibiting the first full scan + scanning || scanning_changes || thread) { + scan_changes_pending = true; + set_process(true); return; + } _update_extensions(); sources_changed.clear(); @@ -1105,16 +1115,18 @@ void EditorFileSystem::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - if (use_threads && thread) { + Thread *active_thread = thread ? thread : thread_sources; + if (use_threads && active_thread) { //abort thread if in progress abort_scan = true; while (scanning) { OS::get_singleton()->delay_usec(1000); } - Thread::wait_to_finish(thread); - memdelete(thread); + Thread::wait_to_finish(active_thread); + memdelete(active_thread); thread = NULL; - WARN_PRINTS("Scan thread aborted..."); + thread_sources = NULL; + WARN_PRINT("Scan thread aborted..."); set_process(false); } @@ -1164,6 +1176,11 @@ void EditorFileSystem::_notification(int p_what) { _queue_update_script_classes(); first_scan = false; } + + if (!is_processing() && scan_changes_pending) { + scan_changes_pending = false; + scan_changes(); + } } } break; } @@ -2138,6 +2155,7 @@ EditorFileSystem::EditorFileSystem() { scan_total = 0; update_script_classes_queued = false; first_scan = true; + scan_changes_pending = false; revalidate_import_files = false; } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index ce9936f9834..381acc0fe21 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -145,6 +145,7 @@ class EditorFileSystem : public Node { bool scanning; bool importing; bool first_scan; + bool scan_changes_pending; float scan_total; String filesystem_settings_version_for_import; bool revalidate_import_files; From a8ae52e99898aef1ead0343576e5505e591ca6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 10 Feb 2020 09:19:02 +0100 Subject: [PATCH 39/64] Ignore hidden files and directories in find in files (cherry picked from commit aeff87686859f5b6d9fde42c2e3cb12fcc2f4adc) --- editor/find_in_files.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp index 4ab90ad3e4f..b24a5c38f21 100644 --- a/editor/find_in_files.cpp +++ b/editor/find_in_files.cpp @@ -235,9 +235,11 @@ void FindInFiles::_scan_dir(String path, PoolStringArray &out_folders) { if (file == "") break; - // Ignore special dirs and hidden dirs (such as .git and .import) + // Ignore special dirs (such as .git and .import) if (file == "." || file == ".." || file.begins_with(".")) continue; + if (dir->current_is_hidden()) + continue; if (dir->current_is_dir()) out_folders.append(file); From edb70682d5dab139adb06afe7975f0f1199045e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 10 Feb 2020 09:18:58 +0100 Subject: [PATCH 40/64] Fix VariantParser::StreamString EOF determination (cherry picked from commit 521da75380be712157fa172e27dda4dabba1de51) --- core/variant_parser.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 6ca9d6c2469..4ce33b0123b 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -51,10 +51,16 @@ bool VariantParser::StreamFile::is_eof() const { CharType VariantParser::StreamString::get_char() { - if (pos >= s.length()) + if (pos > s.length()) { return 0; - else + } else if (pos == s.length()) { + // You need to try to read again when you have reached the end for EOF to be reported, + // so this works the same as files (like StreamFile does) + pos++; + return 0; + } else { return s[pos++]; + } } bool VariantParser::StreamString::is_utf8() const { From 541251dff73a0cff7cf0bcbb9a1129ebed41885b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Mon, 10 Feb 2020 09:19:00 +0100 Subject: [PATCH 41/64] Add ConfigFile::parse() (cherry picked from commit e5bd3b707f07d1f3eb4d4a8a18ee1736ff1fbe76) --- core/io/config_file.cpp | 25 +++++++++++++++++++++---- core/io/config_file.h | 4 ++++ doc/classes/ConfigFile.xml | 10 ++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 5c25cad7702..74e85d0cc0a 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -255,6 +255,22 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) { VariantParser::StreamFile stream; stream.f = f; + Error err = _parse(p_path, &stream); + + memdelete(f); + + return err; +} + +Error ConfigFile::parse(const String &p_data) { + + VariantParser::StreamString stream; + stream.s = p_data; + return _parse("", &stream); +} + +Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) { + String assign; Variant value; VariantParser::Tag next_tag; @@ -270,13 +286,11 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) { next_tag.fields.clear(); next_tag.name = String(); - Error err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); + Error err = VariantParser::parse_tag_assign_eof(p_stream, lines, error_text, next_tag, assign, value, NULL, true); if (err == ERR_FILE_EOF) { - memdelete(f); return OK; } else if (err != OK) { - ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text + "."); - memdelete(f); + ERR_PRINT("ConfgFile - " + p_path + ":" + itos(lines) + " error: " + error_text + "."); return err; } @@ -286,6 +300,8 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) { section = next_tag.name; } } + + return OK; } void ConfigFile::_bind_methods() { @@ -303,6 +319,7 @@ void ConfigFile::_bind_methods() { ClassDB::bind_method(D_METHOD("erase_section_key", "section", "key"), &ConfigFile::erase_section_key); ClassDB::bind_method(D_METHOD("load", "path"), &ConfigFile::load); + ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse); ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save); ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted); diff --git a/core/io/config_file.h b/core/io/config_file.h index 95a581d1566..2d61ef6afe9 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -34,6 +34,7 @@ #include "core/ordered_hash_map.h" #include "core/os/file_access.h" #include "core/reference.h" +#include "core/variant_parser.h" class ConfigFile : public Reference { @@ -46,6 +47,8 @@ class ConfigFile : public Reference { Error _internal_load(const String &p_path, FileAccess *f); Error _internal_save(FileAccess *file); + Error _parse(const String &p_path, VariantParser::Stream *p_stream); + protected: static void _bind_methods(); @@ -64,6 +67,7 @@ public: Error save(const String &p_path); Error load(const String &p_path); + Error parse(const String &p_data); Error load_encrypted(const String &p_path, const Vector &p_key); Error load_encrypted_pass(const String &p_path, const String &p_pass); diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml index e3f96e0987c..0805b81e25a 100644 --- a/doc/classes/ConfigFile.xml +++ b/doc/classes/ConfigFile.xml @@ -129,6 +129,16 @@ + + + + + + + Parses the the passed string as the contents of a config file. The string is parsed and loaded in the ConfigFile object which the method was called on. + Returns one of the [enum Error] code constants ([code]OK[/code] on success). + + From 636093784bb6a264266221387b79c606064ec509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 10 Feb 2020 09:15:27 +0100 Subject: [PATCH 42/64] Travis: Use Python 3 for SCons (cherry picked from commit 83ec7cc42568a730e003b61092e3fd71152a22c4) --- .travis.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c8b123c79c1..d39d6383ea6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,12 +72,20 @@ matrix: env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang EXTRA_ARGS="warnings=extra werror=yes" os: osx compiler: clang + addons: + homebrew: + packages: + - scons - name: iOS export template (debug, Clang) stage: build env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang os: osx compiler: clang + addons: + homebrew: + packages: + - scons - name: Linux headless editor (release_debug, GCC 9, testing project exporting and script running) stage: build @@ -109,16 +117,17 @@ before_install: fi install: - - pip install --user scons; + - if [ "$TRAVIS_OS_NAME" = "linux" ]; then + pyenv global 3.7.1 system; + pip3 install --user scons; + fi + - scons --version - if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$PLATFORM" = "android" ]; then export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64; export PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/bin:${PATH}; java -version; misc/travis/android-tools-linux.sh; fi - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - export PATH=${PATH}:/Users/travis/Library/Python/2.7/bin; - fi before_script: - if [ "$PLATFORM" = "android" ]; then From 50727d7b22b131d0086135e6a1dac592582eeb34 Mon Sep 17 00:00:00 2001 From: muiroc Date: Fri, 7 Feb 2020 01:18:11 +0100 Subject: [PATCH 43/64] Allow per pixel transparency in javascript platform (cherry picked from commit e51c6a0d286a9a6a4a9989738b544bbbb9b41eeb) --- doc/classes/OS.xml | 2 +- platform/javascript/os_javascript.cpp | 21 ++++++++++++++++++++- platform/javascript/os_javascript.h | 4 ++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index ebd0529be96..c74926bd1be 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -960,7 +960,7 @@ If [code]true[/code], the window background is transparent and window frame is removed. Use [code]get_tree().get_root().set_transparent_background(true)[/code] to disable main viewport background rendering. [b]Note:[/b] This property has no effect if [b]Project > Project Settings > Display > Window > Per-pixel transparency > Allowed[/b] setting is disabled. - [b]Note:[/b] This property is implemented on Linux, macOS and Windows. + [b]Note:[/b] This property is implemented on HTML5, Linux, macOS and Windows. The window position relative to the screen, the origin is the top left corner, +Y axis goes to the bottom and +X axis goes to the right. diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 632a7df9e89..d904cc3c961 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -220,6 +220,20 @@ void OS_JavaScript::get_fullscreen_mode_list(List *p_list, int p_scre p_list->push_back(OS::VideoMode(screen.width, screen.height, true)); } +bool OS_JavaScript::get_window_per_pixel_transparency_enabled() const { + if (!is_layered_allowed()) { + return false; + } + return transparency_enabled; +} + +void OS_JavaScript::set_window_per_pixel_transparency_enabled(bool p_enabled) { + if (!is_layered_allowed()) { + return; + } + transparency_enabled = p_enabled; +} + // Keys template @@ -886,10 +900,14 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, EmscriptenWebGLContextAttributes attributes; emscripten_webgl_init_context_attributes(&attributes); - attributes.alpha = false; + attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed"); attributes.antialias = false; ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER); + if (p_desired.layered) { + set_window_per_pixel_transparency_enabled(true); + } + bool gles3 = true; if (p_video_driver == VIDEO_DRIVER_GLES2) { gles3 = false; @@ -1315,6 +1333,7 @@ OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) { window_maximized = false; entering_fullscreen = false; just_exited_fullscreen = false; + transparency_enabled = false; main_loop = NULL; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 5c02a292ee6..65a18830edb 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -46,6 +46,7 @@ class OS_JavaScript : public OS_Unix { bool window_maximized; bool entering_fullscreen; bool just_exited_fullscreen; + bool transparency_enabled; InputDefault *input; Ref deferred_key_event; @@ -123,6 +124,9 @@ public: virtual void set_mouse_mode(MouseMode p_mode); virtual MouseMode get_mouse_mode() const; + virtual bool get_window_per_pixel_transparency_enabled() const; + virtual void set_window_per_pixel_transparency_enabled(bool p_enabled); + virtual bool has_touchscreen_ui_hint() const; virtual bool is_joy_known(int p_device); From f0c89048d888f9873286c3b07bb1827a11a0e327 Mon Sep 17 00:00:00 2001 From: Tomasz Chabora Date: Mon, 10 Feb 2020 21:39:05 +0100 Subject: [PATCH 44/64] Allow to use arrow keys with TOOL_MOVE (cherry picked from commit 18918b4efa7c8ea618cf48a2fce7d41165ce3549) --- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index a0e5b1c6ea3..879de58bbce 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2077,7 +2077,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref &p_event) { } // Move the canvas items with the arrow keys - if (k.is_valid() && k->is_pressed() && tool == TOOL_SELECT && + if (k.is_valid() && k->is_pressed() && (tool == TOOL_SELECT || tool == TOOL_MOVE) && (k->get_scancode() == KEY_UP || k->get_scancode() == KEY_DOWN || k->get_scancode() == KEY_LEFT || k->get_scancode() == KEY_RIGHT)) { if (!k->is_echo()) { // Start moving the canvas items with the keyboard From c81241e6c012fb9c3382a67fec13a70bbfc247ef Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Tue, 11 Feb 2020 11:39:20 +0800 Subject: [PATCH 45/64] Fixes crash when resource file is corrupted (cherry picked from commit 832a5c860bc5287efc0ebf19c4b2af5c5b984972) --- core/io/file_access_compressed.cpp | 8 +++--- core/io/resource_format_binary.cpp | 41 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 87ead37b91d..17cc6ce58f6 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -63,6 +63,10 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) { f = p_base; cmode = (Compression::Mode)f->get_32(); block_size = f->get_32(); + if (block_size == 0) { + f = NULL; // Let the caller to handle the FileAccess object if failed to open as compressed file. + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted."); + } read_total = f->get_32(); int bc = (read_total / block_size) + 1; int acc_ofs = f->get_position() + bc * 4; @@ -125,13 +129,11 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) { char rmagic[5]; f->get_buffer((uint8_t *)rmagic, 4); rmagic[4] = 0; - if (magic != rmagic) { + if (magic != rmagic || open_after_magic(f) != OK) { memdelete(f); f = NULL; return ERR_FILE_UNRECOGNIZED; } - - open_after_magic(f); } return OK; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 272d5c1116a..d3cd61b0703 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -836,15 +836,20 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { uint8_t header[4]; f->get_buffer(header, 4); if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') { - //compressed + // Compressed. FileAccessCompressed *fac = memnew(FileAccessCompressed); - fac->open_after_magic(f); + error = fac->open_after_magic(f); + if (error != OK) { + memdelete(fac); + f->close(); + ERR_FAIL_MSG("Failed to open binary resource file: " + local_path + "."); + } f = fac; } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { - //not normal - + // Not normal. error = ERR_FILE_UNRECOGNIZED; + f->close(); ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + "."); } @@ -919,6 +924,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { if (f->eof_reached()) { error = ERR_FILE_CORRUPT; + f->close(); ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + "."); } } @@ -931,14 +937,20 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) { uint8_t header[4]; f->get_buffer(header, 4); if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') { - //compressed + // Compressed. FileAccessCompressed *fac = memnew(FileAccessCompressed); - fac->open_after_magic(f); + error = fac->open_after_magic(f); + if (error != OK) { + memdelete(fac); + f->close(); + return ""; + } f = fac; } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { - //not normal + // Not normal. error = ERR_FILE_UNRECOGNIZED; + f->close(); return ""; } @@ -1055,14 +1067,19 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons uint8_t header[4]; f->get_buffer(header, 4); if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') { - //compressed + // Compressed. FileAccessCompressed *fac = memnew(FileAccessCompressed); - fac->open_after_magic(f); + Error err = fac->open_after_magic(f); + if (err != OK) { + memdelete(fac); + memdelete(f); + ERR_FAIL_V_MSG(err, "Cannot open file '" + p_path + "'."); + } f = fac; FileAccessCompressed *facw = memnew(FileAccessCompressed); facw->configure("RSCC"); - Error err = facw->_open(p_path + ".depren", FileAccess::WRITE); + err = facw->_open(p_path + ".depren", FileAccess::WRITE); if (err) { memdelete(fac); memdelete(facw); @@ -1072,9 +1089,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons fw = facw; } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { - //not normal - - //error=ERR_FILE_UNRECOGNIZED; + // Not normal. memdelete(f); ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file '" + local_path + "'."); } else { From ba15e5355b03c0c03b68777595364c785f8cdada Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Tue, 11 Feb 2020 18:31:25 -0300 Subject: [PATCH 46/64] Fix problems with concave shapes in the TileSet editor (cherry picked from commit eeb972faefc988833693faea77d81cc8d2d2d2b4) --- editor/plugins/tile_set_editor_plugin.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index b24d5add9fb..d6adc6288b4 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1794,13 +1794,13 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { Array sd = tileset->call("tile_get_shapes", get_current_tile()); if (convex.is_valid()) { - // Make concave + // Make concave. undo_redo->create_action(TTR("Make Polygon Concave")); Ref _concave = memnew(ConcavePolygonShape2D); edited_collision_shape = _concave; _set_edited_shape_points(_get_collision_shape_points(convex)); } else if (concave.is_valid()) { - // Make convex + // Make convex. undo_redo->create_action(TTR("Make Polygon Convex")); Ref _convex = memnew(ConvexPolygonShape2D); edited_collision_shape = _convex; @@ -1810,14 +1810,20 @@ void TileSetEditor::_on_tool_clicked(int p_tool) { if (sd[i].get("shape") == previous_shape) { undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate()); sd.remove(i); - sd.insert(i, edited_collision_shape); - undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd); - undo_redo->add_do_method(this, "_select_edited_shape_coord"); - undo_redo->add_undo_method(this, "_select_edited_shape_coord"); - undo_redo->commit_action(); break; } } + + undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd); + if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) { + undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), edited_collision_shape, Transform2D(), false, edited_shape_coord); + } else { + undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), edited_collision_shape, Transform2D()); + } + undo_redo->add_do_method(this, "_select_edited_shape_coord"); + undo_redo->add_undo_method(this, "_select_edited_shape_coord"); + undo_redo->commit_action(); + _update_toggle_shape_button(); workspace->update(); workspace_container->update(); @@ -1984,11 +1990,8 @@ void TileSetEditor::_set_edited_shape_points(const Vector &points) { } segments.push_back(points[points.size() - 1]); segments.push_back(points[0]); - concave->set_segments(segments); undo_redo->add_do_method(concave.ptr(), "set_segments", segments); undo_redo->add_undo_method(concave.ptr(), "set_segments", concave->get_segments()); - } else { - // Invalid shape } } From 57151c5e314faa0c23409086d1905fbb81e2422b Mon Sep 17 00:00:00 2001 From: geequlim Date: Wed, 12 Feb 2020 17:58:19 +0800 Subject: [PATCH 47/64] Fix hover symbol content position (cherry picked from commit 03d2d01082f2853ff4873a0b66e01d5a66178a42) --- modules/gdscript/language_server/gdscript_text_document.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 0572c5f7469..d5723fd20f7 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -321,6 +321,8 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) { lsp::Hover hover; hover.contents = symbol->render(); + hover.range.start = params.position; + hover.range.end = params.position; return hover.to_json(); } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { From 57de8397b2f3d8d96bf89243ae270ead2d2a2542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 12 Feb 2020 20:06:30 +0100 Subject: [PATCH 48/64] Fix Mono check for unsafe object references (cherry picked from commit 09534e29222fd5e4f1bf7ce7cc910fd589e35d00) --- modules/mono/csharp_script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 9e19e5f8c46..baa01d2e3ab 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -161,11 +161,11 @@ void CSharpLanguage::finish() { #ifdef DEBUG_ENABLED for (Map::Element *E = unsafe_object_references.front(); E; E = E->next()) { - const ObjectID &id = E->get(); + const ObjectID &id = E->key(); Object *obj = ObjectDB::get_instance(id); if (obj) { - ERR_PRINTS("Leaked unsafe reference to object: " + obj->get_class() + ":" + itos(id)); + ERR_PRINTS("Leaked unsafe reference to object: " + obj->to_string()); } else { ERR_PRINTS("Leaked unsafe reference to deleted object: " + itos(id)); } From 34a16ae239140a146ea7a090a6bfbd36bb196ed7 Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 6 Feb 2020 13:01:30 +0100 Subject: [PATCH 49/64] Fix startGame's logic in engine.js. (cherry picked from commit cb29ce8a3ba00a72b67e0520d3e3cac03d41343d) --- platform/javascript/engine.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index 1f78aa672de..227accadb0e 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -134,12 +134,10 @@ this.startGame = function(execName, mainPack) { executableName = execName; - var mainArgs = [ '--main-pack', mainPack ]; + var mainArgs = [ '--main-pack', getPathLeaf(mainPack) ]; return Promise.all([ - // Load from directory, - this.init(getBasePath(mainPack)), - // ...but write to root where the engine expects it. + this.init(getBasePath(execName)), this.preloadFile(mainPack, getPathLeaf(mainPack)) ]).then( Function.prototype.apply.bind(synchronousStart, this, mainArgs) From b90a5d4c805bc62e6aaf1a6b889c113f3de54695 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 13 Feb 2020 23:34:15 +0100 Subject: [PATCH 50/64] Tweak the editor help comment color for better readability (cherry picked from commit 99bfaa6c6096c6ad25d13a3ecb447bb451f88892) --- editor/editor_help.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 556dbcbfc4c..558be5f2fb6 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -50,7 +50,7 @@ void EditorHelp::_init_colors() { text_color = get_color("default_color", "RichTextLabel"); headline_color = get_color("headline_color", "EditorHelp"); base_type_color = title_color.linear_interpolate(text_color, 0.5); - comment_color = text_color * Color(1, 1, 1, 0.4); + comment_color = text_color * Color(1, 1, 1, 0.6); symbol_color = comment_color; value_color = text_color * Color(1, 1, 1, 0.6); qualifier_color = text_color * Color(1, 1, 1, 0.8); From 61901bd7cc6fb7f0c9ba179fb0d5750a92ff9b1c Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Thu, 30 Jan 2020 20:20:33 +0300 Subject: [PATCH 51/64] Fix GlobalConstant/BasicTypeConstant return type in visual scripts (cherry picked from commit c19933eec4a3c2d21a07be823c95f87a2141ca60) --- modules/visual_script/visual_script_nodes.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 86c10801829..36cafeec731 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1842,7 +1842,7 @@ PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) co PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const { String name = GlobalConstants::get_global_constant_name(index); - return PropertyInfo(Variant::REAL, name); + return PropertyInfo(Variant::INT, name); } String VisualScriptGlobalConstant::get_caption() const { @@ -2060,7 +2060,7 @@ PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::INT, "value"); + return PropertyInfo(type, "value"); } String VisualScriptBasicTypeConstant::get_caption() const { @@ -2069,8 +2069,11 @@ String VisualScriptBasicTypeConstant::get_caption() const { } String VisualScriptBasicTypeConstant::get_text() const { - - return Variant::get_type_name(type) + "." + String(name); + if (name == "") { + return Variant::get_type_name(type); + } else { + return Variant::get_type_name(type) + "." + String(name); + } } void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) { @@ -2087,6 +2090,23 @@ StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const { void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { type = p_which; + + List constants; + Variant::get_constants_for_type(type, &constants); + if (constants.size() > 0) { + bool found_name = false; + for (List::Element *E = constants.front(); E; E = E->next()) { + if (E->get() == name) { + found_name = true; + break; + } + } + if (!found_name) { + name = constants[0]; + } + } else { + name = ""; + } _change_notify(); ports_changed_notify(); } From 74f3fbf7efe817dc5cf1b3db1a4f58724f10a46f Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Mon, 10 Feb 2020 10:49:11 +0300 Subject: [PATCH 52/64] Fix VisualScriptClassConstant to be updated properly (cherry picked from commit 386d0fe9887e7cb272aeb05bfe6930bec4114140) --- modules/visual_script/visual_script_nodes.cpp | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 36cafeec731..dc49ed72d0e 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1935,8 +1935,11 @@ PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) con } PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const { - - return PropertyInfo(Variant::INT, String(base_type) + "." + String(name)); + if (name == "") { + return PropertyInfo(Variant::INT, String(base_type)); + } else { + return PropertyInfo(Variant::INT, String(base_type) + "." + String(name)); + } } String VisualScriptClassConstant::get_caption() const { @@ -1958,6 +1961,22 @@ StringName VisualScriptClassConstant::get_class_constant() { void VisualScriptClassConstant::set_base_type(const StringName &p_which) { base_type = p_which; + List constants; + ClassDB::get_integer_constant_list(base_type, &constants, true); + if (constants.size() > 0) { + bool found_name = false; + for (List::Element *E = constants.front(); E; E = E->next()) { + if (E->get() == name) { + found_name = true; + break; + } + } + if (!found_name) { + name = constants[0]; + } + } else { + name = ""; + } _change_notify(); ports_changed_notify(); } From fb56d93163d5843704aaba3c58b85bc7332c8a9b Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Mon, 27 Jan 2020 12:10:51 +0300 Subject: [PATCH 53/64] Better visual shader code generation (cherry picked from commit bfec48abf18f0af0d55d6c63c8b8201bd1c1076c) --- scene/resources/visual_shader.cpp | 111 +++++---- scene/resources/visual_shader.h | 3 + scene/resources/visual_shader_nodes.cpp | 295 +++++++++++++++--------- 3 files changed, 249 insertions(+), 160 deletions(-) diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 08d95420414..4161f743a56 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -33,6 +33,10 @@ #include "core/vmap.h" #include "servers/visual/shader_types.h" +bool VisualShaderNode::is_simple_decl() const { + return simple_decl; +} + void VisualShaderNode::set_output_port_for_preview(int p_index) { port_preview = p_index; @@ -132,6 +136,7 @@ void VisualShaderNode::_bind_methods() { VisualShaderNode::VisualShaderNode() { port_preview = -1; + simple_decl = true; } ///////////////////////////////////////////////////////// @@ -273,6 +278,7 @@ void VisualShaderNodeCustom::_bind_methods() { } VisualShaderNodeCustom::VisualShaderNodeCustom() { + simple_decl = false; } ///////////////////////////////////////////////////////// @@ -1104,17 +1110,17 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } else if (in_type == out_type) { inputs[i] = src_var; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { - inputs[i] = "dot(" + src_var + ",vec3(0.333333,0.333333,0.333333))"; + inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))"; } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { inputs[i] = "vec3(" + src_var + ")"; } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { inputs[i] = "all(bvec3(" + src_var + "))"; } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { - inputs[i] = src_var + ">0.0?true:false"; + inputs[i] = src_var + " > 0.0 ? true : false"; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { - inputs[i] = src_var + "?1.0:0.0"; + inputs[i] = src_var + " ? 1.0 : 0.0"; } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { - inputs[i] = "vec3(" + src_var + "?1.0:0.0)"; + inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)"; } } else { @@ -1130,7 +1136,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } else if (defval.get_type() == Variant::VECTOR3) { Vector3 val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f,%.5f,%.5f);\n", val.x, val.y, val.z); + code += "\tvec3 " + inputs[i] + " = " + vformat("vec3(%.5f, %.5f, %.5f);\n", val.x, val.y, val.z); } else if (defval.get_type() == Variant::TRANSFORM) { Transform val = defval; val.basis.transpose(); @@ -1145,7 +1151,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui values.push_back(val.origin.y); values.push_back(val.origin.z); bool err = false; - code += "\tmat4 " + inputs[i] + " = " + String("mat4( vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,0.0),vec4(%.5f,%.5f,%.5f,1.0) );\n").sprintf(values, &err); + code += "\tmat4 " + inputs[i] + " = " + String("mat4(vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 0.0), vec4(%.5f, %.5f, %.5f, 1.0));\n").sprintf(values, &err); } else { //will go empty, node is expected to know what it is doing at this point and handle it } @@ -1157,15 +1163,29 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui output_vars.resize(vsnode->get_output_port_count()); String *outputs = output_vars.ptrw(); - for (int i = 0; i < output_count; i++) { + if (vsnode->is_simple_decl()) { // less code to generate for some simple_decl nodes + for (int i = 0; i < output_count; i++) { + String var_name = "n_out" + itos(node) + "p" + itos(i); + switch (vsnode->get_output_port_type(i)) { + case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break; + case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break; + case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break; + case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break; + default: { + } + } + } - outputs[i] = "n_out" + itos(node) + "p" + itos(i); - switch (vsnode->get_output_port_type(i)) { - case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break; - case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break; - case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break; - case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break; - default: { + } else { + for (int i = 0; i < output_count; i++) { + outputs[i] = "n_out" + itos(node) + "p" + itos(i); + switch (vsnode->get_output_port_type(i)) { + case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break; + case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break; + case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break; + case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break; + default: { + } } } } @@ -1432,8 +1452,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, @@ -1455,13 +1475,13 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "float(FRONT_FACING ? 1.0 : 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, @@ -1498,7 +1518,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, // Canvas Item, Vertex - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, @@ -1512,13 +1532,13 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, // Canvas Item, Fragment { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_pixel_size", "vec3(SCREEN_PIXEL_SIZE, 1.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, @@ -1526,19 +1546,19 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_height", "LIGHT_HEIGHT" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, @@ -1564,48 +1584,48 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { // Spatial, Fragment - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "vec3(0.0,1.0,0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "vec3(1.0,0.0,0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "vec3(0.0, 1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "vec3(1.0, 0.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "1.0" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0,1.0, 0.0)" }, // Spatial, Light - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" }, // Canvas Item, Vertex - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Canvas Item, Fragment - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Canvas Item, Light - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0,0.0,1.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Particles, Vertex { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0,0.0,1.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "vec3(0.0, 0.0, 1.0)" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_MAX, VisualShader::TYPE_MAX, VisualShaderNode::PORT_TYPE_TRANSFORM, NULL, NULL }, }; @@ -2514,6 +2534,7 @@ VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() { inputs = ""; outputs = ""; editable = false; + simple_decl = false; } ////////////// Expression @@ -2615,7 +2636,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad default: continue; } - output_initializer += "\t" + p_output_vars[i] + "=" + tk + ";\n"; + output_initializer += "\t" + p_output_vars[i] + " = " + tk + ";\n"; } String code; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index f81090d9cb5..f35318e0907 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -176,6 +176,7 @@ class VisualShaderNode : public Resource { Map default_input_values; protected: + bool simple_decl; static void _bind_methods(); public: @@ -188,6 +189,8 @@ public: PORT_TYPE_MAX, }; + bool is_simple_decl() const; + virtual String get_caption() const = 0; virtual int get_input_port_count() const = 0; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 7d8c396b7f4..5a6e8fb76fb 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -187,7 +187,7 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; - code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.r, constant.g, constant.b) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.r, constant.g, constant.b) + ";\n"; code += "\t" + p_output_vars[1] + " = " + vformat("%.6f", constant.a) + ";\n"; return code; @@ -253,7 +253,7 @@ String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const { } String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f,%.6f,%.6f)", constant.x, constant.y, constant.z) + ";\n"; + return "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.x, constant.y, constant.z) + ";\n"; } void VisualShaderNodeVec3Constant::set_constant(Vector3 p_value) { @@ -319,10 +319,10 @@ String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, Vis t.basis.transpose(); String code = "\t" + p_output_vars[0] + " = mat4("; - code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[0].x, t.basis[0].y, t.basis[0].z); - code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[1].x, t.basis[1].y, t.basis[1].z); - code += vformat("vec4(%.6f,%.6f,%.6f,0.0),", t.basis[2].x, t.basis[2].y, t.basis[2].z); - code += vformat("vec4(%.6f,%.6f,%.6f,1.0) );\n", t.origin.x, t.origin.y, t.origin.z); + code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[0].x, t.basis[0].y, t.basis[0].z); + code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[1].x, t.basis[1].y, t.basis[1].z); + code += vformat("vec4(%.6f, %.6f, %.6f, 0.0), ", t.basis[2].x, t.basis[2].y, t.basis[2].z); + code += vformat("vec4(%.6f, %.6f, %.6f, 1.0));\n", t.origin.x, t.origin.y, t.origin.z); return code; } @@ -440,7 +440,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade case TYPE_COLOR: u += " : hint_albedo"; break; case TYPE_NORMALMAP: u += " : hint_normal"; break; } - return u + ";"; + return u + ";\n"; } return String(); @@ -454,16 +454,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\tvec4 " + id + "_read = texture( " + id + " , UV.xy );\n"; + code += "\tvec4 " + id + "_read = texture(" + id + ", UV.xy);\n"; } else { - code += "\tvec4 " + id + "_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\tvec4 " + id + "_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + code += "\tvec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { - code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\tvec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; @@ -482,16 +482,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", UV.xy);\n"; } else { - code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { - code += "\t\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; @@ -507,16 +507,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy , 0.0 );\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, UV.xy, 0.0 );\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy , " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy , 0.0 );\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, 0.0);\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n"; @@ -531,16 +531,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = texture( TEXTURE , UV.xy );\n"; + code += "\t\tvec4 _tex_read = texture(TEXTURE , UV.xy);\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( TEXTURE , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 _tex_read = textureLod(TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 _tex_read = texture( TEXTURE , " + p_input_vars[0] + ".xy );\n"; + code += "\t\tvec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ".xy);\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 _tex_read = textureLod(TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n"; @@ -555,16 +555,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , UV.xy );\n"; + code += "\t\tvec4 _tex_read = texture(NORMAL_TEXTURE, UV.xy);\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( NORMAL_TEXTURE , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 _tex_read = textureLod(NORMAL_TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , " + p_input_vars[0] + ".xy );\n"; + code += "\t\tvec4 _tex_read = texture(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy);\n"; } else { - code += "\t\tvec4 _tex_read = textureLod( NORMAL_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 _tex_read = textureLod(NORMAL_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = _tex_read.rgb;\n"; @@ -589,16 +589,16 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , UV.xy ).r;\n"; + code += "\t\tfloat _depth = texture(DEPTH_TEXTURE, UV.xy).r;\n"; } else { - code += "\t\tfloat _depth = textureLod( DEPTH_TEXTURE , UV.xy , " + p_input_vars[1] + " ).r;\n"; + code += "\t\tfloat _depth = textureLod(DEPTH_TEXTURE, UV.xy, " + p_input_vars[1] + ").r;\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , " + p_input_vars[0] + ".xy ).r;\n"; + code += "\t\tfloat _depth = texture(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy).r;\n"; } else { - code += "\t\tfloat _depth = textureLod( DEPTH_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " ).r;\n"; + code += "\t\tfloat _depth = textureLod(DEPTH_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ").r;\n"; } code += "\t\t" + p_output_vars[0] + " = _depth;\n"; @@ -621,6 +621,26 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: void VisualShaderNodeTexture::set_source(Source p_source) { source = p_source; + switch (source) { + case SOURCE_TEXTURE: + simple_decl = true; + break; + case SOURCE_SCREEN: + simple_decl = false; + break; + case SOURCE_2D_TEXTURE: + simple_decl = false; + break; + case SOURCE_2D_NORMAL: + simple_decl = false; + break; + case SOURCE_DEPTH: + simple_decl = false; + break; + case SOURCE_PORT: + simple_decl = false; + break; + } emit_changed(); emit_signal("editor_refresh_request"); } @@ -822,16 +842,16 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 " + id + "_read = texture( " + id + " , vec3( UV, 0.0 ) );\n"; + code += "\t\tvec4 " + id + "_read = texture(" + id + " , vec3(UV, 0.0));\n"; } else { - code += "\t\tvec4 " + id + "_read = textureLod( " + id + " , vec3( UV, 0.0 )" + " , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_read = textureLod(" + id + " , vec3(UV, 0.0)" + " , " + p_input_vars[1] + " );\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + " );\n"; + code += "\t\tvec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n"; } else { - code += "\t\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; code += "\t\t" + p_output_vars[1] + " = " + id + "_read.a;\n"; @@ -913,6 +933,7 @@ void VisualShaderNodeCubeMap::_bind_methods() { VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() { texture_type = TYPE_DATA; source = SOURCE_TEXTURE; + simple_decl = false; } ////////////// Scalar Op @@ -954,12 +975,12 @@ String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break; case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break; case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break; - case OP_MOD: code += "mod( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_POW: code += "pow( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_MAX: code += "max( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_MIN: code += "min( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_ATAN2: code += "atan( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_STEP: code += "step( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; + case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; } return code; @@ -1046,14 +1067,14 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break; case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break; case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break; - case OP_MOD: code += "mod( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_POW: code += "pow( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_MAX: code += "max( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_MIN: code += "min( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_CROSS: code += "cross( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_ATAN2: code += "atan( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_REFLECT: code += "reflect( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; - case OP_STEP: code += "step( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; break; + case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_CROSS: code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_REFLECT: code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; } return code; @@ -1140,27 +1161,27 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader: switch (op) { case OP_SCREEN: { - code += "\t" + p_output_vars[0] + "=vec3(1.0)-(vec3(1.0)-" + p_input_vars[0] + ")*(vec3(1.0)-" + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") * (vec3(1.0) - " + p_input_vars[1] + ");\n"; } break; case OP_DIFFERENCE: { - code += "\t" + p_output_vars[0] + "=abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ");\n"; } break; case OP_DARKEN: { - code += "\t" + p_output_vars[0] + "=min(" + p_input_vars[0] + "," + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } break; case OP_LIGHTEN: { - code += "\t" + p_output_vars[0] + "=max(" + p_input_vars[0] + "," + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } break; case OP_OVERLAY: { for (int i = 0; i < 3; i++) { code += "\t{\n"; - code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n"; - code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n"; + code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n"; + code += "\t\tfloat blend = " + p_input_vars[1] + "." + axisn[i] + ";\n"; code += "\t\tif (base < 0.5) {\n"; code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = 2.0 * base * blend;\n"; code += "\t\t} else {\n"; @@ -1172,23 +1193,23 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader: } break; case OP_DODGE: { - code += "\t" + p_output_vars[0] + "=(" + p_input_vars[0] + ")/(vec3(1.0)-" + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = (" + p_input_vars[0] + ") / (vec3(1.0) - " + p_input_vars[1] + ");\n"; } break; case OP_BURN: { - code += "\t" + p_output_vars[0] + "=vec3(1.0)-(vec3(1.0)-" + p_input_vars[0] + ")/(" + p_input_vars[1] + ");\n"; + code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") / (" + p_input_vars[1] + ");\n"; } break; case OP_SOFT_LIGHT: { for (int i = 0; i < 3; i++) { code += "\t{\n"; - code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n"; - code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n"; + code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n"; + code += "\t\tfloat blend = " + p_input_vars[1] + "." + axisn[i] + ";\n"; code += "\t\tif (base < 0.5) {\n"; - code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (blend+0.5));\n"; + code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (blend + 0.5));\n"; code += "\t\t} else {\n"; - code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0-base) * (1.0-(blend-0.5)));\n"; + code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0 - base) * (1.0 - (blend - 0.5)));\n"; code += "\t\t}\n"; code += "\t}\n"; } @@ -1198,12 +1219,12 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader: for (int i = 0; i < 3; i++) { code += "\t{\n"; - code += "\t\tfloat base=" + p_input_vars[0] + "." + axisn[i] + ";\n"; - code += "\t\tfloat blend=" + p_input_vars[1] + "." + axisn[i] + ";\n"; + code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n"; + code += "\t\tfloat blend = " + p_input_vars[1] + "." + axisn[i] + ";\n"; code += "\t\tif (base < 0.5) {\n"; - code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (2.0*blend));\n"; + code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (base * (2.0 * blend));\n"; code += "\t\t} else {\n"; - code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0-base) * (1.0-2.0*(blend-0.5)));\n"; + code += "\t\t\t" + p_output_vars[0] + "." + axisn[i] + " = (1.0 - (1.0 - base) * (1.0 - 2.0 * (blend - 0.5)));\n"; code += "\t\t}\n"; code += "\t}\n"; } @@ -1217,6 +1238,35 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader: void VisualShaderNodeColorOp::set_operator(Operator p_op) { op = p_op; + switch (op) { + case OP_SCREEN: + simple_decl = true; + break; + case OP_DIFFERENCE: + simple_decl = true; + break; + case OP_DARKEN: + simple_decl = true; + break; + case OP_LIGHTEN: + simple_decl = true; + break; + case OP_OVERLAY: + simple_decl = false; + break; + case OP_DODGE: + simple_decl = true; + break; + case OP_BURN: + simple_decl = true; + break; + case OP_SOFT_LIGHT: + simple_decl = false; + break; + case OP_HARD_LIGHT: + simple_decl = false; + break; + } emit_changed(); } @@ -1292,9 +1342,9 @@ String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualS } else if (op == OP_BxA) { return "\t" + p_output_vars[0] + " = " + p_input_vars[1] + " * " + p_input_vars[0] + ";\n"; } else if (op == OP_AxB_COMP) { - return "\t" + p_output_vars[0] + " = matrixCompMult( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; + return "\t" + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } else { - return "\t" + p_output_vars[0] + " = matrixCompMult( " + p_input_vars[1] + " , " + p_input_vars[0] + " );\n"; + return "\t" + p_output_vars[0] + " = matrixCompMult(" + p_input_vars[1] + ", " + p_input_vars[0] + ");\n"; } } @@ -1366,13 +1416,13 @@ String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { if (op == OP_AxB) { - return "\t" + p_output_vars[0] + " = ( " + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0) ).xyz;\n"; + return "\t" + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 1.0)).xyz;\n"; } else if (op == OP_BxA) { - return "\t" + p_output_vars[0] + " = ( vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + " ).xyz;\n"; + return "\t" + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 1.0) * " + p_input_vars[0] + ").xyz;\n"; } else if (op == OP_3x3_AxB) { - return "\t" + p_output_vars[0] + " = ( " + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0) ).xyz;\n"; + return "\t" + p_output_vars[0] + " = (" + p_input_vars[0] + " * vec4(" + p_input_vars[1] + ", 0.0)).xyz;\n"; } else { - return "\t" + p_output_vars[0] + " = ( vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + " ).xyz;\n"; + return "\t" + p_output_vars[0] + " = (vec4(" + p_input_vars[1] + ", 0.0) * " + p_input_vars[0] + ").xyz;\n"; } } @@ -1463,7 +1513,7 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad "round($)", "ceil($)", "fract($)", - "min(max($,0.0),1.0)", + "min(max($, 0.0), 1.0)", "-($)", "acosh($)", "asinh($)", @@ -1473,10 +1523,10 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad "inversesqrt($)", "log2($)", "radians($)", - "1.0/($)", + "1.0 / ($)", "roundEven($)", "trunc($)", - "1.0-$" + "1.0 - $" }; return "\t" + p_output_vars[0] + " = " + String(scalar_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; @@ -1579,9 +1629,9 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad static const char *vec_func_id[FUNC_ONEMINUS + 1] = { "normalize($)", - "max(min($,vec3(1.0)),vec3(0.0))", + "max(min($, vec3(1.0)), vec3(0.0))", "-($)", - "1.0/($)", + "1.0 / ($)", "", "", "abs($)", @@ -1612,7 +1662,7 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad "tan($)", "tanh($)", "trunc($)", - "vec3(1.0, 1.0, 1.0)-$" + "vec3(1.0, 1.0, 1.0) - $" }; String code; @@ -1625,18 +1675,18 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad code += "\t\tvec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));\n"; code += "\t\tfloat d = q.x - min(q.w, q.y);\n"; code += "\t\tfloat e = 1.0e-10;\n"; - code += "\t\t" + p_output_vars[0] + "=vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; + code += "\t\t" + p_output_vars[0] + " = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n"; code += "\t}\n"; } else if (func == FUNC_HSV2RGB) { code += "\t{\n"; code += "\t\tvec3 c = " + p_input_vars[0] + ";\n"; code += "\t\tvec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n"; code += "\t\tvec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\n"; - code += "\t\t" + p_output_vars[0] + "=c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"; + code += "\t\t" + p_output_vars[0] + " = c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\n"; code += "\t}\n"; } else { - code += "\t" + p_output_vars[0] + "=" + String(vec_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + String(vec_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; } return code; @@ -1645,6 +1695,13 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad void VisualShaderNodeVectorFunc::set_function(Function p_func) { func = p_func; + if (func == FUNC_RGB2HSV) { + simple_decl = false; + } else if (func == FUNC_HSV2RGB) { + simple_decl = false; + } else { + simple_decl = true; + } emit_changed(); } @@ -1797,6 +1854,7 @@ void VisualShaderNodeColorFunc::_bind_methods() { VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() { func = FUNC_GRAYSCALE; set_input_port_default_value(0, Vector3()); + simple_decl = false; } ////////////// Transform Func @@ -1837,7 +1895,7 @@ String VisualShaderNodeTransformFunc::generate_code(Shader::Mode p_mode, VisualS }; String code; - code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; return code; } @@ -1905,7 +1963,7 @@ String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const { } String VisualShaderNodeDotProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = dot( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; + return "\t" + p_output_vars[0] + " = dot(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } VisualShaderNodeDotProduct::VisualShaderNodeDotProduct() { @@ -1944,7 +2002,7 @@ String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = length( " + p_input_vars[0] + " );\n"; + return "\t" + p_output_vars[0] + " = length(" + p_input_vars[0] + ");\n"; } VisualShaderNodeVectorLen::VisualShaderNodeVectorLen() { @@ -1982,7 +2040,7 @@ String VisualShaderNodeDeterminant::get_output_port_name(int p_port) const { } String VisualShaderNodeDeterminant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = determinant( " + p_input_vars[0] + " );\n"; + return "\t" + p_output_vars[0] + " = determinant(" + p_input_vars[0] + ");\n"; } VisualShaderNodeDeterminant::VisualShaderNodeDeterminant() { @@ -2028,7 +2086,7 @@ String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode, }; String code; - code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; return code; } @@ -2105,7 +2163,7 @@ String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode, }; String code; - code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; return code; } @@ -2180,7 +2238,7 @@ String VisualShaderNodeScalarClamp::get_output_port_name(int p_port) const { } String VisualShaderNodeScalarClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = clamp( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeScalarClamp::VisualShaderNodeScalarClamp() { @@ -2226,7 +2284,7 @@ String VisualShaderNodeVectorClamp::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorClamp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = clamp( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorClamp::VisualShaderNodeVectorClamp() { @@ -2275,7 +2333,7 @@ String VisualShaderNodeFaceForward::get_output_port_name(int p_port) const { } String VisualShaderNodeFaceForward::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = faceforward( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = faceforward(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeFaceForward::VisualShaderNodeFaceForward() { @@ -2322,7 +2380,7 @@ String VisualShaderNodeOuterProduct::get_output_port_name(int p_port) const { } String VisualShaderNodeOuterProduct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = outerProduct( vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0) );\n"; + return "\t" + p_output_vars[0] + " = outerProduct(vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0));\n"; } VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() { @@ -2368,7 +2426,7 @@ String VisualShaderNodeVectorScalarStep::get_output_port_name(int p_port) const } String VisualShaderNodeVectorScalarStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = step( " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n"; + return "\t" + p_output_vars[0] + " = step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } VisualShaderNodeVectorScalarStep::VisualShaderNodeVectorScalarStep() { @@ -2413,7 +2471,7 @@ String VisualShaderNodeScalarSmoothStep::get_output_port_name(int p_port) const } String VisualShaderNodeScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeScalarSmoothStep::VisualShaderNodeScalarSmoothStep() { @@ -2459,7 +2517,7 @@ String VisualShaderNodeVectorSmoothStep::get_output_port_name(int p_port) const } String VisualShaderNodeVectorSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorSmoothStep::VisualShaderNodeVectorSmoothStep() { @@ -2510,7 +2568,7 @@ String VisualShaderNodeVectorScalarSmoothStep::get_output_port_name(int p_port) } String VisualShaderNodeVectorScalarSmoothStep::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = smoothstep( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = smoothstep(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorScalarSmoothStep::VisualShaderNodeVectorScalarSmoothStep() { @@ -2555,7 +2613,7 @@ String VisualShaderNodeVectorDistance::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorDistance::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = distance( " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; + return "\t" + p_output_vars[0] + " = distance(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } VisualShaderNodeVectorDistance::VisualShaderNodeVectorDistance() { @@ -2606,7 +2664,7 @@ String VisualShaderNodeVectorRefract::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorRefract::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = refract( " + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = refract(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { @@ -2652,7 +2710,7 @@ String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const { } String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() { @@ -2698,7 +2756,7 @@ String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() { @@ -2746,7 +2804,7 @@ String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorScalarMix::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = mix(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() { @@ -2792,7 +2850,7 @@ String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const { } String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = vec3( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; + return "\t" + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() { @@ -2841,7 +2899,7 @@ String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const } String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - return "\t" + p_output_vars[0] + " = mat4( vec4(" + p_input_vars[0] + ", 0.0) , vec4(" + p_input_vars[1] + ", 0.0) , vec4(" + p_input_vars[2] + ",0.0), vec4(" + p_input_vars[3] + ",1.0) );\n"; + return "\t" + p_output_vars[0] + " = mat4(vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0), vec4(" + p_input_vars[2] + ", 0.0), vec4(" + p_input_vars[3] + ", 1.0));\n"; } VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() { @@ -3237,15 +3295,15 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 n_tex_read = texture( " + id + " , UV.xy );\n"; + code += "\t\tvec4 n_tex_read = texture(" + id + ", UV.xy);\n"; } else { - code += "\t\tvec4 n_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 n_tex_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 n_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + code += "\t\tvec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n"; } else { - code += "\t\tvec4 n_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 n_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n"; @@ -3309,6 +3367,7 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { texture_type = TYPE_DATA; color_default = COLOR_DEFAULT_WHITE; + simple_decl = false; } ////////////// Texture Uniform (Triplanar) @@ -3549,6 +3608,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() { set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0)); + simple_decl = false; } ////////////// Switch @@ -3611,6 +3671,7 @@ VisualShaderNodeSwitch::VisualShaderNodeSwitch() { set_input_port_default_value(0, false); set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); + simple_decl = false; } ////////////// Switch(scalar) @@ -3765,7 +3826,7 @@ String VisualShaderNodeIs::generate_code(Shader::Mode p_mode, VisualShader::Type }; String code; - code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; return code; } @@ -3900,31 +3961,31 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader: switch (ctype) { case CTYPE_SCALAR: if (func == FUNC_EQUAL) { - code += "\t" + p_output_vars[0] + "=(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + code += "\t" + p_output_vars[0] + " = (abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");"; } else if (func == FUNC_NOT_EQUAL) { - code += "\t" + p_output_vars[0] + "=!(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + code += "\t" + p_output_vars[0] + " = !(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");"; } else { - code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; } break; case CTYPE_VECTOR: code += "\t{\n"; - code += "\t\tbvec3 _bv=" + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; - code += "\t\t" + p_output_vars[0] + "=" + String(conds[condition]).replace("$", "_bv") + ";\n"; + code += "\t\tbvec3 _bv = " + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + String(conds[condition]).replace("$", "_bv") + ";\n"; code += "\t}\n"; break; case CTYPE_BOOLEAN: if (func > FUNC_NOT_EQUAL) - return "\t" + p_output_vars[0] + "=false;\n"; - code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + return "\t" + p_output_vars[0] + " = false;\n"; + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; break; case CTYPE_TRANSFORM: if (func > FUNC_NOT_EQUAL) - return "\t" + p_output_vars[0] + "=false;\n"; - code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + return "\t" + p_output_vars[0] + " = false;\n"; + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; break; default: @@ -3941,18 +4002,22 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) { case CTYPE_SCALAR: set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); + simple_decl = true; break; case CTYPE_VECTOR: set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + simple_decl = false; break; case CTYPE_BOOLEAN: set_input_port_default_value(0, false); set_input_port_default_value(1, false); + simple_decl = true; break; case CTYPE_TRANSFORM: set_input_port_default_value(0, Transform()); set_input_port_default_value(1, Transform()); + simple_decl = true; break; } emit_changed(); From 1f4885fe4941a21535d295e0d37a7b69604f9834 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Sat, 1 Feb 2020 16:25:34 +0300 Subject: [PATCH 54/64] Added missing '\n' in visual shader custom node code generation (cherry picked from commit 9d8b59e86a337d4a4ed6f1577df046c914ab59e3) --- scene/resources/visual_shader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 4161f743a56..d8cac0c2024 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -246,6 +246,7 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader:: code.remove(code.size() - 1); code += "}"; } + code += "\n"; return code; } From 5579eb823b85f9cad22d3d8edabad9b377465624 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Sat, 1 Feb 2020 17:41:49 +0300 Subject: [PATCH 55/64] Few extra formatting fixes for visual shader node generation For 'If' and 'Switch' nodes (cherry picked from commit b0f166f0c5e3d790e352326eed9092d5c4f3ae62) --- scene/resources/visual_shader_nodes.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 5a6e8fb76fb..a22bb34d121 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3586,17 +3586,17 @@ String VisualShaderNodeIf::get_output_port_name(int p_port) const { String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String code; - code += "\tif(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b + code += "\tif(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b code += "\t{\n"; - code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[3] + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + p_input_vars[3] + ";\n"; code += "\t}\n"; - code += "\telse if(" + p_input_vars[0] + "<" + p_input_vars[1] + ")\n"; // a < b + code += "\telse if(" + p_input_vars[0] + " < " + p_input_vars[1] + ")\n"; // a < b code += "\t{\n"; - code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[5] + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + p_input_vars[5] + ";\n"; code += "\t}\n"; code += "\telse\n"; // a > b (or a >= b if abs(a - b) < tolerance is false) code += "\t{\n"; - code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[4] + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + p_input_vars[4] + ";\n"; code += "\t}\n"; return code; } @@ -3658,11 +3658,11 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: String code; code += "\tif(" + p_input_vars[0] + ")\n"; code += "\t{\n"; - code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[1] + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + p_input_vars[1] + ";\n"; code += "\t}\n"; code += "\telse\n"; code += "\t{\n"; - code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[2] + ";\n"; + code += "\t\t" + p_output_vars[0] + " = " + p_input_vars[2] + ";\n"; code += "\t}\n"; return code; } From 1930c79364d50125fb1fb9a11bc2bdc38d6ebc6f Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Mon, 3 Feb 2020 12:33:37 +0300 Subject: [PATCH 56/64] Added missing '\n' in visual shader fresnel node code generation (cherry picked from commit c8639a0013b0c128044d3522f8cbdbd2c143a13c) --- scene/resources/visual_shader_nodes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a22bb34d121..daf770e92a1 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -3764,7 +3764,7 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader: view = p_input_vars[1]; } - return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));"; + return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n"; } String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const { From e10b0c9eaa3daf278e13df6246ce768d2564d47a Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Mon, 3 Feb 2020 15:58:58 +0300 Subject: [PATCH 57/64] Added missing '\n' in visual shader expression node code generation (cherry picked from commit 6e1187ad2f378a5e72021056839c728414e29e37) --- scene/resources/visual_shader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index d8cac0c2024..b3a72ea7b60 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -2644,7 +2644,7 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad code += output_initializer; code += "\t{"; code += _expression; - code += "\n\t}"; + code += "\n\t}\n"; return code; } From 7cb3a20418aed29fef15e646e88d51bf8987629b Mon Sep 17 00:00:00 2001 From: bitstopper Date: Wed, 2 Oct 2019 17:49:52 +0200 Subject: [PATCH 58/64] Fixes broken CPUParticles2D AtlasTextures usage (cherry picked from commit 36d9906d6a5af1913033f3d0a1adcef387201c61) --- scene/2d/cpu_particles_2d.cpp | 38 ++++++++++++++++++++++++++++++----- scene/2d/cpu_particles_2d.h | 2 ++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index f59e3461b1b..acb1b0b5a02 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "cpu_particles_2d.h" - +#include "core/core_string_names.h" #include "scene/2d/canvas_item.h" #include "scene/2d/particles_2d.h" #include "scene/resources/particles_material.h" @@ -169,10 +169,20 @@ void CPUParticles2D::_update_mesh_texture() { vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, tex_size.y)); vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y)); PoolVector uvs; - uvs.push_back(Vector2(0, 0)); - uvs.push_back(Vector2(1, 0)); - uvs.push_back(Vector2(1, 1)); - uvs.push_back(Vector2(0, 1)); + AtlasTexture *atlas_texure = Object::cast_to(*texture); + if (atlas_texure && atlas_texure->get_atlas().is_valid()) { + Rect2 region_rect = atlas_texure->get_region(); + Size2 atlas_size = atlas_texure->get_atlas()->get_size(); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + } else { + uvs.push_back(Vector2(0, 0)); + uvs.push_back(Vector2(1, 0)); + uvs.push_back(Vector2(1, 1)); + uvs.push_back(Vector2(0, 1)); + } PoolVector colors; colors.push_back(Color(1, 1, 1, 1)); colors.push_back(Color(1, 1, 1, 1)); @@ -198,12 +208,29 @@ void CPUParticles2D::_update_mesh_texture() { } void CPUParticles2D::set_texture(const Ref &p_texture) { + if (p_texture == texture) + return; + + if (texture.is_valid()) + texture->disconnect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); texture = p_texture; + + if (texture.is_valid()) + texture->connect(CoreStringNames::get_singleton()->changed, this, "_texture_changed"); + update(); _update_mesh_texture(); } +void CPUParticles2D::_texture_changed() { + + if (texture.is_valid()) { + update(); + _update_mesh_texture(); + } +} + Ref CPUParticles2D::get_texture() const { return texture; @@ -1315,6 +1342,7 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles); ClassDB::bind_method(D_METHOD("_update_render_thread"), &CPUParticles2D::_update_render_thread); + ClassDB::bind_method(D_METHOD("_texture_changed"), &CPUParticles2D::_texture_changed); ADD_GROUP("Emission Shape", "emission_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 085ec99ea00..d59b94bcbba 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -186,6 +186,8 @@ private: void _set_redraw(bool p_redraw); + void _texture_changed(); + protected: static void _bind_methods(); void _notification(int p_what); From 6edb5ac9e9f46bb9101f56e977287852757e59fa Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 19 Jan 2020 23:21:49 +0100 Subject: [PATCH 59/64] Optimize the editor icon generation Icons are no longer upsampled when using an integer editor scale. This makes some icons slightly less crisp, but the icons themselves can be adjusted to mitigate this. When using a non-integer editor scale setting, upsampling is kept as it improves crispness in a far more visible manner. When upsampling is disabled, this speeds up the theme generation by about 100 ms on average, making the project manager and editor start slightly faster. This also speeds up switching between themes. (cherry picked from commit 9e3393a624d3c9d7e0a7f5c8bedbd3eb0d1e1b42) --- editor/editor_themes.cpp | 99 ++++++++++++++++++-------------- modules/svg/image_loader_svg.cpp | 13 +++-- 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 621f5316876..8037045e773 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -89,7 +89,11 @@ Ref editor_generate_icon(int p_index, bool p_convert_color, float // dumb gizmo check bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo"); - ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, true, p_convert_color); + // Upsample icon generation only if the editor scale isn't an integer multiplier. + // Generating upsampled icons is slower, and the benefit is hardly visible + // with integer editor scales. + const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); + ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_color); if ((p_scale - (float)((int)p_scale)) > 0.0 || is_gizmo || p_force_filter) icon->create_from_image(img); // in this case filter really helps @@ -106,7 +110,15 @@ Ref editor_generate_icon(int p_index, bool p_convert_color, float void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) { #ifdef SVG_ENABLED + // The default icon theme is designed to be used for a dark theme. + // This dictionary stores color codes to convert to other colors + // for better readability on a light theme. Dictionary dark_icon_color_dictionary; + + // The names of the icons to never convert, even if one of their colors + // are contained in the dictionary above. + Set exceptions; + if (!p_dark_theme) { // convert color: FROM TO ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // common icon color @@ -172,9 +184,31 @@ void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme = ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#69ec9a", "#2ce573"); // VS rid ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#79f3e8", "#12d5c3"); // VS object ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#77edb1", "#57e99f"); // VS dict + + exceptions.insert("EditorPivot"); + exceptions.insert("EditorHandle"); + exceptions.insert("Editor3DHandle"); + exceptions.insert("Godot"); + exceptions.insert("PanoramaSky"); + exceptions.insert("ProceduralSky"); + exceptions.insert("EditorControlAnchor"); + exceptions.insert("DefaultProjectIcon"); + exceptions.insert("GuiCloseCustomizable"); + exceptions.insert("GuiGraphNodePort"); + exceptions.insert("GuiResizer"); + exceptions.insert("ZoomMore"); + exceptions.insert("ZoomLess"); + exceptions.insert("ZoomReset"); + exceptions.insert("LockViewport"); + exceptions.insert("GroupViewport"); + exceptions.insert("StatusError"); + exceptions.insert("StatusSuccess"); + exceptions.insert("StatusWarning"); + exceptions.insert("NodeWarning"); + exceptions.insert("OverbrightIndicator"); } - // these ones should be converted even if we are using a dark theme + // These ones should be converted even if we are using a dark theme. const Color error_color = p_theme->get_color("error_color", "Editor"); const Color success_color = p_theme->get_color("success_color", "Editor"); const Color warning_color = p_theme->get_color("warning_color", "Editor"); @@ -182,65 +216,44 @@ void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme = dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color; dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color; - List exceptions; - exceptions.push_back("EditorPivot"); - exceptions.push_back("EditorHandle"); - exceptions.push_back("Editor3DHandle"); - exceptions.push_back("Godot"); - exceptions.push_back("PanoramaSky"); - exceptions.push_back("ProceduralSky"); - exceptions.push_back("EditorControlAnchor"); - exceptions.push_back("DefaultProjectIcon"); - exceptions.push_back("GuiCloseCustomizable"); - exceptions.push_back("GuiGraphNodePort"); - exceptions.push_back("GuiResizer"); - exceptions.push_back("ZoomMore"); - exceptions.push_back("ZoomLess"); - exceptions.push_back("ZoomReset"); - exceptions.push_back("LockViewport"); - exceptions.push_back("GroupViewport"); - exceptions.push_back("StatusError"); - exceptions.push_back("StatusSuccess"); - exceptions.push_back("StatusWarning"); - exceptions.push_back("NodeWarning"); - exceptions.push_back("OverbrightIndicator"); - ImageLoaderSVG::set_convert_colors(&dark_icon_color_dictionary); - // generate icons - if (!p_only_thumbs) + // Generate icons. + if (!p_only_thumbs) { for (int i = 0; i < editor_icons_count; i++) { - List::Element *is_exception = exceptions.find(editor_icons_names[i]); - if (is_exception) exceptions.erase(is_exception); - Ref icon = editor_generate_icon(i, !is_exception); + const int is_exception = exceptions.has(editor_icons_names[i]); + const Ref icon = editor_generate_icon(i, !is_exception); + p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon); } + } - // generate thumb files with the given thumb size - bool force_filter = p_thumb_size != 64 && p_thumb_size != 32; // we don't need filter with original resolution + // Generate thumbnail icons with the given thumbnail size. + // We don't need filtering when generating at one of the default resolutions. + const bool force_filter = p_thumb_size != 64 && p_thumb_size != 32; if (p_thumb_size >= 64) { - float scale = (float)p_thumb_size / 64.0 * EDSCALE; + const float scale = (float)p_thumb_size / 64.0 * EDSCALE; for (int i = 0; i < editor_bg_thumbs_count; i++) { - int index = editor_bg_thumbs_indices[i]; - List::Element *is_exception = exceptions.find(editor_icons_names[index]); - if (is_exception) exceptions.erase(is_exception); - Ref icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + const int index = editor_bg_thumbs_indices[i]; + const int is_exception = exceptions.has(editor_icons_names[index]); + const Ref icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon); } } else { - float scale = (float)p_thumb_size / 32.0 * EDSCALE; + const float scale = (float)p_thumb_size / 32.0 * EDSCALE; for (int i = 0; i < editor_md_thumbs_count; i++) { - int index = editor_md_thumbs_indices[i]; - List::Element *is_exception = exceptions.find(editor_icons_names[index]); - if (is_exception) exceptions.erase(is_exception); - Ref icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + const int index = editor_md_thumbs_indices[i]; + const bool is_exception = exceptions.has(editor_icons_names[index]); + const Ref icon = editor_generate_icon(index, !p_dark_theme && !is_exception, scale, force_filter); + p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon); } } ImageLoaderSVG::set_convert_colors(NULL); #else - print_line("SVG support disabled, editor icons won't be rendered."); + WARN_PRINT("SVG support disabled, editor icons won't be rendered."); #endif } diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 57097aaa065..11ae2f81bf9 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -103,15 +103,17 @@ Error ImageLoaderSVG::_create_image(Ref p_image, const PoolVectorwidth * p_scale * upscale); + const int w = (int)(svg_image->width * p_scale * upscale); ERR_FAIL_COND_V_MSG(w > Image::MAX_WIDTH, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max width.", rtos(p_scale))); - int h = (int)(svg_image->height * p_scale * upscale); + const int h = (int)(svg_image->height * p_scale * upscale); ERR_FAIL_COND_V_MSG(h > Image::MAX_HEIGHT, ERR_PARAMETER_RANGE_ERROR, vformat("Can't create image from SVG with scale %s, the resulting image size exceeds max height.", rtos(p_scale))); PoolVector dst_image; @@ -123,8 +125,9 @@ Error ImageLoaderSVG::_create_image(Ref p_image, const PoolVectorcreate(w, h, false, Image::FORMAT_RGBA8, dst_image); - if (upsample) + if (upsample) { p_image->shrink_x2(); + } nsvgDelete(svg_image); From 30ca4a32a8d391f375d45a1a3bf33be54cbe4b9a Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 20 Jan 2020 21:46:42 +0100 Subject: [PATCH 60/64] Export and reference the icon as favicon when exporting to HTML5 This makes the project icon display immediately as a favicon when opening the page, without having to wait for the project to finish loading. (cherry picked from commit 4492cf856b3aab50dabe616d740111907a550c9b) --- misc/dist/html/fixed-size.html | 1 + misc/dist/html/full-size.html | 1 + platform/javascript/export/export.cpp | 55 +++++++++++++++++++-------- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html index 1cc6fd715eb..6c6a3a5d2d4 100644 --- a/misc/dist/html/fixed-size.html +++ b/misc/dist/html/fixed-size.html @@ -2,6 +2,7 @@ +