Skip to content

Commit

Permalink
Replace TwoIterators with Either in bevy_animation (#16036)
Browse files Browse the repository at this point in the history
# Objective

- Less code
- Better iterator (implements `size_hint` for example)

## Solution

- Use `either`
- This change is free because `bevy_animation` depends on `bevy_asset`,
which already depends on `either`

## Testing

CI
  • Loading branch information
stepancheg authored Oct 21, 2024
1 parent 30d8451 commit 465d113
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 26 deletions.
1 change: 1 addition & 0 deletions crates/bevy_animation/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ derive_more = { version = "1", default-features = false, features = [
"from",
"display",
] }
either = "1.13"
thread_local = "1"
uuid = { version = "1.7", features = ["v4"] }
smallvec = "1"
Expand Down
33 changes: 7 additions & 26 deletions crates/bevy_animation/src/gltf_curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use bevy_math::{
};
use bevy_reflect::Reflect;
use derive_more::derive::{Display, Error, From};
use either::Either;

/// A keyframe-defined curve that "interpolates" by stepping at `t = 1.0` to the next keyframe.
#[derive(Debug, Clone, Reflect)]
Expand Down Expand Up @@ -189,11 +190,11 @@ where
match self.core.sample_interp(t) {
InterpolationDatum::Exact(v)
| InterpolationDatum::LeftTail(v)
| InterpolationDatum::RightTail(v) => TwoIterators::Left(v.iter().copied()),
| InterpolationDatum::RightTail(v) => Either::Left(v.iter().copied()),

InterpolationDatum::Between(u, v, s) => {
let interpolated = u.iter().zip(v.iter()).map(move |(x, y)| x.lerp(*y, s));
TwoIterators::Right(interpolated)
Either::Right(interpolated)
}
}
}
Expand Down Expand Up @@ -243,14 +244,14 @@ where
match self.core.sample_interp(t) {
InterpolationDatum::Exact(v)
| InterpolationDatum::LeftTail(v)
| InterpolationDatum::RightTail(v) => TwoIterators::Left(v.iter().cloned()),
| InterpolationDatum::RightTail(v) => Either::Left(v.iter().cloned()),

InterpolationDatum::Between(u, v, s) => {
let interpolated =
u.iter()
.zip(v.iter())
.map(move |(x, y)| if s >= 1.0 { y.clone() } else { x.clone() });
TwoIterators::Right(interpolated)
Either::Right(interpolated)
}
}
}
Expand Down Expand Up @@ -302,10 +303,10 @@ where
// Pick out the part of this that actually represents the position (instead of tangents),
// which is the middle third.
let width = self.core.width();
TwoIterators::Left(v[width..(width * 2)].iter().copied())
Either::Left(v[width..(width * 2)].iter().copied())
}

InterpolationDatum::Between((t0, u), (t1, v), s) => TwoIterators::Right(
InterpolationDatum::Between((t0, u), (t1, v), s) => Either::Right(
cubic_spline_interpolate_slices(self.core.width() / 3, u, v, s, t1 - t0),
),
}
Expand Down Expand Up @@ -392,26 +393,6 @@ pub enum WeightsCurve {
// HELPERS //
//---------//

enum TwoIterators<A, B> {
Left(A),
Right(B),
}

impl<A, B, T> Iterator for TwoIterators<A, B>
where
A: Iterator<Item = T>,
B: Iterator<Item = T>,
{
type Item = T;

fn next(&mut self) -> Option<Self::Item> {
match self {
TwoIterators::Left(a) => a.next(),
TwoIterators::Right(b) => b.next(),
}
}
}

/// Helper function for cubic spline interpolation.
fn cubic_spline_interpolation<T>(
value_start: T,
Expand Down

0 comments on commit 465d113

Please sign in to comment.