renderling/transform/
cpu.rs1use std::sync::{Arc, RwLock};
4
5use craballoc::{runtime::IsRuntime, slab::SlabAllocator, value::Hybrid};
6use crabslab::Id;
7use glam::{Mat4, Quat, Vec3};
8
9use super::shader::TransformDescriptor;
10
11#[derive(Clone, Debug)]
13pub struct Transform {
14 pub(crate) descriptor: Hybrid<TransformDescriptor>,
15}
16
17impl From<&Transform> for Transform {
18 fn from(value: &Transform) -> Self {
19 value.clone()
20 }
21}
22
23impl Transform {
24 pub(crate) fn new(slab: &SlabAllocator<impl IsRuntime>) -> Self {
26 let descriptor = slab.new_value(TransformDescriptor::default());
27 Self { descriptor }
28 }
29
30 pub fn id(&self) -> Id<TransformDescriptor> {
32 self.descriptor.id()
33 }
34
35 pub fn descriptor(&self) -> TransformDescriptor {
37 self.descriptor.get()
38 }
39
40 pub fn set_descriptor(&self, descriptor: TransformDescriptor) -> &Self {
42 self.descriptor.set(descriptor);
43 self
44 }
45
46 pub fn with_descriptor(self, descriptor: TransformDescriptor) -> Self {
48 self.set_descriptor(descriptor);
49 self
50 }
51
52 pub fn as_mat4(&self) -> Mat4 {
54 self.descriptor().into()
55 }
56
57 pub fn translation(&self) -> Vec3 {
59 self.descriptor.get().translation
60 }
61
62 pub fn modify_translation<T: 'static>(&self, f: impl FnOnce(&mut Vec3) -> T) -> T {
68 self.descriptor.modify(|t| f(&mut t.translation))
69 }
70
71 pub fn set_translation(&self, translation: impl Into<Vec3>) -> &Self {
77 self.descriptor
78 .modify(|t| t.translation = translation.into());
79 self
80 }
81
82 pub fn with_translation(self, translation: impl Into<Vec3>) -> Self {
88 self.set_translation(translation);
89 self
90 }
91
92 pub fn rotation(&self) -> Quat {
94 self.descriptor.get().rotation
95 }
96
97 pub fn modify_rotation<T: 'static>(&self, f: impl FnOnce(&mut Quat) -> T) -> T {
103 self.descriptor.modify(|t| f(&mut t.rotation))
104 }
105
106 pub fn set_rotation(&self, rotation: impl Into<Quat>) -> &Self {
112 self.descriptor.modify(|t| t.rotation = rotation.into());
113 self
114 }
115
116 pub fn with_rotation(self, rotation: impl Into<Quat>) -> Self {
122 self.set_rotation(rotation);
123 self
124 }
125
126 pub fn scale(&self) -> Vec3 {
128 self.descriptor.get().scale
129 }
130
131 pub fn modify_scale<T: 'static>(&self, f: impl FnOnce(&mut Vec3) -> T) -> T {
137 self.descriptor.modify(|t| f(&mut t.scale))
138 }
139
140 pub fn set_scale(&self, scale: impl Into<Vec3>) -> &Self {
146 self.descriptor.modify(|t| t.scale = scale.into());
147 self
148 }
149
150 pub fn with_scale(self, scale: impl Into<Vec3>) -> Self {
156 self.set_scale(scale);
157 self
158 }
159}
160
161#[derive(Clone)]
168pub struct NestedTransform {
169 pub(crate) global_transform: Transform,
170 local_transform: Arc<RwLock<TransformDescriptor>>,
171 children: Arc<RwLock<Vec<NestedTransform>>>,
172 parent: Arc<RwLock<Option<NestedTransform>>>,
173}
174
175impl core::fmt::Debug for NestedTransform {
176 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
177 let children = self
178 .children
179 .read()
180 .unwrap()
181 .iter()
182 .map(|nt| nt.global_transform.id())
183 .collect::<Vec<_>>();
184 let parent = self
185 .parent
186 .read()
187 .unwrap()
188 .as_ref()
189 .map(|nt| nt.global_transform.id());
190 f.debug_struct("NestedTransform")
191 .field("local_transform", &self.local_transform)
192 .field("children", &children)
193 .field("parent", &parent)
194 .finish()
195 }
196}
197
198impl From<&NestedTransform> for Transform {
199 fn from(value: &NestedTransform) -> Self {
200 value.global_transform.clone()
201 }
202}
203
204impl From<NestedTransform> for Transform {
205 fn from(value: NestedTransform) -> Self {
206 value.global_transform
207 }
208}
209
210impl NestedTransform {
211 pub(crate) fn new(slab: &SlabAllocator<impl IsRuntime>) -> Self {
213 let nested = NestedTransform {
214 local_transform: Arc::new(RwLock::new(TransformDescriptor::default())),
215 global_transform: Transform::new(slab),
216 children: Default::default(),
217 parent: Default::default(),
218 };
219 nested.mark_dirty();
220 nested
221 }
222
223 pub fn local_translation(&self) -> Vec3 {
225 self.local_transform.read().unwrap().translation
226 }
227
228 pub fn modify_local_translation<T>(&self, f: impl FnOnce(&mut Vec3) -> T) -> T {
234 let t = {
235 let mut local_transform = self.local_transform.write().unwrap();
236 f(&mut local_transform.translation)
237 };
238 self.mark_dirty();
239 t
240 }
241
242 pub fn set_local_translation(&self, translation: impl Into<Vec3>) -> &Self {
248 self.local_transform.write().unwrap().translation = translation.into();
249 self.mark_dirty();
250 self
251 }
252
253 pub fn with_local_translation(self, translation: impl Into<Vec3>) -> Self {
259 self.set_local_translation(translation);
260 self
261 }
262
263 pub fn local_rotation(&self) -> Quat {
265 self.local_transform.read().unwrap().rotation
266 }
267
268 pub fn modify_local_rotation<T>(&self, f: impl FnOnce(&mut Quat) -> T) -> T {
274 let t = {
275 let mut local_transform = self.local_transform.write().unwrap();
276 f(&mut local_transform.rotation)
277 };
278 self.mark_dirty();
279 t
280 }
281
282 pub fn set_local_rotation(&self, rotation: impl Into<Quat>) -> &Self {
288 self.local_transform.write().unwrap().rotation = rotation.into();
289 self.mark_dirty();
290 self
291 }
292
293 pub fn with_local_rotation(self, rotation: impl Into<Quat>) -> Self {
299 self.set_local_rotation(rotation);
300 self
301 }
302
303 pub fn local_scale(&self) -> Vec3 {
305 self.local_transform.read().unwrap().scale
306 }
307
308 pub fn modify_local_scale<T>(&self, f: impl FnOnce(&mut Vec3) -> T) -> T {
314 let t = {
315 let mut local_transform = self.local_transform.write().unwrap();
316 f(&mut local_transform.scale)
317 };
318 self.mark_dirty();
319 t
320 }
321
322 pub fn set_local_scale(&self, scale: impl Into<Vec3>) -> &Self {
328 self.local_transform.write().unwrap().scale = scale.into();
329 self.mark_dirty();
330 self
331 }
332
333 pub fn with_local_scale(self, scale: impl Into<Vec3>) -> Self {
339 self.set_local_scale(scale);
340 self
341 }
342
343 pub fn global_id(&self) -> Id<TransformDescriptor> {
347 self.global_transform.id()
348 }
349
350 pub fn global_descriptor(&self) -> TransformDescriptor {
354 let maybe_parent_guard = self.parent.read().unwrap();
355 let transform = self.local_descriptor();
356 let parent_transform = maybe_parent_guard
357 .as_ref()
358 .map(|parent| parent.global_descriptor())
359 .unwrap_or_default();
360 TransformDescriptor::from(Mat4::from(parent_transform) * Mat4::from(transform))
361 }
362
363 pub fn local_descriptor(&self) -> TransformDescriptor {
365 *self.local_transform.read().unwrap()
366 }
367
368 fn mark_dirty(&self) {
369 self.global_transform
370 .descriptor
371 .set(self.global_descriptor());
372 for child in self.children.read().unwrap().iter() {
373 child.mark_dirty();
374 }
375 }
376
377 pub fn hierarchy(&self) -> Vec<TransformDescriptor> {
381 let mut transforms = vec![];
382 if let Some(parent) = self.parent() {
383 transforms.extend(parent.hierarchy());
384 }
385 transforms.push(self.local_descriptor());
386 transforms
387 }
388
389 pub fn add_child(&self, node: &NestedTransform) {
390 *node.parent.write().unwrap() = Some(self.clone());
391 node.mark_dirty();
392 self.children.write().unwrap().push(node.clone());
393 }
394
395 pub fn remove_child(&self, node: &NestedTransform) {
396 self.children.write().unwrap().retain_mut(|child| {
397 if child.global_transform.id() == node.global_transform.id() {
398 node.mark_dirty();
399 let _ = node.parent.write().unwrap().take();
400 false
401 } else {
402 true
403 }
404 });
405 }
406
407 pub fn parent(&self) -> Option<NestedTransform> {
409 self.parent.read().unwrap().clone()
410 }
411}