1use ranim_core::{
2 animation::Eval,
3 glam::DVec3,
4 traits::{Aabb, AabbPoint, Locate, RotateTransform, ShiftTransformExt},
5};
6
7pub trait RotatingRequirement: RotateTransform + ShiftTransformExt + Clone {}
10impl<T: RotateTransform + ShiftTransformExt + Clone> RotatingRequirement for T {}
11
12pub trait RotatingAnim: RotatingRequirement + Sized + 'static {
15 fn rotating(&mut self, angle: f64, axis: DVec3) -> RotatingAnimation<Self>
17 where
18 Self: Aabb,
19 {
20 self.rotating_at(angle, axis, AabbPoint::CENTER)
21 }
22
23 fn rotating_at<A: Locate<Self>>(
25 &mut self,
26 angle: f64,
27 axis: DVec3,
28 anchor: A,
29 ) -> RotatingAnimation<Self> {
30 RotatingAnimation::new(self.clone(), angle, axis, anchor.locate(self)).apply_to(self)
31 }
32}
33
34impl<T: RotatingRequirement + 'static> RotatingAnim for T {}
35
36pub struct RotatingAnimation<T: RotatingRequirement> {
44 src: T,
45 angle: f64,
46 axis: DVec3,
47 point: DVec3,
48}
49
50impl<T: RotatingRequirement> RotatingAnimation<T> {
51 pub fn new(src: T, angle: f64, axis: DVec3, point: DVec3) -> Self {
53 Self {
54 src,
55 angle,
56 axis,
57 point,
58 }
59 }
60}
61
62impl<T: RotatingRequirement> Eval for RotatingAnimation<T> {
63 type Output = T;
64
65 fn eval_alpha(&self, alpha: f64) -> Self::Output {
66 let mut result = self.src.clone();
67 result.with_origin(self.point, |x| {
68 x.rotate_on_axis(self.axis, self.angle * alpha);
69 });
70 result
71 }
72}