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