Skip to main content

mittens_engine/engine/ecs/component/
transparent_cutout.rs

1use crate::engine::ecs::ComponentId;
2use crate::engine::ecs::component::Component;
3
4/// Marker component: route this renderable into the "transparent cutout" pass.
5///
6/// Intended to be attached as a descendant of a `RenderableComponent`.
7///
8/// Semantics:
9/// - Uses alpha-to-coverage (MSAA) instead of blending.
10/// - Depth test/write stays enabled, so it behaves like opaque geometry for ordering.
11#[derive(Debug, Clone, Copy)]
12pub struct TransparentCutoutComponent {
13    pub enabled: bool,
14}
15
16impl TransparentCutoutComponent {
17    pub fn new() -> Self {
18        Self { enabled: true }
19    }
20
21    pub fn with_enabled(mut self, enabled: bool) -> Self {
22        self.enabled = enabled;
23        self
24    }
25}
26
27impl Default for TransparentCutoutComponent {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl Component for TransparentCutoutComponent {
34    fn name(&self) -> &'static str {
35        "transparent_cutout"
36    }
37
38    fn as_any(&self) -> &dyn std::any::Any {
39        self
40    }
41
42    fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
43        self
44    }
45
46    fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
47        emit.push_intent_now(
48            component,
49            crate::engine::ecs::IntentValue::RegisterTransparentCutout {
50                component_ids: vec![component],
51            },
52        );
53    }
54
55    fn to_mms_ast(
56        &self,
57        _world: &crate::engine::ecs::World,
58    ) -> crate::scripting::ast::ComponentExpression {
59        use crate::engine::ecs::component::ce_helpers::*;
60        if self.enabled {
61            ce("TransparentCutout")
62        } else {
63            ce_call("TransparentCutout", "disabled", vec![])
64        }
65    }
66}