Add linear/cubic angle interpolation to Animation interpolation type
This commit is contained in:
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user