mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 19:42:43 +00:00
Add FPS compatible option in second mode of animation editor snapping
This commit is contained in:
parent
e65a23762b
commit
64d04c375c
@ -63,7 +63,6 @@
|
|||||||
|
|
||||||
constexpr double FPS_DECIMAL = 1.0;
|
constexpr double FPS_DECIMAL = 1.0;
|
||||||
constexpr double SECOND_DECIMAL = 0.0001;
|
constexpr double SECOND_DECIMAL = 0.0001;
|
||||||
constexpr double FPS_STEP_FRACTION = 0.0625;
|
|
||||||
|
|
||||||
void AnimationTrackKeyEdit::_bind_methods() {
|
void AnimationTrackKeyEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_update_obj"), &AnimationTrackKeyEdit::_update_obj);
|
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);
|
step->set_read_only(false);
|
||||||
snap_keys->set_disabled(false);
|
snap_keys->set_disabled(false);
|
||||||
snap_timeline->set_disabled(false);
|
snap_timeline->set_disabled(false);
|
||||||
|
fps_compat->set_disabled(false);
|
||||||
snap_mode->set_disabled(false);
|
snap_mode->set_disabled(false);
|
||||||
auto_fit->set_disabled(false);
|
auto_fit->set_disabled(false);
|
||||||
auto_fit_bezier->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);
|
step->set_read_only(true);
|
||||||
snap_keys->set_disabled(true);
|
snap_keys->set_disabled(true);
|
||||||
snap_timeline->set_disabled(true);
|
snap_timeline->set_disabled(true);
|
||||||
|
fps_compat->set_disabled(true);
|
||||||
snap_mode->set_disabled(true);
|
snap_mode->set_disabled(true);
|
||||||
bezier_edit_icon->set_disabled(true);
|
bezier_edit_icon->set_disabled(true);
|
||||||
auto_fit->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);
|
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.
|
// 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();
|
_update_step_spinbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5045,7 +5051,6 @@ void AnimationTrackEditor::_update_step_spinbox() {
|
|||||||
} else {
|
} else {
|
||||||
step->set_value(1.0 / animation->get_step());
|
step->set_value(1.0 / animation->get_step());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
step->set_value(animation->get_step());
|
step->set_value(animation->get_step());
|
||||||
}
|
}
|
||||||
@ -5054,6 +5059,20 @@ void AnimationTrackEditor::_update_step_spinbox() {
|
|||||||
_update_snap_unit();
|
_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() {
|
void AnimationTrackEditor::_animation_update() {
|
||||||
timeline->queue_redraw();
|
timeline->queue_redraw();
|
||||||
timeline->update_values();
|
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")));
|
bezier_edit_icon->set_button_icon(get_editor_theme_icon(SNAME("EditBezier")));
|
||||||
snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
|
snap_timeline->set_button_icon(get_editor_theme_icon(SNAME("SnapTimeline")));
|
||||||
snap_keys->set_button_icon(get_editor_theme_icon(SNAME("SnapKeys")));
|
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")));
|
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")));
|
selected_filter->set_button_icon(get_editor_theme_icon(SNAME("AnimationFilter")));
|
||||||
imported_anim_warning->set_button_icon(get_editor_theme_icon(SNAME("NodeWarning")));
|
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;
|
double step_value = p_new_step;
|
||||||
if (timeline->is_using_fps()) {
|
if (timeline->is_using_fps()) {
|
||||||
if (step_value != 0.0) {
|
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);
|
step_value = 1.0 / MIN(1000.0, p_new_step);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
timeline->queue_redraw();
|
timeline->queue_redraw();
|
||||||
}
|
}
|
||||||
@ -7314,19 +7333,30 @@ void AnimationTrackEditor::_selection_changed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AnimationTrackEditor::_update_snap_unit() {
|
void AnimationTrackEditor::_update_snap_unit() {
|
||||||
|
nearest_fps = 0;
|
||||||
|
|
||||||
if (step->get_value() <= 0) {
|
if (step->get_value() <= 0) {
|
||||||
snap_unit = 0;
|
snap_unit = 0;
|
||||||
|
_update_nearest_fps_label();
|
||||||
return; // Avoid zero div.
|
return; // Avoid zero div.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeline->is_using_fps()) {
|
if (timeline->is_using_fps()) {
|
||||||
|
_clear_selection(true); // Needs to recreate a spinbox of the KeyEdit.
|
||||||
snap_unit = 1.0 / step->get_value();
|
snap_unit = 1.0 / step->get_value();
|
||||||
} else {
|
} else {
|
||||||
double integer;
|
if (fps_compat->is_pressed()) {
|
||||||
double fraction = Math::modf(step->get_value(), &integer);
|
snap_unit = CLAMP(step->get_value(), 0.0, 1.0);
|
||||||
fraction = 1.0 / Math::round(1.0 / fraction);
|
if (!Math::is_zero_approx(snap_unit)) {
|
||||||
snap_unit = integer + fraction;
|
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) {
|
float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
|
||||||
@ -7347,6 +7377,10 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
|
|||||||
return p_value;
|
return p_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AnimationTrackEditor::get_snap_unit() {
|
||||||
|
return snap_unit;
|
||||||
|
}
|
||||||
|
|
||||||
void AnimationTrackEditor::_show_imported_anim_warning() {
|
void AnimationTrackEditor::_show_imported_anim_warning() {
|
||||||
// It looks terrible on a single line but the TTR extractor doesn't support line breaks yet.
|
// It looks terrible on a single line but the TTR extractor doesn't support line breaks yet.
|
||||||
EditorNode::get_singleton()->show_warning(
|
EditorNode::get_singleton()->show_warning(
|
||||||
@ -7600,6 +7634,18 @@ AnimationTrackEditor::AnimationTrackEditor() {
|
|||||||
snap_keys->set_pressed(true);
|
snap_keys->set_pressed(true);
|
||||||
snap_keys->set_tooltip_text(TTR("Apply snapping to selected key(s)."));
|
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 = memnew(EditorSpinSlider);
|
||||||
step->set_min(0);
|
step->set_min(0);
|
||||||
step->set_max(1000000);
|
step->set_max(1000000);
|
||||||
|
@ -600,6 +600,8 @@ class AnimationTrackEditor : public VBoxContainer {
|
|||||||
AnimationMarkerEdit *marker_edit = nullptr;
|
AnimationMarkerEdit *marker_edit = nullptr;
|
||||||
HSlider *zoom = nullptr;
|
HSlider *zoom = nullptr;
|
||||||
EditorSpinSlider *step = nullptr;
|
EditorSpinSlider *step = nullptr;
|
||||||
|
Button *fps_compat = nullptr;
|
||||||
|
Label *nearest_fps_label = nullptr;
|
||||||
TextureRect *zoom_icon = nullptr;
|
TextureRect *zoom_icon = nullptr;
|
||||||
Button *snap_keys = nullptr;
|
Button *snap_keys = nullptr;
|
||||||
Button *snap_timeline = nullptr;
|
Button *snap_timeline = nullptr;
|
||||||
@ -637,6 +639,8 @@ class AnimationTrackEditor : public VBoxContainer {
|
|||||||
void _track_grab_focus(int p_track);
|
void _track_grab_focus(int p_track);
|
||||||
|
|
||||||
void _update_scroll(double);
|
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_step(double p_new_step);
|
||||||
void _update_length(double p_new_len);
|
void _update_length(double p_new_len);
|
||||||
void _dropped_track(int p_from_track, int p_to_track);
|
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);
|
void _pick_track_select_recursive(TreeItem *p_item, const String &p_filter, Vector<Node *> &p_select_candidates);
|
||||||
|
|
||||||
double snap_unit;
|
double snap_unit;
|
||||||
|
bool fps_compatible = true;
|
||||||
|
int nearest_fps = 0;
|
||||||
void _update_snap_unit();
|
void _update_snap_unit();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -935,6 +941,7 @@ public:
|
|||||||
bool can_add_reset_key() const;
|
bool can_add_reset_key() const;
|
||||||
float get_moving_selection_offset() const;
|
float get_moving_selection_offset() const;
|
||||||
float snap_time(float p_value, bool p_relative = false);
|
float snap_time(float p_value, bool p_relative = false);
|
||||||
|
float get_snap_unit();
|
||||||
bool is_grouping_tracks();
|
bool is_grouping_tracks();
|
||||||
PackedStringArray get_selected_section() const;
|
PackedStringArray get_selected_section() const;
|
||||||
bool is_marker_selected(const StringName &p_marker) const;
|
bool is_marker_selected(const StringName &p_marker) const;
|
||||||
|
1
editor/icons/FPS.svg
Normal file
1
editor/icons/FPS.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 443 B |
@ -580,8 +580,10 @@ float AnimationPlayerEditor::_get_editor_step() const {
|
|||||||
const Ref<Animation> anim = player->get_animation(current);
|
const Ref<Animation> anim = player->get_animation(current);
|
||||||
ERR_FAIL_COND_V(anim.is_null(), 0.0);
|
ERR_FAIL_COND_V(anim.is_null(), 0.0);
|
||||||
|
|
||||||
|
float step = track_editor->get_snap_unit();
|
||||||
|
|
||||||
// Use more precise snapping when holding Shift
|
// 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() {
|
void AnimationPlayerEditor::_animation_name_edited() {
|
||||||
|
Loading…
Reference in New Issue
Block a user