summaryrefslogtreecommitdiffstats
path: root/editor/animation_track_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/animation_track_editor.cpp')
-rw-r--r--editor/animation_track_editor.cpp123
1 files changed, 96 insertions, 27 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 741d127ea2..076ba6d905 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -63,7 +63,6 @@
constexpr double FPS_DECIMAL = 1.0;
constexpr double SECOND_DECIMAL = 0.0001;
-constexpr double FPS_STEP_FRACTION = 0.0625;
void AnimationTrackKeyEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationTrackKeyEdit::_update_obj);
@@ -1440,8 +1439,8 @@ void AnimationTimelineEdit::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
- add_track->set_icon(get_editor_theme_icon(SNAME("Add")));
- loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
+ add_track->set_button_icon(get_editor_theme_icon(SNAME("Add")));
+ loop->set_button_icon(get_editor_theme_icon(SNAME("Loop")));
time_icon->set_texture(get_editor_theme_icon(SNAME("Time")));
add_track->get_popup()->clear();
@@ -1818,15 +1817,15 @@ void AnimationTimelineEdit::update_values() {
switch (animation->get_loop_mode()) {
case Animation::LOOP_NONE: {
- loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
+ loop->set_button_icon(get_editor_theme_icon(SNAME("Loop")));
loop->set_pressed(false);
} break;
case Animation::LOOP_LINEAR: {
- loop->set_icon(get_editor_theme_icon(SNAME("Loop")));
+ loop->set_button_icon(get_editor_theme_icon(SNAME("Loop")));
loop->set_pressed(true);
} break;
case Animation::LOOP_PINGPONG: {
- loop->set_icon(get_editor_theme_icon(SNAME("PingPongLoop")));
+ loop->set_button_icon(get_editor_theme_icon(SNAME("PingPongLoop")));
loop->set_pressed(true);
} break;
default:
@@ -3313,7 +3312,7 @@ Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) {
Button *tb = memnew(Button);
tb->set_flat(true);
tb->set_text(path_cache);
- tb->set_icon(icon_cache);
+ tb->set_button_icon(icon_cache);
tb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
tb->add_theme_constant_override("icon_max_width", get_theme_constant("class_icon_size", EditorStringName(Editor)));
set_drag_preview(tb);
@@ -3776,6 +3775,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re
step->set_read_only(false);
snap_keys->set_disabled(false);
snap_timeline->set_disabled(false);
+ fps_compat->set_disabled(false);
snap_mode->set_disabled(false);
auto_fit->set_disabled(false);
auto_fit_bezier->set_disabled(false);
@@ -3798,6 +3798,7 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim, bool p_re
step->set_read_only(true);
snap_keys->set_disabled(true);
snap_timeline->set_disabled(true);
+ fps_compat->set_disabled(true);
snap_mode->set_disabled(true);
bezier_edit_icon->set_disabled(true);
auto_fit->set_disabled(true);
@@ -5029,7 +5030,12 @@ void AnimationTrackEditor::_snap_mode_changed(int p_mode) {
}
marker_edit->set_use_fps(use_fps);
// To ensure that the conversion results are consistent between serialization and load, the value is snapped with 0.0625 to be a rational number when FPS mode is used.
- step->set_step(use_fps ? FPS_STEP_FRACTION : SECOND_DECIMAL);
+ step->set_step(use_fps ? FPS_DECIMAL : SECOND_DECIMAL);
+ if (use_fps) {
+ fps_compat->hide();
+ } else {
+ fps_compat->show();
+ }
_update_step_spinbox();
}
@@ -5045,7 +5051,6 @@ void AnimationTrackEditor::_update_step_spinbox() {
} else {
step->set_value(1.0 / animation->get_step());
}
-
} else {
step->set_value(animation->get_step());
}
@@ -5054,6 +5059,20 @@ void AnimationTrackEditor::_update_step_spinbox() {
_update_snap_unit();
}
+void AnimationTrackEditor::_update_fps_compat_mode(bool p_enabled) {
+ _update_snap_unit();
+}
+
+void AnimationTrackEditor::_update_nearest_fps_label() {
+ bool is_fps_invalid = nearest_fps == 0;
+ if (is_fps_invalid) {
+ nearest_fps_label->hide();
+ } else {
+ nearest_fps_label->show();
+ nearest_fps_label->set_text("Nearest FPS: " + itos(nearest_fps));
+ }
+}
+
void AnimationTrackEditor::_animation_update() {
timeline->queue_redraw();
timeline->update_values();
@@ -5112,18 +5131,19 @@ void AnimationTrackEditor::_notification(int p_what) {
}
case NOTIFICATION_THEME_CHANGED: {
zoom_icon->set_texture(get_editor_theme_icon(SNAME("Zoom")));
- bezier_edit_icon->set_icon(get_editor_theme_icon(SNAME("EditBezier")));
- snap_timeline->set_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
- snap_keys->set_icon(get_editor_theme_icon(SNAME("SnapKeys")));
- view_group->set_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
- selected_filter->set_icon(get_editor_theme_icon(SNAME("AnimationFilter")));
- imported_anim_warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
- dummy_player_warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
- inactive_player_warning->set_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier")));
+ snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
+ snap_keys->set_button_icon(get_editor_theme_icon(SNAME("SnapKeys")));
+ fps_compat->set_button_icon(get_editor_theme_icon(SNAME("FPS")));
+ view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
+ selected_filter->set_button_icon(get_editor_theme_icon(SNAME("AnimationFilter")));
+ imported_anim_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ dummy_player_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning")));
+ inactive_player_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning")));
main_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_editor_theme_icon(SNAME("Reload")));
- auto_fit->set_icon(get_editor_theme_icon(SNAME("AnimationAutoFit")));
- auto_fit_bezier->set_icon(get_editor_theme_icon(SNAME("AnimationAutoFitBezier")));
+ auto_fit->set_button_icon(get_editor_theme_icon(SNAME("AnimationAutoFit")));
+ auto_fit_bezier->set_button_icon(get_editor_theme_icon(SNAME("AnimationAutoFitBezier")));
const int timeline_separation = get_theme_constant(SNAME("timeline_v_separation"), SNAME("AnimationTrackEditor"));
timeline_vbox->add_theme_constant_override("separation", timeline_separation);
@@ -5160,9 +5180,8 @@ void AnimationTrackEditor::_update_step(double p_new_step) {
double step_value = p_new_step;
if (timeline->is_using_fps()) {
if (step_value != 0.0) {
- // step_value must also be less than or equal to 1000 to ensure that no error accumulates due to interactions with retrieving values from inner range.
+ // A step_value should be less than or equal to 1000 to ensure that no error accumulates due to interactions with retrieving values from inner range.
step_value = 1.0 / MIN(1000.0, p_new_step);
- ;
}
timeline->queue_redraw();
}
@@ -5297,6 +5316,28 @@ void AnimationTrackEditor::_add_track(int p_type) {
return;
}
adding_track_type = p_type;
+ Vector<StringName> valid_types;
+ switch (adding_track_type) {
+ case Animation::TYPE_BLEND_SHAPE: {
+ // Blend Shape is a property of MeshInstance3D.
+ valid_types.push_back(SNAME("MeshInstance3D"));
+ } break;
+ case Animation::TYPE_POSITION_3D:
+ case Animation::TYPE_ROTATION_3D:
+ case Animation::TYPE_SCALE_3D: {
+ // 3D Properties come from nodes inheriting Node3D.
+ valid_types.push_back(SNAME("Node3D"));
+ } break;
+ case Animation::TYPE_AUDIO: {
+ valid_types.push_back(SNAME("AudioStreamPlayer"));
+ valid_types.push_back(SNAME("AudioStreamPlayer2D"));
+ valid_types.push_back(SNAME("AudioStreamPlayer3D"));
+ } break;
+ case Animation::TYPE_ANIMATION: {
+ valid_types.push_back(SNAME("AnimationPlayer"));
+ } break;
+ }
+ pick_track->set_valid_types(valid_types);
pick_track->popup_scenetree_dialog(nullptr, root_node);
pick_track->get_filter_line_edit()->clear();
pick_track->get_filter_line_edit()->grab_focus();
@@ -6337,8 +6378,9 @@ bool AnimationTrackEditor::_is_track_compatible(int p_target_track_idx, Variant:
}
if (path_valid) {
- if (is_source_bezier)
+ if (is_source_bezier) {
p_source_value_type = Variant::FLOAT;
+ }
return property_type == p_source_value_type;
} else {
if (animation->track_get_key_count(p_target_track_idx) > 0) {
@@ -7279,7 +7321,7 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
void AnimationTrackEditor::_view_group_toggle() {
_update_tracks();
- view_group->set_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
+ view_group->set_button_icon(get_editor_theme_icon(view_group->is_pressed() ? SNAME("AnimationTrackList") : SNAME("AnimationTrackGroup")));
bezier_edit->set_filtered(selected_filter->is_pressed());
}
@@ -7313,19 +7355,30 @@ void AnimationTrackEditor::_selection_changed() {
}
void AnimationTrackEditor::_update_snap_unit() {
+ nearest_fps = 0;
+
if (step->get_value() <= 0) {
snap_unit = 0;
+ _update_nearest_fps_label();
return; // Avoid zero div.
}
if (timeline->is_using_fps()) {
+ _clear_selection(true); // Needs to recreate a spinbox of the KeyEdit.
snap_unit = 1.0 / step->get_value();
} else {
- double integer;
- double fraction = Math::modf(step->get_value(), &integer);
- fraction = 1.0 / Math::round(1.0 / fraction);
- snap_unit = integer + fraction;
+ if (fps_compat->is_pressed()) {
+ snap_unit = CLAMP(step->get_value(), 0.0, 1.0);
+ if (!Math::is_zero_approx(snap_unit)) {
+ real_t fps = Math::round(1.0 / snap_unit);
+ nearest_fps = int(fps);
+ snap_unit = 1.0 / fps;
+ }
+ } else {
+ snap_unit = step->get_value();
+ }
}
+ _update_nearest_fps_label();
}
float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
@@ -7346,6 +7399,10 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
return p_value;
}
+float AnimationTrackEditor::get_snap_unit() {
+ return snap_unit;
+}
+
void AnimationTrackEditor::_show_imported_anim_warning() {
// It looks terrible on a single line but the TTR extractor doesn't support line breaks yet.
EditorNode::get_singleton()->show_warning(
@@ -7599,6 +7656,18 @@ AnimationTrackEditor::AnimationTrackEditor() {
snap_keys->set_pressed(true);
snap_keys->set_tooltip_text(TTR("Apply snapping to selected key(s)."));
+ fps_compat = memnew(Button);
+ fps_compat->set_flat(true);
+ bottom_hb->add_child(fps_compat);
+ fps_compat->set_disabled(true);
+ fps_compat->set_toggle_mode(true);
+ fps_compat->set_pressed(true);
+ fps_compat->set_tooltip_text(TTR("Apply snapping to the nearest integer FPS."));
+ fps_compat->connect(SceneStringName(toggled), callable_mp(this, &AnimationTrackEditor::_update_fps_compat_mode));
+
+ nearest_fps_label = memnew(Label);
+ bottom_hb->add_child(nearest_fps_label);
+
step = memnew(EditorSpinSlider);
step->set_min(0);
step->set_max(1000000);