1use crate::cx::*;
2use std::f64::consts::PI;
3
4#[derive(Clone)]
5pub struct AnimArea {
6 pub area: Area,
7 pub start_time: f64,
8 pub total_time: f64
9}
10
11#[derive(Clone)]
12pub struct Anim {
13 pub mode: Play,
14 pub tracks: Vec<Track>
15}
16
17#[derive(Clone)]
18pub enum AnimLastValue {
19 Float(f32),
20 Vec2(Vec2),
21 Vec3(Vec3),
22 Vec4(Vec4),
23 Color(Color),
24}
25
26#[derive(Default, Clone)]
27pub struct Animator {
28 current: Option<Anim>,
29 next: Option<Anim>,
30 pub area: Area,
31 pub theme_update_id: usize,
32 pub last_values: Vec<(InstanceType, AnimLastValue)>,
33}
34
35impl Animator {
36
37 pub fn init<F>(&mut self, cx: &mut Cx, cb: F)
38 where F: Fn(&Cx) -> Anim {
39 if self.theme_update_id != cx.theme_update_id {
40 self.theme_update_id = cx.theme_update_id;
41 let anim = cb(cx);
42 if let Some(anim_area) = cx.playing_anim_areas.iter_mut().find( | v | v.area == self.area) {
44 anim_area.total_time = 0.;
45 }
46 self.set_anim_as_last_values(&anim);
47 }
48 }
49
50 pub fn set_anim_as_last_values(&mut self, anim: &Anim) {
51 for track in &anim.tracks {
52 let ident = track.ident();
54 match track {
55 Track::Color(ft) => {
56 let val = if ft.track.len()>0 {ft.track.last().unwrap().1}else {Color::default()};
57 if let Some((_name, value)) = self.last_values.iter_mut().find( | (name, _) | *name == ident) {
58 *value = AnimLastValue::Color(val);
59 }
60 else {
61 self.last_values.push((ident.clone(), AnimLastValue::Color(val)));
62 }
63 },
64 Track::Vec4(ft) => {
65 let val = if ft.track.len()>0 {ft.track.last().unwrap().1}else {Vec4::default()};
66 if let Some((_name, value)) = self.last_values.iter_mut().find( | (name, _) | *name == ident) {
67 *value = AnimLastValue::Vec4(val);
68 }
69 else {
70 self.last_values.push((ident.clone(), AnimLastValue::Vec4(val)));
71 }
72 },
73 Track::Vec3(ft) => {
74 let val = if ft.track.len()>0 {ft.track.last().unwrap().1}else {Vec3::default()};
75 if let Some((_name, value)) = self.last_values.iter_mut().find( | (name, _) | *name == ident) {
76 *value = AnimLastValue::Vec3(val);
77 }
78 else {
79 self.last_values.push((ident.clone(), AnimLastValue::Vec3(val)));
80 }
81 },
82 Track::Vec2(ft) => {
83 let val = if ft.track.len()>0 {ft.track.last().unwrap().1}else {Vec2::default()};
84 if let Some((_name, value)) = self.last_values.iter_mut().find( | (name, _) | *name == ident) {
85 *value = AnimLastValue::Vec2(val);
86 }
87 else {
88 self.last_values.push((ident.clone(), AnimLastValue::Vec2(val)));
89 }
90 },
91 Track::Float(ft) => {
92 let val = if ft.track.len()>0 {ft.track.last().unwrap().1}else {0.};
93 if let Some((_name, value)) = self.last_values.iter_mut().find( | (name, _) | *name == ident) {
94 *value = AnimLastValue::Float(val);
95 }
96 else {
97 self.last_values.push((ident.clone(), AnimLastValue::Float(val)));
98 }
99 },
100 }
101 }
102 }
103
104 pub fn end(&mut self) {
105 if let Some(current) = self.current.take() {
106 self.set_anim_as_last_values(¤t);
107 }
108 }
109
110 pub fn end_and_set(&mut self, anim: Anim) {
111 self.current = None;
112 self.set_anim_as_last_values(&anim);
113 }
114
115 pub fn term_anim_playing(&mut self) -> bool {
116 if let Some(current) = &self.current {
117 return current.mode.term();
118 }
119 return false
120 }
121
122 pub fn play_anim(&mut self, cx: &mut Cx, anim: Anim) {
123 self.theme_update_id = cx.theme_update_id;
124 if let Some(current) = &self.current {
126 if current.mode.term() { return
128 }
129 }
130
131 if !self.area.is_valid(cx) {
132 self.set_anim_as_last_values(&anim);
133 self.current = Some(anim);
134 return
135 }
136 if let Some(anim_area) = cx.playing_anim_areas.iter_mut().find( | v | v.area == self.area) {
138 if anim.mode.cut() || self.current.is_none() {
140 self.current = Some(anim);
141 anim_area.start_time = std::f64::NAN;
142 self.next = None;
143 anim_area.total_time = self.current.as_ref().unwrap().mode.total_time();
144 }
145 else { self.next = Some(anim);
147 anim_area.total_time = self.current.as_ref().unwrap().mode.total_time() + self.next.as_ref().unwrap().mode.total_time()
149 }
150 }
151 else if self.area != Area::Empty { self.current = Some(anim);
153 self.next = None;
154 cx.playing_anim_areas.push(AnimArea {
155 area: self.area.clone(),
156 start_time: std::f64::NAN,
157 total_time: self.current.as_ref().unwrap().mode.total_time()
158 })
159 }
160 }
161
162 pub fn set_area(&mut self, cx: &mut Cx, area: Area) {
163 if self.area != Area::Empty {
164 cx.update_area_refs(self.area, area.clone());
165 }
166 self.area = area.clone();
167 }
168
169
170 pub fn update_anim_track(&mut self, cx: &mut Cx, time: f64) -> Option<f64> {
171 let anim_index_opt = cx.playing_anim_areas.iter().position( | v | v.area == self.area);
173 if anim_index_opt.is_none() {
174 return None
175 }
176 let anim_index = anim_index_opt.unwrap();
177
178 if cx.playing_anim_areas[anim_index].start_time.is_nan() {
180 cx.playing_anim_areas[anim_index].start_time = time;
181 }
182 let mut start_time = cx.playing_anim_areas[anim_index].start_time;
183
184 if self.current.is_none() { cx.playing_anim_areas.remove(anim_index);
187 return None
188 }
189
190 let current_total_time = self.current.as_ref().unwrap().mode.total_time();
191
192 if time - start_time >= current_total_time && !self.next.is_none() {
194 self.current = self.next.clone();
195 self.next = None;
196 start_time += current_total_time;
198 if let Some(anim) = cx.playing_anim_areas.iter_mut().find( | v | v.area == self.area) {
199 anim.start_time = start_time;
200 anim.total_time -= current_total_time;
201 }
202 Some(self.current.as_ref().unwrap().mode.compute_time(time - start_time))
203 }
204 else {
205 Some(self.current.as_ref().unwrap().mode.compute_time(time - start_time))
206 }
207 }
208
209 pub fn find_track_index(&mut self, ident: InstanceType) -> Option<usize> {
210 for (track_index, track) in &mut self.current.as_ref().unwrap().tracks.iter().enumerate() {
212 if track.ident() == ident {
213 return Some(track_index);
214 }
215 }
216 None
217 }
218
219 pub fn calc_float(&mut self, cx: &mut Cx, ident: InstanceFloat, time: f64) -> f32 {
220 let last = Self::_last_float(ident, &self.last_values);
221 let mut ret = last;
222 if let Some(time) = self.update_anim_track(cx, time) {
223 if let Some(track_index) = self.find_track_index(InstanceType::Float(ident)) {
224 if let Track::Float(ft) = &mut self.current.as_mut().unwrap().tracks[track_index] {
225 ret = Track::compute_track_float(time, &ft.track, &mut ft.cut_init, last, &ft.ease);
226 }
227 }
228 }
229 self.set_last_float(ident, ret);
230 return ret
231 }
232
233 pub fn last_float(&self, _cx: &Cx, ident: InstanceFloat) -> f32 {
234 Self::_last_float(ident, &self.last_values)
235 }
236
237 pub fn _last_float(ident: InstanceFloat, last_float: &Vec<(InstanceType, AnimLastValue)>) -> f32 {
238 if let Some((_, value)) = last_float.iter().find( | v | v.0 == InstanceType::Float(ident)) {
239 if let AnimLastValue::Float(value) = value {
240 return *value
241 }
242 }
243 return 0.0
244 }
245
246 pub fn set_last_float(&mut self, ident: InstanceFloat, value: f32) {
247 Self::_set_last_float(ident, value, &mut self.last_values)
248 }
249
250 pub fn _set_last_float(ident: InstanceFloat, value: f32, last_values: &mut Vec<(InstanceType, AnimLastValue)>) {
251 let ty_ident = InstanceType::Float(ident);
252 if let Some((_, last)) = last_values.iter_mut().find( | v | v.0 == ty_ident) {
253 *last = AnimLastValue::Float(value);
254 }
255 else {
256 last_values.push((ty_ident, AnimLastValue::Float(value)))
257 }
258 }
259
260 pub fn calc_vec2(&mut self, cx: &mut Cx, ident: InstanceVec2, time: f64) -> Vec2 {
261 let last = Self::_last_vec2(ident, &self.last_values);
262 let mut ret = last;
263 if let Some(time) = self.update_anim_track(cx, time) {
264 if let Some(track_index) = self.find_track_index(InstanceType::Vec2(ident)) {
265 if let Track::Vec2(ft) = &mut self.current.as_mut().unwrap().tracks[track_index] {
266 ret = Track::compute_track_vec2(time, &ft.track, &mut ft.cut_init, last, &ft.ease);
267 }
268 }
269 }
270 self.set_last_vec2(ident, ret);
271 return ret
272 }
273
274 pub fn last_vec2(&self, _cx: &Cx, ident: InstanceVec2) -> Vec2 {
275 Self::_last_vec2(ident, &self.last_values)
276 }
277
278 pub fn _last_vec2(ident: InstanceVec2, last_values: &Vec<(InstanceType, AnimLastValue)>) -> Vec2 {
279 if let Some((_, value)) = last_values.iter().find( | v | v.0 == InstanceType::Vec2(ident)) {
280 if let AnimLastValue::Vec2(value) = value {
281 return *value
282 }
283 }
284 return Vec2::default()
285 }
286
287 pub fn set_last_vec2(&mut self, ident: InstanceVec2, value: Vec2) {
288 Self::_set_last_vec2(ident, value, &mut self.last_values);
289 }
290
291 pub fn _set_last_vec2(ident: InstanceVec2, value: Vec2, last_values: &mut Vec<(InstanceType, AnimLastValue)>) {
292 let ty_ident = InstanceType::Vec2(ident);
293 if let Some((_, last)) = last_values.iter_mut().find( | v | v.0 == ty_ident) {
294 *last = AnimLastValue::Vec2(value);
295 }
296 else {
297 last_values.push((ty_ident, AnimLastValue::Vec2(value)))
298 }
299 }
300
301 pub fn calc_vec3(&mut self, cx: &mut Cx, ident: InstanceVec3, time: f64) -> Vec3 {
302 let last = Self::_last_vec3(ident, &self.last_values);
303 let mut ret = last;
304 if let Some(time) = self.update_anim_track(cx, time) {
305 if let Some(track_index) = self.find_track_index(InstanceType::Vec3(ident)) {
306 if let Track::Vec3(ft) = &mut self.current.as_mut().unwrap().tracks[track_index] {
307 ret = Track::compute_track_vec3(time, &ft.track, &mut ft.cut_init, last, &ft.ease);
308 }
309 }
310 }
311 self.set_last_vec3(ident, ret);
312 return ret
313 }
314
315 pub fn last_vec3(&self, _cx: &Cx, ident: InstanceVec3) -> Vec3 {
316 Self::_last_vec3(ident, &self.last_values)
317 }
318
319 pub fn _last_vec3(ident: InstanceVec3, last_values: &Vec<(InstanceType, AnimLastValue)>) -> Vec3 {
320 if let Some((_, value)) = last_values.iter().find( | v | v.0 == InstanceType::Vec3(ident)) {
321 if let AnimLastValue::Vec3(value) = value {
322 return *value
323 }
324 }
325 return Vec3::default()
326 }
327
328 pub fn set_last_vec3(&mut self, ident: InstanceVec3, value: Vec3) {
329 Self::_set_last_vec3(ident, value, &mut self.last_values);
330 }
331
332 pub fn _set_last_vec3(ident: InstanceVec3, value: Vec3, last_values: &mut Vec<(InstanceType, AnimLastValue)>) {
333 let ty_ident = InstanceType::Vec3(ident);
334 if let Some((_, last)) = last_values.iter_mut().find( | v | v.0 == ty_ident) {
335 *last = AnimLastValue::Vec3(value);
336 }
337 else {
338 last_values.push((ty_ident, AnimLastValue::Vec3(value)))
339 }
340 }
341
342 pub fn calc_vec4(&mut self, cx: &mut Cx, ident: InstanceVec4, time: f64) -> Vec4 {
343 let last = Self::_last_vec4(ident, &self.last_values);
344 let mut ret = last;
345 if let Some(time) = self.update_anim_track(cx, time) {
346 if let Some(track_index) = self.find_track_index(InstanceType::Vec4(ident)) {
347 if let Track::Vec4(ft) = &mut self.current.as_mut().unwrap().tracks[track_index] {
348 ret = Track::compute_track_vec4(time, &ft.track, &mut ft.cut_init, last, &ft.ease);
349 }
350 }
351 }
352 self.set_last_vec4(ident, ret);
353 return ret
354 }
355
356 pub fn last_vec4(&self, _cx: &Cx, ident: InstanceVec4) -> Vec4 {
357 Self::_last_vec4(ident, &self.last_values)
358 }
359
360 pub fn _last_vec4(ident: InstanceVec4, last_values: &Vec<(InstanceType, AnimLastValue)>) -> Vec4 {
361 if let Some((_, value)) = last_values.iter().find( | v | v.0 == InstanceType::Vec4(ident)) {
362 if let AnimLastValue::Vec4(value) = value {
363 return *value
364 }
365 }
366 return Vec4::default()
367 }
368
369 pub fn set_last_vec4(&mut self, ident: InstanceVec4, value: Vec4) {
370 Self::_set_last_vec4(ident, value, &mut self.last_values);
371 }
372
373 pub fn _set_last_vec4(ident: InstanceVec4, value: Vec4, last_values: &mut Vec<(InstanceType, AnimLastValue)>) {
374 let ty_ident = InstanceType::Vec4(ident);
375 if let Some((_, last)) = last_values.iter_mut().find( | v | v.0 == ty_ident) {
376 *last = AnimLastValue::Vec4(value);
377 }
378 else {
379 last_values.push((ty_ident, AnimLastValue::Vec4(value)))
380 }
381 }
382
383 pub fn calc_color(&mut self, cx: &mut Cx, ident: InstanceColor, time: f64) -> Color {
384 if let Some(time) = self.update_anim_track(cx, time) {
385 if let Some(track_index) = self.find_track_index(InstanceType::Color(ident)) {
386 if let Track::Color(ft) = &mut self.current.as_mut().unwrap().tracks[track_index] {
387 let last = Self::_last_color(ident, &self.last_values);
388 let ret = Track::compute_track_color(time, &ft.track, &mut ft.cut_init, last, &ft.ease);
389 self.set_last_color(ident, ret);
390 return ret
391 }
392 }
393 }
394
395 return Color::default();
396 }
397
398 pub fn last_color(&self, _cx: &Cx, ident: InstanceColor) -> Color {
399 if let Some((_, value)) = self.last_values.iter().find( | v | v.0 == InstanceType::Color(ident)) {
400 if let AnimLastValue::Color(value) = value {
401 return *value
402 }
403 }
404 Color::default()
405 }
406
407 pub fn _last_color(ident: InstanceColor, last_values: &Vec<(InstanceType, AnimLastValue)>) -> Color {
408 if let Some((_, value)) = last_values.iter().find( | v | v.0 == InstanceType::Color(ident)) {
409 if let AnimLastValue::Color(value) = value {
410 return *value
411 }
412 }
413
414 return Color::default()
415 }
416
417 pub fn set_last_color(&mut self, ident: InstanceColor, value: Color) {
418 Self::_set_last_color(ident, value, &mut self.last_values);
419 }
420
421 pub fn _set_last_color(ident: InstanceColor, value: Color, last_values: &mut Vec<(InstanceType, AnimLastValue)>) {
422 let ty_ident = InstanceType::Color(ident);
423 if let Some((_, last)) = last_values.iter_mut().find( | v | v.0 == ty_ident) {
424 *last = AnimLastValue::Color(value)
425 }
426 else {
427 last_values.push((ty_ident, AnimLastValue::Color(value)))
428 }
429 }
430
431 pub fn last_area(&mut self, _cx: &mut Cx, _area: Area, _time: f64) {
432
433 }
434
435 pub fn calc_area(&mut self, cx: &mut Cx, area: Area, time: f64) {
436
437 if let Some(time) = self.update_anim_track(cx, time) {
438
439 for track_index in 0..self.current.as_ref().unwrap().tracks.len() {
440 match &mut self.current.as_mut().unwrap().tracks[track_index] {
442 Track::Color(ft) => {
443 let init = Self::_last_color(ft.ident, &self.last_values);
444 let ret = Track::compute_track_color(time, &ft.track, &mut ft.cut_init, init, &ft.ease);
445 Self::_set_last_color(ft.ident, ret, &mut self.last_values);
446 area.write_color(cx, ft.ident, ret);
447 },
448 Track::Vec4(ft) => {
449 let init = Self::_last_vec4(ft.ident, &self.last_values);
450 let ret = Track::compute_track_vec4(time, &ft.track, &mut ft.cut_init, init, &ft.ease);
451 Self::_set_last_vec4(ft.ident, ret, &mut self.last_values);
452 area.write_vec4(cx, ft.ident, ret);
453 },
454 Track::Vec3(ft) => {
455 let init = Self::_last_vec3(ft.ident, &self.last_values);
456 let ret = Track::compute_track_vec3(time, &ft.track, &mut ft.cut_init, init, &ft.ease);
457 Self::_set_last_vec3(ft.ident, ret, &mut self.last_values);
458 area.write_vec3(cx, ft.ident, ret);
459 },
460 Track::Vec2(ft) => {
461 let init = Self::_last_vec2(ft.ident, &self.last_values);
462 let ret = Track::compute_track_vec2(time, &ft.track, &mut ft.cut_init, init, &ft.ease);
463 Self::_set_last_vec2(ft.ident, ret, &mut self.last_values);
464 area.write_vec2(cx, ft.ident, ret);
465 },
466 Track::Float(ft) => {
467 let init = Self::_last_float(ft.ident, &self.last_values);
468 let ret = Track::compute_track_float(time, &ft.track, &mut ft.cut_init, init, &ft.ease);
469 Self::_set_last_float(ft.ident, ret, &mut self.last_values);
470 area.write_float(cx, ft.ident, ret);
471 }
472 };
473 }
474 }
476 }
477}
478
479#[derive(Clone)]
480pub enum Ease {
481 Lin,
482 InQuad,
483 OutQuad,
484 InOutQuad,
485 InCubic,
486 OutCubic,
487 InOutCubic,
488 InQuart,
489 OutQuart,
490 InOutQuart,
491 InQuint,
492 OutQuint,
493 InOutQuint,
494 InSine,
495 OutSine,
496 InOutSine,
497 InExp,
498 OutExp,
499 InOutExp,
500 InCirc,
501 OutCirc,
502 InOutCirc,
503 InElastic,
504 OutElastic,
505 InOutElastic,
506 InBack,
507 OutBack,
508 InOutBack,
509 InBounce,
510 OutBounce,
511 InOutBounce,
512 Pow {begin: f64, end: f64},
513 Bezier {cp0: f64, cp1: f64, cp2: f64, cp3: f64}
514 }
519
520
521impl Ease {
522 pub fn map(&self, t: f64) -> f64 {
523 match self {
524 Ease::Lin => {
525 return t.max(0.0).min(1.0);
526 },
527 Ease::Pow {begin, end} => {
528 if t < 0. {
529 return 0.;
530 }
531 if t > 1. {
532 return 1.;
533 }
534 let a = -1. / (begin * begin).max(1.0);
535 let b = 1. + 1. / (end * end).max(1.0);
536 let t2 = (((a - 1.) * -b) / (a * (1. - b))).powf(t);
537 return (-a * b + b * a * t2) / (a * t2 - b);
538 },
539
540 Ease::InQuad => {
541 return t * t;
542 },
543 Ease::OutQuad => {
544 return t * (2.0 - t);
545 },
546 Ease::InOutQuad => {
547 let t = t * 2.0;
548 if t < 1. {
549 return 0.5 * t * t;
550 }
551 else {
552 let t = t - 1.;
553 return -0.5 * (t * (t - 2.) - 1.);
554 }
555 },
556 Ease::InCubic => {
557 return t * t * t;
558 },
559 Ease::OutCubic => {
560 let t2 = t - 1.0;
561 return t2 * t2 * t2 + 1.0;
562 },
563 Ease::InOutCubic => {
564 let t = t * 2.0;
565 if t < 1. {
566 return 0.5 * t * t * t;
567 }
568 else {
569 let t = t - 2.;
570 return 1. / 2. * (t * t * t + 2.);
571 }
572 },
573 Ease::InQuart => {
574 return t * t * t * t
575 },
576 Ease::OutQuart => {
577 let t = t - 1.;
578 return -(t * t * t * t - 1.);
579 },
580 Ease::InOutQuart => {
581 let t = t * 2.0;
582 if t < 1. {
583 return 0.5 * t * t * t * t;
584 }
585 else {
586 let t = t - 2.;
587 return -0.5 * (t * t * t * t - 2.);
588 }
589 },
590 Ease::InQuint => {
591 return t * t * t * t * t;
592 },
593 Ease::OutQuint => {
594 let t = t - 1.;
595 return t * t * t * t * t + 1.;
596 },
597 Ease::InOutQuint => {
598 let t = t * 2.0;
599 if t < 1. {
600 return 0.5 * t * t * t * t * t;
601 }
602 else {
603 let t = t - 2.;
604 return 0.5 * (t * t * t * t * t + 2.);
605 }
606 },
607 Ease::InSine => {
608 return -(t * PI * 0.5).cos() + 1.;
609 },
610 Ease::OutSine => {
611 return (t * PI * 0.5).sin();
612 },
613 Ease::InOutSine => {
614 return -0.5 * ((t * PI).cos() - 1.);
615 },
616 Ease::InExp => {
617 if t < 0.001 {
618 return 0.;
619 }
620 else {
621 return 2.0f64.powf(10. * (t - 1.));
622 }
623 },
624 Ease::OutExp => {
625 if t > 0.999 {
626 return 1.;
627 }
628 else {
629 return -(2.0f64.powf(-10. * t)) + 1.;
630 }
631 },
632 Ease::InOutExp => {
633 if t<0.001 {
634 return 0.;
635 }
636 if t>0.999 {
637 return 1.;
638 }
639 let t = t * 2.0;
640 if t < 1. {
641 return 0.5 * 2.0f64.powf(10. * (t - 1.));
642 }
643 else {
644 let t = t - 1.;
645 return 0.5 * (-(2.0f64.powf(-10. * t)) + 2.);
646 }
647 },
648 Ease::InCirc => {
649 return -((1. - t * t).sqrt() - 1.);
650 },
651 Ease::OutCirc => {
652 let t = t - 1.;
653 return (1. - t * t).sqrt();
654 },
655 Ease::InOutCirc => {
656 let t = t * 2.;
657 if t < 1. {
658 return -0.5 * ((1. - t * t).sqrt() - 1.);
659 }
660 else {
661 let t = t - 2.;
662 return 0.5 * ((1. - t * t).sqrt() + 1.);
663 }
664 },
665 Ease::InElastic => {
666 let p = 0.3;
667 let s = p / 4.0; if t < 0.001 {
669 return 0.;
670 }
671 if t > 0.999 {
672 return 1.;
673 }
674 let t = t - 1.0;
675 return -(2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
676 },
677 Ease::OutElastic => {
678 let p = 0.3;
679 let s = p / 4.0; if t < 0.001 {
682 return 0.;
683 }
684 if t > 0.999 {
685 return 1.;
686 }
687 return 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
688 },
689 Ease::InOutElastic => {
690 let p = 0.3;
691 let s = p / 4.0; if t < 0.001 {
693 return 0.;
694 }
695 if t > 0.999 {
696 return 1.;
697 }
698 let t = t * 2.0;
699 if t < 1. {
700 let t = t - 1.0;
701 return -0.5 * (2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
702 }
703 else {
704 let t = t - 1.0;
705 return 0.5 * 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
706 }
707 },
708 Ease::InBack => {
709 let s = 1.70158;
710 return t * t * ((s + 1.) * t - s);
711 },
712 Ease::OutBack => {
713 let s = 1.70158;
714 let t = t - 1.;
715 return t * t * ((s + 1.) * t + s) + 1.;
716 },
717 Ease::InOutBack => {
718 let s = 1.70158;
719 let t = t * 2.0;
720 if t < 1. {
721 let s = s * 1.525;
722 return 0.5 * (t * t * ((s + 1.) * t - s));
723 }
724 else {
725 let t = t - 2.;
726 return 0.5 * (t * t * ((s + 1.) * t + s) + 2.);
727 }
728 },
729 Ease::InBounce => {
730 return 1.0 - Ease::OutBounce.map(1.0 - t);
731 },
732 Ease::OutBounce => {
733 if t < (1. / 2.75) {
734 return 7.5625 * t * t;
735 }
736 if t < (2. / 2.75) {
737 let t = t - (1.5 / 2.75);
738 return 7.5625 * t * t + 0.75;
739 }
740 if t < (2.5 / 2.75) {
741 let t = t - (2.25 / 2.75);
742 return 7.5625 * t * t + 0.9375;
743 }
744 let t = t - (2.625 / 2.75);
745 return 7.5625 * t * t + 0.984375;
746 },
747 Ease::InOutBounce => {
748 if t <0.5 {
749 return Ease::InBounce.map(t * 2.) * 0.5;
750 }
751 else {
752 return Ease::OutBounce.map(t * 2. - 1.) * 0.5 + 0.5;
753 }
754 },
755 Ease::Bezier {cp0, cp1, cp2, cp3} => {
799 if t < 0. {
800 return 0.;
801 }
802 if t > 1. {
803 return 1.;
804 }
805
806 if (cp0 - cp1).abs() < 0.001 && (cp2 - cp3).abs() < 0.001 {
807 return t;
808 }
809
810 let epsilon = 1.0 / 200.0 * t;
811 let cx = 3.0 * cp0;
812 let bx = 3.0 * (cp2 - cp0) - cx;
813 let ax = 1.0 - cx - bx;
814 let cy = 3.0 * cp1;
815 let by = 3.0 * (cp3 - cp1) - cy;
816 let ay = 1.0 - cy - by;
817 let mut u = t;
818
819 for _i in 0..6 {
820 let x = ((ax * u + bx) * u + cx) * u - t;
821 if x.abs() < epsilon {
822 return ((ay * u + by) * u + cy) * u;
823 }
824 let d = (3.0 * ax * u + 2.0 * bx) * u + cx;
825 if d.abs() < 1e-6 {
826 break;
827 }
828 u = u - x / d;
829 };
830
831 if t > 1. {
832 return (ay + by) + cy;
833 }
834 if t < 0. {
835 return 0.0;
836 }
837
838 let mut w = 0.0;
839 let mut v = 1.0;
840 u = t;
841 for _i in 0..8 {
842 let x = ((ax * u + bx) * u + cx) * u;
843 if (x - t).abs() < epsilon {
844 return ((ay * u + by) * u + cy) * u;
845 }
846
847 if t > x {
848 w = u;
849 }
850 else {
851 v = u;
852 }
853 u = (v - w) * 0.5 + w;
854 }
855
856 return ((ay * u + by) * u + cy) * u;
857 }
858 }
859 }
860}
861
862
863#[derive(Clone)]
864pub struct FloatTrack {
865 pub ident: InstanceFloat,
866 pub ease: Ease,
867 pub cut_init: Option<f32>,
868 pub track: Vec<(f64, f32)>
869}
870
871#[derive(Clone)]
872pub struct Vec2Track {
873 pub ident: InstanceVec2,
874 pub ease: Ease,
875 pub cut_init: Option<Vec2>,
876 pub track: Vec<(f64, Vec2)>
877}
878
879#[derive(Clone)]
880pub struct Vec3Track {
881 pub ident: InstanceVec3,
882 pub ease: Ease,
883 pub cut_init: Option<Vec3>,
884 pub track: Vec<(f64, Vec3)>
885}
886
887#[derive(Clone)]
888pub struct Vec4Track {
889 pub ident: InstanceVec4,
890 pub ease: Ease,
891 pub cut_init: Option<Vec4>,
892 pub track: Vec<(f64, Vec4)>
893}
894
895#[derive(Clone)]
896pub struct ColorTrack {
897 pub ident: InstanceColor,
898 pub ease: Ease,
899 pub cut_init: Option<Color>,
900 pub track: Vec<(f64, Color)>
901}
902
903#[derive(Clone)]
904pub enum Track {
905 Float(FloatTrack),
906 Vec2(Vec2Track),
907 Vec3(Vec3Track),
908 Vec4(Vec4Track),
909 Color(ColorTrack),
910}
911
912impl Track {
913
914 pub fn float(ident: InstanceFloat, ease: Ease, track: Vec<(f64, f32)>) -> Track {
915 Track::Float(FloatTrack {
916 cut_init: None,
917 ease: ease,
918 ident: ident,
919 track: track
920 })
921 }
922
923 pub fn vec2(ident: InstanceVec2, ease: Ease, track: Vec<(f64, Vec2)>) -> Track {
924 Track::Vec2(Vec2Track {
925 cut_init: None,
926 ease: ease,
927 ident: ident,
928 track: track
929 })
930 }
931
932 pub fn vec3(ident: InstanceVec3, ease: Ease, track: Vec<(f64, Vec3)>) -> Track {
933 Track::Vec3(Vec3Track {
934 cut_init: None,
935 ease: ease,
936 ident: ident,
937 track: track
938 })
939 }
940
941 pub fn vec4(ident: InstanceVec4, ease: Ease, track: Vec<(f64, Vec4)>) -> Track {
942 Track::Vec4(Vec4Track {
943 cut_init: None,
944 ease: ease,
945 ident: ident,
946 track: track
947 })
948 }
949
950
951 pub fn color(ident: InstanceColor, ease: Ease, track: Vec<(f64, Color)>) -> Track {
952 Track::Color(ColorTrack {
953 cut_init: None,
954 ease: ease,
955 ident: ident,
956 track: track
957 })
958 }
959
960
961 fn compute_track_float(time: f64, track: &Vec<(f64, f32)>, cut_init: &mut Option<f32>, init: f32, ease: &Ease) -> f32 {
962 if track.is_empty() {return init}
963 fn lerp(a: f32, b: f32, f: f32) -> f32 {
964 return a * (1.0 - f) + b * f;
965 }
966 for i in 0..track.len() {
968 if time >= track[i].0 { let val1 = &track[i];
970 if i == track.len() - 1 { return val1.1.clone()
972 }
973 let val2 = &track[i + 1];
974 let f = ease.map((time - val1.0) / (val2.0 - val1.0)) as f32;
976 return lerp(val1.1, val2.1, f);
977 }
978 }
979 if cut_init.is_none() {
980 *cut_init = Some(init);
981 }
982 let val2 = &track[0];
983 let val1 = cut_init.as_mut().unwrap();
984 let f = ease.map(time / val2.0) as f32;
985 return lerp(*val1, val2.1, f)
986 }
987
988 fn compute_track_vec2(time: f64, track: &Vec<(f64, Vec2)>, cut_init: &mut Option<Vec2>, init: Vec2, ease: &Ease) -> Vec2 {
989 if track.is_empty() {return init}
990 fn lerp(a: Vec2, b: Vec2, f: f32) -> Vec2 {
991 let nf = 1.0 - f;
992 return Vec2 {x: a.x * nf + b.x * f, y: a.y * nf + b.y * f}
993 }
994 for i in 0..track.len() {
996 if time >= track[i].0 { let val1 = &track[i];
998 if i == track.len() - 1 { return val1.1.clone()
1000 }
1001 let val2 = &track[i + 1];
1002 let f = ease.map((time - val1.0) / (val2.0 - val1.0)) as f32;
1004 return lerp(val1.1, val2.1, f);
1005 }
1006 }
1007 if cut_init.is_none() {
1008 *cut_init = Some(init);
1009 }
1010 let val2 = &track[0];
1011 let val1 = cut_init.as_mut().unwrap();
1012 let f = ease.map(time / val2.0) as f32;
1013 return lerp(*val1, val2.1, f)
1014 }
1015
1016 fn compute_track_vec3(time: f64, track: &Vec<(f64, Vec3)>, cut_init: &mut Option<Vec3>, init: Vec3, ease: &Ease) -> Vec3 {
1017 if track.is_empty() {return init}
1018 fn lerp(a: Vec3, b: Vec3, f: f32) -> Vec3 {
1019 let nf = 1.0 - f;
1020 return Vec3 {x: a.x * nf + b.x * f, y: a.y * nf + b.y * f, z: a.z * nf + b.z * f}
1021 }
1022 for i in 0..track.len() {
1024 if time >= track[i].0 { let val1 = &track[i];
1026 if i == track.len() - 1 { return val1.1.clone()
1028 }
1029 let val2 = &track[i + 1];
1030 let f = ease.map((time - val1.0) / (val2.0 - val1.0)) as f32;
1032 return lerp(val1.1, val2.1, f);
1033 }
1034 }
1035 if cut_init.is_none() {
1036 *cut_init = Some(init);
1037 }
1038 let val2 = &track[0];
1039 let val1 = cut_init.as_mut().unwrap();
1040 let f = ease.map(time / val2.0) as f32;
1041 return lerp(*val1, val2.1, f)
1042 }
1043
1044 fn compute_track_vec4(time: f64, track: &Vec<(f64, Vec4)>, cut_init: &mut Option<Vec4>, init: Vec4, ease: &Ease) -> Vec4 {
1045 if track.is_empty() {return init}
1046 fn lerp(a: Vec4, b: Vec4, f: f32) -> Vec4 {
1047 let nf = 1.0 - f;
1048 return Vec4 {x: a.x * nf + b.x * f, y: a.y * nf + b.y * f, z: a.z * nf + b.z * f, w: a.w * nf + b.w * f}
1049 }
1050 for i in 0..track.len() {
1052 if time >= track[i].0 { let val1 = &track[i];
1054 if i == track.len() - 1 { return val1.1.clone()
1056 }
1057 let val2 = &track[i + 1];
1058 let f = ease.map((time - val1.0) / (val2.0 - val1.0)) as f32;
1060 return lerp(val1.1, val2.1, f);
1061 }
1062 }
1063 if cut_init.is_none() {
1064 *cut_init = Some(init);
1065 }
1066 let val2 = &track[0];
1067 let val1 = cut_init.as_mut().unwrap();
1068 let f = ease.map(time / val2.0) as f32;
1069 return lerp(*val1, val2.1, f)
1070 }
1071
1072 fn compute_track_color(time: f64, track: &Vec<(f64, Color)>, cut_init: &mut Option<Color>, init: Color, ease: &Ease) -> Color {
1073 if track.is_empty() {return init}
1074 fn lerp(a: Color, b: Color, f: f32) -> Color {
1075 let nf = 1.0 - f;
1076 return Color {r: a.r * nf + b.r * f, g: a.g * nf + b.g * f, b: a.b * nf + b.b * f, a: a.a * nf + b.a * f}
1077 }
1078 for i in 0..track.len() {
1080 if time >= track[i].0 { let val1 = &track[i];
1082 if i == track.len() - 1 { return val1.1.clone()
1084 }
1085 let val2 = &track[i + 1];
1086 let f = ease.map((time - val1.0) / (val2.0 - val1.0)) as f32;
1088 return lerp(val1.1, val2.1, f);
1089 }
1090 }
1091 if cut_init.is_none() {
1092 *cut_init = Some(init);
1093 }
1094 let val2 = &track[0];
1095 let val1 = cut_init.as_mut().unwrap();
1096 let f = ease.map(time / val2.0) as f32;
1097 return lerp(*val1, val2.1, f)
1098 }
1099
1100 pub fn ident(&self) -> InstanceType {
1101 match self {
1102 Track::Float(ft) => {
1103 InstanceType::Float(ft.ident)
1104 },
1105 Track::Vec2(ft) => {
1106 InstanceType::Vec2(ft.ident)
1107 }
1108 Track::Vec3(ft) => {
1109 InstanceType::Vec3(ft.ident)
1110 }
1111 Track::Vec4(ft) => {
1112 InstanceType::Vec4(ft.ident)
1113 }
1114 Track::Color(ft) => {
1115 InstanceType::Color(ft.ident)
1116 }
1117 }
1118 }
1119
1120 pub fn reset_cut_init(&mut self) {
1121 match self {
1122 Track::Color(at) => {
1123 at.cut_init = None;
1124 },
1125 Track::Vec4(at) => {
1126 at.cut_init = None;
1127 },
1128 Track::Vec3(at) => {
1129 at.cut_init = None;
1130 },
1131 Track::Vec2(at) => {
1132 at.cut_init = None;
1133 },
1134 Track::Float(at) => {
1135 at.cut_init = None;
1136 }
1137 }
1138 }
1139
1140 pub fn ease(&self) -> &Ease {
1141 match self {
1142 Track::Float(ft) => {
1143 &ft.ease
1144 },
1145 Track::Vec2(ft) => {
1146 &ft.ease
1147 }
1148 Track::Vec3(ft) => {
1149 &ft.ease
1150 }
1151 Track::Vec4(ft) => {
1152 &ft.ease
1153 }
1154 Track::Color(ft) => {
1155 &ft.ease
1156 }
1157 }
1158 }
1159}
1160
1161impl Anim {
1162 pub fn new(mode: Play, tracks: Vec<Track>) -> Anim {
1163 Anim {
1164 mode: mode,
1165 tracks: tracks
1166 }
1167 }
1168
1169 pub fn empty() -> Anim {
1170 Anim {
1171 mode: Play::Cut {duration: 0.},
1172 tracks: vec![]
1173 }
1174 }
1175}
1176
1177#[derive(Clone)]
1178pub enum Play {
1179 Chain {duration: f64},
1180 Cut {duration: f64},
1181 Single {duration: f64, cut: bool, term: bool, end: f64},
1182 Loop {duration: f64, cut: bool, term: bool, repeats: f64, end: f64},
1183 Reverse {duration: f64, cut: bool, term: bool, repeats: f64, end: f64},
1184 Bounce {duration: f64, cut: bool, term: bool, repeats: f64, end: f64},
1185 Forever {duration: f64, cut: bool, term: bool},
1186 LoopForever {duration: f64, cut: bool, term: bool, end: f64},
1187 ReverseForever {duration: f64, cut: bool, term: bool, end: f64},
1188 BounceForever {duration: f64, cut: bool, term: bool, end: f64},
1189}
1190
1191impl Play {
1192 pub fn duration(&self) -> f64 {
1193 match self {
1194 Play::Chain {duration, ..} => *duration,
1195 Play::Cut {duration, ..} => *duration,
1196 Play::Single {duration, ..} => *duration,
1197 Play::Loop {duration, ..} => *duration,
1198 Play::Reverse {duration, ..} => *duration,
1199 Play::Bounce {duration, ..} => *duration,
1200 Play::BounceForever {duration, ..} => *duration,
1201 Play::Forever {duration, ..} => *duration,
1202 Play::LoopForever {duration, ..} => *duration,
1203 Play::ReverseForever {duration, ..} => *duration,
1204 }
1205 }
1206 pub fn total_time(&self) -> f64 {
1207 match self {
1208 Play::Chain {duration, ..} => *duration,
1209 Play::Cut {duration, ..} => *duration,
1210 Play::Single {end, duration, ..} => end * duration,
1211 Play::Loop {end, duration, repeats, ..} => end * duration * repeats,
1212 Play::Reverse {end, duration, repeats, ..} => end * duration * repeats,
1213 Play::Bounce {end, duration, repeats, ..} => end * duration * repeats,
1214 Play::BounceForever {..} => std::f64::INFINITY,
1215 Play::Forever {..} => std::f64::INFINITY,
1216 Play::LoopForever {..} => std::f64::INFINITY,
1217 Play::ReverseForever {..} => std::f64::INFINITY,
1218 }
1219 }
1220
1221 pub fn cut(&self) -> bool {
1222 match self {
1223 Play::Cut {..} => true,
1224 Play::Chain {..} => false,
1225 Play::Single {cut, ..} => *cut,
1226 Play::Loop {cut, ..} => *cut,
1227 Play::Reverse {cut, ..} => *cut,
1228 Play::Bounce {cut, ..} => *cut,
1229 Play::BounceForever {cut, ..} => *cut,
1230 Play::Forever {cut, ..} => *cut,
1231 Play::LoopForever {cut, ..} => *cut,
1232 Play::ReverseForever {cut, ..} => *cut,
1233 }
1234 }
1235
1236 pub fn repeats(&self) -> f64 {
1237 match self {
1238 Play::Chain {..} => 1.0,
1239 Play::Cut {..} => 1.0,
1240 Play::Single {..} => 1.0,
1241 Play::Loop {repeats, ..} => *repeats,
1242 Play::Reverse {repeats, ..} => *repeats,
1243 Play::Bounce {repeats, ..} => *repeats,
1244 Play::BounceForever {..} => std::f64::INFINITY,
1245 Play::Forever {..} => std::f64::INFINITY,
1246 Play::LoopForever {..} => std::f64::INFINITY,
1247 Play::ReverseForever {..} => std::f64::INFINITY,
1248 }
1249 }
1250
1251 pub fn term(&self) -> bool {
1252 match self {
1253 Play::Cut {..} => false,
1254 Play::Chain {..} => false,
1255 Play::Single {term, ..} => *term,
1256 Play::Loop {term, ..} => *term,
1257 Play::Reverse {term, ..} => *term,
1258 Play::Bounce {term, ..} => *term,
1259 Play::BounceForever {term, ..} => *term,
1260 Play::Forever {term, ..} => *term,
1261 Play::LoopForever {term, ..} => *term,
1262 Play::ReverseForever {term, ..} => *term,
1263 }
1264 }
1265
1266 pub fn compute_time(&self, time: f64) -> f64 {
1267 match self {
1268 Play::Cut {duration, ..} => {
1269 time / duration
1270 },
1271 Play::Chain {duration, ..} => {
1272 time / duration
1273 },
1274 Play::Single {duration, ..} => {
1275 time / duration
1276 },
1277 Play::Loop {end, duration, ..} => {
1278 (time / duration) % end
1279 },
1280 Play::Reverse {end, duration, ..} => {
1281 end - (time / duration) % end
1282 },
1283 Play::Bounce {end, duration, ..} => {
1284 let mut local_time = (time / duration) % (end * 2.0);
1285 if local_time > *end {
1286 local_time = 2.0 * end - local_time;
1287 };
1288 local_time
1289 },
1290 Play::BounceForever {end, duration, ..} => {
1291 let mut local_time = (time / duration) % (end * 2.0);
1292 if local_time > *end {
1293 local_time = 2.0 * end - local_time;
1294 };
1295 local_time
1296 },
1297 Play::Forever {duration, ..} => {
1298 let local_time = time / duration;
1299 local_time
1300 },
1301 Play::LoopForever {end, duration, ..} => {
1302 let local_time = (time / duration) % end;
1303 local_time
1304 },
1305 Play::ReverseForever {end, duration, ..} => {
1306 let local_time = end - (time / duration) % end;
1307 local_time
1308 },
1309 }
1310 }
1311}