From 0cd149c939c1f756a96381a84801073021ac1e63 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Wed, 10 Apr 2024 12:09:54 +0400 Subject: animation: Tweak clamped duration logic --- src/animation/mod.rs | 8 +++++++- src/animation/spring.rs | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/animation/mod.rs b/src/animation/mod.rs index a68b3342..0a972ab8 100644 --- a/src/animation/mod.rs +++ b/src/animation/mod.rs @@ -17,6 +17,8 @@ pub struct Animation { to: f64, duration: Duration, /// Time until the animation first reaches `to`. + /// + /// Best effort; not always exactly precise. clamped_duration: Duration, start_time: Duration, current_time: Duration, @@ -117,12 +119,14 @@ impl Animation { } pub fn spring(spring: Spring) -> Self { + let _span = tracy_client::span!("Animation::spring"); + // FIXME: ideally we shouldn't use current time here because animations started within the // same frame cycle should have the same start time to be synchronized. let now = get_monotonic_time(); let duration = spring.duration(); - let clamped_duration = spring.clamped_duration(); + let clamped_duration = spring.clamped_duration().unwrap_or(duration); let kind = Kind::Spring(spring); Self { @@ -266,6 +270,8 @@ impl Animation { } /// Returns a value that stops at the target value after first reaching it. + /// + /// Best effort; not always exactly precise. pub fn clamped_value(&self) -> f64 { if self.is_clamped_done() { return self.to; diff --git a/src/animation/spring.rs b/src/animation/spring.rs index 506b01a3..226d7cc2 100644 --- a/src/animation/spring.rs +++ b/src/animation/spring.rs @@ -97,15 +97,15 @@ impl Spring { } /// Computes and returns the duration until the spring reaches its target position. - pub fn clamped_duration(&self) -> Duration { + pub fn clamped_duration(&self) -> Option { let beta = self.params.damping / (2. * self.params.mass); if beta.abs() <= f64::EPSILON || beta < 0. { - return Duration::MAX; + return Some(Duration::MAX); } if (self.to - self.from).abs() <= f64::EPSILON { - return Duration::ZERO; + return Some(Duration::ZERO); } // The first frame is not that important and we avoid finding the trivial 0 for in-place @@ -116,15 +116,15 @@ impl Spring { while (self.to - self.from > f64::EPSILON && self.to - y > self.params.epsilon) || (self.from - self.to > f64::EPSILON && y - self.to > self.params.epsilon) { - if i > 1000 { - return Duration::ZERO; + if i > 3000 { + return None; } i += 1; y = self.oscillate(f64::from(i) / 1000.); } - Duration::from_millis(u64::from(i)) + Some(Duration::from_millis(u64::from(i))) } /// Returns the spring position at a given time in seconds. -- cgit