diff options
Diffstat (limited to 'editor/plugins')
30 files changed, 447 insertions, 276 deletions
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 030d90eeca..24cb660f7a 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -66,9 +66,13 @@ void AnimationNodeBlendTreeEditor::remove_custom_type(const Ref<Script> &p_scrip _update_options_menu(); } -void AnimationNodeBlendTreeEditor::_update_options_menu() { +void AnimationNodeBlendTreeEditor::_update_options_menu(bool p_has_input_ports) { add_node->get_popup()->clear(); + add_node->get_popup()->set_size(Size2i(-1, -1)); for (int i = 0; i < add_options.size(); i++) { + if (p_has_input_ports && add_options[i].input_port_count == 0) { + continue; + } add_node->get_popup()->add_item(add_options[i].name, i); } @@ -309,6 +313,11 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { return; } + if (!from_node.is_empty() && anode->get_input_count() == 0) { + from_node = ""; + return; + } + Point2 instance_pos = graph->get_scroll_ofs(); if (use_popup_menu_position) { instance_pos += popup_menu_position; @@ -328,11 +337,51 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) { undo_redo->create_action(TTR("Add Node to BlendTree")); undo_redo->add_do_method(blend_tree.ptr(), "add_node", name, anode, instance_pos / EDSCALE); undo_redo->add_undo_method(blend_tree.ptr(), "remove_node", name); + + if (!from_node.is_empty()) { + undo_redo->add_do_method(blend_tree.ptr(), "connect_node", name, 0, from_node); + from_node = ""; + } + if (!to_node.is_empty() && to_slot != -1) { + undo_redo->add_do_method(blend_tree.ptr(), "connect_node", to_node, to_slot, name); + to_node = ""; + to_slot = -1; + } + undo_redo->add_do_method(this, "_update_graph"); undo_redo->add_undo_method(this, "_update_graph"); undo_redo->commit_action(); } +void AnimationNodeBlendTreeEditor::_popup(bool p_has_input_ports, const Vector2 &p_popup_position, const Vector2 &p_node_position) { + _update_options_menu(p_has_input_ports); + use_popup_menu_position = true; + popup_menu_position = p_popup_position; + add_node->get_popup()->set_position(p_node_position); + add_node->get_popup()->popup(); +} + +void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) { + _popup(false, graph->get_local_mouse_position(), p_position); +} + +void AnimationNodeBlendTreeEditor::_connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position) { + Ref<AnimationNode> node = blend_tree->get_node(p_from); + if (node.is_valid()) { + from_node = p_from; + _popup(true, p_release_position, graph->get_global_mouse_position()); + } +} + +void AnimationNodeBlendTreeEditor::_connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position) { + Ref<AnimationNode> node = blend_tree->get_node(p_to); + if (node.is_valid()) { + to_node = p_to; + to_slot = p_to_slot; + _popup(false, p_release_position, graph->get_global_mouse_position()); + } +} + void AnimationNodeBlendTreeEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which) { updating = true; undo_redo->create_action(TTR("Node Moved")); @@ -431,14 +480,6 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() { undo_redo->commit_action(); } -void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) { - _update_options_menu(); - use_popup_menu_position = true; - popup_menu_position = graph->get_local_mouse_position(); - add_node->get_popup()->set_position(p_position); - add_node->get_popup()->popup(); -} - void AnimationNodeBlendTreeEditor::_node_selected(Object *p_node) { GraphNode *gn = Object::cast_to<GraphNode>(p_node); ERR_FAIL_COND(!gn); @@ -890,6 +931,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { graph->connect("scroll_offset_changed", callable_mp(this, &AnimationNodeBlendTreeEditor::_scroll_changed)); graph->connect("delete_nodes_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_delete_nodes_request)); graph->connect("popup_request", callable_mp(this, &AnimationNodeBlendTreeEditor::_popup_request)); + graph->connect("connection_to_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_to_empty)); + graph->connect("connection_from_empty", callable_mp(this, &AnimationNodeBlendTreeEditor::_connection_from_empty)); float graph_minimap_opacity = EditorSettings::get_singleton()->get("editors/visual_editors/minimap_opacity"); graph->set_minimap_opacity(graph_minimap_opacity); @@ -905,13 +948,13 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() { add_node->connect("about_to_popup", callable_mp(this, &AnimationNodeBlendTreeEditor::_update_options_menu)); add_options.push_back(AddOption("Animation", "AnimationNodeAnimation")); - add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot")); - add_options.push_back(AddOption("Add2", "AnimationNodeAdd2")); - add_options.push_back(AddOption("Add3", "AnimationNodeAdd3")); - add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2")); - add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3")); - add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek")); - add_options.push_back(AddOption("TimeScale", "AnimationNodeTimeScale")); + add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot", 2)); + add_options.push_back(AddOption("Add2", "AnimationNodeAdd2", 2)); + add_options.push_back(AddOption("Add3", "AnimationNodeAdd3", 3)); + add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2", 2)); + add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3", 3)); + add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek", 1)); + add_options.push_back(AddOption("TimeScale", "AnimationNodeTimeScale", 1)); add_options.push_back(AddOption("Transition", "AnimationNodeTransition")); add_options.push_back(AddOption("BlendTree", "AnimationNodeBlendTree")); add_options.push_back(AddOption("BlendSpace1D", "AnimationNodeBlendSpace1D")); diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h index 9f09069719..0fcafad40e 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.h +++ b/editor/plugins/animation_blend_tree_editor_plugin.h @@ -64,22 +64,28 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { Map<StringName, ProgressBar *> animations; Vector<EditorProperty *> visible_properties; + String to_node = ""; + int to_slot = -1; + String from_node = ""; + void _update_graph(); struct AddOption { String name; String type; Ref<Script> script; - AddOption(const String &p_name = String(), const String &p_type = String()) : + int input_port_count; + AddOption(const String &p_name = String(), const String &p_type = String(), bool p_input_port_count = 0) : name(p_name), - type(p_type) { + type(p_type), + input_port_count(p_input_port_count) { } }; Vector<AddOption> add_options; void _add_node(int p_idx); - void _update_options_menu(); + void _update_options_menu(bool p_has_input_ports = false); static AnimationNodeBlendTreeEditor *singleton; @@ -98,7 +104,6 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { void _anim_selected(int p_index, Array p_options, const String &p_node); void _delete_request(const String &p_which); void _delete_nodes_request(); - void _popup_request(const Vector2 &p_position); bool _update_filters(const Ref<AnimationNode> &anode); void _edit_filters(const String &p_which); @@ -106,6 +111,11 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin { void _filter_toggled(); Ref<AnimationNode> _filter_edit; + void _popup(bool p_has_input_ports, const Vector2 &p_popup_position, const Vector2 &p_node_position); + void _popup_request(const Vector2 &p_position); + void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position); + void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position); + void _property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing); void _removed_from_graph(); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 830b010d01..18b4966f80 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -904,7 +904,7 @@ void AnimationPlayerEditor::edit(AnimationPlayer *p_player) { } } -void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_overlay) { +void AnimationPlayerEditor::forward_force_draw_over_viewport(Control *p_overlay) { if (!onion.can_overlay) { return; } diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index be80b7f4e3..0a514d3ff1 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -238,7 +238,7 @@ public: void set_undo_redo(UndoRedo *p_undo_redo) { undo_redo = p_undo_redo; } void edit(AnimationPlayer *p_player); - void forward_canvas_force_draw_over_viewport(Control *p_overlay); + void forward_force_draw_over_viewport(Control *p_overlay); AnimationPlayerEditor(EditorNode *p_editor, AnimationPlayerEditorPlugin *p_plugin); }; @@ -262,7 +262,8 @@ public: virtual bool handles(Object *p_object) const override; virtual void make_visible(bool p_visible) override; - virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_canvas_force_draw_over_viewport(p_overlay); } + virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); } + virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay) override { anim_editor->forward_force_draw_over_viewport(p_overlay); } AnimationPlayerEditorPlugin(EditorNode *p_node); ~AnimationPlayerEditorPlugin(); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 5405723d10..664b2f521e 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -230,7 +230,7 @@ void EditorAssetLibraryItemDescription::configure(const String &p_title, int p_a description->add_text(TTR("View Files")); description->pop(); description->add_text("\n" + TTR("Description:") + "\n\n"); - description->append_bbcode(p_description); + description->append_text(p_description); set_title(p_title); } diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index d96cc1cd18..db5be94fd2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1295,7 +1295,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { // Drag the pivot (in pivot mode / with V key) if (drag_type == DRAG_NONE) { if ((b.is_valid() && b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || - (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_V)) { + (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_keycode() == KEY_V && tool == TOOL_SELECT && k->get_modifiers_mask() == 0)) { List<CanvasItem *> selection = _get_edited_canvas_items(); // Filters the selection with nodes that allow setting the pivot @@ -5204,7 +5204,9 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { snap_rotation = false; snap_scale = false; snap_relative = false; - snap_pixel = false; + // Enable pixel snapping even if pixel snap rendering is disabled in the Project Settings. + // This results in crisper visuals by preventing 2D nodes from being placed at subpixel coordinates. + snap_pixel = true; snap_target[0] = SNAP_TARGET_NONE; snap_target[1] = SNAP_TARGET_NONE; diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index bfcc293625..fb32d7b1fd 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -39,7 +39,7 @@ #include "scene/resources/rectangle_shape_2d.h" #include "scene/resources/segment_shape_2d.h" #include "scene/resources/separation_ray_shape_2d.h" -#include "scene/resources/world_margin_shape_2d.h" +#include "scene/resources/world_boundary_shape_2d.h" void CollisionShape2DEditor::_node_removed(Node *p_node) { if (p_node == node) { @@ -70,13 +70,13 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { case CONVEX_POLYGON_SHAPE: { } break; - case WORLD_MARGIN_SHAPE: { - Ref<WorldMarginShape2D> line = node->get_shape(); + case WORLD_BOUNDARY_SHAPE: { + Ref<WorldBoundaryShape2D> world_boundary = node->get_shape(); if (idx == 0) { - return line->get_distance(); + return world_boundary->get_distance(); } else { - return line->get_normal(); + return world_boundary->get_normal(); } } break; @@ -147,14 +147,14 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { case CONVEX_POLYGON_SHAPE: { } break; - case WORLD_MARGIN_SHAPE: { + case WORLD_BOUNDARY_SHAPE: { if (idx < 2) { - Ref<WorldMarginShape2D> line = node->get_shape(); + Ref<WorldBoundaryShape2D> world_boundary = node->get_shape(); if (idx == 0) { - line->set_distance(p_point.length()); + world_boundary->set_distance(p_point.length()); } else { - line->set_normal(p_point.normalized()); + world_boundary->set_normal(p_point.normalized()); } canvas_item_editor->update_viewport(); @@ -255,18 +255,18 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { // Cannot be edited directly, use CollisionPolygon2D instead. } break; - case WORLD_MARGIN_SHAPE: { - Ref<WorldMarginShape2D> line = node->get_shape(); + case WORLD_BOUNDARY_SHAPE: { + Ref<WorldBoundaryShape2D> world_boundary = node->get_shape(); if (idx == 0) { - undo_redo->add_do_method(line.ptr(), "set_distance", line->get_distance()); + undo_redo->add_do_method(world_boundary.ptr(), "set_distance", world_boundary->get_distance()); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(line.ptr(), "set_distance", p_org); + undo_redo->add_undo_method(world_boundary.ptr(), "set_distance", p_org); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } else { - undo_redo->add_do_method(line.ptr(), "set_normal", line->get_normal()); + undo_redo->add_do_method(world_boundary.ptr(), "set_normal", world_boundary->get_normal()); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); - undo_redo->add_undo_method(line.ptr(), "set_normal", p_org); + undo_redo->add_undo_method(world_boundary.ptr(), "set_normal", p_org); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } @@ -421,8 +421,8 @@ void CollisionShape2DEditor::_get_current_shape_type() { shape_type = CONCAVE_POLYGON_SHAPE; } else if (Object::cast_to<ConvexPolygonShape2D>(*s)) { shape_type = CONVEX_POLYGON_SHAPE; - } else if (Object::cast_to<WorldMarginShape2D>(*s)) { - shape_type = WORLD_MARGIN_SHAPE; + } else if (Object::cast_to<WorldBoundaryShape2D>(*s)) { + shape_type = WORLD_BOUNDARY_SHAPE; } else if (Object::cast_to<SeparationRayShape2D>(*s)) { shape_type = SEPARATION_RAY_SHAPE; } else if (Object::cast_to<RectangleShape2D>(*s)) { @@ -490,8 +490,8 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla case CONVEX_POLYGON_SHAPE: { } break; - case WORLD_MARGIN_SHAPE: { - Ref<WorldMarginShape2D> shape = node->get_shape(); + case WORLD_BOUNDARY_SHAPE: { + Ref<WorldBoundaryShape2D> shape = node->get_shape(); handles.resize(2); handles.write[0] = shape->get_normal() * shape->get_distance(); diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index 421e674df8..ab95600a52 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -46,7 +46,7 @@ class CollisionShape2DEditor : public Control { CIRCLE_SHAPE, CONCAVE_POLYGON_SHAPE, CONVEX_POLYGON_SHAPE, - WORLD_MARGIN_SHAPE, + WORLD_BOUNDARY_SHAPE, SEPARATION_RAY_SHAPE, RECTANGLE_SHAPE, SEGMENT_SHAPE diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 94966d4fe6..30945826bb 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -278,6 +278,8 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -315,6 +317,8 @@ Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_ } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -352,6 +356,8 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -389,6 +395,8 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -426,6 +434,8 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> & } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } @@ -463,5 +473,7 @@ Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> & } smat->set_render_priority(mat->get_render_priority()); + smat->set_local_to_scene(mat->is_local_to_scene()); + smat->set_name(mat->get_name()); return smat; } diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index 9a2b222f21..574d3ef27e 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -202,7 +202,8 @@ void MeshInstance3DEditor::_menu_option(int p_option) { return; } - Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(); + Mesh::ConvexDecompositionSettings settings; + Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(settings); if (!shapes.size()) { err_dialog->set_text(TTR("Couldn't create any collision shapes.")); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index b3f92c9d95..18e7480287 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -47,23 +47,25 @@ void MeshLibraryEditor::edit(const Ref<MeshLibrary> &p_mesh_library) { } } -void MeshLibraryEditor::_menu_confirm() { +void MeshLibraryEditor::_menu_remove_confirm() { switch (option) { case MENU_OPTION_REMOVE_ITEM: { mesh_library->remove_item(to_erase); } break; - case MENU_OPTION_UPDATE_FROM_SCENE: { - String existing = mesh_library->get_meta("_editor_source_scene"); - ERR_FAIL_COND(existing == ""); - _import_scene_cbk(existing); - - } break; default: { }; } } -void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge) { +void MeshLibraryEditor::_menu_update_confirm(bool p_apply_xforms) { + cd_update->hide(); + apply_xforms = p_apply_xforms; + String existing = mesh_library->get_meta("_editor_source_scene"); + ERR_FAIL_COND(existing == ""); + _import_scene_cbk(existing); +} + +void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge, bool p_apply_xforms) { if (!p_merge) { p_library->clear(); } @@ -108,6 +110,13 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, } p_library->set_item_mesh(id, mesh); + + if (p_apply_xforms) { + p_library->set_item_mesh_transform(id, mi->get_transform()); + } else { + p_library->set_item_mesh_transform(id, Transform3D()); + } + mesh_instances[id] = mi; Vector<MeshLibrary::ShapeData> collisions; @@ -197,15 +206,16 @@ void MeshLibraryEditor::_import_scene_cbk(const String &p_str) { ERR_FAIL_COND_MSG(!scene, "Cannot create an instance from PackedScene '" + p_str + "'."); - _import_scene(scene, mesh_library, option == MENU_OPTION_UPDATE_FROM_SCENE); + _import_scene(scene, mesh_library, option == MENU_OPTION_UPDATE_FROM_SCENE, apply_xforms); memdelete(scene); mesh_library->set_meta("_editor_source_scene", p_str); + menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE), false); } -Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge) { - _import_scene(p_base_scene, ml, p_merge); +Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge, bool p_apply_xforms) { + _import_scene(p_base_scene, ml, p_merge, p_apply_xforms); return OK; } @@ -219,16 +229,21 @@ void MeshLibraryEditor::_menu_cbk(int p_option) { String p = editor->get_inspector()->get_selected_path(); if (p.begins_with("/MeshLibrary/item") && p.get_slice_count("/") >= 3) { to_erase = p.get_slice("/", 3).to_int(); - cd->set_text(vformat(TTR("Remove item %d?"), to_erase)); - cd->popup_centered(Size2(300, 60)); + cd_remove->set_text(vformat(TTR("Remove item %d?"), to_erase)); + cd_remove->popup_centered(Size2(300, 60)); } } break; case MENU_OPTION_IMPORT_FROM_SCENE: { + apply_xforms = false; + file->popup_file_dialog(); + } break; + case MENU_OPTION_IMPORT_FROM_SCENE_APPLY_XFORMS: { + apply_xforms = true; file->popup_file_dialog(); } break; case MENU_OPTION_UPDATE_FROM_SCENE: { - cd->set_text(vformat(TTR("Update from existing scene?:\n%s"), String(mesh_library->get_meta("_editor_source_scene")))); - cd->popup_centered(Size2(500, 60)); + cd_update->set_text(vformat(TTR("Update from existing scene?:\n%s"), String(mesh_library->get_meta("_editor_source_scene")))); + cd_update->popup_centered(Size2(500, 60)); } break; } } @@ -258,16 +273,22 @@ MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) { menu->get_popup()->add_item(TTR("Add Item"), MENU_OPTION_ADD_ITEM); menu->get_popup()->add_item(TTR("Remove Selected Item"), MENU_OPTION_REMOVE_ITEM); menu->get_popup()->add_separator(); - menu->get_popup()->add_item(TTR("Import from Scene"), MENU_OPTION_IMPORT_FROM_SCENE); + menu->get_popup()->add_item(TTR("Import from Scene (Ignore Transforms)"), MENU_OPTION_IMPORT_FROM_SCENE); + menu->get_popup()->add_item(TTR("Import from Scene (Apply Transforms)"), MENU_OPTION_IMPORT_FROM_SCENE_APPLY_XFORMS); menu->get_popup()->add_item(TTR("Update from Scene"), MENU_OPTION_UPDATE_FROM_SCENE); menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE), true); menu->get_popup()->connect("id_pressed", callable_mp(this, &MeshLibraryEditor::_menu_cbk)); menu->hide(); editor = p_editor; - cd = memnew(ConfirmationDialog); - add_child(cd); - cd->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_confirm)); + cd_remove = memnew(ConfirmationDialog); + add_child(cd_remove); + cd_remove->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_remove_confirm)); + cd_update = memnew(ConfirmationDialog); + add_child(cd_update); + cd_update->get_ok_button()->set_text("Apply without Transforms"); + cd_update->get_ok_button()->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(false)); + cd_update->add_button("Apply with Transforms")->connect("pressed", callable_mp(this, &MeshLibraryEditor::_menu_update_confirm), varray(true)); } void MeshLibraryEditorPlugin::edit(Object *p_node) { diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h index 6c33c8bb9e..9e225ffb9b 100644 --- a/editor/plugins/mesh_library_editor_plugin.h +++ b/editor/plugins/mesh_library_editor_plugin.h @@ -41,23 +41,27 @@ class MeshLibraryEditor : public Control { EditorNode *editor; MenuButton *menu; - ConfirmationDialog *cd; + ConfirmationDialog *cd_remove; + ConfirmationDialog *cd_update; EditorFileDialog *file; + bool apply_xforms; int to_erase; enum { MENU_OPTION_ADD_ITEM, MENU_OPTION_REMOVE_ITEM, MENU_OPTION_UPDATE_FROM_SCENE, - MENU_OPTION_IMPORT_FROM_SCENE + MENU_OPTION_IMPORT_FROM_SCENE, + MENU_OPTION_IMPORT_FROM_SCENE_APPLY_XFORMS }; int option; void _import_scene_cbk(const String &p_str); void _menu_cbk(int p_option); - void _menu_confirm(); + void _menu_remove_confirm(); + void _menu_update_confirm(bool p_apply_xforms); - static void _import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge); + static void _import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge, bool p_apply_xforms); protected: static void _bind_methods(); @@ -66,7 +70,7 @@ public: MenuButton *get_menu_button() const { return menu; } void edit(const Ref<MeshLibrary> &p_mesh_library); - static Error update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge = true); + static Error update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge = true, bool p_apply_xforms = false); MeshLibraryEditor(EditorNode *p_editor); }; diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index d20f3d105b..0f98629370 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -34,6 +34,7 @@ #include "core/math/geometry_2d.h" #include "core/math/geometry_3d.h" #include "editor/plugins/node_3d_editor_plugin.h" +#include "scene/3d/audio_listener_3d.h" #include "scene/3d/audio_stream_player_3d.h" #include "scene/3d/camera_3d.h" #include "scene/3d/collision_polygon_3d.h" @@ -45,7 +46,6 @@ #include "scene/3d/light_3d.h" #include "scene/3d/lightmap_gi.h" #include "scene/3d/lightmap_probe.h" -#include "scene/3d/listener_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/3d/navigation_region_3d.h" #include "scene/3d/occluder_instance_3d.h" @@ -53,7 +53,7 @@ #include "scene/3d/position_3d.h" #include "scene/3d/ray_cast_3d.h" #include "scene/3d/reflection_probe.h" -#include "scene/3d/soft_body_3d.h" +#include "scene/3d/soft_dynamic_body_3d.h" #include "scene/3d/spring_arm_3d.h" #include "scene/3d/sprite_3d.h" #include "scene/3d/vehicle_body_3d.h" @@ -69,7 +69,7 @@ #include "scene/resources/separation_ray_shape_3d.h" #include "scene/resources/sphere_shape_3d.h" #include "scene/resources/surface_tool.h" -#include "scene/resources/world_margin_shape_3d.h" +#include "scene/resources/world_boundary_shape_3d.h" #define HANDLE_HALF_SIZE 9.5 @@ -1003,7 +1003,9 @@ String EditorNode3DGizmoPlugin::get_gizmo_name() const { if (get_script_instance() && get_script_instance()->has_method("_get_gizmo_name")) { return get_script_instance()->call("_get_gizmo_name"); } - return TTR("Nameless gizmo"); + + WARN_PRINT_ONCE("A 3D editor gizmo has no name defined (it will appear as \"Unnamed Gizmo\" in the \"View > Gizmos\" menu). To resolve this, override the `_get_gizmo_name()` function to return a String in the script that extends EditorNode3DGizmoPlugin."); + return TTR("Unnamed Gizmo"); } int EditorNode3DGizmoPlugin::get_priority() const { @@ -1481,8 +1483,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { } } -////// - //// player gizmo AudioStreamPlayer3DGizmoPlugin::AudioStreamPlayer3DGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1)); @@ -1621,6 +1621,29 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { ////// +AudioListener3DGizmoPlugin::AudioListener3DGizmoPlugin() { + create_icon_material("audio_listener_3d_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoAudioListener3D", "EditorIcons")); +} + +bool AudioListener3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<AudioListener3D>(p_spatial) != nullptr; +} + +String AudioListener3DGizmoPlugin::get_gizmo_name() const { + return "AudioListener3D"; +} + +int AudioListener3DGizmoPlugin::get_priority() const { + return -1; +} + +void AudioListener3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + const Ref<Material> icon = get_material("audio_listener_3d_icon", p_gizmo); + p_gizmo->add_unscaled_billboard(icon, 0.05); +} + +////// + Camera3DGizmoPlugin::Camera3DGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8)); @@ -1866,7 +1889,7 @@ MeshInstance3DGizmoPlugin::MeshInstance3DGizmoPlugin() { } bool MeshInstance3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { - return Object::cast_to<MeshInstance3D>(p_spatial) != nullptr && Object::cast_to<SoftBody3D>(p_spatial) == nullptr; + return Object::cast_to<MeshInstance3D>(p_spatial) != nullptr && Object::cast_to<SoftDynamicBody3D>(p_spatial) == nullptr; } String MeshInstance3DGizmoPlugin::get_gizmo_name() const { @@ -2489,30 +2512,30 @@ void VehicleWheel3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { /////////// -SoftBody3DGizmoPlugin::SoftBody3DGizmoPlugin() { +SoftDynamicBody3DGizmoPlugin::SoftDynamicBody3DGizmoPlugin() { Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1)); create_material("shape_material", gizmo_color); create_handle_material("handles"); } -bool SoftBody3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { - return Object::cast_to<SoftBody3D>(p_spatial) != nullptr; +bool SoftDynamicBody3DGizmoPlugin::has_gizmo(Node3D *p_spatial) { + return Object::cast_to<SoftDynamicBody3D>(p_spatial) != nullptr; } -String SoftBody3DGizmoPlugin::get_gizmo_name() const { - return "SoftBody3D"; +String SoftDynamicBody3DGizmoPlugin::get_gizmo_name() const { + return "SoftDynamicBody3D"; } -int SoftBody3DGizmoPlugin::get_priority() const { +int SoftDynamicBody3DGizmoPlugin::get_priority() const { return -1; } -bool SoftBody3DGizmoPlugin::is_selectable_when_hidden() const { +bool SoftDynamicBody3DGizmoPlugin::is_selectable_when_hidden() const { return true; } -void SoftBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); +void SoftDynamicBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { + SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); p_gizmo->clear(); @@ -2548,22 +2571,22 @@ void SoftBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_triangles(tm); } -String SoftBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { - return "SoftBody3D pin point"; +String SoftDynamicBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const { + return "SoftDynamicBody3D pin point"; } -Variant SoftBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); +Variant SoftDynamicBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const { + SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); return Variant(soft_body->is_point_pinned(p_id)); } -void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); +void SoftDynamicBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) { + SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); soft_body->pin_point_toggle(p_id); } -bool SoftBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { - SoftBody3D *soft_body = Object::cast_to<SoftBody3D>(p_gizmo->get_spatial_node()); +bool SoftDynamicBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const { + SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node()); return soft_body->is_point_pinned(p_id); } @@ -4537,9 +4560,9 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_handles(handles, handles_material); } - if (Object::cast_to<WorldMarginShape3D>(*s)) { - Ref<WorldMarginShape3D> ps = s; - Plane p = ps->get_plane(); + if (Object::cast_to<WorldBoundaryShape3D>(*s)) { + Ref<WorldBoundaryShape3D> wbs = s; + const Plane &p = wbs->get_plane(); Vector<Vector3> points; Vector3 n1 = p.get_any_perpendicular_normal(); diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 415ed5da5c..24b4a23d4b 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -249,6 +249,19 @@ public: AudioStreamPlayer3DGizmoPlugin(); }; +class AudioListener3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(AudioListener3DGizmoPlugin, EditorNode3DGizmoPlugin); + +public: + bool has_gizmo(Node3D *p_spatial) override; + String get_gizmo_name() const override; + int get_priority() const override; + + void redraw(EditorNode3DGizmo *p_gizmo) override; + + AudioListener3DGizmoPlugin(); +}; + class Camera3DGizmoPlugin : public EditorNode3DGizmoPlugin { GDCLASS(Camera3DGizmoPlugin, EditorNode3DGizmoPlugin); @@ -379,8 +392,8 @@ public: VehicleWheel3DGizmoPlugin(); }; -class SoftBody3DGizmoPlugin : public EditorNode3DGizmoPlugin { - GDCLASS(SoftBody3DGizmoPlugin, EditorNode3DGizmoPlugin); +class SoftDynamicBody3DGizmoPlugin : public EditorNode3DGizmoPlugin { + GDCLASS(SoftDynamicBody3DGizmoPlugin, EditorNode3DGizmoPlugin); public: bool has_gizmo(Node3D *p_spatial) override; @@ -394,7 +407,7 @@ public: void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override; bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override; - SoftBody3DGizmoPlugin(); + SoftDynamicBody3DGizmoPlugin(); }; class VisibleOnScreenNotifier3DGizmoPlugin : public EditorNode3DGizmoPlugin { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 291cafab2b..5263352502 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1831,6 +1831,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { motion = Vector3(scale, scale, scale); } + motion /= click.distance_to(_edit.center); + // Disable local transformation for TRANSFORM_VIEW bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); @@ -6861,9 +6863,10 @@ void Node3DEditor::_register_all_gizmos() { add_gizmo_plugin(Ref<Camera3DGizmoPlugin>(memnew(Camera3DGizmoPlugin))); add_gizmo_plugin(Ref<Light3DGizmoPlugin>(memnew(Light3DGizmoPlugin))); add_gizmo_plugin(Ref<AudioStreamPlayer3DGizmoPlugin>(memnew(AudioStreamPlayer3DGizmoPlugin))); + add_gizmo_plugin(Ref<AudioListener3DGizmoPlugin>(memnew(AudioListener3DGizmoPlugin))); add_gizmo_plugin(Ref<MeshInstance3DGizmoPlugin>(memnew(MeshInstance3DGizmoPlugin))); add_gizmo_plugin(Ref<OccluderInstance3DGizmoPlugin>(memnew(OccluderInstance3DGizmoPlugin))); - add_gizmo_plugin(Ref<SoftBody3DGizmoPlugin>(memnew(SoftBody3DGizmoPlugin))); + add_gizmo_plugin(Ref<SoftDynamicBody3DGizmoPlugin>(memnew(SoftDynamicBody3DGizmoPlugin))); add_gizmo_plugin(Ref<Sprite3DGizmoPlugin>(memnew(Sprite3DGizmoPlugin))); add_gizmo_plugin(Ref<Skeleton3DGizmoPlugin>(memnew(Skeleton3DGizmoPlugin))); add_gizmo_plugin(Ref<Position3DGizmoPlugin>(memnew(Position3DGizmoPlugin))); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 7ef5993ec5..07e4d4ebf0 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -46,6 +46,7 @@ #include "editor/find_in_files.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" +#include "modules/visual_script/visual_script_editor.h" #include "scene/main/window.h" #include "scene/scene_string_names.h" #include "script_text_editor.h" @@ -807,39 +808,35 @@ void ScriptEditor::_copy_script_path() { } void ScriptEditor::_close_other_tabs() { - int child_count = tab_container->get_child_count(); int current_idx = tab_container->get_current_tab(); - for (int i = child_count - 1; i >= 0; i--) { - if (i == current_idx) { - continue; + for (int i = tab_container->get_child_count() - 1; i >= 0; i--) { + if (i != current_idx) { + script_close_queue.push_back(i); } - - tab_container->set_current_tab(i); - ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i)); - - if (se) { - // Maybe there are unsaved changes - if (se->is_unsaved()) { - _ask_close_current_unsaved_tab(se); - continue; - } - } - - _close_current_tab(false); } + _queue_close_tabs(); } void ScriptEditor::_close_all_tabs() { - int child_count = tab_container->get_child_count(); - for (int i = child_count - 1; i >= 0; i--) { - tab_container->set_current_tab(i); - ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i)); + for (int i = tab_container->get_child_count() - 1; i >= 0; i--) { + script_close_queue.push_back(i); + } + _queue_close_tabs(); +} +void ScriptEditor::_queue_close_tabs() { + while (!script_close_queue.is_empty()) { + int idx = script_close_queue.front()->get(); + script_close_queue.pop_front(); + + tab_container->set_current_tab(idx); + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(idx)); if (se) { - // Maybe there are unsaved changes + // Maybe there are unsaved changes. if (se->is_unsaved()) { _ask_close_current_unsaved_tab(se); - continue; + erase_tab_confirm->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &ScriptEditor::_queue_close_tabs), varray(), CONNECT_ONESHOT); + break; } } @@ -1236,14 +1233,15 @@ void ScriptEditor::_menu_option(int p_option) { _update_script_names(); } break; case TOGGLE_SCRIPTS_PANEL: { + toggle_scripts_panel(); if (current) { - ScriptTextEditor *editor = Object::cast_to<ScriptTextEditor>(current); - toggle_scripts_panel(); - if (editor) { - editor->update_toggle_scripts_button(); - } + current->update_toggle_scripts_button(); } else { - toggle_scripts_panel(); + Control *tab = tab_container->get_current_tab_control(); + EditorHelp *editor_help = Object::cast_to<EditorHelp>(tab); + if (editor_help) { + editor_help->update_toggle_scripts_button(); + } } } } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index e2420b4623..7620605570 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -161,6 +161,7 @@ public: virtual void update_settings() = 0; virtual void set_debugger_active(bool p_active) = 0; virtual bool can_lose_focus_on_node_selection() { return true; } + virtual void update_toggle_scripts_button() {} virtual bool show_members_overview() = 0; @@ -308,6 +309,7 @@ class ScriptEditor : public PanelContainer { int history_pos; List<String> previous_scripts; + List<int> script_close_queue; void _tab_changed(int p_which); void _menu_option(int p_option); @@ -340,6 +342,7 @@ class ScriptEditor : public PanelContainer { void _close_docs_tab(); void _close_other_tabs(); void _close_all_tabs(); + void _queue_close_tabs(); void _copy_script_path(); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 48239a5d99..ebd46be3b4 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -876,9 +876,7 @@ String ScriptTextEditor::_get_absolute_path(const String &rel_path) { } void ScriptTextEditor::update_toggle_scripts_button() { - if (code_editor != nullptr) { - code_editor->update_toggle_scripts_button(); - } + code_editor->update_toggle_scripts_button(); } void ScriptTextEditor::_update_connected_methods() { @@ -1242,7 +1240,7 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->set_caret_line(bpoints[bpoints.size() - 1]); tx->center_viewport_to_caret(); } else { - for (int i = bpoints.size(); i >= 0; i--) { + for (int i = bpoints.size() - 1; i >= 0; i--) { int bline = bpoints[i]; if (bline < line) { tx->unfold_line(bline); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 4208d67f17..afe9a7453d 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -197,7 +197,7 @@ public: virtual void add_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) override; virtual void set_syntax_highlighter(Ref<EditorSyntaxHighlighter> p_highlighter) override; - void update_toggle_scripts_button(); + void update_toggle_scripts_button() override; virtual void apply_code() override; virtual RES get_edited_resource() const override; diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp index 7ef680d7ef..c350004f0f 100644 --- a/editor/plugins/skeleton_2d_editor_plugin.cpp +++ b/editor/plugins/skeleton_2d_editor_plugin.cpp @@ -98,9 +98,10 @@ Skeleton2DEditor::Skeleton2DEditor() { options->set_text(TTR("Skeleton2D")); options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Skeleton2D"), SNAME("EditorIcons"))); - options->get_popup()->add_item(TTR("Make Rest Pose (From Bones)"), MENU_OPTION_MAKE_REST); + options->get_popup()->add_item(TTR("Reset to Rest Pose"), MENU_OPTION_MAKE_REST); options->get_popup()->add_separator(); - options->get_popup()->add_item(TTR("Set Bones to Rest Pose"), MENU_OPTION_SET_REST); + // Use the "Overwrite" word to highlight that this is a destructive operation. + options->get_popup()->add_item(TTR("Overwrite Rest Pose"), MENU_OPTION_SET_REST); options->set_switch_on_hover(true); options->get_popup()->connect("id_pressed", callable_mp(this, &Skeleton2DEditor::_menu_option)); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 400f9f560f..8a8d80891a 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -54,22 +54,46 @@ void SpriteFramesEditor::_open_sprite_sheet() { file_split_sheet->popup_file_dialog(); } +int SpriteFramesEditor::_sheet_preview_position_to_frame_index(const Point2 &p_position) { + if (p_position.x < 0 || p_position.y < 0) { + return -1; + } + + Size2i texture_size = split_sheet_preview->get_texture()->get_size(); + int h = split_sheet_h->get_value(); + int v = split_sheet_v->get_value(); + if (h > texture_size.width || v > texture_size.height) { + return -1; + } + + int x = int(p_position.x / sheet_zoom) / (texture_size.width / h); + int y = int(p_position.y / sheet_zoom) / (texture_size.height / v); + if (x >= h || y >= v) { + return -1; + } + return h * y + x; +} + void SpriteFramesEditor::_sheet_preview_draw() { - Size2i size = split_sheet_preview->get_size(); + Size2i texture_size = split_sheet_preview->get_texture()->get_size(); int h = split_sheet_h->get_value(); int v = split_sheet_v->get_value(); - int width = size.width / h; - int height = size.height / v; + + real_t width = (texture_size.width / h) * sheet_zoom; + real_t height = (texture_size.height / v) * sheet_zoom; const float a = 0.3; - for (int i = 1; i < h; i++) { - int x = i * width; - split_sheet_preview->draw_line(Point2(x, 0), Point2(x, size.height), Color(1, 1, 1, a)); - split_sheet_preview->draw_line(Point2(x + 1, 0), Point2(x + 1, size.height), Color(0, 0, 0, a)); + + real_t y_end = v * height; + for (int i = 0; i <= h; i++) { + real_t x = i * width; + split_sheet_preview->draw_line(Point2(x, 0), Point2(x, y_end), Color(1, 1, 1, a)); + split_sheet_preview->draw_line(Point2(x + 1, 0), Point2(x + 1, y_end), Color(0, 0, 0, a)); } - for (int i = 1; i < v; i++) { - int y = i * height; - split_sheet_preview->draw_line(Point2(0, y), Point2(size.width, y), Color(1, 1, 1, a)); - split_sheet_preview->draw_line(Point2(0, y + 1), Point2(size.width, y + 1), Color(0, 0, 0, a)); + real_t x_end = h * width; + for (int i = 0; i <= v; i++) { + real_t y = i * height; + split_sheet_preview->draw_line(Point2(0, y), Point2(x_end, y), Color(1, 1, 1, a)); + split_sheet_preview->draw_line(Point2(0, y + 1), Point2(x_end, y + 1), Color(0, 0, 0, a)); } if (frames_selected.size() == 0) { @@ -83,9 +107,9 @@ void SpriteFramesEditor::_sheet_preview_draw() { for (Set<int>::Element *E = frames_selected.front(); E; E = E->next()) { int idx = E->get(); int xp = idx % h; - int yp = (idx - xp) / h; - int x = xp * width; - int y = yp * height; + int yp = idx / h; + real_t x = xp * width; + real_t y = yp * height; split_sheet_preview->draw_rect(Rect2(x + 5, y + 5, width - 10, height - 10), Color(0, 0, 0, 0.35), true); split_sheet_preview->draw_rect(Rect2(x + 0, y + 0, width - 0, height - 0), Color(0, 0, 0, 1), false); @@ -103,46 +127,43 @@ void SpriteFramesEditor::_sheet_preview_draw() { void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { const Ref<InputEventMouseButton> mb = p_event; if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { - const Size2i size = split_sheet_preview->get_size(); - const int h = split_sheet_h->get_value(); - const int v = split_sheet_v->get_value(); - - const int x = CLAMP(int(mb->get_position().x) * h / size.width, 0, h - 1); - const int y = CLAMP(int(mb->get_position().y) * v / size.height, 0, v - 1); - - const int idx = h * y + x; + const int idx = _sheet_preview_position_to_frame_index(mb->get_position()); + + if (idx != -1) { + if (mb->is_shift_pressed() && last_frame_selected >= 0) { + //select multiple + int from = idx; + int to = last_frame_selected; + if (from > to) { + SWAP(from, to); + } - if (mb->is_shift_pressed() && last_frame_selected >= 0) { - //select multiple - int from = idx; - int to = last_frame_selected; - if (from > to) { - SWAP(from, to); - } + for (int i = from; i <= to; i++) { + // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. + frames_toggled_by_mouse_hover.insert(idx); - for (int i = from; i <= to; i++) { + if (mb->is_ctrl_pressed()) { + frames_selected.erase(i); + } else { + frames_selected.insert(i); + } + } + } else { // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. frames_toggled_by_mouse_hover.insert(idx); - if (mb->is_ctrl_pressed()) { - frames_selected.erase(i); + if (frames_selected.has(idx)) { + frames_selected.erase(idx); } else { - frames_selected.insert(i); + frames_selected.insert(idx); } } - } else { - // Prevent double-toggling the same frame when moving the mouse when the mouse button is still held. - frames_toggled_by_mouse_hover.insert(idx); - - if (frames_selected.has(idx)) { - frames_selected.erase(idx); - } else { - frames_selected.insert(idx); - } } - last_frame_selected = idx; - split_sheet_preview->update(); + if (last_frame_selected != idx || idx != -1) { + last_frame_selected = idx; + split_sheet_preview->update(); + } } if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) { @@ -152,16 +173,9 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) { const Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) { // Select by holding down the mouse button on frames. - const Size2i size = split_sheet_preview->get_size(); - const int h = split_sheet_h->get_value(); - const int v = split_sheet_v->get_value(); - - const int x = CLAMP(int(mm->get_position().x) * h / size.width, 0, h - 1); - const int y = CLAMP(int(mm->get_position().y) * v / size.height, 0, v - 1); - - const int idx = h * y + x; + const int idx = _sheet_preview_position_to_frame_index(mm->get_position()); - if (!frames_toggled_by_mouse_hover.has(idx)) { + if (idx != -1 && !frames_toggled_by_mouse_hover.has(idx)) { // Only allow toggling each tile once per mouse hold. // Otherwise, the selection would constantly "flicker" in and out when moving the mouse cursor. // The mouse button must be released before it can be toggled again. @@ -199,17 +213,17 @@ void SpriteFramesEditor::_sheet_scroll_input(const Ref<InputEvent> &p_event) { } void SpriteFramesEditor::_sheet_add_frames() { - Size2i size = split_sheet_preview->get_texture()->get_size(); + Size2i texture_size = split_sheet_preview->get_texture()->get_size(); int frame_count_x = split_sheet_h->get_value(); int frame_count_y = split_sheet_v->get_value(); - Size2 frame_size(size.width / frame_count_x, size.height / frame_count_y); + Size2 frame_size(texture_size.width / frame_count_x, texture_size.height / frame_count_y); undo_redo->create_action(TTR("Add Frame")); int fc = frames->get_frame_count(edited_anim); Point2 src_origin; - Rect2 src_region(Point2(), size); + Rect2 src_region(Point2(), texture_size); AtlasTexture *src_atlas = Object::cast_to<AtlasTexture>(*split_sheet_preview->get_texture()); if (src_atlas && src_atlas->get_atlas().is_valid()) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 17e30f0cab..5e3b2fb8c1 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -135,6 +135,7 @@ class SpriteFramesEditor : public HSplitContainer { void _open_sprite_sheet(); void _prepare_sprite_sheet(const String &p_file); + int _sheet_preview_position_to_frame_index(const Vector2 &p_position); void _sheet_preview_draw(); void _sheet_spin_changed(double); void _sheet_preview_input(const Ref<InputEvent> &p_event); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 32bcc1a4e6..06ba8a6168 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -513,6 +513,10 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is context_menu->popup(); } +void TextEditor::update_toggle_scripts_button() { + code_editor->update_toggle_scripts_button(); +} + TextEditor::TextEditor() { code_editor = memnew(CodeTextEditor); add_child(code_editor); @@ -521,6 +525,7 @@ TextEditor::TextEditor() { code_editor->connect("validate_script", callable_mp(this, &TextEditor::_validate_script)); code_editor->set_anchors_and_offsets_preset(Control::PRESET_WIDE); code_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); + code_editor->show_toggle_scripts_button(); update_settings(); diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 6bf0042393..9308fec210 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -139,6 +139,7 @@ public: virtual void set_debugger_active(bool p_active) override; virtual void set_tooltip_request_func(String p_method, Object *p_obj) override; virtual void add_callback(const String &p_function, PackedStringArray p_args) override; + void update_toggle_scripts_button() override; virtual Control *get_edit_menu() override; virtual void clear_edit_menu() override; diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 1a6eb7b63b..50ad12635b 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -63,16 +63,16 @@ void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) { void TextureRegionEditor::_region_draw() { Ref<Texture2D> base_tex = nullptr; - if (node_sprite) { - base_tex = node_sprite->get_texture(); + if (atlas_tex.is_valid()) { + base_tex = atlas_tex->get_atlas(); + } else if (node_sprite_2d) { + base_tex = node_sprite_2d->get_texture(); } else if (node_sprite_3d) { base_tex = node_sprite_3d->get_texture(); } else if (node_ninepatch) { base_tex = node_ninepatch->get_texture(); } else if (obj_styleBox.is_valid()) { base_tex = obj_styleBox->get_texture(); - } else if (atlas_tex.is_valid()) { - base_tex = atlas_tex->get_atlas(); } if (base_tex.is_null()) { @@ -332,24 +332,27 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { rect = E; if (Input::get_singleton()->is_key_pressed(KEY_CTRL) && !(Input::get_singleton()->is_key_pressed(Key(KEY_SHIFT | KEY_ALT)))) { Rect2 r; - if (node_sprite) { - r = node_sprite->get_region_rect(); + if (atlas_tex.is_valid()) { + r = atlas_tex->get_region(); + } else if (node_sprite_2d) { + r = node_sprite_2d->get_region_rect(); } else if (node_sprite_3d) { r = node_sprite_3d->get_region_rect(); } else if (node_ninepatch) { r = node_ninepatch->get_region_rect(); } else if (obj_styleBox.is_valid()) { r = obj_styleBox->get_region_rect(); - } else if (atlas_tex.is_valid()) { - r = atlas_tex->get_region(); } rect.expand_to(r.position); rect.expand_to(r.position + r.size); } undo_redo->create_action(TTR("Set Region Rect")); - if (node_sprite) { - undo_redo->add_do_method(node_sprite, "set_region_rect", rect); - undo_redo->add_undo_method(node_sprite, "set_region_rect", node_sprite->get_region_rect()); + if (atlas_tex.is_valid()) { + undo_redo->add_do_method(atlas_tex.ptr(), "set_region", rect); + undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region()); + } else if (node_sprite_2d) { + undo_redo->add_do_method(node_sprite_2d, "set_region_rect", rect); + undo_redo->add_undo_method(node_sprite_2d, "set_region_rect", node_sprite_2d->get_region_rect()); } else if (node_sprite_3d) { undo_redo->add_do_method(node_sprite_3d, "set_region_rect", rect); undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect()); @@ -359,9 +362,6 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { } else if (obj_styleBox.is_valid()) { undo_redo->add_do_method(obj_styleBox.ptr(), "set_region_rect", rect); undo_redo->add_undo_method(obj_styleBox.ptr(), "set_region_rect", obj_styleBox->get_region_rect()); - } else if (atlas_tex.is_valid()) { - undo_redo->add_do_method(atlas_tex.ptr(), "set_region", rect); - undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region()); } undo_redo->add_do_method(this, "_update_rect"); undo_redo->add_undo_method(this, "_update_rect"); @@ -379,16 +379,16 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { drag_from = snap_point(drag_from); } drag = true; - if (node_sprite) { - rect_prev = node_sprite->get_region_rect(); + if (atlas_tex.is_valid()) { + rect_prev = atlas_tex->get_region(); + } else if (node_sprite_2d) { + rect_prev = node_sprite_2d->get_region_rect(); } else if (node_sprite_3d) { rect_prev = node_sprite_3d->get_region_rect(); } else if (node_ninepatch) { rect_prev = node_ninepatch->get_region_rect(); } else if (obj_styleBox.is_valid()) { rect_prev = obj_styleBox->get_region_rect(); - } else if (atlas_tex.is_valid()) { - rect_prev = atlas_tex->get_region(); } for (int i = 0; i < 8; i++) { @@ -419,15 +419,15 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) { edited_margin = -1; } else { undo_redo->create_action(TTR("Set Region Rect")); - if (node_sprite) { - undo_redo->add_do_method(node_sprite, "set_region_rect", node_sprite->get_region_rect()); - undo_redo->add_undo_method(node_sprite, "set_region_rect", rect_prev); + if (atlas_tex.is_valid()) { + undo_redo->add_do_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region()); + undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", rect_prev); + } else if (node_sprite_2d) { + undo_redo->add_do_method(node_sprite_2d, "set_region_rect", node_sprite_2d->get_region_rect()); + undo_redo->add_undo_method(node_sprite_2d, "set_region_rect", rect_prev); } else if (node_sprite_3d) { undo_redo->add_do_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect()); undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", rect_prev); - } else if (atlas_tex.is_valid()) { - undo_redo->add_do_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region()); - undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", rect_prev); } else if (node_ninepatch) { undo_redo->add_do_method(node_ninepatch, "set_region_rect", node_ninepatch->get_region_rect()); undo_redo->add_undo_method(node_ninepatch, "set_region_rect", rect_prev); @@ -693,22 +693,24 @@ void TextureRegionEditor::_zoom_out() { } void TextureRegionEditor::apply_rect(const Rect2 &p_rect) { - if (node_sprite) { - node_sprite->set_region_rect(p_rect); + if (atlas_tex.is_valid()) { + atlas_tex->set_region(p_rect); + } else if (node_sprite_2d) { + node_sprite_2d->set_region_rect(p_rect); } else if (node_sprite_3d) { node_sprite_3d->set_region_rect(p_rect); } else if (node_ninepatch) { node_ninepatch->set_region_rect(p_rect); } else if (obj_styleBox.is_valid()) { obj_styleBox->set_region_rect(p_rect); - } else if (atlas_tex.is_valid()) { - atlas_tex->set_region(p_rect); } } void TextureRegionEditor::_update_rect() { - if (node_sprite) { - rect = node_sprite->get_region_rect(); + if (atlas_tex.is_valid()) { + rect = atlas_tex->get_region(); + } else if (node_sprite_2d) { + rect = node_sprite_2d->get_region_rect(); } else if (node_sprite_3d) { rect = node_sprite_3d->get_region_rect(); } else if (node_ninepatch) { @@ -718,8 +720,6 @@ void TextureRegionEditor::_update_rect() { } } else if (obj_styleBox.is_valid()) { rect = obj_styleBox->get_region_rect(); - } else if (atlas_tex.is_valid()) { - rect = atlas_tex->get_region(); } } @@ -728,16 +728,16 @@ void TextureRegionEditor::_update_autoslice() { autoslice_cache.clear(); Ref<Texture2D> texture = nullptr; - if (node_sprite) { - texture = node_sprite->get_texture(); + if (atlas_tex.is_valid()) { + texture = atlas_tex->get_atlas(); + } else if (node_sprite_2d) { + texture = node_sprite_2d->get_texture(); } else if (node_sprite_3d) { texture = node_sprite_3d->get_texture(); } else if (node_ninepatch) { texture = node_ninepatch->get_texture(); } else if (obj_styleBox.is_valid()) { texture = obj_styleBox->get_texture(); - } else if (atlas_tex.is_valid()) { - texture = atlas_tex->get_atlas(); } if (texture.is_null()) { @@ -823,8 +823,8 @@ void TextureRegionEditor::_notification(int p_what) { } void TextureRegionEditor::_node_removed(Object *p_obj) { - if (p_obj == node_sprite || p_obj == node_sprite_3d || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr()) { - node_sprite = nullptr; + if (p_obj == node_sprite_2d || p_obj == node_sprite_3d || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr()) { + node_sprite_2d = nullptr; node_sprite_3d = nullptr; node_ninepatch = nullptr; obj_styleBox = Ref<StyleBox>(nullptr); @@ -852,17 +852,17 @@ bool TextureRegionEditor::is_ninepatch() { return node_ninepatch != nullptr; } -Sprite3D *TextureRegionEditor::get_sprite_3d() { - return node_sprite_3d; +Sprite2D *TextureRegionEditor::get_sprite_2d() { + return node_sprite_2d; } -Sprite2D *TextureRegionEditor::get_sprite() { - return node_sprite; +Sprite3D *TextureRegionEditor::get_sprite_3d() { + return node_sprite_3d; } void TextureRegionEditor::edit(Object *p_obj) { - if (node_sprite) { - node_sprite->disconnect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); + if (node_sprite_2d) { + node_sprite_2d->disconnect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (node_sprite_3d) { node_sprite_3d->disconnect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); @@ -877,7 +877,7 @@ void TextureRegionEditor::edit(Object *p_obj) { atlas_tex->disconnect("changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } if (p_obj) { - node_sprite = Object::cast_to<Sprite2D>(p_obj); + node_sprite_2d = Object::cast_to<Sprite2D>(p_obj); node_sprite_3d = Object::cast_to<Sprite3D>(p_obj); node_ninepatch = Object::cast_to<NinePatchRect>(p_obj); @@ -898,14 +898,14 @@ void TextureRegionEditor::edit(Object *p_obj) { } _edit_region(); } else { - node_sprite = nullptr; + node_sprite_2d = nullptr; node_sprite_3d = nullptr; node_ninepatch = nullptr; obj_styleBox = Ref<StyleBoxTexture>(nullptr); atlas_tex = Ref<AtlasTexture>(nullptr); } edit_draw->update(); - if ((node_sprite && !node_sprite->is_region_enabled()) || (node_sprite_3d && !node_sprite_3d->is_region_enabled())) { + if ((node_sprite_2d && !node_sprite_2d->is_region_enabled()) || (node_sprite_3d && !node_sprite_3d->is_region_enabled())) { set_process(true); } if (!p_obj) { @@ -922,16 +922,16 @@ void TextureRegionEditor::_texture_changed() { void TextureRegionEditor::_edit_region() { Ref<Texture2D> texture = nullptr; - if (node_sprite) { - texture = node_sprite->get_texture(); + if (atlas_tex.is_valid()) { + texture = atlas_tex->get_atlas(); + } else if (node_sprite_2d) { + texture = node_sprite_2d->get_texture(); } else if (node_sprite_3d) { texture = node_sprite_3d->get_texture(); } else if (node_ninepatch) { texture = node_ninepatch->get_texture(); } else if (obj_styleBox.is_valid()) { texture = obj_styleBox->get_texture(); - } else if (atlas_tex.is_valid()) { - texture = atlas_tex->get_atlas(); } if (texture.is_null()) { @@ -967,7 +967,7 @@ Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const { } TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) { - node_sprite = nullptr; + node_sprite_2d = nullptr; node_sprite_3d = nullptr; node_ninepatch = nullptr; obj_styleBox = Ref<StyleBoxTexture>(nullptr); @@ -1122,7 +1122,9 @@ void TextureRegionEditorPlugin::_editor_visiblity_changed() { void TextureRegionEditorPlugin::make_visible(bool p_visible) { if (p_visible) { texture_region_button->show(); - bool is_node_configured = region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region_enabled()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region_enabled()); + bool is_node_configured = region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch(); + is_node_configured |= region_editor->get_sprite_2d() && region_editor->get_sprite_2d()->is_region_enabled(); + is_node_configured |= region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region_enabled(); if ((is_node_configured && !manually_hidden) || texture_region_button->is_pressed()) { editor->make_bottom_panel_item_visible(region_editor); } diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index d3db0a08a9..c043d6ae33 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -83,7 +83,7 @@ class TextureRegionEditor : public VBoxContainer { Vector2 snap_step; Vector2 snap_separation; - Sprite2D *node_sprite; + Sprite2D *node_sprite_2d; Sprite3D *node_sprite_3d; NinePatchRect *node_ninepatch; Ref<StyleBoxTexture> obj_styleBox; @@ -134,8 +134,8 @@ public: bool is_stylebox(); bool is_atlas_texture(); bool is_ninepatch(); + Sprite2D *get_sprite_2d(); Sprite3D *get_sprite_3d(); - Sprite2D *get_sprite(); void edit(Object *p_obj); TextureRegionEditor(EditorNode *p_editor); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 0add83f64d..6e0a5b00b9 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -327,10 +327,12 @@ void TileAtlasView::_draw_base_tiles_shape_grid() { Vector2i tile_id = tile_set_atlas_source->get_tile_id(i); Vector2 in_tile_base_offset = tile_set_atlas_source->get_tile_effective_texture_offset(tile_id, 0); Rect2i texture_region = tile_set_atlas_source->get_tile_texture_region(tile_id); - Vector2 origin = texture_region.position + (texture_region.size - tile_shape_size) / 2 + in_tile_base_offset; // Draw only if the tile shape fits in the texture region - tile_set->draw_tile_shape(base_tiles_shape_grid, Rect2(origin, tile_shape_size), grid_color); + Transform2D tile_xform; + tile_xform.set_origin(texture_region.position + texture_region.size / 2 + in_tile_base_offset); + tile_xform.set_scale(tile_shape_size); + tile_set->draw_tile_shape(base_tiles_shape_grid, tile_xform, grid_color); } } diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index fd5c59af34..2a75a743a7 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -124,7 +124,9 @@ void GenericTilePolygonEditor::_base_control_draw() { base_control->draw_set_transform_matrix(xform); // Draw the tile shape filled. - tile_set->draw_tile_shape(base_control, Rect2(-tile_size / 2, tile_size), Color(1.0, 1.0, 1.0, 0.3), true); + Transform2D tile_xform; + tile_xform.set_scale(tile_size); + tile_set->draw_tile_shape(base_control, tile_xform, Color(1.0, 1.0, 1.0, 0.3), true); // Draw the background. if (background_texture.is_valid()) { @@ -213,7 +215,7 @@ void GenericTilePolygonEditor::_base_control_draw() { // Draw the tile shape line. base_control->draw_set_transform_matrix(xform); - tile_set->draw_tile_shape(base_control, Rect2(-tile_size / 2, tile_size), grid_color, false); + tile_set->draw_tile_shape(base_control, tile_xform, grid_color, false); base_control->draw_set_transform_matrix(Transform2D()); } @@ -1072,14 +1074,15 @@ void TileDataTextureOffsetEditor::draw_over_tile(CanvasItem *p_canvas_item, Tran ERR_FAIL_COND(!tile_data); Vector2i tile_set_tile_size = tile_set->get_tile_size(); - Rect2i rect = Rect2i(-tile_set_tile_size / 2, tile_set_tile_size); Color color = Color(1.0, 0.0, 0.0); if (p_selected) { Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); color = selection_color; } - tile_set->draw_tile_shape(p_canvas_item, p_transform.xform(rect), color); + Transform2D tile_xform; + tile_xform.set_scale(tile_set_tile_size); + tile_set->draw_tile_shape(p_canvas_item, p_transform * tile_xform, color); } void TileDataPositionEditor::draw_over_tile(CanvasItem *p_canvas_item, Transform2D p_transform, TileMapCell p_cell, bool p_selected) { @@ -1514,9 +1517,10 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas } } else { // Draw hovered tile. - Vector2i tile_size = tile_set->get_tile_size(); - Rect2i rect = p_transform.xform(Rect2i(position - tile_size / 2, tile_size)); - tile_set->draw_tile_shape(p_canvas_item, rect, Color(1.0, 1.0, 1.0, 0.5), true); + Transform2D tile_xform; + tile_xform.set_origin(position); + tile_xform.set_scale(tile_set->get_tile_size()); + tile_set->draw_tile_shape(p_canvas_item, p_transform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } } } @@ -1686,9 +1690,10 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til } } else { // Draw hovered tile. - Vector2i tile_size = tile_set->get_tile_size(); - Rect2i rect = p_transform.xform(Rect2i(position - tile_size / 2, tile_size)); - tile_set->draw_tile_shape(p_canvas_item, rect, Color(1.0, 1.0, 1.0, 0.5), true); + Transform2D tile_xform; + tile_xform.set_origin(position); + tile_xform.set_scale(tile_set->get_tile_size()); + tile_set->draw_tile_shape(p_canvas_item, p_transform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } } } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index b5e070b4d6..acbd5d70ff 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -636,8 +636,10 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over for (int y = rect.position.y; y < rect.get_end().y; y++) { Vector2i coords = Vector2i(x, y); if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) { - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(coords) - tile_shape_size / 2, tile_shape_size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0), false); + Transform2D tile_xform; + tile_xform.set_origin(tile_map->map_to_world(coords)); + tile_xform.set_scale(tile_shape_size); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false); } } } @@ -734,10 +736,12 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Transform2D tile_xform; + tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y))); + tile_xform.set_scale(tile_shape_size); Color color = grid_color; color.a = color.a * opacity; - tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, false); } } } @@ -745,11 +749,11 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Draw the preview. for (Map<Vector2i, TileMapCell>::Element *E = preview.front(); E; E = E->next()) { - Vector2i size = tile_set->get_tile_size(); - Vector2 position = tile_map->map_to_world(E->key()) - size / 2; - Rect2 cell_region = xform.xform(Rect2(position, size)); + Transform2D tile_xform; + tile_xform.set_origin(tile_map->map_to_world(E->key())); + tile_xform.set_scale(tile_set->get_tile_size()); if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) { - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0, 0.5), true); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } else { if (tile_set->has_source(E->get().source_id)) { TileSetSource *source = *tile_set->get_source(E->get().source_id); @@ -791,10 +795,10 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over // Draw the tile. p_overlay->draw_texture_rect_region(atlas_source->get_texture(), dest_rect, source_rect, modulate * Color(1.0, 1.0, 1.0, 0.5), transpose, tile_set->is_uv_clipping()); } else { - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 1.0, 1.0, 0.5), true); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true); } } else { - tile_set->draw_tile_shape(p_overlay, cell_region, Color(0.0, 0.0, 0.0, 0.5), true); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(0.0, 0.0, 0.0, 0.5), true); } } } @@ -3689,8 +3693,10 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { 0.8); // Draw the scaled tile. - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(coords) - Vector2(tile_shape_size) / 2, Vector2(tile_shape_size))); - tile_set->draw_tile_shape(p_overlay, cell_region, color, true, warning_pattern_texture); + Transform2D tile_xform; + tile_xform.set_origin(tile_map->map_to_world(coords)); + tile_xform.set_scale(tile_shape_size); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture); } // Draw the warning icon. @@ -3746,10 +3752,12 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Transform2D tile_xform; + tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y))); + tile_xform.set_scale(tile_shape_size); Color color = grid_color; color.a = color.a * opacity; - tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, false); } } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 50808a25af..aaa085675c 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -4042,7 +4042,7 @@ VisualShaderEditor::VisualShaderEditor() { graph->get_zoom_hbox()->add_child(add_node); add_node->set_text(TTR("Add Node...")); graph->get_zoom_hbox()->move_child(add_node, 0); - add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog), varray(false)); + add_node->connect("pressed", callable_mp(this, &VisualShaderEditor::_show_members_dialog), varray(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX)); preview_shader = memnew(Button); preview_shader->set_flat(true); |