diff options
74 files changed, 1026 insertions, 964 deletions
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 52a6c5d64f..4a2abffae8 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -38,6 +38,7 @@ const int InputEvent::DEVICE_ID_INTERNAL = -2; void InputEvent::set_device(int p_device) { device = p_device; + emit_changed(); } int InputEvent::get_device() const { @@ -131,6 +132,7 @@ void InputEventFromWindow::_bind_methods() { void InputEventFromWindow::set_window_id(int64_t p_id) { window_id = p_id; + emit_changed(); } int64_t InputEventFromWindow::get_window_id() const { @@ -141,6 +143,7 @@ int64_t InputEventFromWindow::get_window_id() const { void InputEventWithModifiers::set_store_command(bool p_enabled) { store_command = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_storing_command() const { @@ -149,6 +152,7 @@ bool InputEventWithModifiers::is_storing_command() const { void InputEventWithModifiers::set_shift_pressed(bool p_enabled) { shift_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_shift_pressed() const { @@ -157,6 +161,7 @@ bool InputEventWithModifiers::is_shift_pressed() const { void InputEventWithModifiers::set_alt_pressed(bool p_enabled) { alt_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_alt_pressed() const { @@ -165,6 +170,7 @@ bool InputEventWithModifiers::is_alt_pressed() const { void InputEventWithModifiers::set_ctrl_pressed(bool p_enabled) { ctrl_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_ctrl_pressed() const { @@ -173,6 +179,7 @@ bool InputEventWithModifiers::is_ctrl_pressed() const { void InputEventWithModifiers::set_meta_pressed(bool p_enabled) { meta_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_meta_pressed() const { @@ -181,6 +188,7 @@ bool InputEventWithModifiers::is_meta_pressed() const { void InputEventWithModifiers::set_command_pressed(bool p_enabled) { command_pressed = p_enabled; + emit_changed(); } bool InputEventWithModifiers::is_command_pressed() const { @@ -291,6 +299,7 @@ void InputEventWithModifiers::_validate_property(PropertyInfo &property) const { void InputEventKey::set_pressed(bool p_pressed) { pressed = p_pressed; + emit_changed(); } bool InputEventKey::is_pressed() const { @@ -299,6 +308,7 @@ bool InputEventKey::is_pressed() const { void InputEventKey::set_keycode(uint32_t p_keycode) { keycode = p_keycode; + emit_changed(); } uint32_t InputEventKey::get_keycode() const { @@ -307,6 +317,7 @@ uint32_t InputEventKey::get_keycode() const { void InputEventKey::set_physical_keycode(uint32_t p_keycode) { physical_keycode = p_keycode; + emit_changed(); } uint32_t InputEventKey::get_physical_keycode() const { @@ -315,6 +326,7 @@ uint32_t InputEventKey::get_physical_keycode() const { void InputEventKey::set_unicode(uint32_t p_unicode) { unicode = p_unicode; + emit_changed(); } uint32_t InputEventKey::get_unicode() const { @@ -323,6 +335,7 @@ uint32_t InputEventKey::get_unicode() const { void InputEventKey::set_echo(bool p_enable) { echo = p_enable; + emit_changed(); } bool InputEventKey::is_echo() const { @@ -469,6 +482,7 @@ void InputEventKey::_bind_methods() { void InputEventMouse::set_button_mask(int p_mask) { button_mask = p_mask; + emit_changed(); } int InputEventMouse::get_button_mask() const { @@ -518,6 +532,7 @@ float InputEventMouseButton::get_factor() const { void InputEventMouseButton::set_button_index(MouseButton p_index) { button_index = p_index; + emit_changed(); } MouseButton InputEventMouseButton::get_button_index() const { @@ -847,6 +862,7 @@ void InputEventMouseMotion::_bind_methods() { void InputEventJoypadMotion::set_axis(JoyAxis p_axis) { axis = p_axis; + emit_changed(); } JoyAxis InputEventJoypadMotion::get_axis() const { @@ -855,6 +871,7 @@ JoyAxis InputEventJoypadMotion::get_axis() const { void InputEventJoypadMotion::set_axis_value(float p_value) { axis_value = p_value; + emit_changed(); } float InputEventJoypadMotion::get_axis_value() const { @@ -949,6 +966,7 @@ void InputEventJoypadMotion::_bind_methods() { void InputEventJoypadButton::set_button_index(JoyButton p_index) { button_index = p_index; + emit_changed(); } JoyButton InputEventJoypadButton::get_button_index() const { diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index e61ce1eeaa..86d5ae7f38 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -1204,16 +1204,32 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin r_tag.name = ""; r_tag.fields.clear(); - while (true) { - char32_t c = p_stream->get_char(); - if (p_stream->is_eof()) { - r_err_str = "Unexpected EOF while parsing simple tag"; - return ERR_PARSE_ERROR; + if (p_stream->is_utf8()) { + CharString cs; + while (true) { + char c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + cs += c; } - if (c == ']') { - break; + r_tag.name.parse_utf8(cs.get_data(), cs.length()); + } else { + while (true) { + char32_t c = p_stream->get_char(); + if (p_stream->is_eof()) { + r_err_str = "Unexpected EOF while parsing simple tag"; + return ERR_PARSE_ERROR; + } + if (c == ']') { + break; + } + r_tag.name += String::chr(c); } - r_tag.name += String::chr(c); } r_tag.name = r_tag.name.strip_edges(); diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index abe06bc7e1..2a378ed03e 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -347,8 +347,6 @@ </member> <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color(1, 1, 1, 1)"> </member> - <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve" default="1.0"> - </member> <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1"> </member> <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml index a02d318f70..753227513b 100644 --- a/doc/classes/EditorPlugin.xml +++ b/doc/classes/EditorPlugin.xml @@ -547,6 +547,7 @@ <return type="void"> </return> <description> + Minimizes the bottom panel. </description> </method> <method name="make_bottom_panel_item_visible"> @@ -555,6 +556,7 @@ <argument index="0" name="item" type="Control"> </argument> <description> + Makes a specific item in the bottom panel visible. </description> </method> <method name="queue_save_layout"> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index f1e7c5f6e1..773f7b1a02 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -169,6 +169,7 @@ The caret's column position inside the [LineEdit]. When set, the text may scroll to accommodate it. </member> <member name="caret_force_displayed" type="bool" setter="set_caret_force_displayed" getter="is_caret_force_displayed" default="false"> + If [code]true[/code], the [LineEdit] will always show the caret, even if focus is lost. </member> <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="false"> Allow moving caret, selecting and removing the individual composite character components. @@ -195,6 +196,28 @@ </member> <member name="max_length" type="int" setter="set_max_length" getter="get_max_length" default="0"> Maximum amount of characters that can be entered inside the [LineEdit]. If [code]0[/code], there is no limit. + When a limit is defined, characters that would exceed [member max_length] are truncated. This happens both for existing [member text] contents when setting the max length, or for new text inserted in the [LineEdit], including pasting. If any input text is truncated, the [signal text_change_rejected] signal is emitted with the truncated substring as parameter. + [b]Example:[/b] + [codeblocks] + [gdscript] + text = "Hello world" + max_length = 5 + # `text` becomes "Hello". + max_length = 10 + text += " goodbye" + # `text` becomes "Hello good". + # `text_change_rejected` is emitted with "bye" as parameter. + [/gdscript] + [csharp] + Text = "Hello world"; + MaxLength = 5; + // `Text` becomes "Hello". + MaxLength = 10; + Text += " goodbye"; + // `Text` becomes "Hello good". + // `text_change_rejected` is emitted with "bye" as parameter. + [/csharp] + [/codeblocks] </member> <member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" /> <member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6"> @@ -237,8 +260,10 @@ </members> <signals> <signal name="text_change_rejected"> + <argument index="0" name="rejected_substring" type="String"> + </argument> <description> - Emitted when trying to append text that would overflow the [member max_length]. + Emitted when appending text that overflows the [member max_length]. The appended text is truncated to fit [member max_length], and the part that couldn't fit is passed as the [code]rejected_substring[/code] argument. </description> </signal> <signal name="text_changed"> diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml index 321a713e26..229a40638a 100644 --- a/doc/classes/PhysicsShapeQueryParameters2D.xml +++ b/doc/classes/PhysicsShapeQueryParameters2D.xml @@ -4,7 +4,7 @@ Parameters to be sent to a 2D shape physics query. </brief_description> <description> - This class contains the shape and other parameters for 2D intersection/collision queries. See also [PhysicsShapeQueryResult2D]. + This class contains the shape and other parameters for 2D intersection/collision queries. </description> <tutorials> </tutorials> diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml index 52916a8418..9ca892acb3 100644 --- a/doc/classes/PhysicsShapeQueryParameters3D.xml +++ b/doc/classes/PhysicsShapeQueryParameters3D.xml @@ -4,7 +4,7 @@ Parameters to be sent to a 3D shape physics query. </brief_description> <description> - This class contains the shape and other parameters for 3D intersection/collision queries. See also [PhysicsShapeQueryResult3D]. + This class contains the shape and other parameters for 3D intersection/collision queries. </description> <tutorials> </tutorials> diff --git a/doc/classes/PhysicsShapeQueryResult2D.xml b/doc/classes/PhysicsShapeQueryResult2D.xml deleted file mode 100644 index 07b7bc90e2..0000000000 --- a/doc/classes/PhysicsShapeQueryResult2D.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsShapeQueryResult2D" inherits="RefCounted" version="4.0"> - <brief_description> - Result of a 2D shape query in [PhysicsServer2D]. - </brief_description> - <description> - The result of a 2D shape query in [PhysicsServer2D]. See also [PhysicsShapeQueryParameters2D]. - </description> - <tutorials> - </tutorials> - <methods> - <method name="get_result_count" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the number of objects that intersected with the shape. - </description> - </method> - <method name="get_result_object" qualifiers="const"> - <return type="Object"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the [Object] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_object_id" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the instance ID of the [Object] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_object_shape" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the child index of the object's [Shape2D] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_rid" qualifiers="const"> - <return type="RID"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the [RID] of the object that intersected with the shape at index [code]idx[/code]. - </description> - </method> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/PhysicsShapeQueryResult3D.xml b/doc/classes/PhysicsShapeQueryResult3D.xml deleted file mode 100644 index d0ca227a68..0000000000 --- a/doc/classes/PhysicsShapeQueryResult3D.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="PhysicsShapeQueryResult3D" inherits="RefCounted" version="4.0"> - <brief_description> - Result of a 3D shape query in [PhysicsServer3D]. - </brief_description> - <description> - The result of a 3D shape query in [PhysicsServer3D]. See also [PhysicsShapeQueryParameters3D]. - </description> - <tutorials> - </tutorials> - <methods> - <method name="get_result_count" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the number of objects that intersected with the shape. - </description> - </method> - <method name="get_result_object" qualifiers="const"> - <return type="Object"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the [Object] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_object_id" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the instance ID of the [Object] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_object_shape" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the child index of the object's [Shape3D] that intersected with the shape at index [code]idx[/code]. - </description> - </method> - <method name="get_result_rid" qualifiers="const"> - <return type="RID"> - </return> - <argument index="0" name="idx" type="int"> - </argument> - <description> - Returns the [RID] of the object that intersected with the shape at index [code]idx[/code]. - </description> - </method> - </methods> - <constants> - </constants> -</class> diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml index b8d8a55412..89695989c8 100644 --- a/doc/classes/Popup.xml +++ b/doc/classes/Popup.xml @@ -13,6 +13,7 @@ <members> <member name="borderless" type="bool" setter="set_flag" getter="get_flag" override="true" default="true" /> <member name="close_on_parent_focus" type="bool" setter="set_close_on_parent_focus" getter="get_close_on_parent_focus" default="true"> + If [code]true[/code], the [Popup] will close when its parent is focused. </member> <member name="transient" type="bool" setter="set_transient" getter="is_transient" override="true" default="true" /> <member name="unresizable" type="bool" setter="set_flag" getter="get_flag" override="true" default="true" /> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 6a3c124c60..5de6c059c3 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -14,6 +14,7 @@ <return type="void"> </return> <description> + A virtual method that is called whenever backspace is triggered. </description> </method> <method name="add_gutter"> @@ -28,6 +29,7 @@ <return type="void"> </return> <description> + Causes the [TextEdit] to perform a backspace. </description> </method> <method name="center_viewport_to_cursor"> @@ -172,6 +174,7 @@ <argument index="0" name="line" type="int"> </argument> <description> + Returns the indent level of a specific line. </description> </method> <method name="get_line" qualifiers="const"> @@ -312,6 +315,7 @@ <return type="int"> </return> <description> + Returns the [TextEdit]'s' tab size. </description> </method> <method name="get_visible_line_count" qualifiers="const"> @@ -667,6 +671,7 @@ <argument index="0" name="size" type="int"> </argument> <description> + Sets the tab size for the [TextEdit] to use. </description> </method> <method name="undo"> diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml index 55f232c004..436e15387d 100644 --- a/doc/classes/TileSet.xml +++ b/doc/classes/TileSet.xml @@ -322,37 +322,37 @@ </constant> <constant name="TILE_OFFSET_AXIS_VERTICAL" value="1" enum="TileOffsetAxis"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_RIGHT_SIDE" value="0" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_RIGHT_SIDE" value="0" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_RIGHT_CORNER" value="1" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_RIGHT_CORNER" value="1" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE" value="2" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE" value="2" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER" value="3" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER" value="3" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_SIDE" value="4" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_SIDE" value="4" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_CORNER" value="5" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_CORNER" value="5" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE" value="6" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_LEFT_SIDE" value="6" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER" value="7" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_BOTTOM_LEFT_CORNER" value="7" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_LEFT_SIDE" value="8" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_LEFT_SIDE" value="8" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_LEFT_CORNER" value="9" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_LEFT_CORNER" value="9" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE" value="10" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_LEFT_SIDE" value="10" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER" value="11" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_LEFT_CORNER" value="11" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_SIDE" value="12" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_SIDE" value="12" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_CORNER" value="13" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_CORNER" value="13" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE" value="14" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_RIGHT_SIDE" value="14" enum="CellNeighbor"> </constant> - <constant name="TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER" value="15" enum="CellNeighbor"> + <constant name="CELL_NEIGHBOR_TOP_RIGHT_CORNER" value="15" enum="CellNeighbor"> </constant> <constant name="TERRAIN_MODE_MATCH_CORNERS_AND_SIDES" value="0" enum="TerrainMode"> </constant> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index be770e6e03..b498b9bb90 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -96,6 +96,14 @@ Returns the column index at [code]position[/code], or -1 if no item is there. </description> </method> + <method name="get_column_expand_ratio" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <description> + </description> + </method> <method name="get_column_title" qualifiers="const"> <return type="String"> </return> @@ -264,12 +272,39 @@ To tell whether a column of an item is selected, use [method TreeItem.is_selected]. </description> </method> + <method name="is_column_clipping_content" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <description> + </description> + </method> + <method name="is_column_expanding" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <description> + </description> + </method> <method name="scroll_to_item"> <return type="void"> </return> <argument index="0" name="item" type="Object"> </argument> <description> + Causes the [Tree] to jump to the specified item. + </description> + </method> + <method name="set_column_clip_content"> + <return type="void"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> </description> </method> <method name="set_column_custom_minimum_width"> @@ -294,6 +329,16 @@ If [code]true[/code], the column will have the "Expand" flag of [Control]. Columns that have the "Expand" flag will use their "min_width" in a similar fashion to [member Control.size_flags_stretch_ratio]. </description> </method> + <method name="set_column_expand_ratio"> + <return type="void"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <argument index="1" name="ratio" type="int"> + </argument> + <description> + </description> + </method> <method name="set_column_title"> <return type="void"> </return> diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index e8f8ae4717..8a880ab9c8 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -41,19 +41,7 @@ #include <windows.h> #include <ws2tcpip.h> #ifndef UWP_ENABLED -#if defined(__MINGW32__) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4) -// MinGW-w64 on Ubuntu 12.04 (our Travis build env) has bugs in this code where -// some includes are missing in dependencies of iphlpapi.h for WINVER >= 0x0600 (Vista). -// We don't use this Vista code for now, so working it around by disabling it. -// MinGW-w64 >= 4.0 seems to be better judging by its headers. -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0501 // Windows XP, disable Vista API #include <iphlpapi.h> -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0600 // Re-enable Vista API -#else -#include <iphlpapi.h> -#endif // MINGW hack #endif #else // UNIX #include <netdb.h> diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp index fe1401bdf9..7ed603410d 100644 --- a/editor/action_map_editor.cpp +++ b/editor/action_map_editor.cpp @@ -1123,6 +1123,7 @@ ActionMapEditor::ActionMapEditor() { action_tree->set_hide_root(true); action_tree->set_column_titles_visible(true); action_tree->set_column_title(0, TTR("Action")); + action_tree->set_column_clip_content(0, true); action_tree->set_column_title(1, TTR("Deadzone")); action_tree->set_column_expand(1, false); action_tree->set_column_custom_minimum_width(1, 80 * EDSCALE); diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp index af83baeff8..1c781c4d98 100644 --- a/editor/debugger/editor_network_profiler.cpp +++ b/editor/debugger/editor_network_profiler.cpp @@ -178,18 +178,23 @@ EditorNetworkProfiler::EditorNetworkProfiler() { counters_display->set_column_titles_visible(true); counters_display->set_column_title(0, TTR("Node")); counters_display->set_column_expand(0, true); + counters_display->set_column_clip_content(0, true); counters_display->set_column_custom_minimum_width(0, 60 * EDSCALE); counters_display->set_column_title(1, TTR("Incoming RPC")); counters_display->set_column_expand(1, false); + counters_display->set_column_clip_content(1, true); counters_display->set_column_custom_minimum_width(1, 120 * EDSCALE); counters_display->set_column_title(2, TTR("Incoming RSET")); counters_display->set_column_expand(2, false); + counters_display->set_column_clip_content(2, true); counters_display->set_column_custom_minimum_width(2, 120 * EDSCALE); counters_display->set_column_title(3, TTR("Outgoing RPC")); counters_display->set_column_expand(3, false); + counters_display->set_column_clip_content(3, true); counters_display->set_column_custom_minimum_width(3, 120 * EDSCALE); counters_display->set_column_title(4, TTR("Outgoing RSET")); counters_display->set_column_expand(4, false); + counters_display->set_column_clip_content(4, true); counters_display->set_column_custom_minimum_width(4, 120 * EDSCALE); add_child(counters_display); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index ba84040b0c..5f4d1b6f36 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -631,13 +631,16 @@ EditorProfiler::EditorProfiler() { variables->set_column_titles_visible(true); variables->set_column_title(0, TTR("Name")); variables->set_column_expand(0, true); - variables->set_column_custom_minimum_width(0, 60 * EDSCALE); + variables->set_column_clip_content(0, true); + variables->set_column_expand_ratio(0, 60); variables->set_column_title(1, TTR("Time")); variables->set_column_expand(1, false); - variables->set_column_custom_minimum_width(1, 100 * EDSCALE); + variables->set_column_clip_content(1, true); + variables->set_column_expand_ratio(1, 100); variables->set_column_title(2, TTR("Calls")); variables->set_column_expand(2, false); - variables->set_column_custom_minimum_width(2, 60 * EDSCALE); + variables->set_column_clip_content(2, true); + variables->set_column_expand_ratio(2, 60); variables->connect("item_edited", callable_mp(this, &EditorProfiler::_item_edited)); graph = memnew(TextureRect); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 171d0574e0..a0e8a3bd35 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -773,12 +773,15 @@ EditorVisualProfiler::EditorVisualProfiler() { variables->set_column_titles_visible(true); variables->set_column_title(0, TTR("Name")); variables->set_column_expand(0, true); + variables->set_column_clip_content(0, true); variables->set_column_custom_minimum_width(0, 60); variables->set_column_title(1, TTR("CPU")); variables->set_column_expand(1, false); + variables->set_column_clip_content(1, true); variables->set_column_custom_minimum_width(1, 60 * EDSCALE); variables->set_column_title(2, TTR("GPU")); variables->set_column_expand(2, false); + variables->set_column_clip_content(2, true); variables->set_column_custom_minimum_width(2, 60 * EDSCALE); variables->connect("cell_selected", callable_mp(this, &EditorVisualProfiler::_item_selected)); diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 0d3fd8c7f6..b877ab030f 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1644,8 +1644,10 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) { error_tree->set_column_expand(0, false); error_tree->set_column_custom_minimum_width(0, 140); + error_tree->set_column_clip_content(0, true); error_tree->set_column_expand(1, true); + error_tree->set_column_clip_content(1, true); error_tree->set_select_mode(Tree::SELECT_ROW); error_tree->set_hide_root(true); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 74a8ad9077..ef571e5c7a 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -226,7 +226,11 @@ DependencyEditor::DependencyEditor() { tree->set_columns(2); tree->set_column_titles_visible(true); tree->set_column_title(0, TTR("Resource")); + tree->set_column_clip_content(0, true); + tree->set_column_expand_ratio(0, 2); tree->set_column_title(1, TTR("Path")); + tree->set_column_clip_content(1, true); + tree->set_column_expand_ratio(1, 1); tree->set_hide_root(true); tree->connect("button_pressed", callable_mp(this, &DependencyEditor::_load_pressed)); @@ -769,9 +773,11 @@ OrphanResourcesDialog::OrphanResourcesDialog() { files = memnew(Tree); files->set_columns(2); files->set_column_titles_visible(true); - files->set_column_custom_minimum_width(1, 100); + files->set_column_custom_minimum_width(1, 100 * EDSCALE); files->set_column_expand(0, true); + files->set_column_clip_content(0, true); files->set_column_expand(1, false); + files->set_column_clip_content(1, true); files->set_column_title(0, TTR("Resource")); files->set_column_title(1, TTR("Owns")); files->set_hide_root(true); diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp index 306a88047a..12ae55fbc1 100644 --- a/editor/editor_autoload_settings.cpp +++ b/editor/editor_autoload_settings.cpp @@ -882,19 +882,17 @@ EditorAutoloadSettings::EditorAutoloadSettings() { tree->set_column_title(0, TTR("Name")); tree->set_column_expand(0, true); - tree->set_column_custom_minimum_width(0, 100 * EDSCALE); + tree->set_column_expand_ratio(0, 1); tree->set_column_title(1, TTR("Path")); tree->set_column_expand(1, true); - tree->set_column_custom_minimum_width(1, 100 * EDSCALE); + tree->set_column_clip_content(1, true); + tree->set_column_expand_ratio(1, 2); tree->set_column_title(2, TTR("Global Variable")); tree->set_column_expand(2, false); - // Reserve enough space for translations of "Global Variable" which may be longer. - tree->set_column_custom_minimum_width(2, 150 * EDSCALE); tree->set_column_expand(3, false); - tree->set_column_custom_minimum_width(3, 120 * EDSCALE); tree->connect("cell_selected", callable_mp(this, &EditorAutoloadSettings::_autoload_selected)); tree->connect("item_edited", callable_mp(this, &EditorAutoloadSettings::_autoload_edited)); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 57ddc64e95..a9bbb92079 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -237,9 +237,11 @@ EditorHelpSearch::EditorHelpSearch() { results_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); results_tree->set_columns(2); results_tree->set_column_title(0, TTR("Name")); + results_tree->set_column_clip_content(0, true); results_tree->set_column_title(1, TTR("Member Type")); results_tree->set_column_expand(1, false); results_tree->set_column_custom_minimum_width(1, 150 * EDSCALE); + results_tree->set_column_clip_content(1, true); results_tree->set_custom_minimum_size(Size2(0, 100) * EDSCALE); results_tree->set_hide_root(true); results_tree->set_select_mode(Tree::SELECT_ROW); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 7d6021b0f6..e7c0b02ae2 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -137,6 +137,7 @@ #include "editor/plugins/gpu_particles_3d_editor_plugin.h" #include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h" #include "editor/plugins/gradient_editor_plugin.h" +#include "editor/plugins/input_event_editor_plugin.h" #include "editor/plugins/item_list_editor_plugin.h" #include "editor/plugins/light_occluder_2d_editor_plugin.h" #include "editor/plugins/lightmap_gi_editor_plugin.h" @@ -3874,6 +3875,21 @@ Ref<ImageTexture> EditorNode::_load_custom_class_icon(const String &p_path) cons return nullptr; } +void EditorNode::_pick_main_scene_custom_action(const String &p_custom_action_name) { + if (p_custom_action_name == "select_current") { + Node *scene = editor_data.get_edited_scene_root(); + + if (!scene) { + show_accept(TTR("There is no defined scene to run."), TTR("OK")); + return; + } + + pick_main_scene->hide(); + current_option = SETTINGS_PICK_MAIN_SCENE; + _dialog_action(scene->get_filename()); + } +} + Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String &p_fallback) const { ERR_FAIL_COND_V(!p_object || !gui_base, nullptr); @@ -4668,6 +4684,14 @@ bool EditorNode::ensure_main_scene(bool p_from_native) { current_option = -1; pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category.")); pick_main_scene->popup_centered(); + + if (editor_data.get_edited_scene_root()) { + select_current_scene_button->set_disabled(false); + select_current_scene_button->grab_focus(); + } else { + select_current_scene_button->set_disabled(true); + } + return false; } @@ -6816,6 +6840,7 @@ EditorNode::EditorNode() { add_editor_plugin(memnew(MeshEditorPlugin(this))); add_editor_plugin(memnew(MaterialEditorPlugin(this))); add_editor_plugin(memnew(GPUParticlesCollisionSDFEditorPlugin(this))); + add_editor_plugin(memnew(InputEventEditorPlugin(this))); for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) { add_editor_plugin(EditorPlugins::create(i, this)); @@ -6944,6 +6969,8 @@ EditorNode::EditorNode() { gui_base->add_child(pick_main_scene); pick_main_scene->get_ok_button()->set_text(TTR("Select")); pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_PICK_MAIN_SCENE)); + select_current_scene_button = pick_main_scene->add_button(TTR("Select Current"), true, "select_current"); + pick_main_scene->connect("custom_action", callable_mp(this, &EditorNode::_pick_main_scene_custom_action)); for (int i = 0; i < _init_callbacks.size(); i++) { _init_callbacks[i](); diff --git a/editor/editor_node.h b/editor/editor_node.h index dcb6ad6e94..07bed6999b 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -301,6 +301,7 @@ private: ConfirmationDialog *save_confirmation; ConfirmationDialog *import_confirmation; ConfirmationDialog *pick_main_scene; + Button *select_current_scene_button; AcceptDialog *accept; EditorAbout *about; AcceptDialog *warning; @@ -663,6 +664,8 @@ private: bool _is_class_editor_disabled_by_feature_profile(const StringName &p_class); Ref<ImageTexture> _load_custom_class_icon(const String &p_path) const; + void _pick_main_scene_custom_action(const String &p_custom_action_name); + protected: void _notification(int p_what); diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 62fbad7bcf..b4e5a58c21 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -212,10 +212,15 @@ EditorPluginSettings::EditorPluginSettings() { plugin_list->set_column_title(3, TTR("Status:")); plugin_list->set_column_title(4, TTR("Edit:")); plugin_list->set_column_expand(0, true); + plugin_list->set_column_clip_content(0, true); plugin_list->set_column_expand(1, false); + plugin_list->set_column_clip_content(1, true); plugin_list->set_column_expand(2, false); + plugin_list->set_column_clip_content(2, true); plugin_list->set_column_expand(3, false); + plugin_list->set_column_clip_content(3, true); plugin_list->set_column_expand(4, false); + plugin_list->set_column_clip_content(4, true); plugin_list->set_column_custom_minimum_width(1, 100 * EDSCALE); plugin_list->set_column_custom_minimum_width(2, 250 * EDSCALE); plugin_list->set_column_custom_minimum_width(3, 80 * EDSCALE); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 6004427c0f..080563f375 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -631,6 +631,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/3d/navigation/zoom_style", 0); hints["editors/3d/navigation/zoom_style"] = PropertyInfo(Variant::INT, "editors/3d/navigation/zoom_style", PROPERTY_HINT_ENUM, "Vertical, Horizontal"); + _initial_set("editors/3d/navigation/emulate_numpad", false); _initial_set("editors/3d/navigation/emulate_3_button_mouse", false); _initial_set("editors/3d/navigation/orbit_modifier", 0); hints["editors/3d/navigation/orbit_modifier"] = PropertyInfo(Variant::INT, "editors/3d/navigation/orbit_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 527ffc86df..3dc854d6bd 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -815,7 +815,8 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { if (searched_string.length() > 0) { // Display the search results. - _search(EditorFileSystem::get_singleton()->get_filesystem(), &file_list, 128); + // Limit the number of results displayed to avoid an infinite loop. + _search(EditorFileSystem::get_singleton()->get_filesystem(), &file_list, 10000); } else { if (display_mode == DISPLAY_MODE_TREE_ONLY || always_show_folders) { // Display folders in the list. diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 91a15f1131..208d4437d3 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -728,7 +728,9 @@ LocalizationEditor::LocalizationEditor() { translation_remap_options->set_column_title(1, TTR("Locale")); translation_remap_options->set_column_titles_visible(true); translation_remap_options->set_column_expand(0, true); + translation_remap_options->set_column_clip_content(0, true); translation_remap_options->set_column_expand(1, false); + translation_remap_options->set_column_clip_content(1, true); translation_remap_options->set_column_custom_minimum_width(1, 200); translation_remap_options->connect("item_edited", callable_mp(this, &LocalizationEditor::_translation_res_option_changed)); translation_remap_options->connect("button_pressed", callable_mp(this, &LocalizationEditor::_translation_res_option_delete)); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 48d7cfdee2..2b92943f7e 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -569,8 +569,10 @@ void AnimationPlayerEditor::_animation_blend() { blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE); blend_editor.tree->set_hide_root(true); - blend_editor.tree->set_column_custom_minimum_width(0, 10); - blend_editor.tree->set_column_custom_minimum_width(1, 3); + blend_editor.tree->set_column_expand_ratio(0, 10); + blend_editor.tree->set_column_clip_content(0, true); + blend_editor.tree->set_column_expand_ratio(1, 3); + blend_editor.tree->set_column_clip_content(1, true); List<StringName> anims; player->get_animation_list(&anims); diff --git a/editor/plugins/input_event_editor_plugin.cpp b/editor/plugins/input_event_editor_plugin.cpp new file mode 100644 index 0000000000..f1aa10844b --- /dev/null +++ b/editor/plugins/input_event_editor_plugin.cpp @@ -0,0 +1,122 @@ +/*************************************************************************/ +/* input_event_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "input_event_editor_plugin.h" + +void InputEventConfigContainer::_bind_methods() { +} + +void InputEventConfigContainer::_configure_pressed() { + config_dialog->popup_and_configure(input_event); +} + +void InputEventConfigContainer::_event_changed() { + input_event_text->set_text(input_event->as_text()); +} + +void InputEventConfigContainer::_config_dialog_confirmed() { + Ref<InputEvent> ie = config_dialog->get_event(); + input_event->copy_from(ie); + _event_changed(); +} + +Size2 InputEventConfigContainer::get_minimum_size() const { + // Don't bother with a minimum x size for the control - we don't want the inspector + // to jump in size if a long text is placed in the label (e.g. Joypad Axis description) + return Size2(0, HBoxContainer::get_minimum_size().y); +} + +void InputEventConfigContainer::set_event(const Ref<InputEvent> &p_event) { + Ref<InputEventKey> k = p_event; + Ref<InputEventMouseButton> m = p_event; + Ref<InputEventJoypadButton> jb = p_event; + Ref<InputEventJoypadMotion> jm = p_event; + + if (k.is_valid()) { + config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_KEY); + } else if (m.is_valid()) { + config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_MOUSE_BUTTON); + } else if (jb.is_valid()) { + config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_BUTTON); + } else if (jm.is_valid()) { + config_dialog->set_allowed_input_types(InputEventConfigurationDialog::InputType::INPUT_JOY_MOTION); + } + + input_event = p_event; + _event_changed(); + input_event->connect("changed", callable_mp(this, &InputEventConfigContainer::_event_changed)); +} + +InputEventConfigContainer::InputEventConfigContainer() { + MarginContainer *mc = memnew(MarginContainer); + mc->add_theme_constant_override("margin_left", 10); + mc->add_theme_constant_override("margin_right", 10); + mc->add_theme_constant_override("margin_top", 10); + mc->add_theme_constant_override("margin_bottom", 10); + add_child(mc); + + HBoxContainer *hb = memnew(HBoxContainer); + mc->add_child(hb); + + open_config_button = memnew(Button); + open_config_button->set_text("Configure"); + open_config_button->connect("pressed", callable_mp(this, &InputEventConfigContainer::_configure_pressed)); + hb->add_child(open_config_button); + + input_event_text = memnew(Label); + hb->add_child(input_event_text); + + config_dialog = memnew(InputEventConfigurationDialog); + config_dialog->connect("confirmed", callable_mp(this, &InputEventConfigContainer::_config_dialog_confirmed)); + add_child(config_dialog); +} + +bool EditorInspectorPluginInputEvent::can_handle(Object *p_object) { + Ref<InputEventKey> k = Ref<InputEventKey>(p_object); + Ref<InputEventMouseButton> m = Ref<InputEventMouseButton>(p_object); + Ref<InputEventJoypadButton> jb = Ref<InputEventJoypadButton>(p_object); + Ref<InputEventJoypadMotion> jm = Ref<InputEventJoypadMotion>(p_object); + + return k.is_valid() || m.is_valid() || jb.is_valid() || jm.is_valid(); +} + +void EditorInspectorPluginInputEvent::parse_begin(Object *p_object) { + Ref<InputEvent> ie = Ref<InputEvent>(p_object); + + InputEventConfigContainer *picker_controls = memnew(InputEventConfigContainer); + picker_controls->set_event(ie); + add_custom_control(picker_controls); +} + +InputEventEditorPlugin::InputEventEditorPlugin(EditorNode *p_node) { + Ref<EditorInspectorPluginInputEvent> plugin; + plugin.instantiate(); + add_inspector_plugin(plugin); +} diff --git a/editor/plugins/input_event_editor_plugin.h b/editor/plugins/input_event_editor_plugin.h new file mode 100644 index 0000000000..bc8293c9e5 --- /dev/null +++ b/editor/plugins/input_event_editor_plugin.h @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* input_event_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef INPUT_EVENT_EDITOR_PLUGIN_H +#define INPUT_EVENT_EDITOR_PLUGIN_H + +#include "editor/action_map_editor.h" +#include "editor/editor_inspector.h" +#include "editor/editor_node.h" + +class InputEventConfigContainer : public HBoxContainer { + GDCLASS(InputEventConfigContainer, HBoxContainer); + + Label *input_event_text; + Button *open_config_button; + + Ref<InputEvent> input_event; + InputEventConfigurationDialog *config_dialog; + + void _config_dialog_confirmed(); + void _configure_pressed(); + + void _event_changed(); + +protected: + static void _bind_methods(); + +public: + virtual Size2 get_minimum_size() const override; + void set_event(const Ref<InputEvent> &p_event); + + InputEventConfigContainer(); +}; + +class EditorInspectorPluginInputEvent : public EditorInspectorPlugin { + GDCLASS(EditorInspectorPluginInputEvent, EditorInspectorPlugin); + +public: + virtual bool can_handle(Object *p_object) override; + virtual void parse_begin(Object *p_object) override; +}; + +class InputEventEditorPlugin : public EditorPlugin { + GDCLASS(InputEventEditorPlugin, EditorPlugin); + +public: + virtual String get_name() const override { return "InputEvent"; } + + InputEventEditorPlugin(EditorNode *p_node); +}; + +#endif // INPUT_EVENT_EDITOR_PLUGIN_H diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 5a4d79cdc8..98a36307b8 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1967,6 +1967,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { return; } + if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_numpad")) { + const uint32_t code = k->get_keycode(); + if (code >= KEY_0 && code <= KEY_9) { + k->set_keycode(code - KEY_0 + KEY_KP_0); + } + } + if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) { if (_edit.mode != TRANSFORM_NONE) { _edit.snap = !_edit.snap; @@ -3250,14 +3257,12 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) { if (!preview) { preview_camera->hide(); } - view_menu->set_disabled(false); surface->update(); } else { previewing = preview; previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace - view_menu->set_disabled(true); surface->update(); } } @@ -3504,7 +3509,6 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) { previewing = Object::cast_to<Camera3D>(pv); previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), previewing->get_camera()); //replace - view_menu->set_disabled(true); surface->update(); preview_camera->set_pressed(true); preview_camera->show(); diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp index a7c11f8521..488aa8c861 100644 --- a/editor/plugins/resource_preloader_editor_plugin.cpp +++ b/editor/plugins/resource_preloader_editor_plugin.cpp @@ -367,8 +367,10 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() { tree = memnew(Tree); tree->connect("button_pressed", callable_mp(this, &ResourcePreloaderEditor::_cell_button_pressed)); tree->set_columns(2); - tree->set_column_custom_minimum_width(0, 2); - tree->set_column_custom_minimum_width(1, 3); + tree->set_column_expand_ratio(0, 2); + tree->set_column_clip_content(0, true); + tree->set_column_expand_ratio(1, 3); + tree->set_column_clip_content(1, true); tree->set_column_expand(0, true); tree->set_column_expand(1, true); tree->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 99d7267eac..be1aeb309f 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -930,11 +930,14 @@ ThemeItemImportTree::ThemeItemImportTree() { import_items_tree->set_column_title(IMPORT_ITEM, TTR("Import")); import_items_tree->set_column_title(IMPORT_ITEM_DATA, TTR("With Data")); import_items_tree->set_column_expand(0, true); + import_items_tree->set_column_clip_content(0, true); import_items_tree->set_column_expand(IMPORT_ITEM, false); import_items_tree->set_column_expand(IMPORT_ITEM_DATA, false); import_items_tree->set_column_custom_minimum_width(0, 160 * EDSCALE); import_items_tree->set_column_custom_minimum_width(IMPORT_ITEM, 80 * EDSCALE); import_items_tree->set_column_custom_minimum_width(IMPORT_ITEM_DATA, 80 * EDSCALE); + import_items_tree->set_column_clip_content(1, true); + import_items_tree->set_column_clip_content(2, true); ScrollContainer *import_bulk_sc = memnew(ScrollContainer); import_bulk_sc->set_custom_minimum_size(Size2(260.0, 0.0) * EDSCALE); diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index 4f696f2a39..477bc9f74d 100644 --- a/modules/gdnative/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp @@ -405,7 +405,7 @@ List<ClassAPI> generate_c_api_classes() { arg_type = Variant::get_type_name(arg_info.type); } } else { - arg_type = Variant::get_type_name(arg_info.type); + arg_type = get_type_name(arg_info); } method_api.argument_names.push_back(arg_name); diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 309abfbff7..8e441e7e07 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -101,12 +101,6 @@ def configure(env, env_mono): mono_lib_names = ["mono-2.0-sgen", "monosgen-2.0"] - is_travis = os.environ.get("TRAVIS") == "true" - - if is_travis: - # Travis CI may have a Mono version lower than 5.12 - env_mono.Append(CPPDEFINES=["NO_PENDING_EXCEPTIONS"]) - if is_android and not env["android_arch"] in android_arch_dirs: raise RuntimeError("This module does not support the specified 'android_arch': " + env["android_arch"]) diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp index ccdb6e9292..c889562732 100644 --- a/modules/websocket/wsl_server.cpp +++ b/modules/websocket/wsl_server.cpp @@ -97,26 +97,31 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) { Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uint64_t p_timeout) { if (OS::get_singleton()->get_ticks_msec() - time > p_timeout) { + print_verbose(vformat("WebSocket handshake timed out after %.3f seconds.", p_timeout * 0.001)); return ERR_TIMEOUT; } + if (use_ssl) { Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL>>(connection); if (ssl.is_null()) { - return FAILED; + ERR_FAIL_V_MSG(ERR_BUG, "Couldn't get StreamPeerSSL for WebSocket handshake."); } ssl->poll(); if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) { return ERR_BUSY; } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) { + print_verbose(vformat("WebSocket SSL connection error during handshake (StreamPeerSSL status code %d).", ssl->get_status())); return FAILED; } } + if (!has_request) { int read = 0; while (true) { - ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "Response headers too big."); + ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "WebSocket response headers are too big."); Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); if (err != OK) { // Got an error + print_verbose(vformat("WebSocket error while getting partial data (StreamPeer error code %d).", err)); return FAILED; } else if (read != 1) { // Busy, wait next poll return ERR_BUSY; @@ -143,17 +148,21 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols, uin req_pos += 1; } } + if (has_request && response_sent < response.size() - 1) { int sent = 0; Error err = connection->put_partial_data((const uint8_t *)response.get_data() + response_sent, response.size() - response_sent - 1, sent); if (err != OK) { + print_verbose(vformat("WebSocket error while putting partial data (StreamPeer error code %d).", err)); return err; } response_sent += sent; } + if (response_sent < response.size() - 1) { return ERR_BUSY; } + return OK; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index d66d7fde4b..1fab47e764 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -279,29 +279,20 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC editText.setView(mRenderView); io.setEdit(editText); - view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - Point fullSize = new Point(); - activity.getWindowManager().getDefaultDisplay().getSize(fullSize); - Rect gameSize = new Rect(); - mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); - - final int keyboardHeight = fullSize.y - gameSize.bottom; - GodotLib.setVirtualKeyboardHeight(keyboardHeight); - } + view.getViewTreeObserver().addOnGlobalLayoutListener(() -> { + Point fullSize = new Point(); + activity.getWindowManager().getDefaultDisplay().getSize(fullSize); + Rect gameSize = new Rect(); + mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); + final int keyboardHeight = fullSize.y - gameSize.bottom; + GodotLib.setVirtualKeyboardHeight(keyboardHeight); }); - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - // Must occur after GodotLib.setup has completed. - for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { - plugin.onRegisterPluginWithGodotNative(); - } - - setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on"))); + mRenderView.queueOnRenderThread(() -> { + for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { + plugin.onRegisterPluginWithGodotNative(); } + setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on"))); }); // Include the returned non-null views in the Godot view hierarchy. @@ -314,14 +305,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } public void setKeepScreenOn(final boolean p_enabled) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (p_enabled) { - getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } else { - getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } + runOnUiThread(() -> { + if (p_enabled) { + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } else { + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } }); } @@ -368,21 +356,14 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC public void alert(final String message, final String title) { final Activity activity = getActivity(); - runOnUiThread(new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setMessage(message).setTitle(title); - builder.setPositiveButton( - "OK", - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } + runOnUiThread(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setMessage(message).setTitle(title); + builder.setPositiveButton( + "OK", + (dialog, id) -> dialog.cancel()); + AlertDialog dialog = builder.create(); + dialog.show(); }); } @@ -753,19 +734,16 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC public void UiChangeListener() { final View decorView = getActivity().getWindow().getDecorView(); - decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { - @Override - public void onSystemUiVisibilityChange(int visibility) { - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - decorView.setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_FULLSCREEN | - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - } + decorView.setOnSystemUiVisibilityChangeListener(visibility -> { + if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + decorView.setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_FULLSCREEN | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } } }); @@ -796,21 +774,18 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC final int typeOfSensor = event.sensor.getType(); if (mRenderView != null) { - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { - GodotLib.accelerometer(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_GRAVITY) { - GodotLib.gravity(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { - GodotLib.magnetometer(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { - GodotLib.gyroscope(x, -y, z); - } + mRenderView.queueOnRenderThread(() -> { + if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { + GodotLib.accelerometer(-x, y, -z); + } + if (typeOfSensor == Sensor.TYPE_GRAVITY) { + GodotLib.gravity(-x, y, -z); + } + if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { + GodotLib.magnetometer(-x, y, -z); + } + if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { + GodotLib.gyroscope(x, -y, z); } }); } @@ -845,12 +820,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC } if (shouldQuit && mRenderView != null) { - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - GodotLib.back(); - } - }); + mRenderView.queueOnRenderThread(GodotLib::back); } } @@ -927,16 +897,14 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC ; if (cnt == 0) return false; - mRenderView.queueOnRenderThread(new Runnable() { - // This method will be called on the rendering thread: - public void run() { - for (int i = 0, n = cc.length; i < n; i++) { - int keyCode; - if ((keyCode = cc[i]) != 0) { - // Simulate key down and up... - GodotLib.key(0, 0, keyCode, true); - GodotLib.key(0, 0, keyCode, false); - } + // This method will be called on the rendering thread: + mRenderView.queueOnRenderThread(() -> { + for (int i = 0, n = cc.length; i < n; i++) { + int keyCode; + if ((keyCode = cc[i]) != 0) { + // Simulate key down and up... + GodotLib.key(0, 0, keyCode, true); + GodotLib.key(0, 0, keyCode, false); } } }); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index b3ee55ea64..a9d45c943b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -232,13 +232,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView public void onResume() { super.onResume(); - queueEvent(new Runnable() { - @Override - public void run() { - // Resume the renderer - godotRenderer.onActivityResumed(); - GodotLib.focusin(); - } + queueEvent(() -> { + // Resume the renderer + godotRenderer.onActivityResumed(); + GodotLib.focusin(); }); } @@ -246,13 +243,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView public void onPause() { super.onPause(); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.focusout(); - // Pause the renderer - godotRenderer.onActivityPaused(); - } + queueEvent(() -> { + GodotLib.focusout(); + // Pause the renderer + godotRenderer.onActivityPaused(); }); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 071872dff8..66882e8e72 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -71,7 +71,7 @@ public class GodotIO { public int last_file_id = 1; - class AssetData { + static class AssetData { public boolean eof = false; public String path; public InputStream is; @@ -230,7 +230,7 @@ public class GodotIO { /// DIRECTORIES ///////////////////////// - class AssetDir { + static class AssetDir { public String[] files; public int current; public String path; diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java index 356ad7c770..6fca7f2a57 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -149,13 +149,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV public void onResume() { super.onResume(); - queueOnVkThread(new Runnable() { - @Override - public void run() { - // Resume the renderer - mRenderer.onVkResume(); - GodotLib.focusin(); - } + queueOnVkThread(() -> { + // Resume the renderer + mRenderer.onVkResume(); + GodotLib.focusin(); }); } @@ -163,13 +160,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV public void onPause() { super.onPause(); - queueOnVkThread(new Runnable() { - @Override - public void run() { - GodotLib.focusout(); - // Pause the renderer - mRenderer.onVkPause(); - } + queueOnVkThread(() -> { + GodotLib.focusout(); + // Pause the renderer + mRenderer.onVkPause(); }); } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index 2c39d06832..1d60c21c60 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -75,12 +75,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener final int x = Math.round(event.getX()); final int y = Math.round(event.getY()); final int buttonMask = event.getButtonState(); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.doubleTap(buttonMask, x, y); - } - }); + queueEvent(() -> GodotLib.doubleTap(buttonMask, x, y)); return true; } @@ -89,12 +84,7 @@ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener //Log.i("GodotGesture", "onScroll"); final int x = Math.round(distanceX); final int y = Math.round(distanceY); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.scroll(x, y); - } - }); + queueEvent(() -> GodotLib.scroll(x, y)); return true; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index e8dcc5a4bc..4dc9157545 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -97,22 +97,12 @@ public class GodotInputHandler implements InputDeviceListener { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joybutton(godotJoyId, button, false); - } - }); + queueEvent(() -> GodotLib.joybutton(godotJoyId, button, false)); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.key(keyCode, scanCode, chr, false); - } - }); + queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, false)); } return true; @@ -143,22 +133,12 @@ public class GodotInputHandler implements InputDeviceListener { final int button = getGodotButton(keyCode); final int godotJoyId = mJoystickIds.get(deviceId); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joybutton(godotJoyId, button, true); - } - }); + queueEvent(() -> GodotLib.joybutton(godotJoyId, button, true)); } } else { final int scanCode = event.getScanCode(); final int chr = event.getUnicodeChar(0); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.key(keyCode, scanCode, chr, true); - } - }); + queueEvent(() -> GodotLib.key(keyCode, scanCode, chr, true)); } return true; @@ -190,19 +170,16 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getActionMasked(); final int pointer_idx = event.getPointerId(event.getActionIndex()); - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_MOVE: - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_POINTER_DOWN: { - GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); - } break; - } + mRenderView.queueOnRenderThread(() -> { + switch (action) { + case MotionEvent.ACTION_DOWN: + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_MOVE: + case MotionEvent.ACTION_POINTER_UP: + case MotionEvent.ACTION_POINTER_DOWN: { + GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); + } break; } }); } @@ -228,13 +205,7 @@ public class GodotInputHandler implements InputDeviceListener { // save value to prevent repeats joystick.axesValues.put(axis, value); final int godotAxisIdx = i; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyaxis(godotJoyId, godotAxisIdx, value); - //Log.i(tag, "GodotLib.joyaxis("+godotJoyId+", "+godotAxisIdx+", "+value+");"); - } - }); + queueEvent(() -> GodotLib.joyaxis(godotJoyId, godotAxisIdx, value)); } } @@ -244,13 +215,7 @@ public class GodotInputHandler implements InputDeviceListener { if (joystick.hatX != hatX || joystick.hatY != hatY) { joystick.hatX = hatX; joystick.hatY = hatY; - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyhat(godotJoyId, hatX, hatY); - //Log.i(tag, "GodotLib.joyhat("+godotJoyId+", "+hatX+", "+hatY+");"); - } - }); + queueEvent(() -> GodotLib.joyhat(godotJoyId, hatX, hatY)); } } return true; @@ -259,12 +224,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.hover(type, x, y); - } - }); + queueEvent(() -> GodotLib.hover(type, x, y)); return true; } else if (event.isFromSource(InputDevice.SOURCE_MOUSE) || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)) { @@ -356,12 +316,7 @@ public class GodotInputHandler implements InputDeviceListener { } mJoysticksDevices.put(deviceId, joystick); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(id, true, joystick.name); - } - }); + queueEvent(() -> GodotLib.joyconnectionchanged(id, true, joystick.name)); } @Override @@ -374,12 +329,7 @@ public class GodotInputHandler implements InputDeviceListener { mJoystickIds.delete(deviceId); mJoysticksDevices.delete(deviceId); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.joyconnectionchanged(godotJoyId, false, ""); - } - }); + queueEvent(() -> GodotLib.joyconnectionchanged(godotJoyId, false, "")); } @Override @@ -468,12 +418,7 @@ public class GodotInputHandler implements InputDeviceListener { final float x = event.getX(); final float y = event.getY(); final int type = event.getAction(); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.hover(type, x, y); - } - }); + queueEvent(() -> GodotLib.hover(type, x, y)); return true; } case MotionEvent.ACTION_BUTTON_PRESS: @@ -483,12 +428,7 @@ public class GodotInputHandler implements InputDeviceListener { final float y = event.getY(); final int buttonsMask = event.getButtonState(); final int action = event.getAction(); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask); - } - }); + queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask)); return true; } case MotionEvent.ACTION_SCROLL: { @@ -498,12 +438,7 @@ public class GodotInputHandler implements InputDeviceListener { final int action = event.getAction(); final float verticalFactor = event.getAxisValue(MotionEvent.AXIS_VSCROLL); final float horizontalFactor = event.getAxisValue(MotionEvent.AXIS_HSCROLL); - queueEvent(new Runnable() { - @Override - public void run() { - GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor); - } - }); + queueEvent(() -> GodotLib.touch(event.getSource(), action, 0, 1, new float[] { 0, x, y }, buttonsMask, verticalFactor, horizontalFactor)); } case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: { diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 3e0e6a65fd..f7a3380a93 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -94,17 +94,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void beforeTextChanged(final CharSequence pCharSequence, final int start, final int count, final int after) { //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - for (int i = 0; i < count; ++i) { - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); - - if (mHasSelection) { - mHasSelection = false; - break; - } + mRenderView.queueOnRenderThread(() -> { + for (int i = 0; i < count; ++i) { + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); + + if (mHasSelection) { + mHasSelection = false; + break; } } }); @@ -118,18 +115,15 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = start; i < start + count; ++i) { newChars[i - start] = pCharSequence.charAt(i); } - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - for (int i = 0; i < count; ++i) { - int key = newChars[i]; - if ((key == '\n') && !mEdit.isMultiline()) { - // Return keys are handled through action events - continue; - } - GodotLib.key(0, 0, key, true); - GodotLib.key(0, 0, key, false); + mRenderView.queueOnRenderThread(() -> { + for (int i = 0; i < count; ++i) { + int key = newChars[i]; + if ((key == '\n') && !mEdit.isMultiline()) { + // Return keys are handled through action events + continue; } + GodotLib.key(0, 0, key, true); + GodotLib.key(0, 0, key, false); } }); } @@ -139,14 +133,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene if (mEdit == pTextView && isFullScreenEdit()) { final String characters = pKeyEvent.getCharacters(); - mRenderView.queueOnRenderThread(new Runnable() { - @Override - public void run() { - for (int i = 0; i < characters.length(); i++) { - final int ch = characters.codePointAt(i); - GodotLib.key(0, 0, ch, true); - GodotLib.key(0, 0, ch, false); - } + mRenderView.queueOnRenderThread(() -> { + for (int i = 0; i < characters.length(); i++) { + final int ch = characters.codePointAt(i); + GodotLib.key(0, 0, ch, true); + GodotLib.key(0, 0, ch, false); } }); } diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index c956fe49ae..56d673afc3 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -634,13 +634,13 @@ String OS_Windows::get_config_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. if (has_environment("XDG_CONFIG_HOME")) { if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) { - return get_environment("XDG_CONFIG_HOME"); + return get_environment("XDG_CONFIG_HOME").replace("\\", "/"); } else { WARN_PRINT_ONCE("`XDG_CONFIG_HOME` is a relative path. Ignoring its value and falling back to `%APPDATA%` or `.` per the XDG Base Directory specification."); } } if (has_environment("APPDATA")) { - return get_environment("APPDATA"); + return get_environment("APPDATA").replace("\\", "/"); } return "."; } @@ -649,7 +649,7 @@ String OS_Windows::get_data_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. if (has_environment("XDG_DATA_HOME")) { if (get_environment("XDG_DATA_HOME").is_absolute_path()) { - return get_environment("XDG_DATA_HOME"); + return get_environment("XDG_DATA_HOME").replace("\\", "/"); } else { WARN_PRINT_ONCE("`XDG_DATA_HOME` is a relative path. Ignoring its value and falling back to `get_config_path()` per the XDG Base Directory specification."); } @@ -661,13 +661,13 @@ String OS_Windows::get_cache_path() const { // The XDG Base Directory specification technically only applies on Linux/*BSD, but it doesn't hurt to support it on Windows as well. if (has_environment("XDG_CACHE_HOME")) { if (get_environment("XDG_CACHE_HOME").is_absolute_path()) { - return get_environment("XDG_CACHE_HOME"); + return get_environment("XDG_CACHE_HOME").replace("\\", "/"); } else { WARN_PRINT_ONCE("`XDG_CACHE_HOME` is a relative path. Ignoring its value and falling back to `%TEMP%` or `get_config_path()` per the XDG Base Directory specification."); } } if (has_environment("TEMP")) { - return get_environment("TEMP"); + return get_environment("TEMP").replace("\\", "/"); } return get_config_path(); } @@ -710,7 +710,7 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const { PWSTR szPath; HRESULT res = SHGetKnownFolderPath(id, 0, nullptr, &szPath); ERR_FAIL_COND_V(res != S_OK, String()); - String path = String::utf16((const char16_t *)szPath); + String path = String::utf16((const char16_t *)szPath).replace("\\", "/"); CoTaskMemFree(szPath); return path; } diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index c1f3827d15..8cab7ca521 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -108,47 +108,47 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); switch (p_type) { case ERR_ERROR: - logf("ERROR:"); + logf_error("ERROR:"); break; case ERR_WARNING: - logf("WARNING:"); + logf_error("WARNING:"); break; case ERR_SCRIPT: - logf("SCRIPT ERROR:"); + logf_error("SCRIPT ERROR:"); break; case ERR_SHADER: - logf("SHADER ERROR:"); + logf_error("SHADER ERROR:"); break; } SetConsoleTextAttribute(hCon, basecol); if (p_rationale && p_rationale[0]) { - logf(" %s\n", p_rationale); + logf_error(" %s\n", p_rationale); } else { - logf(" %s\n", p_code); + logf_error(" %s\n", p_code); } // `FOREGROUND_INTENSITY` alone results in gray text. SetConsoleTextAttribute(hCon, FOREGROUND_INTENSITY); switch (p_type) { case ERR_ERROR: - logf(" at: "); + logf_error(" at: "); break; case ERR_WARNING: - logf(" at: "); + logf_error(" at: "); break; case ERR_SCRIPT: - logf(" at: "); + logf_error(" at: "); break; case ERR_SHADER: - logf(" at: "); + logf_error(" at: "); break; } if (p_rationale && p_rationale[0]) { - logf("(%s:%i)\n", p_file, p_line); + logf_error("(%s:%i)\n", p_file, p_line); } else { - logf("%s (%s:%i)\n", p_function, p_file, p_line); + logf_error("%s (%s:%i)\n", p_function, p_file, p_line); } SetConsoleTextAttribute(hCon, sbi.wAttributes); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 089893e63b..f2d0d9bb22 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1470,19 +1470,23 @@ int LineEdit::get_scroll_offset() const { } void LineEdit::insert_text_at_caret(String p_text) { - if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { - String pre = text.substr(0, caret_column); - String post = text.substr(caret_column, text.length() - caret_column); - text = pre + p_text + post; - _shape(); - TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length()); - if (dir != TextServer::DIRECTION_AUTO) { - input_direction = (TextDirection)dir; + if (max_length > 0) { + // Truncate text to append to fit in max_length, if needed. + int available_chars = max_length - text.length(); + if (p_text.length() > available_chars) { + emit_signal("text_change_rejected", p_text.substr(available_chars)); + p_text = p_text.substr(0, available_chars); } - set_caret_column(caret_column + p_text.length()); - } else { - emit_signal("text_change_rejected"); } + String pre = text.substr(0, caret_column); + String post = text.substr(caret_column, text.length() - caret_column); + text = pre + p_text + post; + _shape(); + TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length()); + if (dir != TextServer::DIRECTION_AUTO) { + input_direction = (TextDirection)dir; + } + set_caret_column(caret_column + p_text.length()); } void LineEdit::clear_internal() { @@ -2158,7 +2162,7 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon); ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text"))); - ADD_SIGNAL(MethodInfo("text_change_rejected")); + ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring"))); ADD_SIGNAL(MethodInfo("text_submitted", PropertyInfo(Variant::STRING, "new_text"))); BIND_ENUM_CONSTANT(ALIGN_LEFT); @@ -2198,7 +2202,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character"); @@ -2221,7 +2225,7 @@ void LineEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column"), "set_caret_column", "get_caret_column"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_caret_column", "get_caret_column"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled"); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 370fdd8b88..6f96b530a6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4008,14 +4008,6 @@ bool TextEdit::is_wrap_enabled() const { return wrap_enabled; } -void TextEdit::set_max_chars(int p_max_chars) { - max_chars = p_max_chars; -} - -int TextEdit::get_max_chars() const { - return max_chars; -} - void TextEdit::_reset_caret_blink_timer() { if (caret_blink_enabled) { draw_caret = true; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 146de50275..dcd5c6d0f8 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -258,7 +258,6 @@ private: uint32_t version = 0; uint32_t saved_version = 0; - int max_chars = 0; bool readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly. Timer *caret_blink_timer; @@ -678,9 +677,6 @@ public: void set_readonly(bool p_readonly); bool is_readonly() const; - void set_max_chars(int p_max_chars); - int get_max_chars() const; - void set_wrap_enabled(bool p_wrap_enabled); bool is_wrap_enabled() const; bool line_wraps(int line) const; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index aac15cd9a5..fd9e87604f 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -975,6 +975,9 @@ Size2 TreeItem::get_minimum_size(int p_column) { } // Icon. + if (cell.mode == CELL_MODE_CHECK) { + size.width += tree->cache.checked->get_width() + tree->cache.hseparation; + } if (cell.icon.is_valid()) { Size2i icon_size = cell.get_icon_size(); if (cell.icon_max_w > 0 && icon_size.width > cell.icon_max_w) { @@ -1249,6 +1252,9 @@ void Tree::update_cache() { cache.item_margin = get_theme_constant("item_margin"); cache.button_margin = get_theme_constant("button_margin"); + cache.font_outline_color = get_theme_color("font_outline_color"); + cache.font_outline_size = get_theme_constant("outline_size"); + cache.draw_guides = get_theme_constant("draw_guides"); cache.guide_color = get_theme_color("guide_color"); cache.draw_relationship_lines = get_theme_constant("draw_relationship_lines"); @@ -1510,7 +1516,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int htotal = 0; int label_h = compute_item_height(p_item); - bool rtl = is_layout_rtl(); + bool rtl = cache.rtl; /* Calculate height of the label part */ label_h += cache.vseparation; @@ -1556,6 +1562,20 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } } + if (!rtl && p_item->cells[i].buttons.size()) { + int button_w = 0; + for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { + Ref<Texture2D> b = p_item->cells[i].buttons[j].texture; + button_w += b->get_size().width + cache.button_pressed->get_minimum_size().width + cache.button_margin; + } + + int total_ofs = ofs - cache.offset.x; + + if (total_ofs + w > p_draw_size.width) { + w = MAX(button_w, p_draw_size.width - total_ofs); + } + } + int bw = 0; for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = p_item->cells[i].buttons[j].texture; @@ -1680,8 +1700,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 } Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_theme_color(p_item->cells[i].selected ? "font_selected_color" : "font_color"); - Color font_outline_color = get_theme_color("font_outline_color"); - int outline_size = get_theme_constant("outline_size"); + Color font_outline_color = cache.font_outline_color; + int outline_size = cache.font_outline_size; Color icon_col = p_item->cells[i].icon_color; if (p_item->cells[i].dirty) { @@ -2139,9 +2159,16 @@ void Tree::_range_click_timeout() { Ref<InputEventMouseButton> mb; mb.instantiate(); + int x_limit = get_size().width - cache.bg->get_minimum_size().width; + if (h_scroll->is_visible()) { + x_limit -= h_scroll->get_minimum_size().width; + } + + cache.rtl = is_layout_rtl(); + propagate_mouse_activated = false; // done from outside, so signal handler can't clear the tree in the middle of emit (which is a common case) blocked++; - propagate_mouse_event(pos + cache.offset, 0, 0, false, root, MOUSE_BUTTON_LEFT, mb); + propagate_mouse_event(pos + cache.offset, 0, 0, x_limit + cache.offset.width, false, root, MOUSE_BUTTON_LEFT, mb); blocked--; if (range_click_timer->is_one_shot()) { @@ -2164,7 +2191,7 @@ void Tree::_range_click_timeout() { } } -int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) { +int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int x_limit, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) { int item_h = compute_item_height(p_item) + cache.vseparation; bool skip = (p_item == root && hide_root); @@ -2189,6 +2216,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool int col = -1; int col_ofs = 0; int col_width = 0; + + int limit_w = x_limit; + for (int i = 0; i < columns.size(); i++) { col_width = get_column_width(i); @@ -2204,6 +2234,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool if (x > col_width) { col_ofs += col_width; x -= col_width; + limit_w -= col_width; continue; } @@ -2217,10 +2248,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool int margin = x_ofs + cache.item_margin; //-cache.hseparation; //int lm = cache.bg->get_margin(SIDE_LEFT); col_width -= margin; + limit_w -= margin; col_ofs += margin; x -= margin; } else { col_width -= cache.hseparation; + limit_w -= cache.hseparation; x -= cache.hseparation; } @@ -2234,6 +2267,16 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool bool already_selected = c.selected; bool already_cursor = (p_item == selected_item) && col == selected_col; + if (!cache.rtl && p_item->cells[col].buttons.size()) { + int button_w = 0; + for (int j = p_item->cells[col].buttons.size() - 1; j >= 0; j--) { + Ref<Texture2D> b = p_item->cells[col].buttons[j].texture; + button_w += b->get_size().width + cache.button_pressed->get_minimum_size().width + cache.button_margin; + } + + col_width = MAX(button_w, MIN(limit_w, col_width)); + } + for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture2D> b = c.buttons[j].texture; int w = b->get_size().width + cache.button_pressed->get_minimum_size().width; @@ -2255,6 +2298,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool //emit_signal("button_pressed"); return -1; } + col_width -= w + cache.button_margin; } @@ -2465,7 +2509,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool TreeItem *c = p_item->first_child; while (c) { - int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, p_double_click, c, p_button, p_mod); + int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, x_limit, p_double_click, c, p_button, p_mod); if (child_h < 0) { return -1; // break, stop propagating, no need to anymore @@ -3143,8 +3187,14 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { pressing_for_editor = false; propagate_mouse_activated = false; + int x_limit = get_size().width - cache.bg->get_minimum_size().width; + if (h_scroll->is_visible()) { + x_limit -= h_scroll->get_minimum_size().width; + } + + cache.rtl = is_layout_rtl(); blocked++; - propagate_mouse_event(pos + cache.offset, 0, 0, b->is_double_click(), root, b->get_button_index(), b); + propagate_mouse_event(pos + cache.offset, 0, 0, x_limit + cache.offset.width, b->is_double_click(), root, b->get_button_index(), b); blocked--; if (pressing_for_editor) { @@ -3496,6 +3546,9 @@ void Tree::_notification(int p_what) { Point2 draw_ofs; draw_ofs += bg->get_offset(); Size2 draw_size = get_size() - bg->get_minimum_size(); + if (h_scroll->is_visible()) { + draw_size.width -= h_scroll->get_minimum_size().width; + } bg->draw(ci, Rect2(Point2(), get_size())); @@ -3504,6 +3557,8 @@ void Tree::_notification(int p_what) { draw_ofs.y += tbh; draw_size.y -= tbh; + cache.rtl = is_layout_rtl(); + if (root && get_size().x > 0 && get_size().y > 0) { draw_item(Point2(), draw_ofs, draw_size, root); } @@ -3515,7 +3570,7 @@ void Tree::_notification(int p_what) { Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? cache.title_button_hover : cache.title_button); Ref<Font> f = cache.tb_font; Rect2 tbrect = Rect2(ofs2 - cache.offset.x, bg->get_margin(SIDE_TOP), get_column_width(i), tbh); - if (is_layout_rtl()) { + if (cache.rtl) { tbrect.position.x = get_size().width - tbrect.size.x - tbrect.position.x; } sb->draw(ci, tbrect); @@ -3761,6 +3816,36 @@ void Tree::set_column_expand(int p_column, bool p_expand) { update(); } +void Tree::set_column_expand_ratio(int p_column, int p_ratio) { + ERR_FAIL_INDEX(p_column, columns.size()); + columns.write[p_column].expand_ratio = p_ratio; + update(); +} + +void Tree::set_column_clip_content(int p_column, bool p_fit) { + ERR_FAIL_INDEX(p_column, columns.size()); + + columns.write[p_column].clip_content = p_fit; + update(); +} + +bool Tree::is_column_expanding(int p_column) const { + ERR_FAIL_INDEX_V(p_column, columns.size(), false); + + return columns[p_column].expand; +} +int Tree::get_column_expand_ratio(int p_column) const { + ERR_FAIL_INDEX_V(p_column, columns.size(), 1); + + return columns[p_column].expand_ratio; +} + +bool Tree::is_column_clipping_content(int p_column) const { + ERR_FAIL_INDEX_V(p_column, columns.size(), false); + + return columns[p_column].clip_content; +} + TreeItem *Tree::get_selected() const { return selected_item; } @@ -3820,11 +3905,14 @@ TreeItem *Tree::get_next_selected(TreeItem *p_item) { int Tree::get_column_minimum_width(int p_column) const { ERR_FAIL_INDEX_V(p_column, columns.size(), -1); - if (columns[p_column].custom_min_width != 0) { - return columns[p_column].custom_min_width; - } else { + int min_width = columns[p_column].custom_min_width; + + if (show_column_titles) { + min_width = MAX(cache.font->get_string_size(columns[p_column].title).width, min_width); + } + + if (!columns[p_column].clip_content) { int depth = 0; - int min_width = 0; TreeItem *next; for (TreeItem *item = get_root(); item; item = next) { next = item->get_next_visible(); @@ -3848,13 +3936,16 @@ int Tree::get_column_minimum_width(int p_column) const { } min_width = MAX(min_width, item_size.width); } - return min_width; } + + return min_width; } int Tree::get_column_width(int p_column) const { ERR_FAIL_INDEX_V(p_column, columns.size(), -1); + int column_width = get_column_minimum_width(p_column); + if (columns[p_column].expand) { int expand_area = get_size().width; @@ -3868,31 +3959,24 @@ int Tree::get_column_width(int p_column) const { expand_area -= v_scroll->get_combined_minimum_size().width; } - int expanding_columns = 0; int expanding_total = 0; for (int i = 0; i < columns.size(); i++) { - if (!columns[i].expand) { - expand_area -= get_column_minimum_width(i); - } else { - expanding_total += get_column_minimum_width(i); - expanding_columns++; + expand_area -= get_column_minimum_width(i); + if (columns[i].expand) { + expanding_total += columns[i].expand_ratio; } } - if (expand_area < expanding_total) { - return get_column_minimum_width(p_column); + if (expand_area >= expanding_total && expanding_total > 0) { + column_width += expand_area * columns[p_column].expand_ratio / expanding_total; } + } - ERR_FAIL_COND_V(expanding_columns == 0, -1); // shouldn't happen - if (expanding_total == 0) { - return 0; - } else { - return expand_area * get_column_minimum_width(p_column) / expanding_total; - } - } else { - return get_column_minimum_width(p_column); + if (p_column < columns.size() - 1) { + column_width += cache.hseparation; } + return column_width; } void Tree::propagate_set_columns(TreeItem *p_item) { @@ -4549,6 +4633,12 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_root"), &Tree::get_root); ClassDB::bind_method(D_METHOD("set_column_custom_minimum_width", "column", "min_width"), &Tree::set_column_custom_minimum_width); ClassDB::bind_method(D_METHOD("set_column_expand", "column", "expand"), &Tree::set_column_expand); + ClassDB::bind_method(D_METHOD("set_column_expand_ratio", "column", "ratio"), &Tree::set_column_expand_ratio); + ClassDB::bind_method(D_METHOD("set_column_clip_content", "column", "enable"), &Tree::set_column_clip_content); + ClassDB::bind_method(D_METHOD("is_column_expanding", "column"), &Tree::is_column_expanding); + ClassDB::bind_method(D_METHOD("is_column_clipping_content", "column"), &Tree::is_column_clipping_content); + ClassDB::bind_method(D_METHOD("get_column_expand_ratio", "column"), &Tree::get_column_expand_ratio); + ClassDB::bind_method(D_METHOD("get_column_width", "column"), &Tree::get_column_width); ClassDB::bind_method(D_METHOD("set_hide_root", "enable"), &Tree::set_hide_root); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index fd5fcd7838..10e6642303 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -411,7 +411,9 @@ private: struct ColumnInfo { int custom_min_width = 0; + int expand_ratio = 1; bool expand = true; + bool clip_content = false; String title; Ref<TextLine> text_buf; Dictionary opentype_features; @@ -450,7 +452,7 @@ private: void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color); int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item); void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = nullptr, bool *r_in_range = nullptr, bool p_force_deselect = false); - int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod); + int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int x_limit, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod); void _text_editor_submit(String p_text); void _text_editor_modal_close(); void value_editor_changed(double p_value); @@ -504,6 +506,7 @@ private: Color parent_hl_line_color; Color children_hl_line_color; Color custom_button_font_highlight; + Color font_outline_color; int hseparation = 0; int vseparation = 0; @@ -518,6 +521,7 @@ private: int draw_guides = 0; int scroll_border = 0; int scroll_speed = 0; + int font_outline_size = 0; enum ClickType { CLICK_NONE, @@ -540,6 +544,8 @@ private: Point2i text_editor_position; + bool rtl = false; + } cache; int _get_title_button_height() const; @@ -547,6 +553,7 @@ private: void _scroll_moved(float p_value); HScrollBar *h_scroll; VScrollBar *v_scroll; + bool h_scroll_enabled = true; bool v_scroll_enabled = true; @@ -632,8 +639,14 @@ public: void set_column_custom_minimum_width(int p_column, int p_min_width); void set_column_expand(int p_column, bool p_expand); + void set_column_expand_ratio(int p_column, int p_ratio); + void set_column_clip_content(int p_column, bool p_fit); int get_column_minimum_width(int p_column) const; int get_column_width(int p_column) const; + int get_column_expand_ratio(int p_column) const; + + bool is_column_expanding(int p_column) const; + bool is_column_clipping_content(int p_column) const; void set_hide_root(bool p_enabled); bool is_root_hidden() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 85bd08529c..24a9b12733 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -937,14 +937,12 @@ void register_scene_types() { ClassDB::add_compatibility_class("Physics2DServerSW", "PhysicsServer2DSW"); ClassDB::add_compatibility_class("Physics2DServer", "PhysicsServer2D"); ClassDB::add_compatibility_class("Physics2DShapeQueryParameters", "PhysicsShapeQueryParameters2D"); - ClassDB::add_compatibility_class("Physics2DShapeQueryResult", "PhysicsShapeQueryResult2D"); ClassDB::add_compatibility_class("Physics2DTestMotionResult", "PhysicsTestMotionResult2D"); ClassDB::add_compatibility_class("PhysicsBody", "PhysicsBody3D"); ClassDB::add_compatibility_class("PhysicsDirectBodyState", "PhysicsDirectBodyState3D"); ClassDB::add_compatibility_class("PhysicsDirectSpaceState", "PhysicsDirectSpaceState3D"); ClassDB::add_compatibility_class("PhysicsServer", "PhysicsServer3D"); ClassDB::add_compatibility_class("PhysicsShapeQueryParameters", "PhysicsShapeQueryParameters3D"); - ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D"); ClassDB::add_compatibility_class("PinJoint", "PinJoint3D"); ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D"); ClassDB::add_compatibility_class("ProceduralSky", "Sky"); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index e522ce6774..47c5c3df28 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -345,7 +345,6 @@ void BaseMaterial3D::init_shaders() { shader_names->refraction_texture_channel = "refraction_texture_channel"; shader_names->transmittance_color = "transmittance_color"; - shader_names->transmittance_curve = "transmittance_curve"; shader_names->transmittance_depth = "transmittance_depth"; shader_names->transmittance_boost = "transmittance_boost"; @@ -692,7 +691,6 @@ void BaseMaterial3D::_update_shader() { code += "uniform vec4 transmittance_color : hint_color;\n"; code += "uniform float transmittance_depth;\n"; code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n"; - code += "uniform float transmittance_curve;\n"; code += "uniform float transmittance_boost;\n"; } @@ -1001,9 +999,9 @@ void BaseMaterial3D::_update_shader() { code += "\tSPECULAR = specular;\n"; } else { if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tfloat orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n"; + code += "\tvec4 orm_tex = triplanar_texture(texture_orm,uv1_power_normal,uv1_triplanar_pos);\n"; } else { - code += "\tfloat orm_tex = texture(texture_orm,base_uv);\n"; + code += "\tvec4 orm_tex = texture(texture_orm,base_uv);\n"; } code += "\tROUGHNESS = orm_tex.g;\n"; @@ -1194,7 +1192,6 @@ void BaseMaterial3D::_update_shader() { code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n"; code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n"; - code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n"; code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n"; } @@ -1438,15 +1435,6 @@ float BaseMaterial3D::get_transmittance_depth() const { return transmittance_depth; } -void BaseMaterial3D::set_transmittance_curve(float p_curve) { - transmittance_curve = p_curve; - RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve); -} - -float BaseMaterial3D::get_transmittance_curve() const { - return transmittance_curve; -} - void BaseMaterial3D::set_transmittance_boost(float p_boost) { transmittance_boost = p_boost; RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost); @@ -1765,7 +1753,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NONE; } - if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) { + if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture")) { property.usage = PROPERTY_USAGE_NONE; } @@ -2269,9 +2257,6 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth); ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth); - ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve); - ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve); - ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost); ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost); @@ -2506,7 +2491,6 @@ void BaseMaterial3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost"); ADD_GROUP("Back Lighting", "backlight_"); @@ -2723,7 +2707,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : set_backlight(Color(0, 0, 0)); set_transmittance_color(Color(1, 1, 1, 1)); set_transmittance_depth(0.1); - set_transmittance_curve(1.0); set_transmittance_boost(0.0); set_refraction(0.05); set_point_size(1); diff --git a/scene/resources/material.h b/scene/resources/material.h index cd91d05a60..80e5e94466 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -389,7 +389,6 @@ private: StringName heightmap_scale; StringName subsurface_scattering_strength; StringName transmittance_color; - StringName transmittance_curve; StringName transmittance_depth; StringName transmittance_boost; StringName backlight; @@ -458,7 +457,6 @@ private: float transmittance_amount; Color transmittance_color; float transmittance_depth; - float transmittance_curve; float transmittance_boost; Color backlight; @@ -602,9 +600,6 @@ public: void set_transmittance_depth(float p_depth); float get_transmittance_depth() const; - void set_transmittance_curve(float p_curve); - float get_transmittance_curve() const; - void set_transmittance_boost(float p_boost); float get_transmittance_boost() const; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 4f854ff229..deee22f05f 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -2245,22 +2245,22 @@ void TileSet::_bind_methods() { BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_HORIZONTAL); BIND_ENUM_CONSTANT(TILE_OFFSET_AXIS_VERTICAL); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_RIGHT_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_LEFT_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_CORNER); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE); - BIND_ENUM_CONSTANT(TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_RIGHT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_BOTTOM_LEFT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_LEFT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_LEFT_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_CORNER); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_SIDE); + BIND_ENUM_CONSTANT(CELL_NEIGHBOR_TOP_RIGHT_CORNER); BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS_AND_SIDES); BIND_ENUM_CONSTANT(TERRAIN_MODE_MATCH_CORNERS); diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 12200989fd..ec0ff57a5e 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -418,37 +418,6 @@ void PhysicsDirectSpaceState2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState2D::_get_rest_info); } -int PhysicsShapeQueryResult2D::get_result_count() const { - return result.size(); -} - -RID PhysicsShapeQueryResult2D::get_result_rid(int p_idx) const { - return result[p_idx].rid; -} - -ObjectID PhysicsShapeQueryResult2D::get_result_object_id(int p_idx) const { - return result[p_idx].collider_id; -} - -Object *PhysicsShapeQueryResult2D::get_result_object(int p_idx) const { - return result[p_idx].collider; -} - -int PhysicsShapeQueryResult2D::get_result_object_shape(int p_idx) const { - return result[p_idx].shape; -} - -PhysicsShapeQueryResult2D::PhysicsShapeQueryResult2D() { -} - -void PhysicsShapeQueryResult2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult2D::get_result_count); - ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult2D::get_result_rid); - ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult2D::get_result_object_id); - ClassDB::bind_method(D_METHOD("get_result_object", "idx"), &PhysicsShapeQueryResult2D::get_result_object); - ClassDB::bind_method(D_METHOD("get_result_object_shape", "idx"), &PhysicsShapeQueryResult2D::get_result_object_shape); -} - /////////////////////////////// Vector2 PhysicsTestMotionResult2D::get_motion() const { diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 1059c197cc..6737aacaf0 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -92,8 +92,6 @@ public: PhysicsDirectBodyState2D(); }; -class PhysicsShapeQueryResult2D; - //used for script class PhysicsShapeQueryParameters2D : public RefCounted { GDCLASS(PhysicsShapeQueryParameters2D, RefCounted); @@ -203,26 +201,6 @@ public: PhysicsDirectSpaceState2D(); }; -class PhysicsShapeQueryResult2D : public RefCounted { - GDCLASS(PhysicsShapeQueryResult2D, RefCounted); - - Vector<PhysicsDirectSpaceState2D::ShapeResult> result; - - friend class PhysicsDirectSpaceState2D; - -protected: - static void _bind_methods(); - -public: - int get_result_count() const; - RID get_result_rid(int p_idx) const; - ObjectID get_result_object_id(int p_idx) const; - Object *get_result_object(int p_idx) const; - int get_result_object_shape(int p_idx) const; - - PhysicsShapeQueryResult2D(); -}; - class PhysicsTestMotionResult2D; class PhysicsServer2D : public Object { diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 144b2e18cd..7a0253506c 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -365,37 +365,6 @@ void PhysicsDirectSpaceState3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState3D::_get_rest_info); } -int PhysicsShapeQueryResult3D::get_result_count() const { - return result.size(); -} - -RID PhysicsShapeQueryResult3D::get_result_rid(int p_idx) const { - return result[p_idx].rid; -} - -ObjectID PhysicsShapeQueryResult3D::get_result_object_id(int p_idx) const { - return result[p_idx].collider_id; -} - -Object *PhysicsShapeQueryResult3D::get_result_object(int p_idx) const { - return result[p_idx].collider; -} - -int PhysicsShapeQueryResult3D::get_result_object_shape(int p_idx) const { - return result[p_idx].shape; -} - -PhysicsShapeQueryResult3D::PhysicsShapeQueryResult3D() { -} - -void PhysicsShapeQueryResult3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult3D::get_result_count); - ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult3D::get_result_rid); - ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult3D::get_result_object_id); - ClassDB::bind_method(D_METHOD("get_result_object", "idx"), &PhysicsShapeQueryResult3D::get_result_object); - ClassDB::bind_method(D_METHOD("get_result_object_shape", "idx"), &PhysicsShapeQueryResult3D::get_result_object_shape); -} - /////////////////////////////// Vector3 PhysicsTestMotionResult3D::get_motion() const { diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 1fabedc6ad..78fc026747 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -94,8 +94,6 @@ public: PhysicsDirectBodyState3D(); }; -class PhysicsShapeQueryResult3D; - class PhysicsShapeQueryParameters3D : public RefCounted { GDCLASS(PhysicsShapeQueryParameters3D, RefCounted); friend class PhysicsDirectSpaceState3D; @@ -196,26 +194,6 @@ public: PhysicsDirectSpaceState3D(); }; -class PhysicsShapeQueryResult3D : public RefCounted { - GDCLASS(PhysicsShapeQueryResult3D, RefCounted); - - Vector<PhysicsDirectSpaceState3D::ShapeResult> result; - - friend class PhysicsDirectSpaceState3D; - -protected: - static void _bind_methods(); - -public: - int get_result_count() const; - RID get_result_rid(int p_idx) const; - ObjectID get_result_object_id(int p_idx) const; - Object *get_result_object(int p_idx) const; - int get_result_object_shape(int p_idx) const; - - PhysicsShapeQueryResult3D(); -}; - class RenderingServerHandler { public: virtual void set_vertex(int p_vertex_id, const void *p_vector3) = 0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 4e309927bb..2118dca015 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -212,14 +212,12 @@ void register_server_types() { ClassDB::register_virtual_class<PhysicsDirectBodyState2D>(); ClassDB::register_virtual_class<PhysicsDirectSpaceState2D>(); - ClassDB::register_virtual_class<PhysicsShapeQueryResult2D>(); ClassDB::register_class<PhysicsTestMotionResult2D>(); ClassDB::register_class<PhysicsShapeQueryParameters2D>(); ClassDB::register_class<PhysicsShapeQueryParameters3D>(); ClassDB::register_virtual_class<PhysicsDirectBodyState3D>(); ClassDB::register_virtual_class<PhysicsDirectSpaceState3D>(); - ClassDB::register_virtual_class<PhysicsShapeQueryResult3D>(); ClassDB::register_class<PhysicsTestMotionResult3D>(); // Physics 2D diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index b0a1a2c939..5cf8895c8e 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1377,6 +1377,24 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI RD::get_singleton()->compute_list_end(p_barrier); } +void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) { + ResolvePushConstant push_constant; + push_constant.screen_size[0] = p_screen_size.x; + push_constant.screen_size[1] = p_screen_size.y; + push_constant.samples = p_samples; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1); + + RD::get_singleton()->compute_list_end(p_barrier); +} + void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { Sort::PushConstant push_constant; push_constant.total_elements = p_size; @@ -1879,6 +1897,7 @@ EffectsRD::EffectsRD() { Vector<String> resolve_modes; resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n"); resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n"); + resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n"); resolve.shader.initialize(resolve_modes); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index b4ddd400a8..33d32f0c57 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -581,6 +581,7 @@ class EffectsRD { enum ResolveMode { RESOLVE_MODE_GI, RESOLVE_MODE_GI_VOXEL_GI, + RESOLVE_MODE_DEPTH, RESOLVE_MODE_MAX }; @@ -746,6 +747,7 @@ public: void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void sort_buffer(RID p_uniform_set, int p_size); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 3ab2f0eed2..22bfd03115 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1150,6 +1150,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); } RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); + static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; //first of all, make a new render pass //fill up ubo @@ -1259,7 +1260,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi); render_list[RENDER_LIST_OPAQUE].sort_by_key(); - render_list[RENDER_LIST_ALPHA].sort_by_depth(); + render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority(); _fill_instance_data(RENDER_LIST_OPAQUE, p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr); _fill_instance_data(RENDER_LIST_ALPHA); @@ -1390,10 +1391,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (needs_pre_resolve) { RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); } - static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; - storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]); + storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); } else if (finish_depth) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); + storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); } RD::get_singleton()->draw_command_end_label(); } @@ -1497,7 +1497,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); + storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]); } if (using_separate_specular) { diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 6cb9fea91a..750c0167e7 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -551,7 +551,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { } }; - void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha + void sort_by_reverse_depth_and_priority() { //used for alpha SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter; sorter.sort(elements.ptr(), elements.size()); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 2be906d1b1..61f3047a34 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -320,8 +320,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { } else { //specular write blend_state = blend_state_opaque_specular; - depth_stencil.enable_depth_test = false; - depth_stencil.enable_depth_write = false; } } @@ -631,7 +629,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.renames["SSS_STRENGTH"] = "sss_strength"; actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; - actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve"; actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; actions.renames["BACKLIGHT"] = "backlight"; actions.renames["AO"] = "ao"; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index e7521e6bef..7fbd6e23b0 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -374,7 +374,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR); render_list[RENDER_LIST_OPAQUE].sort_by_key(); - render_list[RENDER_LIST_ALPHA].sort_by_depth(); + render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority(); // we no longer use this... _fill_instance_data(RENDER_LIST_OPAQUE); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index d5c0cca6c7..f40f713c03 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -356,7 +356,7 @@ protected: } }; - void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha + void sort_by_reverse_depth_and_priority() { //used for alpha SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter; sorter.sort(elements.ptr(), elements.size()); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index a7308e54ef..807417c1e3 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -621,7 +621,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.renames["SSS_STRENGTH"] = "sss_strength"; actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; - actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve"; actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; actions.renames["BACKLIGHT"] = "backlight"; actions.renames["AO"] = "ao"; diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index a4610e081c..fecf812a8c 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -6,6 +6,11 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +#ifdef MODE_RESOLVE_DEPTH +layout(set = 0, binding = 0) uniform sampler2DMS source_depth; +layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth; +#endif + #ifdef MODE_RESOLVE_GI layout(set = 0, binding = 0) uniform sampler2DMS source_depth; layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness; @@ -34,6 +39,17 @@ void main() { return; } +#ifdef MODE_RESOLVE_DEPTH + + float depth_avg = 0.0; + for (int i = 0; i < params.sample_count; i++) { + depth_avg += texelFetch(source_depth, pos, i).r; + } + depth_avg /= float(params.sample_count); + imageStore(dest_depth, pos, vec4(depth_avg)); + +#endif + #ifdef MODE_RESOLVE_GI float best_depth = 1e20; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 8538030263..74d5af5cb6 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -547,9 +547,8 @@ void main() { vec3 view = -normalize(vertex_interp); vec3 albedo = vec3(1.0); vec3 backlight = vec3(0.0); - vec4 transmittance_color = vec4(0.0); + vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0); float transmittance_depth = 0.0; - float transmittance_curve = 1.0; float transmittance_boost = 0.0; float metallic = 0.0; float specular = 0.5; @@ -634,12 +633,8 @@ void main() { } #ifdef LIGHT_TRANSMITTANCE_USED -#ifdef SSS_MODE_SKIN - transmittance_color.a = sss_strength; -#else transmittance_color.a *= sss_strength; #endif -#endif #ifndef USE_SHADOW_TO_OPACITY @@ -1423,57 +1418,18 @@ void main() { BIAS_FUNC(v, 0) pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; - - transmittance_z = z - shadow_z; - } -#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 1) pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; - - transmittance_z = z - shadow_z; - } -#endif } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; - - transmittance_z = z - shadow_z; - } -#endif } else { vec4 v = vec4(vertex, 1.0); @@ -1481,19 +1437,6 @@ void main() { BIAS_FUNC(v, 3) pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); -#ifdef LIGHT_TRANSMITTANCE_USED - { - vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0); - vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex; - trans_coord /= trans_coord.w; - - float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; - - transmittance_z = z - shadow_z; - } -#endif } pssm_coord /= pssm_coord.w; @@ -1562,8 +1505,8 @@ void main() { trans_coord /= trans_coord.w; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; + shadow_z *= directional_lights.data[i].shadow_z_range.x; + float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x; transmittance_z = z - shadow_z; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { @@ -1572,8 +1515,8 @@ void main() { trans_coord /= trans_coord.w; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; + shadow_z *= directional_lights.data[i].shadow_z_range.y; + float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y; transmittance_z = z - shadow_z; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { @@ -1582,8 +1525,8 @@ void main() { trans_coord /= trans_coord.w; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; + shadow_z *= directional_lights.data[i].shadow_z_range.z; + float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z; transmittance_z = z - shadow_z; @@ -1593,221 +1536,219 @@ void main() { trans_coord /= trans_coord.w; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; - shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; - float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; + shadow_z *= directional_lights.data[i].shadow_z_range.w; + float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w; transmittance_z = z - shadow_z; } + } #endif - float shadow = 1.0; + float shadow = 1.0; - if (i < 4) { - shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; - } else { - shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; - } + if (i < 4) { + shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; + } else { + shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; + } - blur_shadow(shadow); + blur_shadow(shadow); - light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, + light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, - transmittance_z, + transmittance_color, + transmittance_depth, + transmittance_boost, + transmittance_z, #endif #ifdef LIGHT_RIM_USED - rim, rim_tint, albedo, + rim, rim_tint, albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - binormal, tangent, anisotropy, + binormal, tangent, anisotropy, #endif #ifdef USE_SOFT_SHADOW - directional_lights.data[i].size, + directional_lights.data[i].size, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, - specular_light); - } + diffuse_light, + specular_light); } + } - { //omni lights + { //omni lights - uint cluster_omni_offset = cluster_offset; + uint cluster_omni_offset = cluster_offset; - uint item_min; - uint item_max; - uint item_from; - uint item_to; + uint item_min; + uint item_max; + uint item_from; + uint item_to; - cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS - item_from = subgroupBroadcastFirst(subgroupMin(item_from)); - item_to = subgroupBroadcastFirst(subgroupMax(item_to)); + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); #endif - for (uint i = item_from; i < item_to; i++) { - uint mask = cluster_buffer.data[cluster_omni_offset + i]; - mask &= cluster_get_range_clip_mask(i, item_min, item_max); + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_omni_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); #ifdef USE_SUBGROUPS - uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); #else uint merged_mask = mask; #endif - while (merged_mask != 0) { - uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here - continue; - } + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } #endif - uint light_index = 32 * i + bit; + uint light_index = 32 * i + bit; - if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { - continue; //not masked - } + if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } - if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { - continue; // Statically baked light and object uses lightmap, skip - } + if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip + } - float shadow = light_process_omni_shadow(light_index, vertex, view); + float shadow = light_process_omni_shadow(light_index, vertex, view); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, + light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED - rim, - rim_tint, - albedo, + rim, + rim_tint, + albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, binormal, anisotropy, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, specular_light); - } + diffuse_light, specular_light); } } + } - { //spot lights + { //spot lights - uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size; + uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size; - uint item_min; - uint item_max; - uint item_from; - uint item_to; + uint item_min; + uint item_max; + uint item_from; + uint item_to; - cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); + cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); #ifdef USE_SUBGROUPS - item_from = subgroupBroadcastFirst(subgroupMin(item_from)); - item_to = subgroupBroadcastFirst(subgroupMax(item_to)); + item_from = subgroupBroadcastFirst(subgroupMin(item_from)); + item_to = subgroupBroadcastFirst(subgroupMax(item_to)); #endif - for (uint i = item_from; i < item_to; i++) { - uint mask = cluster_buffer.data[cluster_spot_offset + i]; - mask &= cluster_get_range_clip_mask(i, item_min, item_max); + for (uint i = item_from; i < item_to; i++) { + uint mask = cluster_buffer.data[cluster_spot_offset + i]; + mask &= cluster_get_range_clip_mask(i, item_min, item_max); #ifdef USE_SUBGROUPS - uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); + uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); #else uint merged_mask = mask; #endif - while (merged_mask != 0) { - uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + while (merged_mask != 0) { + uint bit = findMSB(merged_mask); + merged_mask &= ~(1 << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here - continue; - } + if (((1 << bit) & mask) == 0) { //do not process if not originally here + continue; + } #endif - uint light_index = 32 * i + bit; + uint light_index = 32 * i + bit; - if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { - continue; //not masked - } + if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { + continue; //not masked + } - if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { - continue; // Statically baked light and object uses lightmap, skip - } + if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { + continue; // Statically baked light and object uses lightmap, skip + } - float shadow = light_process_spot_shadow(light_index, vertex, view); + float shadow = light_process_spot_shadow(light_index, vertex, view); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, + light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_curve, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif #ifdef LIGHT_RIM_USED - rim, - rim_tint, - albedo, + rim, + rim_tint, + albedo, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_gloss, #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, binormal, anisotropy, #endif #ifdef USE_SHADOW_TO_OPACITY - alpha, + alpha, #endif - diffuse_light, specular_light); - } + diffuse_light, specular_light); } } + } #ifdef USE_SHADOW_TO_OPACITY - alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); + alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); #if defined(ALPHA_SCISSOR_USED) - if (alpha < alpha_scissor) { - discard; - } + if (alpha < alpha_scissor) { + discard; + } #endif // ALPHA_SCISSOR_USED #ifdef USE_OPAQUE_PREPASS - if (alpha < opaque_prepass_threshold) { - discard; - } + if (alpha < opaque_prepass_threshold) { + discard; + } #endif // USE_OPAQUE_PREPASS @@ -1819,126 +1760,126 @@ void main() { #ifdef MODE_RENDER_SDF - { - vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; - ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); - - uint albedo16 = 0x1; //solid flag - albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; - albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6; - albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1; - - imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16)); - - uint facing_bits = 0; - const vec3 aniso_dir[6] = vec3[]( - vec3(1, 0, 0), - vec3(0, 1, 0), - vec3(0, 0, 1), - vec3(-1, 0, 0), - vec3(0, -1, 0), - vec3(0, 0, -1)); - - vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); - - float closest_dist = -1e20; - - for (uint i = 0; i < 6; i++) { - float d = dot(cam_normal, aniso_dir[i]); - if (d > closest_dist) { - closest_dist = d; - facing_bits = (1 << i); - } + { + vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; + ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); + + uint albedo16 = 0x1; //solid flag + albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; + albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6; + albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1; + + imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16)); + + uint facing_bits = 0; + const vec3 aniso_dir[6] = vec3[]( + vec3(1, 0, 0), + vec3(0, 1, 0), + vec3(0, 0, 1), + vec3(-1, 0, 0), + vec3(0, -1, 0), + vec3(0, 0, -1)); + + vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); + + float closest_dist = -1e20; + + for (uint i = 0; i < 6; i++) { + float d = dot(cam_normal, aniso_dir[i]); + if (d > closest_dist) { + closest_dist = d; + facing_bits = (1 << i); } + } - imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits + imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits - if (length(emission) > 0.001) { - float lumas[6]; - vec3 light_total = vec3(0); + if (length(emission) > 0.001) { + float lumas[6]; + vec3 light_total = vec3(0); - for (int i = 0; i < 6; i++) { - float strength = max(0.0, dot(cam_normal, aniso_dir[i])); - vec3 light = emission * strength; - light_total += light; - lumas[i] = max(light.r, max(light.g, light.b)); - } + for (int i = 0; i < 6; i++) { + float strength = max(0.0, dot(cam_normal, aniso_dir[i])); + vec3 light = emission * strength; + light_total += light; + lumas[i] = max(light.r, max(light.g, light.b)); + } - float luma_total = max(light_total.r, max(light_total.g, light_total.b)); + float luma_total = max(light_total.r, max(light_total.g, light_total.b)); - uint light_aniso = 0; + uint light_aniso = 0; - for (int i = 0; i < 6; i++) { - light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5); - } + for (int i = 0; i < 6; i++) { + light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5); + } - //compress to RGBE9995 to save space + //compress to RGBE9995 to save space - const float pow2to9 = 512.0f; - const float B = 15.0f; - const float N = 9.0f; - const float LN2 = 0.6931471805599453094172321215; + const float pow2to9 = 512.0f; + const float B = 15.0f; + const float N = 9.0f; + const float LN2 = 0.6931471805599453094172321215; - float cRed = clamp(light_total.r, 0.0, 65408.0); - float cGreen = clamp(light_total.g, 0.0, 65408.0); - float cBlue = clamp(light_total.b, 0.0, 65408.0); + float cRed = clamp(light_total.r, 0.0, 65408.0); + float cGreen = clamp(light_total.g, 0.0, 65408.0); + float cBlue = clamp(light_total.b, 0.0, 65408.0); - float cMax = max(cRed, max(cGreen, cBlue)); + float cMax = max(cRed, max(cGreen, cBlue)); - float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B; + float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B; - float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f); + float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f); - float exps = expp + 1.0f; + float exps = expp + 1.0f; - if (0.0 <= sMax && sMax < pow2to9) { - exps = expp; - } + if (0.0 <= sMax && sMax < pow2to9) { + exps = expp; + } - float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); - float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); - float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); - //store as 8985 to have 2 extra neighbour bits - uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); + float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); + float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); + float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); + //store as 8985 to have 2 extra neighbour bits + uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); - imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); - imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); - } + imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); + imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); } + } #endif #ifdef MODE_RENDER_MATERIAL - albedo_output_buffer.rgb = albedo; - albedo_output_buffer.a = alpha; + albedo_output_buffer.rgb = albedo; + albedo_output_buffer.a = alpha; - normal_output_buffer.rgb = normal * 0.5 + 0.5; - normal_output_buffer.a = 0.0; - depth_output_buffer.r = -vertex.z; + normal_output_buffer.rgb = normal * 0.5 + 0.5; + normal_output_buffer.a = 0.0; + depth_output_buffer.r = -vertex.z; - orm_output_buffer.r = ao; - orm_output_buffer.g = roughness; - orm_output_buffer.b = metallic; - orm_output_buffer.a = sss_strength; + orm_output_buffer.r = ao; + orm_output_buffer.g = roughness; + orm_output_buffer.b = metallic; + orm_output_buffer.a = sss_strength; - emission_output_buffer.rgb = emission; - emission_output_buffer.a = 0.0; + emission_output_buffer.rgb = emission; + emission_output_buffer.a = 0.0; #endif #ifdef MODE_RENDER_NORMAL_ROUGHNESS - normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); + normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); #ifdef MODE_RENDER_VOXEL_GI - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances - uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; - uint index2 = instances.data[instance_index].gi_offset >> 16; - voxel_gi_buffer.x = index1 & 0xFF; - voxel_gi_buffer.y = index2 & 0xFF; - } else { - voxel_gi_buffer.x = 0xFF; - voxel_gi_buffer.y = 0xFF; - } + if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances + uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; + uint index2 = instances.data[instance_index].gi_offset >> 16; + voxel_gi_buffer.x = index1 & 0xFF; + voxel_gi_buffer.y = index2 & 0xFF; + } else { + voxel_gi_buffer.x = 0xFF; + voxel_gi_buffer.y = 0xFF; + } #endif #endif //MODE_RENDER_NORMAL_ROUGHNESS @@ -1996,4 +1937,4 @@ void main() { #endif //MODE_MULTIPLE_RENDER_TARGETS #endif //MODE_RENDER_DEPTH - } +} diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 709ea45b88..b6e89acb46 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -80,7 +80,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #ifdef LIGHT_TRANSMITTANCE_USED vec4 transmittance_color, float transmittance_depth, - float transmittance_curve, float transmittance_boost, float transmittance_z, #endif @@ -189,9 +188,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, #ifdef LIGHT_TRANSMITTANCE_USED -#ifdef SSS_MODE_SKIN - { +#ifdef SSS_MODE_SKIN float scale = 8.25 / transmittance_depth; float d = scale * abs(transmittance_z); float dd = -d * d; @@ -203,19 +201,15 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation, vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI); - } #else - if (transmittance_depth > 0.0) { - float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0); - - fade = pow(max(0.0, 1.0 - fade), transmittance_curve); - fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0); - - diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade; + float scale = 8.25 / transmittance_depth; + float d = scale * abs(transmittance_z); + float dd = -d * d; + diffuse_light += exp(dd) * transmittance_color.rgb * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI); +#endif } - -#endif //SSS_MODE_SKIN +#else #endif //LIGHT_TRANSMITTANCE_USED } @@ -577,7 +571,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED vec4 transmittance_color, float transmittance_depth, - float transmittance_curve, float transmittance_boost, #endif #ifdef LIGHT_RIM_USED @@ -617,20 +610,22 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v //redo shadowmapping, but shrink the model a bit to avoid arctifacts vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0)); - shadow_len = length(splane.xyz); - splane = normalize(splane.xyz); + float shadow_len = length(splane.xyz); + splane.xyz = normalize(splane.xyz); if (splane.z >= 0.0) { splane.z += 1.0; - + clamp_rect.y += clamp_rect.w; } else { splane.z = 1.0 - splane.z; } splane.xy /= splane.z; + splane.xy = splane.xy * 0.5 + 0.5; splane.z = shadow_len * omni_lights.data[idx].inv_radius; splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; + // splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data.shadow_atlas_pixel_size ); splane.w = 1.0; //needed? i think it should be 1 already float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; @@ -704,7 +699,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED transmittance_color, transmittance_depth, - transmittance_curve, transmittance_boost, transmittance_z, #endif @@ -829,7 +823,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED vec4 transmittance_color, float transmittance_depth, - float transmittance_curve, float transmittance_boost, #endif #ifdef LIGHT_RIM_USED @@ -876,13 +869,17 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float transmittance_z = transmittance_depth; transmittance_color.a *= light_attenuation; { - splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0)); + vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0)); splane /= splane.w; splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; - //reconstruct depth - shadow_z /= spot_lights.data[idx].inv_radius; + + shadow_z = shadow_z * 2.0 - 1.0; + float z_far = 1.0 / spot_lights.data[idx].inv_radius; + float z_near = 0.01; + shadow_z = 2.0 * z_near * z_far / (z_far + z_near - shadow_z * (z_far - z_near)); + //distance to light plane float z = dot(spot_dir, -light_rel_vec); transmittance_z = z - shadow_z; @@ -898,7 +895,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v #ifdef LIGHT_TRANSMITTANCE_USED transmittance_color, transmittance_depth, - transmittance_curve, transmittance_boost, transmittance_z, #endif diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index aa8a0b96c5..1bc17e140f 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -543,7 +543,6 @@ void main() { vec3 backlight = vec3(0.0); vec4 transmittance_color = vec4(0.0); float transmittance_depth = 0.0; - float transmittance_curve = 1.0; float transmittance_boost = 0.0; float metallic = 0.0; float specular = 0.5; @@ -1293,7 +1292,6 @@ void main() { #ifdef LIGHT_TRANSMITTANCE_USED transmittance_color, transmittance_depth, - transmittance_curve, transmittance_boost, transmittance_z, #endif @@ -1344,7 +1342,6 @@ void main() { #ifdef LIGHT_TRANSMITTANCE_USED transmittance_color, transmittance_depth, - transmittance_curve, transmittance_boost, #endif */ @@ -1393,7 +1390,6 @@ void main() { #ifdef LIGHT_TRANSMITTANCE_USED transmittance_color, transmittance_depth, - transmittance_curve, transmittance_boost, #endif */ diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index c4e7511374..376d23ccb3 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -122,7 +122,6 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; diff --git a/tests/test_class_db.h b/tests/test_class_db.h index 75785fa5ed..29edf5a4a0 100644 --- a/tests/test_class_db.h +++ b/tests/test_class_db.h @@ -754,6 +754,9 @@ void add_exposed_classes(Context &r_context) { const List<StringName> &enum_constants = enum_map.get(*k); for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { const StringName &constant_name = E->get(); + TEST_FAIL_COND(String(constant_name).find("::") != -1, + "Enum constant contains '::', check bindings to remove the scope: '", + String(class_name), ".", String(enum_.name), ".", String(constant_name), "'."); int *value = class_info->constant_map.getptr(constant_name); TEST_FAIL_COND(!value, "Missing enum constant value: '", String(class_name), ".", String(enum_.name), ".", String(constant_name), "'."); @@ -773,8 +776,11 @@ void add_exposed_classes(Context &r_context) { for (const List<String>::Element *E = constants.front(); E; E = E->next()) { const String &constant_name = E->get(); + TEST_FAIL_COND(constant_name.find("::") != -1, + "Constant contains '::', check bindings to remove the scope: '", + String(class_name), ".", constant_name, "'."); int *value = class_info->constant_map.getptr(StringName(E->get())); - TEST_FAIL_COND(!value, "Missing enum constant value: '", String(class_name), ".", String(constant_name), "'."); + TEST_FAIL_COND(!value, "Missing constant value: '", String(class_name), ".", String(constant_name), "'."); ConstantData constant; constant.name = constant_name; |