mraphics_core/animation/predefined/
basic.rs1use crate::{Action, Animation, RenderInstance, Renderable};
2use nalgebra::{UnitQuaternion, UnitVector3, Vector3};
3use std::{cell::RefCell, rc::Rc};
4
5pub struct MeshAnimation {
6 pub mesh_id: usize,
7 pub on_update: Box<dyn FnMut(&mut RenderInstance, f32, f32)>,
8 pub on_start: Box<dyn FnMut()>,
9 pub on_stop: Box<dyn FnMut()>,
10}
11
12impl MeshAnimation {
13 pub fn new<R: Renderable>(mesh: &R) -> Self {
14 Self {
15 mesh_id: mesh.identifier(),
16 on_update: Box::new(|_, _, _| {}),
17 on_start: Box::new(|| {}),
18 on_stop: Box::new(|| {}),
19 }
20 }
21
22 pub fn with_on_update<F: FnMut(&mut RenderInstance, f32, f32) + 'static>(
23 mut self,
24 closure: F,
25 ) -> Self {
26 self.on_update = Box::new(closure);
27 self
28 }
29
30 pub fn with_on_start<F: FnMut() + 'static>(mut self, closure: F) -> Self {
31 self.on_start = Box::new(closure);
32 self
33 }
34
35 pub fn with_on_stop<F: FnMut() + 'static>(mut self, closure: F) -> Self {
36 self.on_stop = Box::new(closure);
37 self
38 }
39}
40
41impl Animation for MeshAnimation {
42 fn into_action(mut self, scene: std::rc::Rc<std::cell::RefCell<crate::Scene>>) -> Action {
43 let mut out = Action::new();
44
45 out.on_start = self.on_start;
46 out.on_stop = self.on_stop;
47
48 out.on_update = Box::new(move |progress, elapsed_time| {
49 (self.on_update)(
50 scene
51 .borrow_mut()
52 .acquire_instance_mut_unchecked(self.mesh_id),
53 progress,
54 elapsed_time,
55 )
56 });
57
58 out
59 }
60}
61
62pub struct RotateAxisAngle {
63 pub mesh_index: usize,
64 pub axis: UnitVector3<f32>,
65 pub angle_rad: f32,
66}
67
68impl RotateAxisAngle {
69 pub fn new<R: Renderable>(mesh: &R, axis: UnitVector3<f32>, angle_rad: f32) -> Self {
70 Self {
71 mesh_index: mesh.identifier(),
72 axis,
73 angle_rad,
74 }
75 }
76
77 pub fn new_normalize<R: Renderable>(mesh: &R, axis: Vector3<f32>, angle_rad: f32) -> Self {
78 Self {
79 mesh_index: mesh.identifier(),
80 axis: UnitVector3::new_normalize(axis),
81 angle_rad,
82 }
83 }
84}
85
86impl Animation for RotateAxisAngle {
87 fn into_action(self, scene: std::rc::Rc<std::cell::RefCell<crate::Scene>>) -> Action {
88 let mut out = Action::new();
89 let start_rotation = Rc::new(RefCell::new(UnitQuaternion::identity()));
90
91 let scene_clone = scene.clone();
92 let start_rotation_clone = start_rotation.clone();
93
94 out.on_start = Box::new(move || {
95 start_rotation_clone.borrow_mut().clone_from(
96 scene_clone
97 .borrow()
98 .acquire_instance_unchecked(self.mesh_index)
99 .rotation(),
100 );
101 });
102 out.on_update = Box::new(move |p, _| {
103 scene
104 .borrow_mut()
105 .acquire_instance_mut_unchecked(self.mesh_index)
106 .set_rotation(
107 &(UnitQuaternion::from_axis_angle(&self.axis, self.angle_rad * p)
108 * &*start_rotation.borrow()),
109 );
110 });
111
112 out
113 }
114}