summaryrefslogtreecommitdiff
path: root/editor/animation_track_editor.cpp
diff options
context:
space:
mode:
authorSilc Renew <tokage.it.lab@gmail.com>2022-08-26 11:42:00 +0900
committerSilc Renew <tokage.it.lab@gmail.com>2022-08-27 07:58:22 +0900
commit931fb4dc11509357297bcdcc6a8d6b11638ff585 (patch)
treecd078a938be475cc20bba35ac856103b9e524239 /editor/animation_track_editor.cpp
parent4808d01b2bcda54db15e1e2649e0a38c37886ee1 (diff)
Add linear/cubic angle interpolation to Animation interpolation type
Diffstat (limited to 'editor/animation_track_editor.cpp')
-rw-r--r--editor/animation_track_editor.cpp44
1 files changed, 39 insertions, 5 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index ddce4f8a36..86d08de430 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -2122,10 +2122,12 @@ void AnimationTrackEdit::_notification(int p_what) {
get_theme_icon(SNAME("InterpWrapClamp"), SNAME("EditorIcons")),
get_theme_icon(SNAME("InterpWrapLoop"), SNAME("EditorIcons")),
};
- Ref<Texture2D> interp_icon[3] = {
+ Ref<Texture2D> interp_icon[5] = {
get_theme_icon(SNAME("InterpRaw"), SNAME("EditorIcons")),
get_theme_icon(SNAME("InterpLinear"), SNAME("EditorIcons")),
get_theme_icon(SNAME("InterpCubic"), SNAME("EditorIcons")),
+ get_theme_icon(SNAME("InterpLinearAngle"), SNAME("EditorIcons")),
+ get_theme_icon(SNAME("InterpCubicAngle"), SNAME("EditorIcons")),
};
Ref<Texture2D> cont_icon[4] = {
get_theme_icon(SNAME("TrackContinuous"), SNAME("EditorIcons")),
@@ -2848,6 +2850,23 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
menu->add_icon_item(get_theme_icon(SNAME("InterpRaw"), SNAME("EditorIcons")), TTR("Nearest"), MENU_INTERPOLATION_NEAREST);
menu->add_icon_item(get_theme_icon(SNAME("InterpLinear"), SNAME("EditorIcons")), TTR("Linear"), MENU_INTERPOLATION_LINEAR);
menu->add_icon_item(get_theme_icon(SNAME("InterpCubic"), SNAME("EditorIcons")), TTR("Cubic"), MENU_INTERPOLATION_CUBIC);
+ // Check is angle property.
+ AnimationPlayerEditor *ape = AnimationPlayerEditor::get_singleton();
+ if (ape) {
+ AnimationPlayer *ap = ape->get_player();
+ if (ap) {
+ NodePath path = animation->track_get_path(track);
+ Node *nd = ap->get_node(ap->get_root())->get_node(NodePath(path.get_concatenated_names()));
+ StringName prop = path.get_concatenated_subnames();
+ PropertyInfo prop_info;
+ ClassDB::get_property_info(nd->get_class(), prop, &prop_info);
+ bool is_angle = prop_info.type == Variant::FLOAT && prop_info.hint_string.find("radians") != -1;
+ if (is_angle) {
+ menu->add_icon_item(get_theme_icon(SNAME("InterpLinearAngle"), SNAME("EditorIcons")), TTR("Linear Angle"), MENU_INTERPOLATION_LINEAR_ANGLE);
+ menu->add_icon_item(get_theme_icon(SNAME("InterpCubicAngle"), SNAME("EditorIcons")), TTR("Cubic Angle"), MENU_INTERPOLATION_CUBIC_ANGLE);
+ }
+ }
+ }
menu->reset_size();
Vector2 popup_pos = get_screen_position() + interp_mode_rect.position + Vector2(0, interp_mode_rect.size.height);
@@ -3188,7 +3207,9 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
} break;
case MENU_INTERPOLATION_NEAREST:
case MENU_INTERPOLATION_LINEAR:
- case MENU_INTERPOLATION_CUBIC: {
+ case MENU_INTERPOLATION_CUBIC:
+ case MENU_INTERPOLATION_LINEAR_ANGLE:
+ case MENU_INTERPOLATION_CUBIC_ANGLE: {
Animation::InterpolationType interp_mode = Animation::InterpolationType(p_index - MENU_INTERPOLATION_NEAREST);
undo_redo->create_action(TTR("Change Animation Interpolation Mode"));
undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", track, interp_mode);
@@ -6042,6 +6063,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
Vector<int> keys = E->value;
int len = keys.size() - 1;
+ // Special case for angle interpolation.
+ bool is_using_angle = animation->track_get_interpolation_type(track) == Animation::INTERPOLATION_LINEAR_ANGLE || animation->track_get_interpolation_type(track) == Animation::INTERPOLATION_CUBIC_ANGLE;
+
// Make insert queue.
Vector<Pair<double, Variant>> insert_queue;
for (int i = 0; i < len; i++) {
@@ -6051,6 +6075,12 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
double to_t = animation->track_get_key_time(track, keys[i + 1]);
Variant from_v = animation->track_get_key_value(track, keys[i]);
Variant to_v = animation->track_get_key_value(track, keys[i + 1]);
+ if (is_using_angle) {
+ real_t a = from_v;
+ real_t b = to_v;
+ real_t to_diff = fmod(b - a, Math_TAU);
+ to_v = a + fmod(2.0 * to_diff, Math_TAU) - to_diff;
+ }
Variant delta_v;
Variant::sub(to_v, from_v, delta_v);
double duration = to_t - from_t;
@@ -6192,10 +6222,14 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
do_bake |= b_bs && type == Animation::TYPE_BLEND_SHAPE;
do_bake |= b_v && type == Animation::TYPE_VALUE;
if (do_bake && !animation->track_is_compressed(i)) {
- if (animation->track_get_interpolation_type(i) == Animation::INTERPOLATION_NEAREST) {
- continue; // Nearest interpolation cannot be baked.
+ Animation::InterpolationType it = animation->track_get_interpolation_type(i);
+ if (it == Animation::INTERPOLATION_NEAREST) {
+ continue; // Nearest and Angle interpolation cannot be baked.
}
+ // Special case for angle interpolation.
+ bool is_using_angle = it == Animation::INTERPOLATION_LINEAR_ANGLE || it == Animation::INTERPOLATION_CUBIC_ANGLE;
+
// Make insert queue.
Vector<Pair<double, Variant>> insert_queue;
@@ -6259,7 +6293,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
// Insert keys.
- undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", i, Animation::INTERPOLATION_LINEAR);
+ undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", i, is_using_angle ? Animation::INTERPOLATION_LINEAR_ANGLE : Animation::INTERPOLATION_LINEAR);
for (int j = insert_queue.size() - 1; j >= 0; j--) {
undo_redo->add_do_method(animation.ptr(), "track_insert_key", i, insert_queue[j].first, insert_queue[j].second);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key", i, j);