diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp index 232160d17c7..ec3805885e3 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.cpp +++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp @@ -96,7 +96,7 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const { case RECTANGLE_SHAPE: { Ref rect = node->get_shape(); - if (idx < 3) { + if (idx < 8) { return rect->get_extents().abs(); } @@ -175,16 +175,26 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) { } break; case RECTANGLE_SHAPE: { - if (idx < 3) { + if (idx < 8) { Ref rect = node->get_shape(); + Vector2 extents = (Point2)original; - Vector2 extents = rect->get_extents(); - if (idx == 2) { - extents = p_point; - } else { - extents[idx] = p_point[idx]; + if (RECT_HANDLES[idx].x != 0) { + extents.x = p_point.x * RECT_HANDLES[idx].x; + } + if (RECT_HANDLES[idx].y != 0) { + extents.y = p_point.y * RECT_HANDLES[idx].y; + } + + if (Input::get_singleton()->is_key_pressed(KEY_ALT)) { + rect->set_extents(extents.abs()); + node->set_global_position(original_transform.get_origin()); + } else { + rect->set_extents(((Point2)original + (extents - (Point2)original) * 0.5).abs()); + Point2 pos = original_transform.affine_inverse().xform(original_transform.get_origin()); + pos += (extents - (Point2)original) * RECT_HANDLES[idx] * 0.5; + node->set_global_position(original_transform.xform(pos)); } - rect->set_extents(extents.abs()); canvas_item_editor->update_viewport(); } @@ -279,8 +289,10 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) { Ref rect = node->get_shape(); undo_redo->add_do_method(rect.ptr(), "set_extents", rect->get_extents()); + undo_redo->add_do_method(node, "set_global_transform", node->get_global_transform()); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); undo_redo->add_undo_method(rect.ptr(), "set_extents", p_org); + undo_redo->add_undo_method(node, "set_global_transform", original_transform); undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); } break; @@ -341,6 +353,8 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref &p_e } original = get_handle_value(edit_handle); + original_transform = node->get_global_transform(); + last_point = original; pressed = true; return true; @@ -368,13 +382,26 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref &p_e } Vector2 cpoint = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())); - cpoint = node->get_global_transform().affine_inverse().xform(cpoint); + cpoint = original_transform.affine_inverse().xform(cpoint); + last_point = cpoint; set_handle(edit_handle, cpoint); return true; } + Ref k = p_event; + + if (k.is_valid()) { + if (edit_handle == -1 || !pressed || k->is_echo()) { + return false; + } + + if (shape_type == RECTANGLE_SHAPE && k->get_scancode() == KEY_ALT) { + set_handle(edit_handle, last_point); // Update handle when Alt key is toggled. + } + } + return false; } @@ -491,16 +518,12 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla case RECTANGLE_SHAPE: { Ref shape = node->get_shape(); - handles.resize(3); + handles.resize(8); Vector2 ext = shape->get_extents(); - handles.write[0] = Point2(ext.x, 0); - handles.write[1] = Point2(0, -ext.y); - handles.write[2] = Point2(ext.x, -ext.y); - - p_overlay->draw_texture(h, gt.xform(handles[0]) - size); - p_overlay->draw_texture(h, gt.xform(handles[1]) - size); - p_overlay->draw_texture(h, gt.xform(handles[2]) - size); - + for (int i = 0; i < handles.size(); i++) { + handles.write[i] = RECT_HANDLES[i] * ext; + p_overlay->draw_texture(h, gt.xform(handles[i]) - size); + } } break; case SEGMENT_SHAPE: { diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h index c22edbe1f32..15b0e5ac3d6 100644 --- a/editor/plugins/collision_shape_2d_editor_plugin.h +++ b/editor/plugins/collision_shape_2d_editor_plugin.h @@ -31,6 +31,8 @@ #ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H #define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H +#include "core/os/input.h" +#include "core/os/keyboard.h" #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -52,6 +54,17 @@ class CollisionShape2DEditor : public Control { SEGMENT_SHAPE }; + const Point2 RECT_HANDLES[8] = { + Point2(1, 0), + Point2(1, 1), + Point2(0, 1), + Point2(-1, 1), + Point2(-1, 0), + Point2(-1, -1), + Point2(0, -1), + Point2(1, -1), + }; + EditorNode *editor; UndoRedo *undo_redo; CanvasItemEditor *canvas_item_editor; @@ -63,6 +76,8 @@ class CollisionShape2DEditor : public Control { int edit_handle; bool pressed; Variant original; + Transform2D original_transform; + Point2 last_point; Variant get_handle_value(int idx) const; void set_handle(int idx, Point2 &p_point);