summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
authorThaddeus Crews <repiteo@outlook.com>2024-11-11 14:18:24 -0600
committerThaddeus Crews <repiteo@outlook.com>2024-11-11 14:18:24 -0600
commit93815e7e9767058ec5bf54c2bae442bbfcfc074e (patch)
treecc0e8484c1623678797fb58007fdc6005deb697b /editor
parente5b77b184f3547289256d40f04b8bc6a7efdc055 (diff)
parent64d04c375c7a0ec73774d2b977eb30b064a38051 (diff)
downloadredot-engine-93815e7e9767058ec5bf54c2bae442bbfcfc074e.tar.gz
Merge pull request #99013 from TokageItLab/fps-compat-toggle
Add FPS compatible option in second mode of the animation editor snapping
Diffstat (limited to 'editor')
-rw-r--r--editor/animation_track_editor.cpp64
-rw-r--r--editor/animation_track_editor.h7
-rw-r--r--editor/icons/FPS.svg1
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp4
4 files changed, 66 insertions, 10 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index bc79b14d4a..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);
@@ -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();
@@ -5115,6 +5134,7 @@ void AnimationTrackEditor::_notification(int p_what) {
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")));
@@ -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();
}
@@ -7336,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) {
@@ -7369,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(
@@ -7622,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);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 1053468452..e7271f1941 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -600,6 +600,8 @@ class AnimationTrackEditor : public VBoxContainer {
AnimationMarkerEdit *marker_edit = nullptr;
HSlider *zoom = nullptr;
EditorSpinSlider *step = nullptr;
+ Button *fps_compat = nullptr;
+ Label *nearest_fps_label = nullptr;
TextureRect *zoom_icon = nullptr;
Button *snap_keys = nullptr;
Button *snap_timeline = nullptr;
@@ -637,6 +639,8 @@ class AnimationTrackEditor : public VBoxContainer {
void _track_grab_focus(int p_track);
void _update_scroll(double);
+ void _update_nearest_fps_label();
+ void _update_fps_compat_mode(bool p_enabled);
void _update_step(double p_new_step);
void _update_length(double p_new_len);
void _dropped_track(int p_from_track, int p_to_track);
@@ -853,6 +857,8 @@ class AnimationTrackEditor : public VBoxContainer {
void _pick_track_select_recursive(TreeItem *p_item, const String &p_filter, Vector<Node *> &p_select_candidates);
double snap_unit;
+ bool fps_compatible = true;
+ int nearest_fps = 0;
void _update_snap_unit();
protected:
@@ -935,6 +941,7 @@ public:
bool can_add_reset_key() const;
float get_moving_selection_offset() const;
float snap_time(float p_value, bool p_relative = false);
+ float get_snap_unit();
bool is_grouping_tracks();
PackedStringArray get_selected_section() const;
bool is_marker_selected(const StringName &p_marker) const;
diff --git a/editor/icons/FPS.svg b/editor/icons/FPS.svg
new file mode 100644
index 0000000000..5ee818c308
--- /dev/null
+++ b/editor/icons/FPS.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#e0e0e0" d="M7.25 4h-2v8h2v-2c1.656 0 3-1.344 3-3 0-1.657-1.344-3-3-3zm0 4v-2c.553 0 1 .448 1 1s-.447 1-1 1zM.25 7v5h2v-2h2v-2h-2v-1c0-.553.447-1 1-1h1v-2h-1c-1.656 0-3 1.344-3 3zM13.25 7c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h2v-2h-2c-1.381 0-2.5 1.119-2.5 2.5s1.119 2.5 2.5 2.5c.276 0 .5.224.5.5s-.224.5-.5.5h-2v2h2c1.381 0 2.5-1.119 2.5-2.5s-1.119-2.5-2.5-2.5z"/></svg> \ No newline at end of file
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index d089aedc63..4edd021b4d 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -580,8 +580,10 @@ float AnimationPlayerEditor::_get_editor_step() const {
const Ref<Animation> anim = player->get_animation(current);
ERR_FAIL_COND_V(anim.is_null(), 0.0);
+ float step = track_editor->get_snap_unit();
+
// Use more precise snapping when holding Shift
- return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
+ return Input::get_singleton()->is_key_pressed(Key::SHIFT) ? step * 0.25 : step;
}
void AnimationPlayerEditor::_animation_name_edited() {