diff options
| -rw-r--r-- | doc/classes/CollisionPolygon2D.xml | 1 | ||||
| -rw-r--r-- | doc/classes/Image.xml | 11 | ||||
| -rw-r--r-- | doc/classes/Node.xml | 2 | ||||
| -rw-r--r-- | doc/classes/ProjectSettings.xml | 4 | ||||
| -rw-r--r-- | doc/classes/RenderingDevice.xml | 2 | ||||
| -rw-r--r-- | editor/import/3d/resource_importer_obj.cpp | 35 | ||||
| -rw-r--r-- | editor/plugins/polygon_2d_editor_plugin.cpp | 152 | ||||
| -rw-r--r-- | editor/plugins/polygon_2d_editor_plugin.h | 9 | ||||
| -rw-r--r-- | misc/extension_api_validation/4.2-stable.expected | 2 | ||||
| -rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
| -rw-r--r-- | modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs | 2 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs | 13 | ||||
| -rw-r--r-- | scene/gui/popup_menu.cpp | 4 | ||||
| -rw-r--r-- | scene/main/node.cpp | 34 | ||||
| -rw-r--r-- | scene/theme/default_theme.cpp | 16 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp | 3 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl | 2 | ||||
| -rw-r--r-- | servers/rendering/rendering_device.compat.inc | 2 | ||||
| -rw-r--r-- | servers/rendering/rendering_device.h | 2 |
19 files changed, 174 insertions, 124 deletions
diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index d6f3b7cb5d..acb3f66c17 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -25,6 +25,7 @@ </member> <member name="polygon" type="PackedVector2Array" setter="set_polygon" getter="get_polygon" default="PackedVector2Array()"> The polygon's list of vertices. Each point will be connected to the next, and the final point will be connected to the first. + [b]Note:[/b] The returned vertices are in the local coordinate space of the given [CollisionPolygon2D]. [b]Warning:[/b] The returned value is a clone of the [PackedVector2Array], not a reference. </member> </members> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 872277b033..6c1ecb3aea 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -19,6 +19,7 @@ <param index="1" name="contrast" type="float" /> <param index="2" name="saturation" type="float" /> <description> + Adjusts this image's [param brightness], [param contrast], and [param saturation] by the given values. Does not work if the image is compressed (see [method is_compressed]). </description> </method> <method name="blend_rect"> @@ -163,6 +164,7 @@ <return type="int" enum="Image.UsedChannels" /> <param index="0" name="source" type="int" enum="Image.CompressSource" default="0" /> <description> + Returns the color channels used by this image, as one of the [enum UsedChannels] constants. If the image is compressed, the original [param source] must be specified. </description> </method> <method name="fill"> @@ -612,6 +614,7 @@ OpenGL texture format [code]RGBA[/code] with four components, each with a bitdepth of 4. </constant> <constant name="FORMAT_RGB565" value="7" enum="Format"> + OpenGL texture format [code]RGB[/code] with three components. Red and blue have a bitdepth of 5, and green has a bitdepth of 6. </constant> <constant name="FORMAT_RF" value="8" enum="Format"> OpenGL texture format [code]GL_R32F[/code] where there's one component, a 32-bit floating-point value. @@ -696,8 +699,10 @@ [b]Note:[/b] When creating an [ImageTexture], an sRGB to linear color space conversion is performed. </constant> <constant name="FORMAT_ETC2_RA_AS_RG" value="33" enum="Format"> + [url=https://en.wikipedia.org/wiki/Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression format 2[/url] ([code]RGBA8[/code] variant), which compresses RA data and interprets it as two channels (red and green). See also [constant FORMAT_ETC2_RGBA8]. </constant> <constant name="FORMAT_DXT5_RA_AS_RG" value="34" enum="Format"> + The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] texture format also known as Block Compression 3 or BC3, which compresses RA data and interprets it as two channels (red and green). See also [constant FORMAT_DXT5]. </constant> <constant name="FORMAT_ASTC_4x4" value="35" enum="Format"> [url=https://en.wikipedia.org/wiki/Adaptive_scalable_texture_compression]Adaptive Scalable Texture Compression[/url]. This implements the 4x4 (high quality) mode. @@ -761,16 +766,22 @@ Represents the size of the [enum CompressMode] enum. </constant> <constant name="USED_CHANNELS_L" value="0" enum="UsedChannels"> + The image only uses one channel for luminance (grayscale). </constant> <constant name="USED_CHANNELS_LA" value="1" enum="UsedChannels"> + The image uses two channels for luminance and alpha, respectively. </constant> <constant name="USED_CHANNELS_R" value="2" enum="UsedChannels"> + The image only uses the red channel. </constant> <constant name="USED_CHANNELS_RG" value="3" enum="UsedChannels"> + The image uses two channels for red and green. </constant> <constant name="USED_CHANNELS_RGB" value="4" enum="UsedChannels"> + The image uses three channels for red, green, and blue. </constant> <constant name="USED_CHANNELS_RGBA" value="5" enum="UsedChannels"> + The image uses four channels for red, green, blue, and alpha. </constant> <constant name="COMPRESS_SOURCE_GENERIC" value="0" enum="CompressSource"> Source texture (before compression) is a regular texture. Default for all textures. diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 8fb2e65faf..5dd3d22062 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -739,7 +739,7 @@ <param index="0" name="new_parent" type="Node" /> <param index="1" name="keep_global_transform" type="bool" default="true" /> <description> - Changes the parent of this [Node] to the [param new_parent]. The node needs to already have a parent. + Changes the parent of this [Node] to the [param new_parent]. The node needs to already have a parent. The node's [member owner] is preserved if its owner is still reachable from the new location (i.e., the node is still a descendant of the new parent after the operation). If [param keep_global_transform] is [code]true[/code], the node's global transform will be preserved if supported. [Node2D], [Node3D] and [Control] support this argument (but [Control] keeps only position). </description> </method> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 8640879a4e..b351a6dae6 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -810,7 +810,9 @@ Main window can't be focused. No-focus window will ignore all input, except mouse clicks. </member> <member name="display/window/size/resizable" type="bool" setter="" getter="" default="true"> - Allows the window to be resizable by default. + If [code]true[/code], allows the window to be resizable by default. + [b]Note:[/b] This property is only read when the project starts. To change whether the window is resizable at runtime, set [member Window.unresizable] instead on the root Window, which can be retrieved using [code]get_viewport().get_window()[/code]. [member Window.unresizable] takes the opposite value of this setting. + [b]Note:[/b] Certain window managers can be configured to ignore the non-resizable status of a window. Do not rely on this setting as a guarantee that the window will [i]never[/i] be resizable. [b]Note:[/b] This setting is ignored on iOS. </member> <member name="display/window/size/transparent" type="bool" setter="" getter="" default="false"> diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml index 495bec24dc..54f3281e17 100644 --- a/doc/classes/RenderingDevice.xml +++ b/doc/classes/RenderingDevice.xml @@ -2170,7 +2170,7 @@ <constant name="INITIAL_ACTION_CLEAR_REGION" value="1" enum="InitialAction" is_deprecated="true"> [i]Deprecated.[/i] Use [constant INITIAL_ACTION_CLEAR] instead. </constant> - <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="0" enum="InitialAction" is_deprecated="true"> + <constant name="INITIAL_ACTION_CLEAR_REGION_CONTINUE" value="1" enum="InitialAction" is_deprecated="true"> [i]Deprecated.[/i] Use [constant INITIAL_ACTION_LOAD] instead. </constant> <constant name="INITIAL_ACTION_KEEP" value="0" enum="InitialAction" is_deprecated="true"> diff --git a/editor/import/3d/resource_importer_obj.cpp b/editor/import/3d/resource_importer_obj.cpp index 082e78fdbe..a5e51636af 100644 --- a/editor/import/3d/resource_importer_obj.cpp +++ b/editor/import/3d/resource_importer_obj.cpp @@ -202,7 +202,7 @@ static Error _parse_material_library(const String &p_path, HashMap<String, Ref<S return OK; } -static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, bool p_disable_compression, List<String> *r_missing_deps) { +static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, bool p_disable_compression, List<String> *r_missing_deps) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path)); @@ -220,7 +220,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ ERR_FAIL_COND_V_MSG(coff_header_machines.find(first_bytes) != -1, ERR_FILE_CORRUPT, vformat("Couldn't read OBJ file '%s', it seems to be binary, corrupted, or empty.", p_path)); f->seek(0); - Ref<ArrayMesh> mesh; + Ref<ImporterMesh> mesh; mesh.instantiate(); bool generate_tangents = p_generate_tangents; @@ -400,24 +400,24 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ print_verbose("OBJ: Current material library " + current_material_library + " has " + itos(material_map.has(current_material_library))); print_verbose("OBJ: Current material " + current_material + " has " + itos(material_map.has(current_material_library) && material_map[current_material_library].has(current_material))); - + Ref<StandardMaterial3D> material; if (material_map.has(current_material_library) && material_map[current_material_library].has(current_material)) { - Ref<StandardMaterial3D> &material = material_map[current_material_library][current_material]; + material = material_map[current_material_library][current_material]; if (!colors.is_empty()) { material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); } surf_tool->set_material(material); } - mesh = surf_tool->commit(mesh, mesh_flags); - if (!current_material.is_empty()) { - mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename()); + mesh->set_surface_name(mesh->get_surface_count() - 1, current_material.get_basename()); } else if (!current_group.is_empty()) { - mesh->surface_set_name(mesh->get_surface_count() - 1, current_group); + mesh->set_surface_name(mesh->get_surface_count() - 1, current_group); } + Array array = surf_tool->commit_to_arrays(); + mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, array, TypedArray<Array>(), Dictionary(), material, name, mesh_flags); + print_verbose("OBJ: Added surface :" + mesh->get_surface_name(mesh->get_surface_count() - 1)); - print_verbose("OBJ: Added surface :" + mesh->surface_get_name(mesh->get_surface_count() - 1)); surf_tool->clear(); surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES); } @@ -476,7 +476,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ } Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { - List<Ref<Mesh>> meshes; + List<Ref<ImporterMesh>> meshes; Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, false, Vector3(1, 1, 1), Vector3(0, 0, 0), p_flags & IMPORT_FORCE_DISABLE_MESH_COMPRESSION, r_missing_deps); @@ -489,16 +489,9 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, co Node3D *scene = memnew(Node3D); - for (const Ref<Mesh> &m : meshes) { - Ref<ImporterMesh> mesh; - mesh.instantiate(); - mesh->set_name(m->get_name()); - for (int i = 0; i < m->get_surface_count(); i++) { - mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i), String(), m->surface_get_format(i)); - } - + for (Ref<ImporterMesh> m : meshes) { ImporterMeshInstance3D *mi = memnew(ImporterMeshInstance3D); - mi->set_mesh(mesh); + mi->set_mesh(m); mi->set_name(m->get_name()); scene->add_child(mi, true); mi->set_owner(scene); @@ -565,7 +558,7 @@ bool ResourceImporterOBJ::get_option_visibility(const String &p_path, const Stri } Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { - List<Ref<Mesh>> meshes; + List<Ref<ImporterMesh>> meshes; Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], p_options["force_disable_mesh_compression"], nullptr); @@ -574,7 +567,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s String save_path = p_save_path + ".mesh"; - err = ResourceSaver::save(meshes.front()->get(), save_path); + err = ResourceSaver::save(meshes.front()->get()->get_mesh(), save_path); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Mesh to file '" + save_path + "'."); diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index f8e6c71a4c..148ba7d7ca 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -36,6 +36,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_zoom_widget.h" #include "editor/plugins/canvas_item_editor_plugin.h" #include "scene/2d/skeleton_2d.h" #include "scene/gui/check_box.h" @@ -96,10 +97,14 @@ void Polygon2DEditor::_notification(int p_what) { b_snap_grid->set_icon(get_editor_theme_icon(SNAME("Grid"))); b_snap_enable->set_icon(get_editor_theme_icon(SNAME("SnapGrid"))); - uv_icon_zoom->set_texture(get_editor_theme_icon(SNAME("Zoom"))); uv_vscroll->set_anchors_and_offsets_preset(PRESET_RIGHT_WIDE); uv_hscroll->set_anchors_and_offsets_preset(PRESET_BOTTOM_WIDE); + // Avoid scrollbar overlapping. + Size2 hmin = uv_hscroll->get_combined_minimum_size(); + Size2 vmin = uv_vscroll->get_combined_minimum_size(); + uv_hscroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, -vmin.width); + uv_vscroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, -hmin.height); [[fallthrough]]; } case NOTIFICATION_THEME_CHANGED: { @@ -317,6 +322,7 @@ void Polygon2DEditor::_menu_option(int p_option) { uv_edit->popup_centered_ratio(0.85); } _update_bone_list(); + get_tree()->connect("process_frame", callable_mp(this, &Polygon2DEditor::_center_view), CONNECT_ONE_SHOT); } break; case UVEDIT_POLYGON_TO_UV: { Vector<Vector2> points = node->get_polygon(); @@ -470,7 +476,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { } Transform2D mtx; - mtx.columns[2] = -uv_draw_ofs; + mtx.columns[2] = -uv_draw_ofs * uv_draw_zoom; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); @@ -941,36 +947,79 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { uv_edit_draw->queue_redraw(); } } +} - Ref<InputEventMagnifyGesture> magnify_gesture = p_input; - if (magnify_gesture.is_valid()) { - uv_zoom->set_value(uv_zoom->get_value() * magnify_gesture->get_factor()); +void Polygon2DEditor::_center_view() { + Size2 texture_size; + if (node->get_texture().is_valid()) { + texture_size = node->get_texture()->get_size(); + Vector2 zoom_factor = (uv_edit_draw->get_size() - Vector2(1, 1) * 50 * EDSCALE) / texture_size; + zoom_widget->set_zoom(MIN(zoom_factor.x, zoom_factor.y)); + } else { + zoom_widget->set_zoom(EDSCALE); } + // Recalculate scroll limits. + _update_zoom_and_pan(false); - Ref<InputEventPanGesture> pan_gesture = p_input; - if (pan_gesture.is_valid()) { - uv_hscroll->set_value(uv_hscroll->get_value() + uv_hscroll->get_page() * pan_gesture->get_delta().x / 8); - uv_vscroll->set_value(uv_vscroll->get_value() + uv_vscroll->get_page() * pan_gesture->get_delta().y / 8); - } + Size2 offset = (texture_size - uv_edit_draw->get_size() / uv_draw_zoom) / 2; + uv_hscroll->set_value_no_signal(offset.x); + uv_vscroll->set_value_no_signal(offset.y); + _update_zoom_and_pan(false); } void Polygon2DEditor::_uv_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) { - uv_hscroll->set_value(uv_hscroll->get_value() - p_scroll_vec.x); - uv_vscroll->set_value(uv_vscroll->get_value() - p_scroll_vec.y); + uv_hscroll->set_value_no_signal(uv_hscroll->get_value() - p_scroll_vec.x / uv_draw_zoom); + uv_vscroll->set_value_no_signal(uv_vscroll->get_value() - p_scroll_vec.y / uv_draw_zoom); + _update_zoom_and_pan(false); } void Polygon2DEditor::_uv_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event) { - uv_zoom->set_value(uv_zoom->get_value() * p_zoom_factor); + zoom_widget->set_zoom(uv_draw_zoom * p_zoom_factor); + uv_draw_ofs += p_origin / uv_draw_zoom - p_origin / zoom_widget->get_zoom(); + uv_hscroll->set_value_no_signal(uv_draw_ofs.x); + uv_vscroll->set_value_no_signal(uv_draw_ofs.y); + _update_zoom_and_pan(false); } -void Polygon2DEditor::_uv_scroll_changed(real_t) { - if (updating_uv_scroll) { - return; +void Polygon2DEditor::_update_zoom_and_pan(bool p_zoom_at_center) { + uv_draw_ofs = Vector2(uv_hscroll->get_value(), uv_vscroll->get_value()); + real_t previous_zoom = uv_draw_zoom; + uv_draw_zoom = zoom_widget->get_zoom(); + if (p_zoom_at_center) { + Vector2 center = uv_edit_draw->get_size() / 2; + uv_draw_ofs += center / previous_zoom - center / uv_draw_zoom; + } + + Point2 min_corner; + Point2 max_corner; + if (node->get_texture().is_valid()) { + max_corner += node->get_texture()->get_size(); + } + + Vector<Vector2> points = uv_edit_mode[0]->is_pressed() ? node->get_uv() : node->get_polygon(); + for (int i = 0; i < points.size(); i++) { + min_corner = min_corner.min(points[i]); + max_corner = max_corner.max(points[i]); } + Size2 page_size = uv_edit_draw->get_size() / uv_draw_zoom; + Vector2 margin = Vector2(50, 50) * EDSCALE / uv_draw_zoom; + min_corner -= page_size - margin; + max_corner += page_size - margin; + + uv_hscroll->set_block_signals(true); + uv_hscroll->set_min(min_corner.x); + uv_hscroll->set_max(max_corner.x); + uv_hscroll->set_page(page_size.x); + uv_hscroll->set_value(uv_draw_ofs.x); + uv_hscroll->set_block_signals(false); + + uv_vscroll->set_block_signals(true); + uv_vscroll->set_min(min_corner.y); + uv_vscroll->set_max(max_corner.y); + uv_vscroll->set_page(page_size.y); + uv_vscroll->set_value(uv_draw_ofs.y); + uv_vscroll->set_block_signals(false); - uv_draw_ofs.x = uv_hscroll->get_value(); - uv_draw_ofs.y = uv_vscroll->get_value(); - uv_draw_zoom = uv_zoom->get_value(); uv_edit_draw->queue_redraw(); } @@ -987,7 +1036,7 @@ void Polygon2DEditor::_uv_draw() { String warning; Transform2D mtx; - mtx.columns[2] = -uv_draw_ofs; + mtx.columns[2] = -uv_draw_ofs * uv_draw_zoom; mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom)); // Draw texture as a background if editing uvs or no uv mapping exist. @@ -1094,7 +1143,6 @@ void Polygon2DEditor::_uv_draw() { polygon_fill_color.push_back(pf); } Color prev_color = Color(0.5, 0.5, 0.5); - Rect2 rect; int uv_draw_max = uvs.size(); @@ -1222,40 +1270,6 @@ void Polygon2DEditor::_uv_draw() { //draw paint circle uv_edit_draw->draw_circle(bone_paint_pos, bone_paint_radius->get_value() * EDSCALE, Color(1, 1, 1, 0.1)); } - - rect.position = -uv_edit_draw->get_size(); - rect.size = uv_edit_draw->get_size() * 2.0 + base_tex->get_size() * uv_draw_zoom; - - updating_uv_scroll = true; - - uv_hscroll->set_min(rect.position.x); - uv_hscroll->set_max(rect.position.x + rect.size.x); - if (ABS(rect.position.x - (rect.position.x + rect.size.x)) <= uv_edit_draw->get_size().x) { - uv_hscroll->hide(); - } else { - uv_hscroll->show(); - uv_hscroll->set_page(uv_edit_draw->get_size().x); - uv_hscroll->set_value(uv_draw_ofs.x); - } - - uv_vscroll->set_min(rect.position.y); - uv_vscroll->set_max(rect.position.y + rect.size.y); - if (ABS(rect.position.y - (rect.position.y + rect.size.y)) <= uv_edit_draw->get_size().y) { - uv_vscroll->hide(); - } else { - uv_vscroll->show(); - uv_vscroll->set_page(uv_edit_draw->get_size().y); - uv_vscroll->set_value(uv_draw_ofs.y); - } - - Size2 hmin = uv_hscroll->get_combined_minimum_size(); - Size2 vmin = uv_vscroll->get_combined_minimum_size(); - - // Avoid scrollbar overlapping. - uv_hscroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, uv_vscroll->is_visible() ? -vmin.width : 0); - uv_vscroll->set_anchor_and_offset(SIDE_BOTTOM, ANCHOR_END, uv_hscroll->is_visible() ? -hmin.height : 0); - - updating_uv_scroll = false; } void Polygon2DEditor::_bind_methods() { @@ -1480,33 +1494,20 @@ Polygon2DEditor::Polygon2DEditor() { sb_step_y->connect("value_changed", callable_mp(this, &Polygon2DEditor::_set_snap_step_y)); grid_settings_vb->add_margin_child(TTR("Grid Step Y:"), sb_step_y); - uv_mode_hb->add_child(memnew(VSeparator)); - uv_icon_zoom = memnew(TextureRect); - uv_icon_zoom->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - uv_mode_hb->add_child(uv_icon_zoom); - uv_zoom = memnew(HSlider); - uv_zoom->set_min(0.01); - uv_zoom->set_max(16); - uv_zoom->set_value(1); - uv_zoom->set_step(0.01); - uv_zoom->set_v_size_flags(SIZE_SHRINK_CENTER); - - uv_mode_hb->add_child(uv_zoom); - uv_zoom->set_custom_minimum_size(Size2(80 * EDSCALE, 0)); - uv_zoom_value = memnew(SpinBox); - uv_zoom->share(uv_zoom_value); - uv_zoom_value->set_custom_minimum_size(Size2(50, 0)); - uv_mode_hb->add_child(uv_zoom_value); - uv_zoom->connect("value_changed", callable_mp(this, &Polygon2DEditor::_uv_scroll_changed)); + zoom_widget = memnew(EditorZoomWidget); + uv_edit_draw->add_child(zoom_widget); + zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE); + zoom_widget->connect("zoom_changed", callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(true)); + zoom_widget->set_shortcut_context(nullptr); uv_vscroll = memnew(VScrollBar); uv_vscroll->set_step(0.001); uv_edit_draw->add_child(uv_vscroll); - uv_vscroll->connect("value_changed", callable_mp(this, &Polygon2DEditor::_uv_scroll_changed)); + uv_vscroll->connect("value_changed", callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(false)); uv_hscroll = memnew(HScrollBar); uv_hscroll->set_step(0.001); uv_edit_draw->add_child(uv_hscroll); - uv_hscroll->connect("value_changed", callable_mp(this, &Polygon2DEditor::_uv_scroll_changed)); + uv_hscroll->connect("value_changed", callable_mp(this, &Polygon2DEditor::_update_zoom_and_pan).unbind(1).bind(false)); bone_scroll_main_vb = memnew(VBoxContainer); bone_scroll_main_vb->hide(); @@ -1535,7 +1536,6 @@ Polygon2DEditor::Polygon2DEditor() { point_drag_index = -1; uv_drag = false; uv_create = false; - updating_uv_scroll = false; bone_painting = false; error = memnew(AcceptDialog); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 8c52984b59..164aa3eccc 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -35,6 +35,7 @@ class AcceptDialog; class ButtonGroup; +class EditorZoomWidget; class HScrollBar; class HSlider; class Label; @@ -85,12 +86,10 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { Panel *uv_edit_background = nullptr; Polygon2D *preview_polygon = nullptr; Control *uv_edit_draw = nullptr; - HSlider *uv_zoom = nullptr; - SpinBox *uv_zoom_value = nullptr; + EditorZoomWidget *zoom_widget = nullptr; HScrollBar *uv_hscroll = nullptr; VScrollBar *uv_vscroll = nullptr; MenuButton *uv_menu = nullptr; - TextureRect *uv_icon_zoom = nullptr; Ref<ViewPanner> uv_panner; void _uv_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event); @@ -129,7 +128,6 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { Vector<int> polygon_create; UVMode uv_move_current; Vector2 uv_drag_from; - bool updating_uv_scroll; AcceptDialog *error = nullptr; @@ -145,7 +143,8 @@ class Polygon2DEditor : public AbstractPolygon2DEditor { void _cancel_editing(); void _update_polygon_editing_state(); - void _uv_scroll_changed(real_t); + void _center_view(); + void _update_zoom_and_pan(bool p_zoom_at_center); void _uv_input(const Ref<InputEvent> &p_input); void _uv_draw(); void _uv_mode(int p_mode); diff --git a/misc/extension_api_validation/4.2-stable.expected b/misc/extension_api_validation/4.2-stable.expected index 53303ebec4..2c52144896 100644 --- a/misc/extension_api_validation/4.2-stable.expected +++ b/misc/extension_api_validation/4.2-stable.expected @@ -35,7 +35,7 @@ GH-84976 Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/FinalAction/values/FINAL_ACTION_CONTINUE': value changed value in new API, from 2.0 to 0. Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/FinalAction/values/FINAL_ACTION_MAX': value changed value in new API, from 3.0 to 2. Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CLEAR': value changed value in new API, from 0.0 to 1. -Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CLEAR_REGION_CONTINUE': value changed value in new API, from 2.0 to 0. +Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CLEAR_REGION_CONTINUE': value changed value in new API, from 2.0 to 1. Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_CONTINUE': value changed value in new API, from 5.0 to 0. Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_DROP': value changed value in new API, from 4.0 to 2. Validate extension JSON: Error: Field 'classes/RenderingDevice/enums/InitialAction/values/INITIAL_ACTION_KEEP': value changed value in new API, from 3.0 to 0. diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 2bbd56776a..ac6977504a 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2365,6 +2365,8 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) { MethodInfo mi; mi.name = name; + mi.return_val = PropertyInfo::from_dict(method_info_dict["return_val"]); + Array params = method_info_dict["params"]; for (int j = 0; j < params.size(); j++) { diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs index 147ef852b3..1113629fef 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs @@ -146,7 +146,7 @@ namespace Godot.SourceGenerators DiagnosticSeverity.Error, isEnabledByDefault: true, description, - helpLinkUri: string.Format(_helpLinkFormat, "GD1003")), + helpLinkUri: string.Format(_helpLinkFormat, "GD0103")), location, location?.SourceTree?.FilePath)); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index a087b20308..968afa664b 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -662,6 +662,19 @@ namespace Godot.Bridge methodInfo.Add("name", method.Name); + var returnVal = new Collections.Dictionary() + { + { "name", method.ReturnVal.Name }, + { "type", (int)method.ReturnVal.Type }, + { "usage", (int)method.ReturnVal.Usage } + }; + if (method.ReturnVal.ClassName != null) + { + returnVal["class_name"] = method.ReturnVal.ClassName; + } + + methodInfo.Add("return_val", returnVal); + var methodParams = new Collections.Array(); if (method.Arguments != null) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 8af05bd205..12e8d3eba9 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -794,9 +794,7 @@ void PopupMenu::_draw_items() { } } - Color icon_color(1, 1, 1, items[i].disabled && !items[i].separator ? 0.5 : 1); - - icon_color *= items[i].icon_modulate; + Color icon_color = items[i].icon_modulate; // For non-separator items, add some padding for the content. if (!items[i].separator) { diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1dd3b8bd1b..a6b7ca8188 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1736,8 +1736,40 @@ void Node::reparent(Node *p_parent, bool p_keep_global_transform) { return; } + bool preserve_owner = data.owner && (data.owner == p_parent || data.owner->is_ancestor_of(p_parent)); + Node *owner_temp = data.owner; + LocalVector<Node *> common_parents; + + // If the new parent is related to the owner, find all children of the reparented node who have the same owner so that we can reassign them. + if (preserve_owner) { + LocalVector<Node *> to_visit; + + to_visit.push_back(this); + common_parents.push_back(this); + + while (to_visit.size() > 0) { + Node *check = to_visit[to_visit.size() - 1]; + to_visit.resize(to_visit.size() - 1); + + for (int i = 0; i < check->get_child_count(); i++) { + Node *child = check->get_child(i, false); + to_visit.push_back(child); + if (child->data.owner == owner_temp) { + common_parents.push_back(child); + } + } + } + } + data.parent->remove_child(this); p_parent->add_child(this); + + // Reassign the old owner to those found nodes. + if (preserve_owner) { + for (Node *E : common_parents) { + E->set_owner(owner_temp); + } + } } Node *Node::get_parent() const { @@ -1925,7 +1957,7 @@ void Node::set_owner(Node *p_owner) { return; } - Node *check = this->get_parent(); + Node *check = get_parent(); bool owner_valid = false; while (check) { diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index d1b854246b..2a1894e690 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -299,13 +299,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("focus", "CheckBox", cbx_focus); theme->set_icon("checked", "CheckBox", icons["checked"]); - theme->set_icon("checked_disabled", "CheckBox", icons["checked"]); + theme->set_icon("checked_disabled", "CheckBox", icons["checked_disabled"]); theme->set_icon("unchecked", "CheckBox", icons["unchecked"]); - theme->set_icon("unchecked_disabled", "CheckBox", icons["unchecked"]); + theme->set_icon("unchecked_disabled", "CheckBox", icons["unchecked_disabled"]); theme->set_icon("radio_checked", "CheckBox", icons["radio_checked"]); - theme->set_icon("radio_checked_disabled", "CheckBox", icons["radio_checked"]); + theme->set_icon("radio_checked_disabled", "CheckBox", icons["radio_checked_disabled"]); theme->set_icon("radio_unchecked", "CheckBox", icons["radio_unchecked"]); - theme->set_icon("radio_unchecked_disabled", "CheckBox", icons["radio_unchecked"]); + theme->set_icon("radio_unchecked_disabled", "CheckBox", icons["radio_unchecked_disabled"]); theme->set_font("font", "CheckBox", Ref<Font>()); theme->set_font_size("font_size", "CheckBox", -1); @@ -685,13 +685,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("labeled_separator_right", "PopupMenu", separator_horizontal); theme->set_icon("checked", "PopupMenu", icons["checked"]); - theme->set_icon("checked_disabled", "PopupMenu", icons["checked"]); + theme->set_icon("checked_disabled", "PopupMenu", icons["checked_disabled"]); theme->set_icon("unchecked", "PopupMenu", icons["unchecked"]); - theme->set_icon("unchecked_disabled", "PopupMenu", icons["unchecked"]); + theme->set_icon("unchecked_disabled", "PopupMenu", icons["unchecked_disabled"]); theme->set_icon("radio_checked", "PopupMenu", icons["radio_checked"]); - theme->set_icon("radio_checked_disabled", "PopupMenu", icons["radio_checked"]); + theme->set_icon("radio_checked_disabled", "PopupMenu", icons["radio_checked_disabled"]); theme->set_icon("radio_unchecked", "PopupMenu", icons["radio_unchecked"]); - theme->set_icon("radio_unchecked_disabled", "PopupMenu", icons["radio_unchecked"]); + theme->set_icon("radio_unchecked_disabled", "PopupMenu", icons["radio_unchecked_disabled"]); theme->set_icon("submenu", "PopupMenu", icons["popup_menu_arrow_right"]); theme->set_icon("submenu_mirrored", "PopupMenu", icons["popup_menu_arrow_left"]); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 28fccbaf88..283b3ee09a 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1721,8 +1721,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1)); Rect2i rect((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2); - RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR : RD::INITIAL_ACTION_LOAD; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, RD::FINAL_ACTION_STORE, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); Projection projection; { diff --git a/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl index db710b7cdd..e87f644bb0 100644 --- a/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl @@ -30,7 +30,7 @@ void main() { vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); uv_interp.xy = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 -#ifdef MULTIVIEW +#ifdef USE_MULTIVIEW uv_interp.z = ViewIndex; #endif } diff --git a/servers/rendering/rendering_device.compat.inc b/servers/rendering/rendering_device.compat.inc index f79c9c9f7c..edc08e972d 100644 --- a/servers/rendering/rendering_device.compat.inc +++ b/servers/rendering/rendering_device.compat.inc @@ -59,8 +59,8 @@ RenderingDevice::InitialAction RenderingDevice::_convert_initial_action_84976(In case 0: // INITIAL_ACTION_CLEAR return INITIAL_ACTION_CLEAR; case 1: // INITIAL_ACTION_CLEAR_REGION - return INITIAL_ACTION_CLEAR; case 2: // INITIAL_ACTION_CLEAR_REGION_CONTINUE + return INITIAL_ACTION_CLEAR; case 3: // INITIAL_ACTION_KEEP return INITIAL_ACTION_LOAD; case 4: // INITIAL_ACTION_DROP diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 6c98ccfeda..2ccef66308 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -335,7 +335,7 @@ public: INITIAL_ACTION_MAX, #ifndef DISABLE_DEPRECATED INITIAL_ACTION_CLEAR_REGION = INITIAL_ACTION_CLEAR, - INITIAL_ACTION_CLEAR_REGION_CONTINUE = INITIAL_ACTION_LOAD, + INITIAL_ACTION_CLEAR_REGION_CONTINUE = INITIAL_ACTION_CLEAR, INITIAL_ACTION_KEEP = INITIAL_ACTION_LOAD, INITIAL_ACTION_DROP = INITIAL_ACTION_DISCARD, INITIAL_ACTION_CONTINUE = INITIAL_ACTION_LOAD, |
