Skip to content

Commit a592639

Browse files
committed
Merge pull request #103956 from dugramen/curve-handles-outwards
Path2D prefer control points for outward curve
2 parents f810c74 + 4fbf38d commit a592639

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

editor/plugins/path_2d_editor_plugin.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,25 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
110110
moving_screen_from = gpoint;
111111
return true;
112112
} else if (mode == MODE_EDIT || mode == MODE_EDIT_CURVE) {
113+
control_points_in_range = 0;
113114
// In/out controls can be moved in multiple modes.
114115
if (dist_to_p_out < grab_threshold && i < (curve->get_point_count() - 1)) {
115116
action = ACTION_MOVING_OUT;
116117
action_point = i;
117118
moving_from = curve->get_point_out(i);
118119
moving_screen_from = gpoint;
119120
orig_in_length = curve->get_point_in(action_point).length();
120-
return true;
121-
} else if (dist_to_p_in < grab_threshold && i > 0) {
121+
control_points_in_range += 1;
122+
}
123+
if (dist_to_p_in < grab_threshold && i > 0) {
122124
action = ACTION_MOVING_IN;
123125
action_point = i;
124126
moving_from = curve->get_point_in(i);
125127
moving_screen_from = gpoint;
126128
orig_out_length = curve->get_point_out(action_point).length();
129+
control_points_in_range += 1;
130+
}
131+
if (control_points_in_range > 0) {
127132
return true;
128133
}
129134
}
@@ -298,6 +303,27 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
298303
Ref<InputEventMouseMotion> mm = p_event;
299304

300305
if (mm.is_valid()) {
306+
// When both control points were in range of click,
307+
// pick the point that drags the curve outwards.
308+
if (control_points_in_range == 2) {
309+
control_points_in_range = 0;
310+
Ref<Curve2D> curve = node->get_curve();
311+
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_screen_transform();
312+
Point2 relative = xform.affine_inverse().basis_xform(mm->get_relative());
313+
real_t angle_in = relative.angle_to(curve->get_point_position(action_point - 1) - curve->get_point_position(action_point));
314+
real_t angle_out = relative.angle_to(curve->get_point_position(action_point + 1) - curve->get_point_position(action_point));
315+
316+
if (Math::abs(angle_in) < Math::abs(angle_out)) {
317+
action = ACTION_MOVING_IN;
318+
moving_from = curve->get_point_in(action_point);
319+
orig_out_length = curve->get_point_out(action_point).length();
320+
} else {
321+
action = ACTION_MOVING_OUT;
322+
moving_from = curve->get_point_out(action_point);
323+
orig_in_length = curve->get_point_in(action_point).length();
324+
}
325+
}
326+
301327
if (action == ACTION_NONE && mode == MODE_EDIT) {
302328
// Handle Edge Follow
303329
bool old_edge = on_edge;

editor/plugins/path_2d_editor_plugin.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ class Path2DEditor : public HBoxContainer {
9696
Vector2 edge_point;
9797
Vector2 original_mouse_pos;
9898

99+
// Number of control points in range of the last click.
100+
// 0, 1, or 2.
101+
int control_points_in_range = 0;
102+
99103
void _mode_selected(int p_mode);
100104
void _handle_option_pressed(int p_option);
101105
void _cancel_current_action();

0 commit comments

Comments
 (0)