oxygengine_animation/
transition.rs

1use crate::phase::Phase;
2use core::Scalar;
3use serde::{Deserialize, Serialize};
4use std::ops::Range;
5
6#[derive(Debug, Default, Clone, Serialize, Deserialize)]
7pub struct Transition<T> {
8    from: T,
9    to: T,
10    #[serde(default)]
11    pub phase: Phase,
12    #[serde(default)]
13    pub playing: bool,
14    #[serde(default)]
15    time: Scalar,
16}
17
18impl<T> Transition<T>
19where
20    T: Clone,
21{
22    pub fn new(from: T, to: T, phase: Phase) -> Self {
23        Self {
24            from,
25            to,
26            playing: false,
27            time: phase.time_frame().start,
28            phase,
29        }
30    }
31
32    pub fn instant(value: T) -> Self {
33        Self::new(
34            value.clone(),
35            value,
36            Phase::point(1.0).expect("Could not create point phase for instant transition"),
37        )
38    }
39
40    pub fn time(&self) -> Scalar {
41        self.time
42    }
43
44    pub fn start(&mut self) {
45        self.time = self.phase.time_frame().start;
46    }
47
48    pub fn end(&mut self) {
49        self.time = self.phase.time_frame().end;
50    }
51
52    pub fn set_time(&mut self, time: Scalar) {
53        self.time = time
54            .max(self.phase.time_frame().start)
55            .min(self.phase.time_frame().end);
56    }
57
58    pub fn in_progress(&self) -> bool {
59        self.time < self.phase.time_frame().end
60    }
61
62    pub fn is_complete(&self) -> bool {
63        !self.in_progress()
64    }
65
66    pub fn from(&self) -> &T {
67        &self.from
68    }
69
70    pub fn from_mut(&mut self) -> &mut T {
71        &mut self.from
72    }
73
74    pub fn to(&self) -> &T {
75        &self.to
76    }
77
78    pub fn to_mut(&mut self) -> &mut T {
79        &mut self.to
80    }
81
82    pub fn time_frame(&self) -> Range<Scalar> {
83        self.phase.time_frame()
84    }
85
86    pub fn duration(&self) -> Scalar {
87        self.phase.duration()
88    }
89
90    pub fn phase(&self) -> Scalar {
91        self.sample(self.time)
92    }
93
94    pub fn sample(&self, time: Scalar) -> Scalar {
95        self.phase.sample(time)
96    }
97
98    pub fn set(&mut self, value: T) {
99        self.from = self.to.clone();
100        self.to = value;
101        self.time = 0.0;
102    }
103
104    pub fn process(&mut self, delta_time: Scalar) {
105        if self.playing {
106            let time_frame = self.phase.time_frame();
107            let time = self.time + delta_time;
108            if time >= time_frame.end {
109                self.playing = false;
110            }
111            self.time = time.max(time_frame.start).min(time_frame.end);
112        }
113    }
114}
115
116#[derive(Debug, Default, Clone, Serialize, Deserialize)]
117pub struct SwitchTransition {
118    value: bool,
119    #[serde(default)]
120    pub phase: Phase,
121    #[serde(default)]
122    pub playing: bool,
123    #[serde(default)]
124    time: Scalar,
125}
126
127impl SwitchTransition {
128    pub fn new(value: bool, phase: Phase) -> Self {
129        let time = if value {
130            phase.time_frame().end
131        } else {
132            phase.time_frame().start
133        };
134        Self {
135            value,
136            phase,
137            playing: false,
138            time,
139        }
140    }
141
142    pub fn instant(value: bool) -> Self {
143        Self::new(
144            value,
145            Phase::point(1.0).expect("Could not create point phase for instant switch"),
146        )
147    }
148
149    pub fn time(&self) -> Scalar {
150        self.time
151    }
152
153    pub fn start(&mut self) {
154        self.time = if self.value {
155            self.phase.time_frame().start
156        } else {
157            self.phase.time_frame().end
158        };
159    }
160
161    pub fn end(&mut self) {
162        self.time = if self.value {
163            self.phase.time_frame().end
164        } else {
165            self.phase.time_frame().start
166        };
167    }
168
169    pub fn set_time(&mut self, time: Scalar) {
170        self.time = time
171            .max(self.phase.time_frame().start)
172            .min(self.phase.time_frame().end);
173    }
174
175    pub fn in_progress(&self) -> bool {
176        if self.value {
177            self.time < self.phase.time_frame().end
178        } else {
179            self.time > self.phase.time_frame().start
180        }
181    }
182
183    pub fn is_complete(&self) -> bool {
184        !self.in_progress()
185    }
186
187    pub fn value(&self) -> bool {
188        self.value
189    }
190
191    pub fn duration(&self) -> Scalar {
192        self.phase.duration()
193    }
194
195    pub fn phase(&self) -> Scalar {
196        self.sample(self.time)
197    }
198
199    pub fn sample(&self, time: Scalar) -> Scalar {
200        self.phase.sample(time)
201    }
202
203    pub fn set(&mut self, value: bool) {
204        self.value = value;
205    }
206
207    pub fn process(&mut self, delta_time: Scalar) {
208        if self.playing {
209            let time_frame = self.phase.time_frame();
210            let time = if self.value {
211                let time = self.time + delta_time;
212                if time >= time_frame.end {
213                    self.playing = false;
214                }
215                time
216            } else {
217                let time = self.time - delta_time;
218                if time <= time_frame.start {
219                    self.playing = false;
220                }
221                time
222            };
223            self.time = time.max(time_frame.start).min(time_frame.end);
224        }
225    }
226}