diff options
Diffstat (limited to 'editor/animation_bezier_editor.cpp')
-rw-r--r-- | editor/animation_bezier_editor.cpp | 102 |
1 files changed, 64 insertions, 38 deletions
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index e9cf22af85..f7f88ad0d5 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -187,7 +187,7 @@ void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const V Vector2 from = p_from; Vector2 to = p_to; - if (from.x == to.x) { + if (from.x == to.x && from.y == to.y) { return; } if (to.x < from.x) { @@ -222,11 +222,6 @@ void AnimationBezierTrackEdit::_notification(int p_what) { bezier_icon = get_theme_icon(SNAME("KeyBezierPoint"), SNAME("EditorIcons")); bezier_handle_icon = get_theme_icon(SNAME("KeyBezierHandle"), SNAME("EditorIcons")); selected_icon = get_theme_icon(SNAME("KeyBezierSelected"), SNAME("EditorIcons")); - if (handle_mode_option->get_item_count() == 0) { - handle_mode_option->add_icon_item(get_theme_icon(SNAME("BezierHandlesFree"), SNAME("EditorIcons")), TTR("Free"), HANDLE_MODE_FREE); - handle_mode_option->add_icon_item(get_theme_icon(SNAME("BezierHandlesBalanced"), SNAME("EditorIcons")), TTR("Balanced"), HANDLE_MODE_BALANCED); - handle_mode_option->add_icon_item(get_theme_icon(SNAME("BezierHandlesMirror"), SNAME("EditorIcons")), TTR("Mirror"), HANDLE_MODE_MIRROR); - } } if (p_what == NOTIFICATION_RESIZED) { int right_limit = get_size().width - timeline->get_buttons_width(); @@ -420,9 +415,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) { //draw editor handles { - float scale = timeline->get_zoom_scale(); edit_points.clear(); + float scale = timeline->get_zoom_scale(); for (int i = 0; i < animation->track_get_key_count(track); i++) { float offset = animation->track_get_key_time(track, i); float value = animation->bezier_track_get_key_value(track, i); @@ -438,7 +433,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { if (moving_handle != 0 && moving_handle_key == i) { in_vec = moving_handle_left; } - Vector2 pos_in = Vector2(((offset + in_vec.x) - timeline->get_value()) * scale + limit, _bezier_h_to_pixel(value + in_vec.y)); + Vector2 pos_in(((offset + in_vec.x) - timeline->get_value()) * scale + limit, _bezier_h_to_pixel(value + in_vec.y)); Vector2 out_vec = animation->bezier_track_get_key_out_handle(track, i); @@ -446,7 +441,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { out_vec = moving_handle_right; } - Vector2 pos_out = Vector2(((offset + out_vec.x) - timeline->get_value()) * scale + limit, _bezier_h_to_pixel(value + out_vec.y)); + Vector2 pos_out(((offset + out_vec.x) - timeline->get_value()) * scale + limit, _bezier_h_to_pixel(value + out_vec.y)); _draw_line_clipped(pos, pos_in, accent, limit, right_limit); _draw_line_clipped(pos, pos_out, accent, limit, right_limit); @@ -581,11 +576,21 @@ void AnimationBezierTrackEdit::_clear_selection() { update(); } +void AnimationBezierTrackEdit::_change_selected_keys_handle_mode(Animation::HandleMode p_mode) { + undo_redo->create_action(TTR("Update Selected Key Handles")); + double ratio = timeline->get_zoom_scale() * v_zoom; + for (Set<int>::Element *E = selection.back(); E; E = E->prev()) { + const int key_index = E->get(); + undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_handle_mode", track, key_index, animation->bezier_track_get_key_handle_mode(track, key_index), ratio); + undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_handle_mode", track, key_index, p_mode, ratio); + } + undo_redo->commit_action(); +} + void AnimationBezierTrackEdit::_clear_selection_for_anim(const Ref<Animation> &p_anim) { if (!(animation == p_anim)) { return; } - //selection.clear(); _clear_selection(); } @@ -667,6 +672,9 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { menu->add_icon_item(get_theme_icon(SNAME("Duplicate"), SNAME("EditorIcons")), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE); menu->add_separator(); menu->add_icon_item(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE); + menu->add_separator(); + menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesFree"), SNAME("EditorIcons")), TTR("Make Handles Free"), MENU_KEY_SET_HANDLE_FREE); + menu->add_icon_item(get_theme_icon(SNAME("BezierHandlesBalanced"), SNAME("EditorIcons")), TTR("Make Handles Balanced"), MENU_KEY_SET_HANDLE_BALANCED); } menu->set_as_minsize(); @@ -676,10 +684,6 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { - if (close_icon_rect.has_point(mb->get_position())) { - emit_signal(SNAME("close_request")); - return; - } for (const KeyValue<int, Rect2> &E : subtracks) { if (E.value.has_point(mb->get_position())) { set_animation_and_track(animation, E.key); @@ -746,7 +750,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { //insert new point if (mb->is_command_pressed() && mb->get_position().x >= timeline->get_name_limit() && mb->get_position().x < get_size().width - timeline->get_buttons_width()) { Array new_point; - new_point.resize(5); + new_point.resize(6); float h = (get_size().height / 2 - mb->get_position().y) * v_zoom + v_scroll; @@ -755,6 +759,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { new_point[2] = 0; new_point[3] = 0.25; new_point[4] = 0; + new_point[5] = 0; float time = ((mb->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale()) + timeline->get_value(); while (animation->track_find_key(track, time, true) != -1) { @@ -986,33 +991,49 @@ void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) { if (moving_handle == -1) { moving_handle_left = moving_handle_value; - if (moving_handle_left.x > 0) { - moving_handle_left.x = 0; - } - if (handle_mode_option->get_selected() == HANDLE_MODE_BALANCED) { - Vector2 scale = Vector2(timeline->get_zoom_scale(), v_zoom); - moving_handle_right = (-(moving_handle_left * scale).normalized() * (moving_handle_right * scale).length()) / scale; + if (animation->bezier_track_get_key_handle_mode(track, moving_handle_key) == Animation::HANDLE_MODE_BALANCED) { + double ratio = timeline->get_zoom_scale() * v_zoom; + Transform2D xform; + xform.set_scale(Vector2(1.0, 1.0 / ratio)); - } else if (handle_mode_option->get_selected() == HANDLE_MODE_MIRROR) { - moving_handle_right = -moving_handle_left; - } - } + Vector2 vec_out = xform.xform(moving_handle_right); + Vector2 vec_in = xform.xform(moving_handle_left); - if (moving_handle == 1) { - moving_handle_right = moving_handle_value; - if (moving_handle_right.x < 0) { - moving_handle_right.x = 0; + moving_handle_right = xform.affine_inverse().xform(-vec_in.normalized() * vec_out.length()); } + } else if (moving_handle == 1) { + moving_handle_right = moving_handle_value; + + if (animation->bezier_track_get_key_handle_mode(track, moving_handle_key) == Animation::HANDLE_MODE_BALANCED) { + double ratio = timeline->get_zoom_scale() * v_zoom; + Transform2D xform; + xform.set_scale(Vector2(1.0, 1.0 / ratio)); - if (handle_mode_option->get_selected() == HANDLE_MODE_BALANCED) { - Vector2 scale = Vector2(timeline->get_zoom_scale(), v_zoom); - moving_handle_left = (-(moving_handle_right * scale).normalized() * (moving_handle_left * scale).length()) / scale; - } else if (handle_mode_option->get_selected() == HANDLE_MODE_MIRROR) { - moving_handle_left = -moving_handle_right; + Vector2 vec_in = xform.xform(moving_handle_left); + Vector2 vec_out = xform.xform(moving_handle_right); + + moving_handle_left = xform.affine_inverse().xform(-vec_out.normalized() * vec_in.length()); } } + update(); + } + + bool is_finishing_key_handle_drag = moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT; + if (is_finishing_key_handle_drag) { + undo_redo->create_action(TTR("Move Bezier Points")); + if (moving_handle == -1) { + double ratio = timeline->get_zoom_scale() * v_zoom; + undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", track, moving_handle_key, moving_handle_left, ratio); + undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, moving_handle_key, animation->bezier_track_get_key_in_handle(track, moving_handle_key), ratio); + } else if (moving_handle == 1) { + double ratio = timeline->get_zoom_scale() * v_zoom; + undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", track, moving_handle_key, moving_handle_right, ratio); + undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_out_handle", track, moving_handle_key, animation->bezier_track_get_key_out_handle(track, moving_handle_key), ratio); + } + undo_redo->commit_action(); + moving_handle = 0; update(); } } @@ -1021,7 +1042,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { switch (p_index) { case MENU_KEY_INSERT: { Array new_point; - new_point.resize(5); + new_point.resize(6); float h = (get_size().height / 2 - menu_insert_key.y) * v_zoom + v_scroll; @@ -1030,6 +1051,7 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { new_point[2] = 0; new_point[3] = 0.25; new_point[4] = 0; + new_point[5] = Animation::HANDLE_MODE_BALANCED; float time = ((menu_insert_key.x - timeline->get_name_limit()) / timeline->get_zoom_scale()) + timeline->get_value(); while (animation->track_find_key(track, time, true) != -1) { @@ -1048,6 +1070,12 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) { case MENU_KEY_DELETE: { delete_selection(); } break; + case MENU_KEY_SET_HANDLE_FREE: { + _change_selected_keys_handle_mode(Animation::HANDLE_MODE_FREE); + } break; + case MENU_KEY_SET_HANDLE_BALANCED: { + _change_selected_keys_handle_mode(Animation::HANDLE_MODE_BALANCED); + } break; } } @@ -1118,6 +1146,7 @@ void AnimationBezierTrackEdit::delete_selection() { undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); undo_redo->commit_action(); + //selection.clear(); } } @@ -1150,8 +1179,6 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() { set_focus_mode(FOCUS_CLICK); set_clip_contents(true); - handle_mode = HANDLE_MODE_FREE; - handle_mode_option = memnew(OptionButton); close_button = memnew(Button); close_button->connect("pressed", Callable(this, SNAME("emit_signal")), varray(SNAME("close_request"))); @@ -1160,7 +1187,6 @@ AnimationBezierTrackEdit::AnimationBezierTrackEdit() { right_column = memnew(VBoxContainer); right_column->add_child(close_button); right_column->add_spacer(); - right_column->add_child(handle_mode_option); add_child(right_column); menu = memnew(PopupMenu); |