diff options
52 files changed, 406 insertions, 174 deletions
diff --git a/core/class_db.h b/core/class_db.h index 490deb7873..34301d6cba 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -114,6 +114,7 @@ public: APIType api; ClassInfo *inherits_ptr; + void *class_ptr; HashMap<StringName, MethodBind *> method_map; HashMap<StringName, int> constant_map; HashMap<StringName, List<StringName> > enum_map; @@ -177,6 +178,7 @@ public: ERR_FAIL_COND(!t); t->creation_func = &creator<T>; t->exposed = true; + t->class_ptr = T::get_class_ptr_static(); T::register_custom_data_to_otdb(); } @@ -188,6 +190,7 @@ public: ClassInfo *t = classes.getptr(T::get_class_static()); ERR_FAIL_COND(!t); t->exposed = true; + t->class_ptr = T::get_class_ptr_static(); //nothing } @@ -206,6 +209,7 @@ public: ERR_FAIL_COND(!t); t->creation_func = &_create_ptr_func<T>; t->exposed = true; + t->class_ptr = T::get_class_ptr_static(); T::register_custom_data_to_otdb(); } @@ -293,6 +297,15 @@ public: return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7); } + template <class N, class M> + static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) { + + MethodBind *bind = create_method_bind(p_method); + const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 }; + + return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8); + } + template <class M> static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) { diff --git a/core/image.cpp b/core/image.cpp index 5f99fe1532..672f850a1f 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -2432,19 +2432,19 @@ Color Image::get_pixel(int p_x, int p_y) const { } case FORMAT_RGBA4444: { uint16_t u = ((uint16_t *)ptr)[ofs]; - float r = (u & 0xF) / 15.0; - float g = ((u >> 4) & 0xF) / 15.0; - float b = ((u >> 8) & 0xF) / 15.0; - float a = ((u >> 12) & 0xF) / 15.0; + float r = ((u >> 12) & 0xF) / 15.0; + float g = ((u >> 8) & 0xF) / 15.0; + float b = ((u >> 4) & 0xF) / 15.0; + float a = (u & 0xF) / 15.0; return Color(r, g, b, a); } case FORMAT_RGBA5551: { uint16_t u = ((uint16_t *)ptr)[ofs]; - float r = (u & 0x1F) / 15.0; - float g = ((u >> 5) & 0x1F) / 15.0; - float b = ((u >> 10) & 0x1F) / 15.0; - float a = ((u >> 15) & 0x1) / 1.0; + float r = ((u >> 11) & 0x1F) / 15.0; + float g = ((u >> 6) & 0x1F) / 15.0; + float b = ((u >> 1) & 0x1F) / 15.0; + float a = (u & 0x1) / 1.0; return Color(r, g, b, a); } case FORMAT_RF: { @@ -2558,10 +2558,10 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { uint16_t rgba = 0; - rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15)); - rgba |= uint16_t(CLAMP(p_color.g * 15.0, 0, 15)) << 4; - rgba |= uint16_t(CLAMP(p_color.b * 15.0, 0, 15)) << 8; - rgba |= uint16_t(CLAMP(p_color.a * 15.0, 0, 15)) << 12; + rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15)) << 12; + rgba |= uint16_t(CLAMP(p_color.g * 15.0, 0, 15)) << 8; + rgba |= uint16_t(CLAMP(p_color.b * 15.0, 0, 15)) << 4; + rgba |= uint16_t(CLAMP(p_color.a * 15.0, 0, 15)); ((uint16_t *)ptr)[ofs] = rgba; @@ -2570,10 +2570,10 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) { uint16_t rgba = 0; - rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)); - rgba |= uint16_t(CLAMP(p_color.g * 31.0, 0, 31)) << 5; - rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 10; - rgba |= uint16_t(p_color.a > 0.5 ? 1 : 0) << 15; + rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31)) << 11; + rgba |= uint16_t(CLAMP(p_color.g * 31.0, 0, 31)) << 6; + rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 1; + rgba |= uint16_t(p_color.a > 0.5 ? 1 : 0); ((uint16_t *)ptr)[ofs] = rgba; diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index aaa7eb64c9..2708cb8c01 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -139,6 +139,9 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee if (p_peer == network_peer) return; // Nothing to do + ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, + "Supplied NetworkedMultiplayerPeer must be connecting or connected."); + if (network_peer.is_valid()) { network_peer->disconnect("peer_connected", this, "_add_peer"); network_peer->disconnect("peer_disconnected", this, "_del_peer"); @@ -150,8 +153,6 @@ void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_pee network_peer = p_peer; - ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED, "Supplied NetworkedNetworkPeer must be connecting or connected."); - if (network_peer.is_valid()) { network_peer->connect("peer_connected", this, "_add_peer"); network_peer->connect("peer_disconnected", this, "_del_peer"); diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml index 22e4a21757..419a0c5248 100644 --- a/doc/classes/EditorSpatialGizmo.xml +++ b/doc/classes/EditorSpatialGizmo.xml @@ -51,6 +51,8 @@ </argument> <argument index="2" name="billboard" type="bool" default="false"> </argument> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> + </argument> <description> Adds lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this function during [method redraw]. </description> @@ -76,6 +78,8 @@ </argument> <argument index="1" name="default_scale" type="float" default="1"> </argument> + <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> + </argument> <description> Adds an unscaled billboard for visualization. Call this function during [method redraw]. </description> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 193cfeb0ff..e3f1165c55 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -129,6 +129,7 @@ child_node.get_parent().remove_child(child_node) add_child(child_node) [/codeblock] + [b]Note:[/b] If you want a child to be persisted to a [PackedScene], you must set [member owner] in addition to calling [method add_child]. This is typically relevant for [url=https://godot.readthedocs.io/en/latest/tutorials/misc/running_code_in_the_editor.html]tool scripts[/url] and [url=https://godot.readthedocs.io/en/latest/tutorials/plugins/editor/index.html]editor plugins[/url]. If [method add_child] is called without setting [member owner], the newly added [Node] will not be visible in the scene tree, though it will be visible in the 2D/3D view. </description> </method> <method name="add_child_below_node"> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 265e87eba3..22f4dc2d83 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -906,6 +906,7 @@ </member> <member name="exit_code" type="int" setter="set_exit_code" getter="get_exit_code" default="0"> The exit code passed to the OS when the main loop exits. By convention, an exit code of [code]0[/code] indicates success whereas a non-zero exit code indicates an error. For portability reasons, the exit code should be set between 0 and 125 (inclusive). + [b]Note:[/b] This value will be ignored if using [method SceneTree.quit] with an [code]exit_code[/code] argument passed. </member> <member name="keep_screen_on" type="bool" setter="set_keep_screen_on" getter="is_keep_screen_on" default="true"> If [code]true[/code], the engine tries to keep the screen on while the game is running. Useful on mobile. diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml index 1d7e5f8080..1a72ba60ab 100644 --- a/doc/classes/Object.xml +++ b/doc/classes/Object.xml @@ -203,7 +203,7 @@ <argument index="0" name="property" type="String"> </argument> <description> - Returns the [Variant] value of the given [code]property[/code]. + Returns the [Variant] value of the given [code]property[/code]. If the [code]property[/code] doesn't exist, this will return [code]null[/code]. </description> </method> <method name="get_class" qualifiers="const"> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 0635dd8935..6a4105ca2f 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -185,8 +185,10 @@ <method name="quit"> <return type="void"> </return> + <argument index="0" name="exit_code" type="int" default="-1"> + </argument> <description> - Quits the application. + Quits the application. A process [code]exit_code[/code] can optionally be passed as an argument. If this argument is [code]0[/code] or greater, it will override the [member OS.exit_code] defined before quitting the application. </description> </method> <method name="reload_current_scene"> diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index f57730a591..94920d57e5 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -23,10 +23,10 @@ </method> </methods> <members> - <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" /> <member name="follow_focus" type="bool" setter="set_follow_focus" getter="is_following_focus" default="false"> If [code]true[/code], the ScrollContainer will automatically scroll to focused children (including indirect children) to make sure they are fully visible. </member> + <member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" override="true" default="true" /> <member name="scroll_deadzone" type="int" setter="set_deadzone" getter="get_deadzone" default="0"> </member> <member name="scroll_horizontal" type="int" setter="set_h_scroll" getter="get_h_scroll" default="0"> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 1f584ad317..e5f126c344 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -150,6 +150,7 @@ If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden. </member> <member name="use_hidden_tabs_for_min_size" type="bool" setter="set_use_hidden_tabs_for_min_size" getter="get_use_hidden_tabs_for_min_size" default="false"> + If [code]true[/code], children [Control] nodes that are hidden have their minimum size take into account in the total, instead of only the currently visible one. </member> </members> <signals> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index dd4330b00b..aa1f8638d2 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -43,14 +43,18 @@ <argument index="1" name="idx" type="int" default="-1"> </argument> <description> - Create an item in the tree and add it as the last child of [code]parent[/code]. If [code]parent[/code] is [code]null[/code], it will be added as the root's last child, or it'll be the the root itself if the tree is empty. + Creates an item in the tree and adds it as a child of [code]parent[/code]. + If [code]parent[/code] is [code]null[/code], the root item will be the parent, or the new item will be the root itself if the tree is empty. + The new item will be the [code]idx[/code]th child of parent, or it will be the last child if there are not enough siblings. </description> </method> <method name="ensure_cursor_is_visible"> <return type="void"> </return> <description> - Makes the currently selected item visible. This will scroll the tree to make sure the selected item is visible. + Makes the currently focused cell visible. + This will scroll the tree if necessary. In [constant SELECT_ROW] mode, this will not do horizontal scrolling, as all the cells in the selected row is focused logically. + [b]Note:[/b] Despite the name of this method, the focus cursor itself is only visible in [constant SELECT_MULTI] mode. </description> </method> <method name="get_column_at_position" qualifiers="const"> @@ -59,7 +63,7 @@ <argument index="0" name="position" type="Vector2"> </argument> <description> - Returns the column index under the given point. + Returns the column index at [code]position[/code], or -1 if no item is there. </description> </method> <method name="get_column_title" qualifiers="const"> @@ -93,8 +97,9 @@ <argument index="0" name="position" type="Vector2"> </argument> <description> - If [member drop_mode_flags] includes [constant DROP_MODE_INBETWEEN], returns -1 if [code]position[/code] is the upper part of a tree item at that position, 1 for the lower part, and additionally 0 for the middle part if [member drop_mode_flags] includes [constant DROP_MODE_ON_ITEM]. - Otherwise, returns 0. If there are no tree items at [code]position[/code], returns -100. + Returns the drop section at [code]position[/code], or -100 if no item is there. + Values -1, 0, or 1 will be returned for the "above item", "on item", and "below item" drop sections, respectively. See [enum DropModeFlags] for a description of each drop section. + To get the item which the returned drop section is relative to, use [method get_item_at_position]. </description> </method> <method name="get_edited" qualifiers="const"> @@ -119,7 +124,7 @@ <argument index="1" name="column" type="int" default="-1"> </argument> <description> - Returns the rectangle area for the specified item. If column is specified, only get the position and size of that column, otherwise get the rectangle containing all columns. + Returns the rectangle area for the specified item. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns. </description> </method> <method name="get_item_at_position" qualifiers="const"> @@ -137,7 +142,8 @@ <argument index="0" name="from" type="Object"> </argument> <description> - Returns the next selected item after the given one. + Returns the next selected item after the given one, or [code]null[/code] if the end is reached. + If [code]from[/code] is [code]null[/code], this returns the first selected item. </description> </method> <method name="get_pressed_button" qualifiers="const"> @@ -151,7 +157,7 @@ <return type="TreeItem"> </return> <description> - Returns the tree's root item. + Returns the tree's root item, or [code]null[/code] if the tree is empty. </description> </method> <method name="get_scroll" qualifiers="const"> @@ -165,14 +171,18 @@ <return type="TreeItem"> </return> <description> - Returns the currently selected item. + Returns the currently focused item, or [code]null[/code] if no item is focused. + In [constant SELECT_ROW] and [constant SELECT_SINGLE] modes, the focused item is same as the selected item. In [constant SELECT_MULTI] mode, the focused item is the item under the focus cursor, not necessarily selected. + To get the currently selected item(s), use [method get_next_selected]. </description> </method> <method name="get_selected_column" qualifiers="const"> <return type="int"> </return> <description> - Returns the current selection's column. + Returns the currently focused column, or -1 if no column is focused. + In [constant SELECT_SINGLE] mode, the focused column is the selected column. In [constant SELECT_ROW] mode, the focused column is always 0 if any item is selected. In [constant SELECT_MULTI] mode, the focused column is the column under the focus cursor, and there are not necessarily any column selected. + To tell whether a column of an item is selected, use [method TreeItem.is_selected]. </description> </method> <method name="set_column_expand"> @@ -230,6 +240,7 @@ </member> <member name="drop_mode_flags" type="int" setter="set_drop_mode_flags" getter="get_drop_mode_flags" default="0"> The drop mode as an OR combination of flags. See [enum DropModeFlags] constants. Once dropping is done, reverts to [constant DROP_MODE_DISABLED]. Setting this during [method Control.can_drop_data] is recommended. + This controls the drop sections, i.e. the decision and drawing of possible drop locations based on the mouse position. </member> <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" override="true" enum="Control.FocusMode" default="2" /> <member name="hide_folding" type="bool" setter="set_hide_folding" getter="is_folding_hidden" default="false"> @@ -278,6 +289,7 @@ <argument index="0" name="position" type="Vector2"> </argument> <description> + Emitted when the right mouse button is pressed in the empty space of the tree. </description> </signal> <signal name="empty_tree_rmb_selected"> @@ -343,23 +355,34 @@ </signal> <signal name="nothing_selected"> <description> + Emitted when a left mouse button click does not select any item. </description> </signal> </signals> <constants> <constant name="SELECT_SINGLE" value="0" enum="SelectMode"> - Allows selection of a single item at a time. + Allows selection of a single cell at a time. From the perspective of items, only a single item is allowed to be selected. And there is only one column selected in the selected item. + The focus cursor is always hidden in this mode, but it is positioned at the current selection, making the currently selected item the currently focused item. </constant> <constant name="SELECT_ROW" value="1" enum="SelectMode"> + Allows selection of a single row at a time. From the perspective of items, only a single items is allowed to be selected. And all the columns are selected in the selected item. + The focus cursor is always hidden in this mode, but it is positioned at the first column of the current selection, making the currently selected item the currently focused item. </constant> <constant name="SELECT_MULTI" value="2" enum="SelectMode"> - Allows selection of multiple items at the same time. + Allows selection of multiple cells at the same time. From the perspective of items, multiple items are allowed to be selected. And there can be multiple columns selected in each selected item. + The focus cursor is visible in this mode, the item or column under the cursor is not necessarily selected. </constant> <constant name="DROP_MODE_DISABLED" value="0" enum="DropModeFlags"> + Disables all drop sections, but still allows to detect the "on item" drop section by [method get_drop_section_at_position]. + [b]Note:[/b] This is the default flag, it has no effect when combined with other flags. </constant> <constant name="DROP_MODE_ON_ITEM" value="1" enum="DropModeFlags"> + Enables the "on item" drop section. This drop section covers the entire item. + When combined with [constant DROP_MODE_INBETWEEN], this drop section halves the height and stays centered vertically. </constant> <constant name="DROP_MODE_INBETWEEN" value="2" enum="DropModeFlags"> + Enables "above item" and "below item" drop sections. The "above item" drop section covers the top half of the item, and the "below item" drop section covers the bottom half. + When combined with [constant DROP_MODE_ON_ITEM], these drop sections halves the height and stays on top / bottom accordingly. </constant> </constants> <theme_items> diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 612bfb41c6..5c29601134 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -424,6 +424,8 @@ </argument> <argument index="10" name="antialiased" type="bool" default="false"> </argument> + <argument index="11" name="antialiasing_use_indices" type="bool" default="false"> + </argument> <description> Adds a triangle array to the [CanvasItem]'s draw commands. </description> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index 7164e8cb0a..1571bae847 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="float" category="Built-In Types" version="3.2"> <brief_description> - Float built-in type + Float built-in type. </brief_description> <description> Float built-in type. diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 45c9e66c73..10c9846fde 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -1033,7 +1033,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur #ifdef GLES_OVER_GL if (polygon->antialiased) { glEnable(GL_LINE_SMOOTH); - _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + if (polygon->antialiasing_use_indices) { + _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } else { + _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } glDisable(GL_LINE_SMOOTH); } #endif diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 657148cb40..94a7d4e1b5 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -2435,22 +2435,10 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: if (surface->blend_shape_data.size()) { ERR_PRINT_ONCE("Blend shapes are not supported in OpenGL ES 2.0"); } - surface->data = array; - surface->index_data = p_index_array; -#else - // Even on non-tools builds, a copy of the surface->data is needed in certain circumstances. - // Rigged meshes using the USE_SKELETON_SOFTWARE path need to read bone data - // from surface->data. - - // if USE_SKELETON_SOFTWARE is active - if (config.use_skeleton_software) { - // if this geometry is used specifically for skinning - if (p_format & (VS::ARRAY_FORMAT_BONES | VS::ARRAY_FORMAT_WEIGHTS)) - surface->data = array; - } - // An alternative is to always make a copy of surface->data. #endif + surface->data = array; + surface->index_data = p_index_array; surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size; for (int i = 0; i < surface->skeleton_bone_used.size(); i++) { diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index c6067e7f58..55a38c917f 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -901,7 +901,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur #ifdef GLES_OVER_GL if (polygon->antialiased) { glEnable(GL_LINE_SMOOTH); - _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + if (polygon->antialiasing_use_indices) { + _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } else { + _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + } glDisable(GL_LINE_SMOOTH); } #endif @@ -1413,7 +1417,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons } if (skeleton) { - glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1); + glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); glBindTexture(GL_TEXTURE_2D, skeleton->texture); state.using_skeleton = true; } else { @@ -1677,7 +1681,6 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons bool light_rebind = state.canvas_shader.bind(); if (light_rebind) { - state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate); state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform); state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D()); @@ -1686,6 +1689,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons } else { state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, Vector2(1.0, 1.0)); } + if (state.using_skeleton) { + state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform); + state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse); + } } glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index ec18c83df3..07ee9cd010 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -55,7 +55,7 @@ out highp vec2 pixel_size_interp; #endif #ifdef USE_SKELETON -uniform mediump sampler2D skeleton_texture; // texunit:-1 +uniform mediump sampler2D skeleton_texture; // texunit:-4 uniform highp mat4 skeleton_transform; uniform highp mat4 skeleton_transform_inverse; #endif diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index ea76aad168..86611bd20a 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -195,7 +195,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { String res_path = "res://" + path; if (FileAccess::exists(res_path)) { ti->set_custom_color(0, get_color("error_color", "Editor")); - ti->set_tooltip(0, res_path + " (Already Exists)"); + ti->set_tooltip(0, vformat(TTR("%s (Already Exists)"), res_path)); ti->set_checked(0, false); } else { ti->set_tooltip(0, res_path); @@ -288,11 +288,11 @@ void EditorAssetInstaller::ok_pressed() { unzClose(pkg); if (failed_files.size()) { - String msg = "The following files failed extraction from package:\n\n"; + String msg = TTR("The following files failed extraction from package:") + "\n\n"; for (int i = 0; i < failed_files.size(); i++) { if (i > 15) { - msg += "\nAnd " + itos(failed_files.size() - i) + " more files."; + msg += "\n" + vformat(TTR("And %s more files."), itos(failed_files.size() - i)); break; } msg += failed_files[i]; @@ -317,7 +317,7 @@ EditorAssetInstaller::EditorAssetInstaller() { add_child(vb); tree = memnew(Tree); - vb->add_margin_child("Package Contents:", tree, true); + vb->add_margin_child(TTR("Package Contents:"), tree, true); tree->connect("item_edited", this, "_item_edited"); error = memnew(AcceptDialog); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 07b4a1ea31..365238222f 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -1290,7 +1290,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) { Error err = ResourceSaver::save(p_string, AudioServer::get_singleton()->generate_bus_layout()); if (err != OK) { - EditorNode::get_singleton()->show_warning("Error saving file: " + p_string); + EditorNode::get_singleton()->show_warning(vformat(TTR("Error saving file: %s"), p_string)); return; } diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 4949d1a4e5..f5128103f3 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -1479,9 +1479,16 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) { if (d.has("alphaMode")) { const String &am = d["alphaMode"]; - if (am != "OPAQUE") { + if (am == "BLEND") { material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); material->set_depth_draw_mode(SpatialMaterial::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); + } else if (am == "MASK") { + material->set_flag(SpatialMaterial::FLAG_USE_ALPHA_SCISSOR, true); + if (d.has("alphaCutoff")) { + material->set_alpha_scissor_threshold(d["alphaCutoff"]); + } else { + material->set_alpha_scissor_threshold(0.5f); + } } } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 71afddba11..2b0c582b49 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -4216,11 +4216,13 @@ void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) { void CanvasItemEditor::_update_zoom_label() { String zoom_text; + // The zoom level displayed is relative to the editor scale + // (like in most image editors). if (zoom >= 10) { - // Don't show a decimal when the zoom level is higher than 1000 % - zoom_text = rtos(Math::round(zoom * 100)) + " %"; + // Don't show a decimal when the zoom level is higher than 1000 %. + zoom_text = rtos(Math::round((zoom / EDSCALE) * 100)) + " %"; } else { - zoom_text = rtos(Math::stepify(zoom * 100, 0.1)) + " %"; + zoom_text = rtos(Math::stepify((zoom / EDSCALE) * 100, 0.1)) + " %"; } zoom_reset->set_text(zoom_text); @@ -4231,7 +4233,7 @@ void CanvasItemEditor::_button_zoom_minus() { } void CanvasItemEditor::_button_zoom_reset() { - _zoom_on_position(1.0, viewport_scrollable->get_size() / 2.0); + _zoom_on_position(1.0 * EDSCALE, viewport_scrollable->get_size() / 2.0); } void CanvasItemEditor::_button_zoom_plus() { @@ -4993,7 +4995,8 @@ void CanvasItemEditor::_bind_methods() { Dictionary CanvasItemEditor::get_state() const { Dictionary state; - state["zoom"] = zoom; + // Take the editor scale into account. + state["zoom"] = zoom / EDSCALE; state["ofs"] = view_offset; state["grid_offset"] = grid_offset; state["grid_step"] = grid_step; @@ -5030,7 +5033,9 @@ void CanvasItemEditor::set_state(const Dictionary &p_state) { bool update_scrollbars = false; Dictionary state = p_state; if (state.has("zoom")) { - zoom = p_state["zoom"]; + // Compensate the editor scale, so that the editor scale can be changed + // and the zoom level will still be the same (relative to the editor scale). + zoom = float(p_state["zoom"]) * EDSCALE; _update_zoom_label(); } @@ -5246,7 +5251,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { show_rulers = true; show_guides = true; show_edit_locks = true; - zoom = 1; + zoom = 1.0 / EDSCALE; view_offset = Point2(-150 - RULER_WIDTH, -95 - RULER_WIDTH); previous_update_view_offset = view_offset; // Moves the view a little bit to the left so that (0,0) is visible. The values a relative to a 16/10 screen grid_offset = Point2(); diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp index 33ae9363dc..655048c271 100644 --- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp +++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp @@ -296,9 +296,9 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) { emission_mask->add_child(emvb); emission_mask_mode = memnew(OptionButton); emvb->add_margin_child(TTR("Emission Mask"), emission_mask_mode); - emission_mask_mode->add_item("Solid Pixels", EMISSION_MODE_SOLID); - emission_mask_mode->add_item("Border Pixels", EMISSION_MODE_BORDER); - emission_mask_mode->add_item("Directed Border Pixels", EMISSION_MODE_BORDER_DIRECTED); + emission_mask_mode->add_item(TTR("Solid Pixels"), EMISSION_MODE_SOLID); + emission_mask_mode->add_item(TTR("Border Pixels"), EMISSION_MODE_BORDER); + emission_mask_mode->add_item(TTR("Directed Border Pixels"), EMISSION_MODE_BORDER_DIRECTED); emission_colors = memnew(CheckBox); emission_colors->set_text(TTR("Capture from Pixel")); emvb->add_margin_child(TTR("Emission Colors"), emission_colors); diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp index 441739de5f..b036368bc8 100644 --- a/editor/plugins/particles_2d_editor_plugin.cpp +++ b/editor/plugins/particles_2d_editor_plugin.cpp @@ -424,9 +424,9 @@ Particles2DEditorPlugin::Particles2DEditorPlugin(EditorNode *p_node) { emission_mask->add_child(emvb); emission_mask_mode = memnew(OptionButton); emvb->add_margin_child(TTR("Emission Mask"), emission_mask_mode); - emission_mask_mode->add_item("Solid Pixels", EMISSION_MODE_SOLID); - emission_mask_mode->add_item("Border Pixels", EMISSION_MODE_BORDER); - emission_mask_mode->add_item("Directed Border Pixels", EMISSION_MODE_BORDER_DIRECTED); + emission_mask_mode->add_item(TTR("Solid Pixels"), EMISSION_MODE_SOLID); + emission_mask_mode->add_item(TTR("Border Pixels"), EMISSION_MODE_BORDER); + emission_mask_mode->add_item(TTR("Directed Border Pixels"), EMISSION_MODE_BORDER_DIRECTED); emission_colors = memnew(CheckBox); emission_colors->set_text(TTR("Capture from Pixel")); emvb->add_margin_child(TTR("Emission Colors"), emission_colors); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 4c36e15eb4..e1f9ed497c 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -46,7 +46,7 @@ void ScriptCreateDialog::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: case NOTIFICATION_ENTER_TREE: { for (int i = 0; i < ScriptServer::get_language_count(); i++) { - String lang = ScriptServer::get_language(i)->get_name(); + String lang = ScriptServer::get_language(i)->get_type(); Ref<Texture> lang_icon = get_icon(lang, "EditorIcons"); if (lang_icon.is_valid()) { language_menu->set_item_icon(i, lang_icon); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 3ea5272ebf..89713c2579 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -736,11 +736,11 @@ void EditorSpatialGizmo::set_plugin(EditorSpatialGizmoPlugin *p_plugin) { void EditorSpatialGizmo::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false), DEFVAL(Color(1, 1, 1))); + ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard", "modulate"), &EditorSpatialGizmo::add_lines, DEFVAL(false), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton", "material"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(Ref<SkinReference>()), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments); ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorSpatialGizmo::add_collision_triangles); - ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1), DEFVAL(Color(1, 1, 1))); + ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale", "modulate"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("add_handles", "handles", "material", "billboard", "secondary"), &EditorSpatialGizmo::add_handles, DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_spatial_node", "node"), &EditorSpatialGizmo::_set_spatial_node); ClassDB::bind_method(D_METHOD("get_spatial_node"), &EditorSpatialGizmo::get_spatial_node); diff --git a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml index 78a8e94012..9509adfb18 100644 --- a/modules/enet/doc_classes/NetworkedMultiplayerENet.xml +++ b/modules/enet/doc_classes/NetworkedMultiplayerENet.xml @@ -49,7 +49,7 @@ <argument index="3" name="out_bandwidth" type="int" default="0"> </argument> <description> - Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]"*"[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4096 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [constant OK] if a server was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the server could not be created. + Create server that listens to connections via [code]port[/code]. The port needs to be an available, unused port between 0 and 65535. Note that ports below 1024 are privileged and may require elevated permissions depending on the platform. To change the interface the server listens on, use [method set_bind_ip]. The default IP is the wildcard [code]"*"[/code], which listens on all available interfaces. [code]max_clients[/code] is the maximum number of clients that are allowed at once, any number up to 4095 may be used, although the achievable number of simultaneous clients may be far lower and depends on the application. For additional details on the bandwidth parameters, see [method create_client]. Returns [constant OK] if a server was created, [constant ERR_ALREADY_IN_USE] if this NetworkedMultiplayerENet instance already has an open connection (in which case you need to call [method close_connection] first) or [constant ERR_CANT_CREATE] if the server could not be created. </description> </method> <method name="disconnect_peer"> diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index 0e75f8fd37..61fc7688c5 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -75,7 +75,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE); ERR_FAIL_COND_V(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(p_max_clients < 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_in_bandwidth < 0, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(p_out_bandwidth < 0, ERR_INVALID_PARAMETER); diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index 7cd5e2eb12..b80138c99d 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -139,6 +139,18 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f return; } + if (force_etc1_format) { + // If VRAM compression is using ETC, but image has alpha, convert to RGBA4444 or LA8 + // This saves space while maintaining the alpha channel + if (detected_channels == Image::DETECTED_RGBA) { + p_img->convert(Image::FORMAT_RGBA4444); + return; + } else if (detected_channels == Image::DETECTED_LA) { + p_img->convert(Image::FORMAT_LA8); + return; + } + } + uint32_t imgw = p_img->get_width(), imgh = p_img->get_height(); Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels); diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 174ef14ec2..6ef1f2f4b9 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -170,6 +170,19 @@ bool GDAPI godot_is_instance_valid(const godot_object *p_object) { return ObjectDB::instance_validate((Object *)p_object); } +void *godot_get_class_tag(const godot_string_name *p_class) { + StringName class_name = *(StringName *)p_class; + ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(class_name); + return class_info ? class_info->class_ptr : NULL; +} + +godot_object *godot_object_cast_to(const godot_object *p_object, void *p_class_tag) { + if (!p_object) return NULL; + Object *o = (Object *)p_object; + + return o->is_class_ptr(p_class_tag) ? (godot_object *)o : NULL; +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 9e5295a936..7e2ca49f8d 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -140,6 +140,21 @@ "arguments": [ ["const godot_pool_color_array *", "p_self"] ] + }, + { + "name": "godot_get_class_tag", + "return_type": "void *", + "arguments": [ + ["const godot_string_name *", "p_class"] + ] + }, + { + "name": "godot_object_cast_to", + "return_type": "godot_object *", + "arguments": [ + ["const godot_object *", "p_object"], + ["void *", "p_class_tag"] + ] } ] }, diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 5a6333e814..2fe59b8a73 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -286,6 +286,10 @@ void GDAPI godot_print(const godot_string *p_message); bool GDAPI godot_is_instance_valid(const godot_object *p_object); +//tags used for safe dynamic casting +void GDAPI *godot_get_class_tag(const godot_string_name *p_class); +godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag); + #ifdef __cplusplus } #endif diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 94cd2536e3..b3d1b67af5 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -49,6 +49,7 @@ void GDScriptTextDocument::_bind_methods() { ClassDB::bind_method(D_METHOD("colorPresentation"), &GDScriptTextDocument::colorPresentation); ClassDB::bind_method(D_METHOD("hover"), &GDScriptTextDocument::hover); ClassDB::bind_method(D_METHOD("definition"), &GDScriptTextDocument::definition); + ClassDB::bind_method(D_METHOD("declaration"), &GDScriptTextDocument::declaration); ClassDB::bind_method(D_METHOD("show_native_symbol_in_editor"), &GDScriptTextDocument::show_native_symbol_in_editor); } @@ -340,84 +341,96 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) { } Array GDScriptTextDocument::definition(const Dictionary &p_params) { - Array arr; + lsp::TextDocumentPositionParams params; + params.load(p_params); + List<const lsp::DocumentSymbol *> symbols; + Array arr = this->find_symbols(params, symbols); + return arr; +} +Variant GDScriptTextDocument::declaration(const Dictionary &p_params) { lsp::TextDocumentPositionParams params; params.load(p_params); + List<const lsp::DocumentSymbol *> symbols; + Array arr = this->find_symbols(params, symbols); + if (arr.empty() && !symbols.empty() && !symbols.front()->get()->native_class.empty()) { // Find a native symbol + const lsp::DocumentSymbol *symbol = symbols.front()->get(); + if (GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) { + String id; + switch (symbol->kind) { + case lsp::SymbolKind::Class: + id = "class_name:" + symbol->name; + break; + case lsp::SymbolKind::Constant: + id = "class_constant:" + symbol->native_class + ":" + symbol->name; + break; + case lsp::SymbolKind::Property: + case lsp::SymbolKind::Variable: + id = "class_property:" + symbol->native_class + ":" + symbol->name; + break; + case lsp::SymbolKind::Enum: + id = "class_enum:" + symbol->native_class + ":" + symbol->name; + break; + case lsp::SymbolKind::Method: + case lsp::SymbolKind::Function: + id = "class_method:" + symbol->native_class + ":" + symbol->name; + break; + default: + id = "class_global:" + symbol->native_class + ":" + symbol->name; + break; + } + call_deferred("show_native_symbol_in_editor", id); + } else { + notify_client_show_symbol(symbol); + } + } + return arr; +} - const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params); +GDScriptTextDocument::GDScriptTextDocument() { + file_checker = FileAccess::create(FileAccess::ACCESS_RESOURCES); +} + +GDScriptTextDocument::~GDScriptTextDocument() { + memdelete(file_checker); +} + +void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) { + String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path); + GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content); +} + +void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) { + ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id); + OS::get_singleton()->move_window_to_foreground(); +} + +Array GDScriptTextDocument::find_symbols(const lsp::TextDocumentPositionParams &p_location, List<const lsp::DocumentSymbol *> &r_list) { + Array arr; + const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(p_location); if (symbol) { lsp::Location location; location.uri = symbol->uri; location.range = symbol->range; - const String &path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(symbol->uri); if (file_checker->file_exists(path)) { arr.push_back(location.to_json()); - } else if (!symbol->native_class.empty()) { - if (GDScriptLanguageProtocol::get_singleton()->is_goto_native_symbols_enabled()) { - String id; - switch (symbol->kind) { - case lsp::SymbolKind::Class: - id = "class_name:" + symbol->name; - break; - case lsp::SymbolKind::Constant: - id = "class_constant:" + symbol->native_class + ":" + symbol->name; - break; - case lsp::SymbolKind::Property: - case lsp::SymbolKind::Variable: - id = "class_property:" + symbol->native_class + ":" + symbol->name; - break; - case lsp::SymbolKind::Enum: - id = "class_enum:" + symbol->native_class + ":" + symbol->name; - break; - case lsp::SymbolKind::Method: - case lsp::SymbolKind::Function: - id = "class_method:" + symbol->native_class + ":" + symbol->name; - break; - default: - id = "class_global:" + symbol->native_class + ":" + symbol->name; - break; - } - call_deferred("show_native_symbol_in_editor", id); - } else { - notify_client_show_symbol(symbol); - } } + r_list.push_back(symbol); } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { - List<const lsp::DocumentSymbol *> list; - GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(params, list); + GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_related_symbols(p_location, list); for (List<const lsp::DocumentSymbol *>::Element *E = list.front(); E; E = E->next()) { - if (const lsp::DocumentSymbol *s = E->get()) { if (!s->uri.empty()) { lsp::Location location; location.uri = s->uri; location.range = s->range; arr.push_back(location.to_json()); + r_list.push_back(s); } } } } - return arr; } - -GDScriptTextDocument::GDScriptTextDocument() { - file_checker = FileAccess::create(FileAccess::ACCESS_RESOURCES); -} - -GDScriptTextDocument::~GDScriptTextDocument() { - memdelete(file_checker); -} - -void GDScriptTextDocument::sync_script_content(const String &p_path, const String &p_content) { - String path = GDScriptLanguageProtocol::get_singleton()->get_workspace()->get_file_path(p_path); - GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_script(path, p_content); -} - -void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) { - ScriptEditor::get_singleton()->call_deferred("_help_class_goto", p_symbol_id); - OS::get_singleton()->move_window_to_foreground(); -} diff --git a/modules/gdscript/language_server/gdscript_text_document.h b/modules/gdscript/language_server/gdscript_text_document.h index 8a7c6fb98c..d93d828003 100644 --- a/modules/gdscript/language_server/gdscript_text_document.h +++ b/modules/gdscript/language_server/gdscript_text_document.h @@ -51,6 +51,7 @@ protected: Array native_member_completions; private: + Array find_symbols(const lsp::TextDocumentPositionParams &p_location, List<const lsp::DocumentSymbol *> &r_list); lsp::TextDocumentItem load_document_item(const Variant &p_param); void notify_client_show_symbol(const lsp::DocumentSymbol *symbol); @@ -65,6 +66,7 @@ public: Array colorPresentation(const Dictionary &p_params); Variant hover(const Dictionary &p_params); Array definition(const Dictionary &p_params); + Variant declaration(const Dictionary &p_params); void initialize(); diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj index ae727e8789..b6bb0aac34 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj @@ -32,7 +32,7 @@ <Reference Include="System" /> <Reference Include="Microsoft.Build" /> <Reference Include="DotNet.Glob, Version=2.1.1.0, Culture=neutral, PublicKeyToken=b68cc888b4f632d1, processorArchitecture=MSIL"> - <HintPath>packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> + <HintPath>$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> </Reference> </ItemGroup> <ItemGroup> diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index df817e47e9..0462ef1125 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -541,7 +541,7 @@ namespace Godot return true; } - public static Color Color8(byte r8, byte g8, byte b8, byte a8) + public static Color Color8(byte r8, byte g8, byte b8, byte a8 = 255) { return new Color(r8 / 255f, g8 / 255f, b8 / 255f, a8 / 255f); } @@ -605,6 +605,74 @@ namespace Godot throw new ArgumentOutOfRangeException("Invalid color code. Blue part is not valid hexadecimal: " + rgba); } + public static Color operator +(Color left, Color right) + { + left.r += right.r; + left.g += right.g; + left.b += right.b; + left.a += right.a; + return left; + } + + public static Color operator -(Color left, Color right) + { + left.r -= right.r; + left.g -= right.g; + left.b -= right.b; + left.a -= right.a; + return left; + } + + public static Color operator -(Color color) + { + return Colors.White - color; + } + + public static Color operator *(Color color, float scale) + { + color.r *= scale; + color.g *= scale; + color.b *= scale; + color.a *= scale; + return color; + } + + public static Color operator *(float scale, Color color) + { + color.r *= scale; + color.g *= scale; + color.b *= scale; + color.a *= scale; + return color; + } + + public static Color operator *(Color left, Color right) + { + left.r *= right.r; + left.g *= right.g; + left.b *= right.b; + left.a *= right.a; + return left; + } + + public static Color operator /(Color color, float scale) + { + color.r /= scale; + color.g /= scale; + color.b /= scale; + color.a /= scale; + return color; + } + + public static Color operator /(Color left, Color right) + { + left.r /= right.r; + left.g /= right.g; + left.b /= right.b; + left.a /= right.a; + return left; + } + public static bool operator ==(Color left, Color right) { return left.Equals(right); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index 54821fe790..ddfed180b5 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -266,12 +266,14 @@ namespace Godot public static int Sign(int s) { + if (s == 0) return 0; return s < 0 ? -1 : 1; } - public static real_t Sign(real_t s) + public static int Sign(real_t s) { - return s < 0f ? -1f : 1f; + if (s == 0) return 0; + return s < 0 ? -1 : 1; } public static real_t Sin(real_t s) diff --git a/modules/mono/icons/icon_c_#.svg b/modules/mono/icons/icon_c_sharp_script.svg index 69664ca553..69664ca553 100644 --- a/modules/mono/icons/icon_c_#.svg +++ b/modules/mono/icons/icon_c_sharp_script.svg diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 7f25face15..4a022f0a9c 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -316,7 +316,7 @@ void Line2D::_draw() { lb.colors, lb.uvs, Vector<int>(), Vector<float>(), texture_rid, -1, RID(), - _antialiased); + _antialiased, true); // DEBUG // Draw wireframe diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 56467517d1..65912c1c07 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -171,9 +171,17 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) { } } - if (!p_event->is_pressed()) { // pressed state should be correct with button_up signal + if (!p_event->is_pressed()) { + Ref<InputEventMouseButton> mouse_button = p_event; + if (mouse_button.is_valid()) { + if (!has_point(mouse_button->get_position())) { + status.hovering = false; + } + } + // pressed state should be correct with button_up signal emit_signal("button_up"); status.press_attempt = false; + status.pressing_inside = false; } update(); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index bab8d9167b..01f4070883 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -573,9 +573,7 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) { } if (index < 0 || index >= presets.size()) return; - preset->set_tooltip("Color: #" + presets[index].to_html(presets[index].a < 1) + "\n" - "LMB: Set color\n" - "RMB: Remove preset"); + preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Set color\nRMB: Remove preset"), presets[index].to_html(presets[index].a < 1))); } } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index e6333a6179..87f17838cf 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -309,6 +309,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) { bool was_during_grabbed_click = during_grabbed_click; during_grabbed_click = false; + initial_button_mask = 0; int over = _get_mouse_over(b->get_position()); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 3cf17bd210..964f376dbd 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -2745,9 +2745,13 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventPanGesture> pan_gesture = p_event; if (pan_gesture.is_valid()) { - double prev_value = v_scroll->get_value(); + double prev_v = v_scroll->get_value(); v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8); - if (v_scroll->get_value() != prev_value) { + + double prev_h = h_scroll->get_value(); + h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8); + + if (v_scroll->get_value() != prev_v || h_scroll->get_value() != prev_h) { accept_event(); } } @@ -3455,30 +3459,48 @@ int Tree::get_item_offset(TreeItem *p_item) const { } void Tree::ensure_cursor_is_visible() { - - if (!is_inside_tree()) + if (!is_inside_tree()) { return; + } + if (!selected_item || (selected_col == -1)) { + return; // Nothing under cursor. + } - TreeItem *selected = get_selected(); - if (!selected) - return; - int ofs = get_item_offset(selected); - if (ofs == -1) - return; + const Size2 area_size = get_size() - cache.bg->get_minimum_size(); - const int tbh = _get_title_button_height(); - ofs -= tbh; + int y_offset = get_item_offset(selected_item); + if (y_offset != -1) { + const int tbh = _get_title_button_height(); + y_offset -= tbh; - const int marginh = cache.bg->get_margin(MARGIN_TOP) + cache.bg->get_margin(MARGIN_BOTTOM); - int h = compute_item_height(selected) + cache.vseparation; - int screenh = get_size().height - h_scroll->get_combined_minimum_size().height - marginh - tbh; + const int cell_h = compute_item_height(selected_item) + cache.vseparation; + const int screen_h = area_size.height - h_scroll->get_combined_minimum_size().height - tbh; - if (h > screenh) { //screen size is too small, maybe it was not resized yet. - v_scroll->set_value(ofs); - } else if (ofs + h > v_scroll->get_value() + screenh) { - v_scroll->call_deferred("set_value", ofs - screenh + h); - } else if (ofs < v_scroll->get_value()) { - v_scroll->set_value(ofs); + if (cell_h > screen_h) { // Screen size is too small, maybe it was not resized yet. + v_scroll->set_value(y_offset); + } else if (y_offset + cell_h > v_scroll->get_value() + screen_h) { + v_scroll->call_deferred("set_value", y_offset - screen_h + cell_h); + } else if (y_offset < v_scroll->get_value()) { + v_scroll->set_value(y_offset); + } + } + + if (select_mode != SELECT_ROW) { // Cursor always at col 0 in this mode. + int x_offset = 0; + for (int i = 0; i < selected_col; i++) { + x_offset += get_column_width(i); + } + + const int cell_w = get_column_width(selected_col); + const int screen_w = area_size.width - v_scroll->get_combined_minimum_size().width; + + if (cell_w > screen_w) { + h_scroll->set_value(x_offset); + } else if (x_offset + cell_w > h_scroll->get_value() + screen_w) { + h_scroll->call_deferred("set_value", x_offset - screen_w + cell_w); + } else if (x_offset < h_scroll->get_value()) { + h_scroll->set_value(x_offset); + } } } diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 09b001b377..da147e7112 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -631,7 +631,13 @@ void SceneTree::finish() { timers.clear(); } -void SceneTree::quit() { +void SceneTree::quit(int p_exit_code) { + + if (p_exit_code >= 0) { + // Override the exit code if a positive argument is given (the default is `-1`). + // This is a shorthand for calling `set_exit_code()` on the OS singleton then quitting. + OS::get_singleton()->set_exit_code(p_exit_code); + } _quit = true; } @@ -1812,8 +1818,6 @@ bool SceneTree::is_refusing_new_network_connections() const { void SceneTree::_bind_methods() { - //ClassDB::bind_method(D_METHOD("call_group","call_flags","group","method","arg1","arg2"),&SceneMainLoop::_call_group,DEFVAL(Variant()),DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("get_root"), &SceneTree::get_root); ClassDB::bind_method(D_METHOD("has_group", "name"), &SceneTree::has_group); @@ -1837,7 +1841,7 @@ void SceneTree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_count"), &SceneTree::get_node_count); ClassDB::bind_method(D_METHOD("get_frame"), &SceneTree::get_frame); - ClassDB::bind_method(D_METHOD("quit"), &SceneTree::quit); + ClassDB::bind_method(D_METHOD("quit", "exit_code"), &SceneTree::quit, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("set_screen_stretch", "mode", "aspect", "minsize", "shrink"), &SceneTree::set_screen_stretch, DEFVAL(1)); diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 9bb24238f2..55304fb12d 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -303,7 +303,7 @@ public: void set_auto_accept_quit(bool p_enable); void set_quit_on_go_back(bool p_enable); - void quit(); + void quit(int p_exit_code = -1); void set_input_as_handled(); bool is_input_handled(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b74b0fac1f..ab4dbb758a 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -30,6 +30,8 @@ #include "material.h" +#include "core/engine.h" + #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" #endif @@ -191,7 +193,10 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) { void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { - if (shader.is_valid()) { + // Only connect/disconnect the signal when running in the editor. + // This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`) + // does nothing in non-editor builds anyway. See GH-34741 for details. + if (shader.is_valid() && Engine::get_singleton()->is_editor_hint()) { shader->disconnect("changed", this, "_shader_changed"); } @@ -200,7 +205,10 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { RID rid; if (shader.is_valid()) { rid = shader->get_rid(); - shader->connect("changed", this, "_shader_changed"); + + if (Engine::get_singleton()->is_editor_hint()) { + shader->connect("changed", this, "_shader_changed"); + } } VS::get_singleton()->material_set_shader(_get_material(), rid); diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index c1f09cda21..74741a946c 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -782,6 +782,7 @@ public: RID normal_map; int count; bool antialiased; + bool antialiasing_use_indices; CommandPolygon() { type = TYPE_POLYGON; diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index d4fba708b1..e07e188ec6 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -778,12 +778,13 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2 polygon->indices = indices; polygon->count = indices.size(); polygon->antialiased = p_antialiased; + polygon->antialiasing_use_indices = false; canvas_item->rect_dirty = true; canvas_item->commands.push_back(polygon); } -void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, bool p_antialiased) { +void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, bool p_antialiased, bool p_antialiasing_use_indices) { Item *canvas_item = canvas_item_owner.getornull(p_item); ERR_FAIL_COND(!canvas_item); @@ -823,6 +824,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector polygon->indices = indices; polygon->count = count; polygon->antialiased = p_antialiased; + polygon->antialiasing_use_indices = p_antialiasing_use_indices; canvas_item->rect_dirty = true; canvas_item->commands.push_back(polygon); diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 366ec4d689..a2c641ce76 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -200,7 +200,7 @@ public: void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()); void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()); void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false); - void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), bool p_antialiased = false); + void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), bool p_antialiased = false, bool p_antialiasing_use_indices = false); void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID()); void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()); void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 51521446cd..54c46b1812 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -602,7 +602,7 @@ public: BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID) BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) - BIND11(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, bool) + BIND12(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, bool, bool) BIND6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID) BIND4(canvas_item_add_multimesh, RID, RID, RID, RID) BIND4(canvas_item_add_particles, RID, RID, RID, RID) diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index c218c47b43..f5875f4fad 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -520,7 +520,7 @@ public: FUNC11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID) FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID) FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool) - FUNC11(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, bool) + FUNC12(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID, bool, bool) FUNC6(canvas_item_add_mesh, RID, const RID &, const Transform2D &, const Color &, RID, RID) FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID) FUNC4(canvas_item_add_particles, RID, RID, RID, RID) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 8ba2b42b4b..1f72848b15 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1974,7 +1974,7 @@ void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate", "normal_map"), &VisualServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width", "normal_map"), &VisualServer::canvas_item_add_primitive, DEFVAL(1.0), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_polygon", "item", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &VisualServer::canvas_item_add_polygon, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(RID()), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "bones", "weights", "texture", "count", "normal_map", "antialiased"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(Vector<int>()), DEFVAL(Vector<float>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "bones", "weights", "texture", "count", "normal_map", "antialiased", "antialiasing_use_indices"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(Vector<int>()), DEFVAL(Vector<float>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()), DEFVAL(false), DEFVAL(false)); ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "transform", "modulate", "texture", "normal_map"), &VisualServer::canvas_item_add_mesh, DEFVAL(Transform2D()), DEFVAL(Color(1, 1, 1)), DEFVAL(RID()), DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map"), &VisualServer::canvas_item_add_particles); diff --git a/servers/visual_server.h b/servers/visual_server.h index 80c2142458..9aeee731b3 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -903,7 +903,7 @@ public: virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0; - virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), bool p_antialiased = false) = 0; + virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID(), bool p_antialiased = false, bool p_antialiasing_use_indices = false) = 0; virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform = Transform2D(), const Color &p_modulate = Color(1, 1, 1), RID p_texture = RID(), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0; virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map) = 0; |