Skip to main content

mittens_engine/engine/ecs/component/
skinned_mesh.rs

1use crate::engine::ecs::component::Component;
2use crate::engine::graphics::SkinId;
3
4/// Runtime skinning metadata for a renderable.
5///
6/// Intended to be attached as a descendant of a `RenderableComponent`.
7///
8/// This is per-renderable because the computed skinning palette depends on the mesh's world
9/// transform (we compute mesh-local skinning matrices).
10#[derive(Debug, Clone)]
11pub struct SkinnedMeshComponent {
12    /// glTF skin index within the source asset.
13    pub skin_index: usize,
14
15    /// Runtime-only: reference to a World-owned skin instance.
16    ///
17    /// This avoids duplicating joint/IBM arrays for every primitive/renderable.
18    pub skin_id: Option<SkinId>,
19}
20
21impl SkinnedMeshComponent {
22    pub fn new(skin_index: usize) -> Self {
23        Self {
24            skin_index,
25            skin_id: None,
26        }
27    }
28}
29
30impl Component for SkinnedMeshComponent {
31    fn name(&self) -> &'static str {
32        "skinned_mesh"
33    }
34
35    fn as_any(&self) -> &dyn std::any::Any {
36        self
37    }
38
39    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
40        self
41    }
42
43    fn init(
44        &mut self,
45        _emit: &mut dyn crate::engine::ecs::SignalEmitter,
46        _component: crate::engine::ecs::ComponentId,
47    ) {
48        // No-op: SkinnedMeshSystem discovers these each frame.
49    }
50
51    fn to_mms_ast(
52        &self,
53        _world: &crate::engine::ecs::World,
54    ) -> crate::scripting::ast::ComponentExpression {
55        use crate::engine::ecs::component::ce_helpers::*;
56        ce_call("SkinnedMesh", "new", vec![num(self.skin_index as f64)])
57    }
58}