From 6f066779b5e70b468e51c81f1f896925e72eb917 Mon Sep 17 00:00:00 2001 From: JannisX11 Date: Sat, 6 Apr 2024 00:40:35 +0200 Subject: [PATCH] Wrap around catmull rom keyframes in loop, closes #1965 Improve animation looping preview smoothness --- js/animations/timeline.js | 33 ++++++++++++++++------------- js/animations/timeline_animators.js | 4 ++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/js/animations/timeline.js b/js/animations/timeline.js index 3baf63aee..215739c0e 100644 --- a/js/animations/timeline.js +++ b/js/animations/timeline.js @@ -549,23 +549,24 @@ const Timeline = { Timeline.loop() }, loop() { - Animator.preview(true); - if (Animation.selected && Timeline.time < (Animation.selected.length||1e3)) { + if (!Animation.selected) return; - var new_time; - if (Animation.selected && Animation.selected.anim_time_update) { - var new_time = Animator.MolangParser.parse(Animation.selected.anim_time_update); - } - if (new_time == undefined || new_time <= Timeline.time) { - var new_time = Animator.MolangParser.parse('query.anim_time + query.delta_time') - } - let time = Timeline.time + (new_time - Timeline.time) * (Timeline.playback_speed/100) - if (Animation.selected.loop == 'hold') { - time = Math.clamp(time, 0, Animation.selected.length); - } - Timeline.last_frame_timecode = Date.now(); - Timeline.setTime(time); + let max_length = Animation.selected.length || 1e3; + let new_time; + if (Animation.selected && Animation.selected.anim_time_update) { + new_time = Animator.MolangParser.parse(Animation.selected.anim_time_update); + } + if (new_time == undefined || new_time <= Timeline.time) { + new_time = Animator.MolangParser.parse('query.anim_time + query.delta_time') + } + let time = Timeline.time + (new_time - Timeline.time) * (Timeline.playback_speed/100) + if (Animation.selected.loop == 'hold') { + time = Math.clamp(time, 0, Animation.selected.length); + } + Timeline.last_frame_timecode = Date.now(); + if (time < max_length) { + Timeline.setTime(time); } else { if (Animation.selected.loop == 'loop' || BarItems.looped_animation_playback.value) { Timeline.setTime(0) @@ -574,9 +575,11 @@ const Timeline = { Animator.preview() Timeline.pause() } else if (Animation.selected.loop == 'hold') { + Timeline.setTime(max_length); Timeline.pause() } } + Animator.preview(true); }, pause() { Animator.preview(); diff --git a/js/animations/timeline_animators.js b/js/animations/timeline_animators.js index 95a14de73..6ef0c26fa 100644 --- a/js/animations/timeline_animators.js +++ b/js/animations/timeline_animators.js @@ -435,6 +435,10 @@ class BoneAnimator extends GeneralAnimator { let before_index = sorted.indexOf(before); let before_plus = sorted[before_index-1]; let after_plus = sorted[before_index+2]; + if (this.animation.loop == 'loop' && sorted.length >= 3) { + if (!before_plus) before_plus = sorted.at(-2); + if (!after_plus) after_plus = sorted[1]; + } return mapAxes(axis => before.getCatmullromLerp(before_plus, before, after, after_plus, axis, alpha));