1#[cfg(cpu)]
7mod cpu;
8#[cfg(cpu)]
9pub use cpu::*;
10
11#[cfg(test)]
12mod test {
13 use craballoc::{prelude::SlabAllocator, runtime::CpuRuntime};
14 use glam::{Mat4, Quat, Vec3};
15
16 use crate::{
17 math::IsMatrix,
18 transform::{shader::TransformDescriptor, NestedTransform},
19 };
20
21 #[test]
22 fn matrix_hierarchy_sanity() {
23 let a: Mat4 = TransformDescriptor {
24 translation: Vec3::new(100.0, 100.0, 0.0),
25 ..Default::default()
26 }
27 .into();
28 let b: Mat4 = TransformDescriptor {
29 scale: Vec3::splat(0.5),
30 ..Default::default()
31 }
32 .into();
33 let c1 = a * b;
34 let c2 = b * a;
35 assert_ne!(c1, c2);
36 }
37
38 #[test]
39 fn nested_transform_fox_rigging() {
40 pub fn legacy_get_world_transform(tfrm: &NestedTransform) -> (Vec3, Quat, Vec3) {
41 let mut mat = Mat4::IDENTITY;
42 let mut local = Some(tfrm.clone());
43 while let Some(t) = local.take() {
44 let transform = t.local_descriptor();
45 mat = Mat4::from_scale_rotation_translation(
46 transform.scale,
47 transform.rotation,
48 transform.translation,
49 ) * mat;
50 local = t.parent();
51 }
52 let (s, r, t) = mat.to_scale_rotation_translation_or_id();
53 (t, r, s)
54 }
55
56 let slab = SlabAllocator::new(CpuRuntime, "transform", ());
57 let a = NestedTransform::new(&slab);
58 a.set_local_translation(Vec3::splat(100.0));
59 let b = NestedTransform::new(&slab);
60 b.set_local_rotation(Quat::from_scaled_axis(Vec3::Z));
61 let c = NestedTransform::new(&slab);
62 c.set_local_scale(Vec3::splat(2.0));
63
64 a.add_child(&b);
65 b.add_child(&c);
66
67 let TransformDescriptor {
68 translation,
69 rotation,
70 scale,
71 } = c.global_descriptor();
72 let global_transform = (translation, rotation, scale);
73 let legacy_transform = legacy_get_world_transform(&c);
74 assert_eq!(legacy_transform, global_transform);
75
76 c.set_local_translation(Vec3::ONE);
77
78 let all_updates = slab.get_updated_source_ids();
79 assert_eq!(
80 std::collections::HashSet::from_iter([
81 a.global_transform.descriptor.notifier_index(),
82 b.global_transform.descriptor.notifier_index(),
83 c.global_transform.descriptor.notifier_index()
84 ]),
85 all_updates
86 );
87
88 let TransformDescriptor {
89 translation,
90 rotation,
91 scale,
92 } = c.global_descriptor();
93 let global_transform = (translation, rotation, scale);
94 let legacy_transform = legacy_get_world_transform(&c);
95 assert_eq!(legacy_transform, global_transform);
96 }
97}