Skip to main content

mittens_engine/engine/ecs/component/
collision.rs

1use crate::engine::ecs::ComponentId;
2use crate::engine::ecs::component::Component;
3
4use crate::engine::ecs::system::model::collision_types::CollisionMode;
5
6/// Enables collision participation for an entity.
7///
8/// Shape can be provided via a child `CollisionShapeComponent`.
9/// If absent, the CollisionSystem will try to infer a shape from a sibling `RenderableComponent`
10/// using known built-in meshes (initially cube/sphere only).
11#[derive(Debug, Clone)]
12pub struct CollisionComponent {
13    pub mode: CollisionMode,
14
15    component: Option<ComponentId>,
16}
17
18impl CollisionComponent {
19    pub fn new(mode: CollisionMode) -> Self {
20        Self {
21            mode,
22            component: None,
23        }
24    }
25
26    #[allow(non_snake_case)]
27    pub fn STATIC() -> Self {
28        Self::new(CollisionMode::Static)
29    }
30
31    #[allow(non_snake_case)]
32    pub fn KINEMATIC() -> Self {
33        Self::new(CollisionMode::Kinematic)
34    }
35
36    #[allow(non_snake_case)]
37    pub fn RIGGED() -> Self {
38        Self::new(CollisionMode::Rigged)
39    }
40}
41
42impl Default for CollisionComponent {
43    fn default() -> Self {
44        Self::STATIC()
45    }
46}
47
48impl Component for CollisionComponent {
49    fn name(&self) -> &'static str {
50        "collision"
51    }
52
53    fn set_id(&mut self, component: ComponentId) {
54        self.component = Some(component);
55    }
56
57    fn as_any(&self) -> &dyn std::any::Any {
58        self
59    }
60
61    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
62        self
63    }
64
65    fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
66        emit.push_intent_now(
67            component,
68            crate::engine::ecs::IntentValue::RegisterCollision {
69                component_ids: vec![component],
70            },
71        );
72    }
73
74    fn cleanup(
75        &mut self,
76        emit: &mut dyn crate::engine::ecs::SignalEmitter,
77        component: ComponentId,
78    ) {
79        emit.push_intent_now(
80            component,
81            crate::engine::ecs::IntentValue::RemoveCollision {
82                component_ids: vec![component],
83            },
84        );
85    }
86
87    fn to_mms_ast(
88        &self,
89        _world: &crate::engine::ecs::World,
90    ) -> crate::scripting::ast::ComponentExpression {
91        use crate::engine::ecs::component::ce_helpers::*;
92        let ctor = match self.mode {
93            CollisionMode::Static => "static",
94            CollisionMode::Kinematic => "kinematic",
95            CollisionMode::Rigged => "rigged",
96        };
97        ce_call("Collision", ctor, vec![])
98    }
99}