mraphics_core/animation/predefined/
transform.rs1use crate::{
2 Action, Animation, InstanceUpdater, Interpolatable, MeshHandle, MeshLike, MeshPool, MraphicsID,
3 Representable, Scene,
4 anim_curve::{AnimCurve, Linear},
5};
6use nalgebra::{Matrix3, Vector3};
7use std::{cell::RefCell, marker::PhantomData, rc::Rc};
8
9pub trait Transformable: MeshLike + Representable
11where
12 Self::Intermediate: Interpolatable + InstanceUpdater,
13{
14 fn apply_transform<Trans: Fn(&[f32; 3]) -> [f32; 3]>(
20 &self,
21 transform: Trans,
22 ) -> Self::Intermediate;
23}
24
25pub struct PointwiseTransform<Trans, M>
26where
27 Trans: Fn(&[f32; 3]) -> [f32; 3] + 'static,
28 M: Transformable + 'static,
29 M::Intermediate: Interpolatable + InstanceUpdater,
30{
31 pub mesh_id: MraphicsID,
33
34 pub transform: Trans,
36
37 pub curve: Box<dyn AnimCurve>,
39
40 _marker: PhantomData<M>,
41}
42
43impl<Trans, M> PointwiseTransform<Trans, M>
44where
45 Trans: Fn(&[f32; 3]) -> [f32; 3] + 'static,
46 M: Transformable + 'static,
47 M::Intermediate: Interpolatable + InstanceUpdater,
48{
49 pub fn new(mesh_handle: &MeshHandle<M>, trans: Trans) -> Self {
50 Self {
51 mesh_id: mesh_handle.identifier(),
52 transform: trans,
53
54 curve: Box::new(Linear),
55
56 _marker: PhantomData,
57 }
58 }
59
60 pub fn with_curve<Curve: AnimCurve + 'static>(mut self, curve: Curve) -> Self {
61 self.curve = Box::new(curve);
62 self
63 }
64}
65
66impl<Trans, M> Animation<'static> for PointwiseTransform<Trans, M>
67where
68 Trans: Fn(&[f32; 3]) -> [f32; 3] + 'static,
69 M: Transformable + 'static,
70 M::Intermediate: Interpolatable + InstanceUpdater,
71{
72 fn into_action(
73 self,
74 mesh_pool: Rc<RefCell<MeshPool>>,
75 scene: Rc<RefCell<Scene>>,
76 ) -> Action<'static> {
77 let mut out = Action::new();
78 let original = Rc::new(RefCell::new(None));
79 let transformed = Rc::new(RefCell::new(None));
80
81 out.on_start = Box::new({
82 let oringinal = original.clone();
83 let transformed = transformed.clone();
84 let mesh_pool = mesh_pool.clone();
85 move || {
86 *oringinal.borrow_mut() = Some(
87 mesh_pool
88 .borrow()
89 .acquire_mesh_unchecked::<M>(self.mesh_id)
90 .as_intermediate(),
91 );
92
93 *transformed.borrow_mut() = Some(
94 mesh_pool
95 .borrow()
96 .acquire_mesh_unchecked::<M>(self.mesh_id)
97 .apply_transform(&self.transform),
98 );
99 }
100 });
101
102 out.on_update = Box::new({
103 let original = original.clone();
104 let transformed = transformed.clone();
105 move |p: f32, _t: f32| {
106 original
107 .borrow()
108 .as_ref()
109 .unwrap()
110 .interpolate(
111 &transformed.borrow().as_ref().unwrap(),
112 self.curve.sample(p),
113 )
114 .update_instance(
115 &mut scene
116 .borrow_mut()
117 .acquire_instance_mut_unchecked(self.mesh_id),
118 );
119 }
120 });
121
122 out.on_stop = Box::new({
123 let transformed = transformed.clone();
124 move || {
125 mesh_pool
126 .borrow_mut()
127 .acquire_mesh_mut_unchecked::<M>(self.mesh_id)
128 .update_from_intermediate(transformed.borrow().as_ref().unwrap());
129 }
130 });
131
132 out
133 }
134}
135
136pub struct MatrixTransform<M>
137where
138 M: Transformable + 'static,
139 M::Intermediate: Interpolatable + InstanceUpdater,
140{
141 pub mesh_id: MraphicsID,
143
144 pub matrix: Matrix3<f32>,
145
146 pub curve: Box<dyn AnimCurve>,
147
148 _marker: PhantomData<M>,
149}
150
151impl<M> MatrixTransform<M>
152where
153 M: Transformable + 'static,
154 M::Intermediate: Interpolatable + InstanceUpdater,
155{
156 pub fn new(mesh_handle: &MeshHandle<M>, matrix: Matrix3<f32>) -> Self {
157 Self {
158 mesh_id: mesh_handle.identifier(),
159 matrix,
160
161 curve: Box::new(Linear),
162
163 _marker: PhantomData,
164 }
165 }
166
167 pub fn with_curve<Curve: AnimCurve + 'static>(mut self, curve: Curve) -> Self {
168 self.curve = Box::new(curve);
169 self
170 }
171}
172
173impl<M> Animation<'static> for MatrixTransform<M>
174where
175 M: Transformable + 'static,
176 M::Intermediate: Interpolatable + InstanceUpdater,
177{
178 fn into_action(
179 self,
180 mesh_pool: Rc<RefCell<MeshPool>>,
181 scene: Rc<RefCell<Scene>>,
182 ) -> Action<'static> {
183 let mut out = Action::new();
184 let original = Rc::new(RefCell::new(None));
185 let transformed = Rc::new(RefCell::new(None));
186
187 out.on_start = Box::new({
188 let oringinal = original.clone();
189 let transformed = transformed.clone();
190 let mesh_pool = mesh_pool.clone();
191 move || {
192 *oringinal.borrow_mut() = Some(
193 mesh_pool
194 .borrow()
195 .acquire_mesh_unchecked::<M>(self.mesh_id)
196 .as_intermediate(),
197 );
198
199 *transformed.borrow_mut() = Some(
200 mesh_pool
201 .borrow()
202 .acquire_mesh_unchecked::<M>(self.mesh_id)
203 .apply_transform(|point: &[f32; 3]| {
204 let transformed = self.matrix * &Vector3::from_row_slice(point);
205 return [transformed[0], transformed[1], transformed[2]];
206 }),
207 );
208 }
209 });
210
211 out.on_update = Box::new({
212 let original = original.clone();
213 let transformed = transformed.clone();
214 move |p: f32, _t: f32| {
215 original
216 .borrow()
217 .as_ref()
218 .unwrap()
219 .interpolate(
220 &transformed.borrow().as_ref().unwrap(),
221 self.curve.sample(p),
222 )
223 .update_instance(
224 &mut scene
225 .borrow_mut()
226 .acquire_instance_mut_unchecked(self.mesh_id),
227 );
228 }
229 });
230
231 out.on_stop = Box::new({
232 let transformed = transformed.clone();
233 move || {
234 mesh_pool
235 .borrow_mut()
236 .acquire_mesh_mut_unchecked::<M>(self.mesh_id)
237 .update_from_intermediate(transformed.borrow().as_ref().unwrap());
238 }
239 });
240
241 out
242 }
243}