Skip to content

Commit 2716838

Browse files
AtlaStarlaurentmackay
authored andcommitted
Allow fractional FPS values in Animation Editor
Closes godotengine#97548. Care also taken to not reopen issue godotengine#92273 by ensuring that the value rounds to the nearest sixteenth. Optionally any factor of 2 should work while ensuring that there isn't error accumulation. Further testing to ensure issue godotengine#91729 isn't reopened, but initial testing suggests that the issue will not reopen with this PR.
1 parent 01d1257 commit 2716838

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

editor/animation_track_editor.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@
6161
#include "scene/main/window.h"
6262
#include "servers/audio/audio_stream.h"
6363

64-
constexpr double FPS_DECIMAL = 1;
64+
constexpr double FPS_DECIMAL = 1.0;
6565
constexpr double SECOND_DECIMAL = 0.0001;
66+
constexpr double FACTOR = 0.0625;
6667

6768
void AnimationTrackKeyEdit::_bind_methods() {
6869
ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationTrackKeyEdit::_update_obj);
@@ -1799,7 +1800,7 @@ void AnimationTimelineEdit::update_values() {
17991800
}
18001801

18011802
editing = true;
1802-
if (use_fps && animation->get_step() > 0) {
1803+
if (use_fps && animation->get_step() > 0.0) {
18031804
length->set_value(animation->get_length() / animation->get_step());
18041805
length->set_step(FPS_DECIMAL);
18051806
length->set_tooltip_text(TTR("Animation length (frames)"));
@@ -5016,7 +5017,6 @@ void AnimationTrackEditor::_snap_mode_changed(int p_mode) {
50165017
key_edit->set_use_fps(use_fps);
50175018
}
50185019
marker_edit->set_use_fps(use_fps);
5019-
step->set_step(use_fps ? FPS_DECIMAL : SECOND_DECIMAL);
50205020
_update_step_spinbox();
50215021
}
50225022

@@ -5027,12 +5027,10 @@ void AnimationTrackEditor::_update_step_spinbox() {
50275027
step->set_block_signals(true);
50285028

50295029
if (timeline->is_using_fps()) {
5030-
if (animation->get_step() == 0) {
5031-
step->set_value(0);
5030+
if (animation->get_step() == 0.0) {
5031+
step->set_value(0.0);
50325032
} else {
5033-
// The value stored within tscn cannot restored the original FPS due to lack of precision,
5034-
// so the value should be limited to integer.
5035-
step->set_value(Math::round(1.0 / animation->get_step()));
5033+
step->set_value(1.0 / animation->get_step());
50365034
}
50375035

50385036
} else {
@@ -5146,7 +5144,9 @@ void AnimationTrackEditor::_update_step(double p_new_step) {
51465144

51475145
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
51485146
undo_redo->create_action(TTR("Change Animation Step"));
5149-
float step_value = p_new_step;
5147+
// To ensure that the conversion results are consistent between serialization and load, the value is snapped with 0.0625 to be a rational number.
5148+
// 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.
5149+
double step_value = MIN(1000.0, Math::snapped(p_new_step, FACTOR));
51505150
if (timeline->is_using_fps()) {
51515151
if (step_value != 0.0) {
51525152
step_value = 1.0 / step_value;
@@ -6363,8 +6363,8 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) {
63636363
return;
63646364
}
63656365
float anim_step = animation->get_step();
6366-
if (anim_step == 0) {
6367-
anim_step = 1;
6366+
if (anim_step == 0.0) {
6367+
anim_step = 1.0;
63686368
}
63696369
if (p_from_mouse_event && Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
63706370
// Use more precise snapping when holding Shift.
@@ -6374,8 +6374,8 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) {
63746374

63756375
float pos = timeline->get_play_position();
63766376
pos = Math::snapped(pos - anim_step, anim_step);
6377-
if (pos < 0) {
6378-
pos = 0;
6377+
if (pos < 0.0) {
6378+
pos = 0.0;
63796379
}
63806380
set_anim_pos(pos);
63816381
_timeline_changed(pos, false);
@@ -6386,8 +6386,8 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeli
63866386
return;
63876387
}
63886388
float anim_step = animation->get_step();
6389-
if (anim_step == 0) {
6390-
anim_step = 1;
6389+
if (anim_step == 0.0) {
6390+
anim_step = 1.0;
63916391
}
63926392
if (p_from_mouse_event && Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
63936393
// Use more precise snapping when holding Shift.

0 commit comments

Comments
 (0)