oxygengine_animation/
animation.rs

1use crate::{
2    curve::{Curved, CurvedChange},
3    phase::Phase,
4    spline::Spline,
5};
6use core::Scalar;
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
8
9#[derive(Debug, Default, Clone, Serialize, Deserialize)]
10#[serde(bound = "T: Serialize + DeserializeOwned")]
11pub struct Animation<T>
12where
13    T: Default + Clone + Curved + CurvedChange,
14{
15    pub value_spline: Spline<T>,
16    #[serde(default)]
17    pub time_phase: Phase,
18    #[serde(default)]
19    pub playing: bool,
20    #[serde(default)]
21    pub looped: bool,
22    #[serde(default)]
23    time: Scalar,
24}
25
26impl<T> Animation<T>
27where
28    T: Default + Clone + Curved + CurvedChange,
29{
30    pub fn new(value_spline: Spline<T>, time_phase: Phase) -> Self {
31        Self {
32            value_spline,
33            time_phase,
34            playing: false,
35            looped: false,
36            time: 0.0,
37        }
38    }
39
40    pub fn instant(value: T) -> Self {
41        Self::new(
42            Spline::point(value)
43                .expect("Could not create point value spline for instant animation"),
44            Phase::point(1.0).expect("Could not create point time phase for instant animation"),
45        )
46    }
47
48    pub fn time(&self) -> Scalar {
49        self.time
50    }
51
52    pub fn start(&mut self) {
53        self.time = 0.0;
54    }
55
56    pub fn end(&mut self) {
57        self.time = self.duration();
58    }
59
60    pub fn set_time(&mut self, time: Scalar) {
61        self.time = time.max(0.0).min(self.duration());
62    }
63
64    pub fn in_progress(&self) -> bool {
65        self.playing
66    }
67
68    pub fn is_complete(&self) -> bool {
69        !self.in_progress()
70    }
71
72    pub fn duration(&self) -> Scalar {
73        self.time_phase.duration()
74    }
75
76    pub fn value(&self) -> T {
77        self.sample(self.time)
78    }
79
80    pub fn sample(&self, time: Scalar) -> T {
81        self.value_spline.sample(self.time_phase.sample(time))
82    }
83
84    pub fn process(&mut self, delta_time: Scalar) {
85        if self.playing {
86            let duration = self.duration();
87            let mut time = self.time + delta_time;
88            if time >= duration {
89                if self.looped {
90                    time = 0.0;
91                } else {
92                    self.playing = false;
93                }
94            }
95            self.time = time.max(0.0).min(duration);
96        }
97    }
98}
99
100#[derive(Debug, Default, Clone, Serialize, Deserialize)]
101pub struct PhaseAnimation {
102    pub value_phase: Phase,
103    #[serde(default)]
104    pub playing: bool,
105    #[serde(default)]
106    pub looped: bool,
107    #[serde(default)]
108    time: Scalar,
109}
110
111impl PhaseAnimation {
112    pub fn new(value_phase: Phase) -> Self {
113        Self {
114            value_phase,
115            playing: false,
116            looped: false,
117            time: 0.0,
118        }
119    }
120
121    pub fn instant(value: Scalar) -> Self {
122        Self::new(
123            Phase::point(value).expect("Could not create point phase for instant phase animation"),
124        )
125    }
126
127    pub fn time(&self) -> Scalar {
128        self.time
129    }
130
131    pub fn start(&mut self) {
132        self.time = 0.0;
133    }
134
135    pub fn end(&mut self) {
136        self.time = self.duration();
137    }
138
139    pub fn set_time(&mut self, time: Scalar) {
140        self.time = time.max(0.0).min(self.duration());
141    }
142
143    pub fn in_progress(&self) -> bool {
144        self.playing
145    }
146
147    pub fn is_complete(&self) -> bool {
148        !self.in_progress()
149    }
150
151    pub fn duration(&self) -> Scalar {
152        self.value_phase.duration()
153    }
154
155    pub fn value(&self) -> Scalar {
156        self.sample(self.time)
157    }
158
159    pub fn sample(&self, time: Scalar) -> Scalar {
160        self.value_phase.sample(time)
161    }
162
163    pub fn process(&mut self, delta_time: Scalar) {
164        if self.playing {
165            let duration = self.duration();
166            let mut time = self.time + delta_time;
167            if time >= duration {
168                if self.looped {
169                    time = 0.0;
170                } else {
171                    self.playing = false;
172                }
173            }
174            self.time = time.max(0.0).min(duration);
175        }
176    }
177}
178
179#[derive(Debug, Default, Clone, Serialize, Deserialize)]
180#[serde(bound = "T: Serialize + DeserializeOwned")]
181pub struct Interpolation<T>
182where
183    T: Default + Clone + Curved,
184{
185    #[serde(default)]
186    pub from: T,
187    #[serde(default)]
188    pub to: T,
189    #[serde(default)]
190    pub time_phase: Phase,
191    #[serde(default)]
192    pub playing: bool,
193    #[serde(default)]
194    pub looped: bool,
195    #[serde(default)]
196    time: Scalar,
197}
198
199impl<T> Interpolation<T>
200where
201    T: Default + Clone + Curved,
202{
203    pub fn new(from: T, to: T, time_phase: Phase) -> Self {
204        Self {
205            from,
206            to,
207            time_phase,
208            playing: false,
209            looped: false,
210            time: 0.0,
211        }
212    }
213
214    pub fn instant(value: T) -> Self {
215        Self::new(
216            value.clone(),
217            value,
218            Phase::point(1.0).expect("Could not create point time phase for instant animation"),
219        )
220    }
221
222    pub fn time(&self) -> Scalar {
223        self.time
224    }
225
226    pub fn start(&mut self) {
227        self.time = 0.0;
228    }
229
230    pub fn end(&mut self) {
231        self.time = self.duration();
232    }
233
234    pub fn set_time(&mut self, time: Scalar) {
235        self.time = time.max(0.0).min(self.duration());
236    }
237
238    pub fn in_progress(&self) -> bool {
239        self.playing
240    }
241
242    pub fn is_complete(&self) -> bool {
243        !self.in_progress()
244    }
245
246    pub fn duration(&self) -> Scalar {
247        self.time_phase.duration()
248    }
249
250    pub fn value(&self) -> T {
251        self.sample(self.time)
252    }
253
254    pub fn sample(&self, time: Scalar) -> T {
255        self.from
256            .interpolate(&self.to, self.time_phase.sample(time))
257    }
258
259    pub fn set(&mut self, value: T) {
260        self.from = self.value();
261        self.to = value;
262        self.time = 0.0;
263    }
264
265    pub fn process(&mut self, delta_time: Scalar) {
266        if self.playing {
267            let duration = self.duration();
268            let mut time = self.time + delta_time;
269            if time >= duration {
270                if self.looped {
271                    time = 0.0;
272                } else {
273                    self.playing = false;
274                }
275            }
276            self.time = time.max(0.0).min(duration);
277        }
278    }
279}