oxygengine_animation/
animation.rs1use 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}