Skip to main content

mittens_engine/engine/ecs/component/
raycastable_shape.rs

1use crate::engine::ecs::component::Component;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum RaycastableShapeType {
5    /// Explicitly pick this renderable using an AABB only.
6    Aabb,
7
8    /// A finite cone aligned to the renderable's local +Z axis.
9    Cone,
10
11    /// A 2D ring/annulus lying in the renderable's local XY plane.
12    Ring2D,
13
14    /// A 2D quad lying in the renderable's local XY plane.
15    Quad2D,
16
17    /// A 2D triangle lying in the renderable's local XY plane.
18    Triangle2D,
19
20    /// A tetrahedron shape.
21    Tetrahedron,
22
23    /// A box/cube shape.
24    Box,
25
26    /// No explicit shape; infer from `Renderable.base_mesh`.
27    InferFromBaseMesh,
28}
29
30impl Default for RaycastableShapeType {
31    fn default() -> Self {
32        Self::InferFromBaseMesh
33    }
34}
35
36/// Explicit raycast/picking shape descriptor for a renderable.
37///
38/// This is intended to unify broad-phase bounds selection and future narrow-phase hit tests.
39/// For now, the engine can infer a shape from `Renderable.base_mesh` when this component is
40/// absent (or set to `InferFromBaseMesh`).
41#[derive(Debug, Clone, Copy, Default)]
42pub struct RaycastableShapeComponent {
43    pub shape: RaycastableShapeType,
44}
45
46impl RaycastableShapeComponent {
47    pub fn new(shape: RaycastableShapeType) -> Self {
48        Self { shape }
49    }
50
51    pub fn infer_from_base_mesh() -> Self {
52        Self::new(RaycastableShapeType::InferFromBaseMesh)
53    }
54
55    pub fn aabb() -> Self {
56        Self::new(RaycastableShapeType::Aabb)
57    }
58
59    pub fn cone() -> Self {
60        Self::new(RaycastableShapeType::Cone)
61    }
62
63    pub fn ring_2d() -> Self {
64        Self::new(RaycastableShapeType::Ring2D)
65    }
66}
67
68impl Component for RaycastableShapeComponent {
69    fn as_any(&self) -> &dyn std::any::Any {
70        self
71    }
72
73    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
74        self
75    }
76
77    fn name(&self) -> &'static str {
78        "raycastable_shape"
79    }
80
81    fn to_mms_ast(
82        &self,
83        _world: &crate::engine::ecs::World,
84    ) -> crate::scripting::ast::ComponentExpression {
85        use crate::engine::ecs::component::ce_helpers::*;
86        let ctor = match self.shape {
87            RaycastableShapeType::Aabb => "aabb",
88            RaycastableShapeType::Cone => "cone",
89            RaycastableShapeType::Ring2D => "ring_2d",
90            RaycastableShapeType::Quad2D => "quad_2d",
91            RaycastableShapeType::Triangle2D => "triangle_2d",
92            RaycastableShapeType::Tetrahedron => "tetrahedron",
93            RaycastableShapeType::Box => "box",
94            RaycastableShapeType::InferFromBaseMesh => "infer_from_base_mesh",
95        };
96        ce_call("RaycastableShape", ctor, vec![])
97    }
98}