Skip to main content

mittens_engine/engine/ecs/component/
transform_pipeline.rs

1use super::Component;
2
3#[derive(Debug, Clone, Copy, Default)]
4pub struct TransformForkTRSComponent;
5
6impl TransformForkTRSComponent {
7    pub fn new() -> Self {
8        Self
9    }
10}
11
12impl Component for TransformForkTRSComponent {
13    fn name(&self) -> &'static str {
14        "transform_fork_trs"
15    }
16
17    fn as_any(&self) -> &dyn std::any::Any {
18        self
19    }
20
21    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
22        self
23    }
24}
25
26#[derive(Debug, Clone, Copy, Default)]
27pub struct TransformMergeTRSComponent;
28
29impl TransformMergeTRSComponent {
30    pub fn new() -> Self {
31        Self
32    }
33}
34
35impl Component for TransformMergeTRSComponent {
36    fn name(&self) -> &'static str {
37        "transform_merge_trs"
38    }
39
40    fn as_any(&self) -> &dyn std::any::Any {
41        self
42    }
43
44    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
45        self
46    }
47}
48
49#[derive(Debug, Clone, Copy, Default)]
50pub struct TransformDropComponent;
51
52impl TransformDropComponent {
53    pub fn new() -> Self {
54        Self
55    }
56}
57
58impl Component for TransformDropComponent {
59    fn name(&self) -> &'static str {
60        "transform_drop"
61    }
62
63    fn as_any(&self) -> &dyn std::any::Any {
64        self
65    }
66
67    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
68        self
69    }
70}
71
72/// Samples the world transform of an ancestor TransformComponent and injects it into the
73/// pipeline channel this component is placed under (TransformMapTranslation or
74/// TransformMapRotation).
75///
76/// `skip` controls how many TransformComponent ancestors to climb past from the pipeline
77/// owner before sampling. The walk starts at the pipeline component and goes up:
78///
79/// - `skip = 0` — the driven TransformComponent directly above the pipeline (same as Pass)
80/// - `skip = 1` — the next TransformComponent above that (e.g. the armature bone above the
81///   InputXR-driven T in a splice topology)
82///
83/// The default is `skip = 1`, which is the common case for head/neck bone rotation splices.
84#[derive(Debug, Clone, Copy)]
85pub struct TransformSampleAncestorComponent {
86    pub skip: usize,
87}
88
89impl TransformSampleAncestorComponent {
90    pub fn new() -> Self {
91        Self { skip: 1 }
92    }
93
94    pub fn with_skip(mut self, skip: usize) -> Self {
95        self.skip = skip;
96        self
97    }
98}
99
100impl Default for TransformSampleAncestorComponent {
101    fn default() -> Self {
102        Self::new()
103    }
104}
105
106impl Component for TransformSampleAncestorComponent {
107    fn name(&self) -> &'static str {
108        "transform_sample_ancestor"
109    }
110
111    fn as_any(&self) -> &dyn std::any::Any {
112        self
113    }
114
115    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
116        self
117    }
118
119    fn to_mms_ast(
120        &self,
121        _world: &crate::engine::ecs::World,
122    ) -> crate::scripting::ast::ComponentExpression {
123        use crate::engine::ecs::component::ce_helpers::*;
124        ce_call(
125            "TransformSampleAncestor",
126            "skip",
127            vec![num(self.skip as f64)],
128        )
129    }
130}