Skip to main content

BackgroundComponent

Struct BackgroundComponent 

Source
pub struct BackgroundComponent {
    pub occlusion_and_lighting: bool,
    pub ray_casting: bool,
}

Fields§

§occlusion_and_lighting: bool

If true, renderables under this node render in the background occluded+lit stage.

This stage is intended to depth-test/write against itself (for self-occlusion) and participate in lighting, while still not occluding the foreground (the renderer clears depth before drawing the foreground).

§ray_casting: bool

If true, renderables under this node are eligible for ray casting (BVH insertion).

Default is false because background scene dressing (clouds, skyboxes, etc.) typically should not be hit-testable.

Implementations§

Source§

impl BackgroundComponent

Source

pub fn new() -> Self

Examples found in repository?
examples/vr-input.rs (line 65)
62fn spawn_sun_background(universe: &mut engine::Universe) {
63    let bg_root = universe
64        .world
65        .add_component(engine::ecs::component::BackgroundComponent::new());
66    universe.add(bg_root);
67
68    let circle_mesh = universe.render_assets.get_mesh(BuiltinMeshType::Circle2D);
69
70    // Big yellow disk.
71    let sun_t = universe.world.add_component(
72        TransformComponent::new()
73            .with_position(2.0, 1.5, -8.0)
74            .with_scale(3.5, 3.5, 3.5),
75    );
76    let sun_r = universe
77        .world
78        .add_component(RenderableComponent::new(Renderable::new(
79            circle_mesh,
80            MaterialHandle::TOON_MESH,
81        )));
82    let sun_color = universe
83        .world
84        .add_component(ColorComponent::rgba(1.0, 0.85, 0.15, 1.0));
85    let sun_emissive = universe.world.add_component(EmissiveComponent::on());
86
87    let _ = universe.attach(bg_root, sun_t);
88    let _ = universe.attach(sun_t, sun_r);
89    let _ = universe.attach(sun_r, sun_color);
90    let _ = universe.attach(sun_r, sun_emissive);
91
92    // Small white highlight disk.
93    let highlight_t = universe.world.add_component(
94        TransformComponent::new()
95            .with_position(-0.35, 0.35, -0.01)
96            .with_scale(0.45, 0.45, 0.45),
97    );
98    let highlight_r = universe
99        .world
100        .add_component(RenderableComponent::new(Renderable::new(
101            circle_mesh,
102            MaterialHandle::TOON_MESH,
103        )));
104    let highlight_color = universe
105        .world
106        .add_component(ColorComponent::rgba(1.0, 1.0, 1.0, 1.0));
107    let highlight_emissive = universe.world.add_component(EmissiveComponent::on());
108
109    let _ = universe.attach(sun_t, highlight_t);
110    let _ = universe.attach(highlight_t, highlight_r);
111    let _ = universe.attach(highlight_r, highlight_color);
112    let _ = universe.attach(highlight_r, highlight_emissive);
113}
More examples
Hide additional examples
examples/vtuber-mirror-example.rs (line 110)
77fn main() {
78    mittens_engine::example_support::ensure_model_assets();
79    utils::logger::init();
80
81    let output = scripting::MeowMeowRunner::eval(include_str!("vtuber-mirror-example.mms"));
82
83    for error in &output.errors {
84        eprintln!("[mms] {error}");
85    }
86    println!(
87        "[mms] {} intent(s) from vtuber-mirror-example.mms",
88        output.intents.len()
89    );
90    println!(
91        "[vtuber-mirror-example] expected XR-only views: 2 XR eye views plus mirror-derived views; no desktop scene view unless a Camera3D/Camera2D is added"
92    );
93
94    let world = engine::ecs::World::default();
95    let mut universe = engine::Universe::new(world);
96
97    let scope = engine::ecs::ComponentId::default();
98    for intent in output.intents {
99        universe.command_queue.push_intent_now(scope, intent);
100    }
101
102    universe.systems.process_commands(
103        &mut universe.world,
104        &mut universe.visuals,
105        &mut universe.render_assets,
106        &mut universe.command_queue,
107    );
108
109    let bg_root = universe.world.add_component(
110        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
111    );
112    universe.add(bg_root);
113
114    let cloud_params = example_util::CloudRingParams {
115        cloud_count: 10,
116        radius: 34.0,
117        center_y: 8.5,
118        puffs_per_cloud: 28,
119        angle_jitter: 0.30,
120        high_y_probability: 0.45,
121        high_y_multiplier: 1.28,
122        seed: 0x57_55_B0_0Au32,
123    };
124    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
125
126    for kind in [
127        SignalKind::DragStart,
128        SignalKind::DragMove,
129        SignalKind::DragEnd,
130        SignalKind::Click,
131    ] {
132        universe
133            .systems
134            .rx
135            .add_global_handler(kind, on_xr_pointer_event);
136    }
137
138    universe.enable_repl();
139    engine::Windowing::run_app(universe).expect("Windowing failed");
140}
examples/vtuber-editor-example.rs (line 111)
77fn main() {
78    mittens_engine::example_support::ensure_model_assets();
79    utils::logger::init();
80
81    let output = scripting::MeowMeowRunner::eval(include_str!("vtuber-editor-example.mms"));
82
83    for error in &output.errors {
84        eprintln!("[mms] {error}");
85    }
86    println!(
87        "[mms] {} intent(s) from vtuber-editor-example.mms",
88        output.intents.len()
89    );
90    println!(
91        "[vtuber-editor-example] expected XR-only views: 2 XR eye views plus mirror-derived views; no desktop scene view unless a Camera3D/Camera2D is added"
92    );
93
94    let world = engine::ecs::World::default();
95
96    let mut universe = engine::Universe::new(world);
97
98    let scope = engine::ecs::ComponentId::default();
99    for intent in output.intents {
100        universe.command_queue.push_intent_now(scope, intent);
101    }
102
103    universe.systems.process_commands(
104        &mut universe.world,
105        &mut universe.visuals,
106        &mut universe.render_assets,
107        &mut universe.command_queue,
108    );
109
110    let bg_root = universe.world.add_component(
111        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
112    );
113    universe.add(bg_root);
114
115    let cloud_params = example_util::CloudRingParams {
116        cloud_count: 10,
117        radius: 34.0,
118        center_y: 8.5,
119        puffs_per_cloud: 28,
120        angle_jitter: 0.30,
121        high_y_probability: 0.45,
122        high_y_multiplier: 1.28,
123        seed: 0x57_55_B0_0Au32,
124    };
125    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
126
127    for kind in [
128        SignalKind::DragStart,
129        SignalKind::DragMove,
130        SignalKind::DragEnd,
131        SignalKind::Click,
132    ] {
133        universe
134            .systems
135            .rx
136            .add_global_handler(kind, on_xr_pointer_event);
137    }
138
139    universe.enable_repl();
140    engine::Windowing::run_app(universe).expect("Windowing failed");
141}
examples/vtuber-example.rs (line 115)
11fn main() {
12    mittens_engine::example_support::ensure_model_assets();
13    utils::logger::init();
14
15    let world = engine::ecs::World::default();
16    let mut universe = engine::Universe::new(world);
17
18    // Light pink background.
19    let background = universe
20        .world
21        .add_component(BackgroundColorComponent::new());
22    let background_c = universe
23        .world
24        .add_component(ColorComponent::rgba(1.0, 0.82, 0.90, 1.0));
25    let _ = universe.world.add_child(background, background_c);
26    universe.add(background);
27
28    // Small ambient so shadowed areas aren't pure black.
29    let ambient = universe
30        .world
31        .add_component(AmbientLightComponent::rgb(0.10, 0.10, 0.12));
32    universe.add(ambient);
33
34    // --- Camera rig (WASD + mouse) ---
35    // InputComponent is the root, and it owns a Transform (the camera rig).
36    let input = universe
37        .world
38        .add_component(InputComponent::new().with_speed(1.5));
39    let input_mode = universe.world.add_component(
40        InputTransformModeComponent::forward_z()
41            .with_fps_rotation()
42            .with_roll_axis_y(),
43    );
44    let _ = universe.attach(input, input_mode);
45
46    // Start slightly pulled back looking towards the origin.
47    let rig_transform = universe
48        .world
49        .add_component(TransformComponent::new().with_position(0.0, 0.0, 6.0));
50    let _ = universe.attach(input, rig_transform);
51
52    let camera3d = universe.world.add_component(Camera3DComponent::new());
53    let _ = universe.attach(rig_transform, camera3d);
54
55    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
56    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
57
58    universe.add(input);
59
60    // --- lighting ---
61    // Directional key light (slightly down + forward Z).
62    let sun = universe.world.add_component(
63        DirectionalLightComponent::new()
64            .with_intensity(1.2)
65            .with_color(1.0, 0.98, 0.94),
66    );
67    let sun_dir = universe
68        .world
69        .add_component(TransformComponent::new().with_position(0.0, -0.35, 1.0));
70    let _ = universe.attach(sun_dir, sun);
71    universe.add(sun_dir);
72
73    let light_transform = universe.world.add_component(
74        TransformComponent::new()
75            .with_position(1.0, 6.0, 3.0)
76            .with_scale(0.1, 0.1, 0.1),
77    );
78    let light = universe.world.add_component(
79        engine::ecs::component::PointLightComponent::new()
80            .with_distance(120.0)
81            .with_color(1.0, 1.0, 1.0),
82    );
83    let _ = universe.attach(light_transform, light);
84    universe.add(light_transform);
85
86    // --- VTuber model ---
87    let model_root = universe.world.add_component(TransformComponent::new());
88    let model = universe
89        .world
90        .add_component(GLTFComponent::new("assets/models/pc-rei.hoodie.glb"));
91    // emissive for pc-rei
92    let emissive = universe
93        .world
94        .add_component(engine::ecs::component::EmissiveComponent::on());
95
96    let _ = universe.attach(model, emissive);
97
98    let xr_input = universe.world.add_component(InputXRComponent::on());
99    let xr_gamepad = universe
100        .world
101        .add_component(engine::ecs::component::InputXRGamepadComponent::new().speed(1.5));
102    let xr_head = universe.world.add_component(TransformComponent::new());
103    let xr_camera = universe.world.add_component(CameraXRComponent::on());
104    let _ = universe.attach(xr_input, xr_head);
105    let _ = universe.attach(xr_input, xr_gamepad);
106    let _ = universe.attach(xr_head, xr_camera);
107    let _ = universe.attach(xr_head, model_root);
108
109    let _ = universe.attach(model_root, model);
110    universe.add(xr_input);
111    universe.add(model_root);
112
113    // --- Background clouds (occluded + lit) ---
114    let bg_root = universe.world.add_component(
115        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
116    );
117    universe.add(bg_root);
118    let mut cloud_params = example_util::CloudRingParams::default();
119    cloud_params.cloud_count = 8; // +3 clusters
120    cloud_params.angle_jitter = 0.35;
121    cloud_params.high_y_probability = 0.5;
122    cloud_params.high_y_multiplier = 1.5;
123    cloud_params.seed = 0x57_55_B0_01u32;
124    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
125
126    // --- Simple environment ---
127    let spawn_cube = |universe: &mut engine::Universe,
128                      position: (f32, f32, f32),
129                      scale: (f32, f32, f32),
130                      color: (f32, f32, f32, f32)| {
131        let transform = universe.world.add_component(
132            TransformComponent::new()
133                .with_position(position.0, position.1, position.2)
134                .with_scale(scale.0, scale.1, scale.2),
135        );
136        let renderable = universe.world.add_component(RenderableComponent::cube());
137        let color = universe
138            .world
139            .add_component(ColorComponent::rgba(color.0, color.1, color.2, color.3));
140
141        let _ = universe.attach(transform, renderable);
142        let _ = universe.attach(renderable, color);
143
144        universe.add(transform);
145    };
146
147    // floor
148    spawn_cube(
149        &mut universe,
150        (0.0, -0.05, 0.0),
151        (10.0, 0.1, 10.0),
152        (0.92, 0.92, 0.92, 1.0),
153    );
154
155    // back wall
156    spawn_cube(
157        &mut universe,
158        (0.0, 1.5, -5.0),
159        (10.0, 3.0, 1.0),
160        (0.95, 0.94, 0.96, 1.0),
161    );
162
163    // desk
164    spawn_cube(
165        &mut universe,
166        (0.0, 0.35, 1.0),
167        (1.0, 0.75, 0.5),
168        (0.75, 0.70, 0.65, 1.0),
169    );
170
171    let xr_root = universe
172        .world
173        .add_component(engine::ecs::component::XrComponent::on());
174    universe.add(xr_root);
175
176    universe.systems.process_commands(
177        &mut universe.world,
178        &mut universe.visuals,
179        &mut universe.render_assets,
180        &mut universe.command_queue,
181    );
182
183    universe.enable_repl();
184    engine::Windowing::run_app(universe).expect("Windowing failed");
185}
examples/gestures-and-gizmos.rs (line 69)
13fn build_gestures_and_gizmos_scene(universe: &mut engine::Universe) -> Scene {
14    use engine::ecs::component::{
15        BackgroundColorComponent, BackgroundComponent, Camera3DComponent, ColorComponent,
16        DirectionalLightComponent, InputComponent, InputTransformModeComponent, PointerComponent,
17        RaycastableComponent, RenderableComponent, TransformComponent, TransformGizmoComponent,
18    };
19    use engine::graphics::BuiltinMeshType;
20    use engine::graphics::primitives::{MaterialHandle, Renderable};
21
22    let tri_mesh = universe.render_assets.get_mesh(BuiltinMeshType::Triangle2D);
23    let cube_mesh = universe.render_assets.get_mesh(BuiltinMeshType::Cube);
24    let tetra_mesh = universe
25        .render_assets
26        .get_mesh(BuiltinMeshType::Tetrahedron);
27
28    // BackgroundColor { C.rgba }
29    let bg_color = universe
30        .world
31        .add_component(BackgroundColorComponent::new());
32    let bg_color_c = universe
33        .world
34        .add_component(ColorComponent::rgba(0.90, 0.90, 0.90, 1.0));
35    let _ = universe.world.add_child(bg_color, bg_color_c);
36    universe.add(bg_color);
37
38    // ambient light
39    let ambient = universe
40        .world
41        .add_component(AmbientLightComponent::rgb(0.25, 0.25, 0.25));
42    universe.add(ambient);
43
44    // ground plane
45    let ground_tx = universe.world.add_component(
46        TransformComponent::new()
47            .with_position(0.0, -2.5, 0.0)
48            .with_scale(20.0, 1.0, 20.0),
49    );
50    let ground_r = universe
51        .world
52        .add_component(RenderableComponent::new(Renderable::new(
53            universe.render_assets.get_mesh(BuiltinMeshType::Cube),
54            MaterialHandle::TOON_MESH,
55        )));
56    let ground_c = universe
57        .world
58        .add_component(ColorComponent::rgba(0.75, 0.75, 0.75, 1.0));
59    let _ = universe.attach(ground_tx, ground_r);
60    let _ = universe.attach(ground_r, ground_c);
61    let _ = universe.add(ground_tx);
62
63    // Background {
64    //     with_occlusion_and_lighting()
65    //     // using the example utils to add clouds to the background
66    // }
67    let bg_root = universe
68        .world
69        .add_component(BackgroundComponent::new().with_occlusion_and_lighting());
70    universe.add(bg_root);
71
72    // DirectionalLight {
73    //     T { translate [1, 1, 1] }
74    // }
75    // Directional lights encode their direction in the node's world position.
76    let sun_t = universe
77        .world
78        .add_component(TransformComponent::new().with_position(1.0, 1.0, 1.0));
79    let sun = universe
80        .world
81        .add_component(DirectionalLightComponent::new());
82    let _ = universe.attach(sun_t, sun);
83    universe.add(sun_t);
84
85    // i = input
86    // t = transform
87    // c3d = camera3d
88    //
89    // I {
90    //     T {
91    //         C3D { with_fps_rotation().with_roll_axis_y() }
92    //     }
93    // }
94    let input = universe
95        .world
96        .add_component(InputComponent::new().with_speed(2.5));
97    let input_mode = universe.world.add_component(
98        InputTransformModeComponent::forward_z()
99            .with_fps_rotation()
100            .with_roll_axis_y(),
101    );
102
103    let _ = universe.attach(input, input_mode);
104
105    // Forward is -Z, so put the camera at +Z looking toward the origin.
106    let rig_t = universe
107        .world
108        .add_component(TransformComponent::new().with_position(0.0, 0.0, 3.5));
109    let _ = universe.attach(input, rig_t);
110
111    let cam = universe
112        .world
113        .add_component(Camera3DComponent::new().with_far(600.0).with_fov(70.0));
114    let _ = universe.attach(rig_t, cam);
115
116    // Opt-in: treat this camera rig as a pointer source.
117    let pointer = universe.world.add_component(PointerComponent::new());
118    let _ = universe.attach(cam, pointer);
119
120    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
121    example_util::spawn_desktop_camera_controls_hint(universe, rig_t);
122
123    fn spawn_shape_with_gizmo(
124        universe: &mut engine::Universe,
125        mesh: engine::graphics::primitives::CpuMeshHandle,
126        pos: [f32; 3],
127        scale: [f32; 3],
128        rot_euler: [f32; 3],
129        color: [f32; 4],
130    ) {
131        let t = universe.world.add_component(
132            TransformComponent::new()
133                .with_position(pos[0], pos[1], pos[2])
134                .with_scale(scale[0], scale[1], scale[2])
135                .with_rotation_euler(rot_euler[0], rot_euler[1], rot_euler[2]),
136        );
137        let r = universe
138            .world
139            .add_component(RenderableComponent::new(Renderable::new(
140                mesh,
141                MaterialHandle::TOON_MESH,
142            )));
143        let c = universe
144            .world
145            .add_component(ColorComponent::rgba(color[0], color[1], color[2], color[3]));
146        let rc = universe
147            .world
148            .add_component(RaycastableComponent::enabled());
149        let g = universe.world.add_component(TransformGizmoComponent::new());
150
151        let _ = universe.attach(t, r);
152        let _ = universe.attach(r, c);
153        let _ = universe.attach(r, rc);
154        let _ = universe.attach(t, g);
155
156        universe.add(t);
157    }
158
159    fn spawn_shape_raycastable_no_gizmo(
160        universe: &mut engine::Universe,
161        mesh: engine::graphics::primitives::CpuMeshHandle,
162        pos: [f32; 3],
163        scale: [f32; 3],
164        rot_euler: [f32; 3],
165        color: [f32; 4],
166    ) {
167        let t = universe.world.add_component(
168            TransformComponent::new()
169                .with_position(pos[0], pos[1], pos[2])
170                .with_scale(scale[0], scale[1], scale[2])
171                .with_rotation_euler(rot_euler[0], rot_euler[1], rot_euler[2]),
172        );
173        let r = universe
174            .world
175            .add_component(RenderableComponent::new(Renderable::new(
176                mesh,
177                MaterialHandle::TOON_MESH,
178            )));
179        let c = universe
180            .world
181            .add_component(ColorComponent::rgba(color[0], color[1], color[2], color[3]));
182        let rc = universe
183            .world
184            .add_component(RaycastableComponent::enabled());
185
186        let _ = universe.attach(t, r);
187        let _ = universe.attach(r, c);
188        let _ = universe.attach(r, rc);
189
190        universe.add(t);
191    }
192
193    spawn_shape_with_gizmo(
194        universe,
195        tri_mesh,
196        [-1.2, 0.0, 0.0],
197        [0.65, 0.65, 0.65],
198        [0.0, 0.0, 0.0],
199        [0.2, 0.9, 0.25, 1.0],
200    );
201    spawn_shape_with_gizmo(
202        universe,
203        cube_mesh,
204        [0.0, 0.0, 0.0],
205        [0.55, 0.55, 0.55],
206        [0.0, 0.0, 0.0],
207        [0.95, 0.25, 0.2, 1.0],
208    );
209    spawn_shape_with_gizmo(
210        universe,
211        tetra_mesh,
212        [1.2, 0.0, 0.0],
213        [0.7, 0.7, 0.7],
214        [0.0, 0.0, 0.0],
215        [0.2, 0.55, 1.0, 1.0],
216    );
217
218    // Standalone tetrahedron: no gizmo, but explicitly raycastable.
219    // This helps isolate tetra picking vs gizmo-handle interception.
220    spawn_shape_raycastable_no_gizmo(
221        universe,
222        tetra_mesh,
223        [2.6, -0.6, 0.0],
224        [0.95, 0.95, 0.95],
225        [0.0, 0.0, 0.0],
226        [0.85, 0.85, 1.0, 1.0],
227    );
228
229    universe.add(input);
230
231    Scene { bg_root }
232}
examples/background-example.rs (line 84)
20fn main() {
21    mittens_engine::example_support::ensure_model_assets();
22    utils::logger::init();
23
24    let world = engine::ecs::World::default();
25    let mut universe = engine::Universe::new(world);
26
27    // Dark-ish background clear color so the effect reads.
28    let clear = universe
29        .world
30        .add_component(engine::ecs::component::BackgroundColorComponent::new());
31    let clear_c = universe
32        .world
33        .add_component(engine::ecs::component::ColorComponent::rgba(
34            0.01, 0.01, 0.02, 1.0,
35        ));
36    let _ = universe.world.add_child(clear, clear_c);
37    universe.add(clear);
38
39    // --- Camera rig (WASD/QE) ---
40    let input = universe
41        .world
42        .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
43    let input_mode = universe.world.add_component(
44        engine::ecs::component::InputTransformModeComponent::forward_z().with_roll_axis_y(),
45    );
46    let _ = universe.attach(input, input_mode);
47
48    // Start pulled back so both background + foreground are in view.
49    let rig_transform = universe.world.add_component(
50        engine::ecs::component::TransformComponent::new().with_position(0.0, 1.0, 6.0),
51    );
52    let _ = universe.attach(input, rig_transform);
53
54    let camera3d = universe
55        .world
56        .add_component(engine::ecs::component::Camera3DComponent::new());
57    let _ = universe.attach(rig_transform, camera3d);
58
59    // Simple light for toon-shaded foreground.
60    let light = universe.world.add_component(
61        engine::ecs::component::PointLightComponent::new()
62            .with_distance(50.0)
63            .with_color(1.0, 1.0, 1.0),
64    );
65    let light_transform = universe.world.add_component(
66        engine::ecs::component::TransformComponent::new().with_position(0.0, 6.0, 2.0),
67    );
68    let _ = universe.attach(light_transform, light);
69
70    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
71    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
72
73    universe.add(input);
74    universe.add(light_transform);
75
76    let cube_mesh = universe
77        .render_assets
78        .get_mesh(engine::graphics::BuiltinMeshType::Cube);
79
80    // --- Background world ---
81    // Any renderables under this node will go through the background draw list.
82    let bg_root = universe
83        .world
84        .add_component(engine::ecs::component::BackgroundComponent::new());
85    universe.add(bg_root);
86
87    // A large thin "ground" plane in the background layer.
88    // (Using a scaled cube for now; visually it's a plane.)
89    let ground_tx = universe.world.add_component(
90        engine::ecs::component::TransformComponent::new()
91            .with_position(0.0, -40.0, 0.0)
92            .with_scale(200.0, 1.0, 200.0),
93    );
94    let ground_renderable =
95        universe
96            .world
97            .add_component(engine::ecs::component::RenderableComponent::new(
98                engine::graphics::primitives::Renderable::new(
99                    cube_mesh,
100                    engine::graphics::primitives::MaterialHandle::UNLIT_MESH,
101                ),
102            ));
103    let ground_color = universe
104        .world
105        .add_component(engine::ecs::component::ColorComponent::rgba(
106            0.015, 0.02, 0.03, 1.0,
107        ));
108
109    let _ = universe.attach(bg_root, ground_tx);
110    let _ = universe.attach(ground_tx, ground_renderable);
111    let _ = universe.attach(ground_renderable, ground_color);
112
113    // Add some bright "stars" (small unlit cubes) scattered on a sphere.
114    // Use a grid + jitter + conditional skip so the distribution looks more even.
115    let lat_steps: u32 = 24;
116    let lon_steps: u32 = 48;
117    let density: f32 = 0.14;
118    let radius = 25.0;
119
120    for lat in 0..lat_steps {
121        for lon in 0..lon_steps {
122            let cell = lon + lat * lon_steps;
123            if rand01(cell ^ 0x5a1d_c0de) > density {
124                continue;
125            }
126
127            // Jitter within the cell.
128            let jx = rand01(cell ^ 0xA341_316C) - 0.5;
129            let jy = rand01(cell ^ 0xC801_3EA4) - 0.5;
130
131            // Latitude in [-pi/2, +pi/2], longitude in [0, 2pi).
132            let lat_t = (lat as f32 + 0.5 + 0.9 * jy) / (lat_steps as f32);
133            let lon_t = (lon as f32 + 0.5 + 0.9 * jx) / (lon_steps as f32);
134            let phi = (lat_t - 0.5) * std::f32::consts::PI; // [-pi/2,+pi/2]
135            let theta = lon_t * std::f32::consts::TAU;
136
137            let x = phi.cos() * theta.cos();
138            let y = phi.sin();
139            let z = phi.cos() * theta.sin();
140
141            let px = x * radius;
142            let py = y * radius;
143            let pz = z * radius;
144
145            let scale = 0.12 + rand01(cell.wrapping_add(12345)) * 0.20;
146
147            let tx = universe.world.add_component(
148                engine::ecs::component::TransformComponent::new()
149                    .with_position(px, py, pz)
150                    .with_scale(scale, scale, scale),
151            );
152            let renderable =
153                universe
154                    .world
155                    .add_component(engine::ecs::component::RenderableComponent::new(
156                        engine::graphics::primitives::Renderable::new(
157                            cube_mesh,
158                            engine::graphics::primitives::MaterialHandle::UNLIT_MESH,
159                        ),
160                    ));
161
162            let c = 0.75 + rand01(cell.wrapping_mul(3)) * 0.25;
163            let color = universe
164                .world
165                .add_component(engine::ecs::component::ColorComponent::rgba(c, c, c, 1.0));
166
167            let _ = universe.attach(bg_root, tx);
168            let _ = universe.attach(tx, renderable);
169            let _ = universe.attach(renderable, color);
170        }
171    }
172
173    // --- Foreground world ---
174    // A small cube field that should parallax as you move.
175    let fg_root = universe.world.add_component(
176        engine::ecs::component::TransformComponent::new().with_position(0.0, 0.0, 0.0),
177    );
178
179    let n: i32 = 8;
180    let step: f32 = 0.8;
181    for z in 0..n {
182        for x in 0..n {
183            let px = (x - n / 2) as f32 * step;
184            let pz = -(z as f32) * step;
185
186            let tx = universe.world.add_component(
187                engine::ecs::component::TransformComponent::new()
188                    .with_position(px, 0.5, pz)
189                    .with_scale(0.25, 0.25, 0.25),
190            );
191            let renderable =
192                universe
193                    .world
194                    .add_component(engine::ecs::component::RenderableComponent::new(
195                        engine::graphics::primitives::Renderable::new(
196                            cube_mesh,
197                            engine::graphics::primitives::MaterialHandle::TOON_MESH,
198                        ),
199                    ));
200
201            let fx = (x as f32) / ((n - 1) as f32);
202            let fz = (z as f32) / ((n - 1) as f32);
203            let color = universe
204                .world
205                .add_component(engine::ecs::component::ColorComponent::rgba(
206                    0.2 + 0.8 * fx,
207                    0.2 + 0.8 * (1.0 - fz),
208                    0.4,
209                    1.0,
210                ));
211
212            let _ = universe.attach(fg_root, tx);
213            let _ = universe.attach(tx, renderable);
214            let _ = universe.attach(renderable, color);
215        }
216    }
217
218    universe.add(fg_root);
219
220    universe.systems.process_commands(
221        &mut universe.world,
222        &mut universe.visuals,
223        &mut universe.render_assets,
224        &mut universe.command_queue,
225    );
226
227    universe.enable_repl();
228    engine::Windowing::run_app(universe).expect("Windowing failed");
229}
Source

pub fn with_occlusion_and_lighting(self) -> Self

Examples found in repository?
examples/vtuber-mirror-example.rs (line 110)
77fn main() {
78    mittens_engine::example_support::ensure_model_assets();
79    utils::logger::init();
80
81    let output = scripting::MeowMeowRunner::eval(include_str!("vtuber-mirror-example.mms"));
82
83    for error in &output.errors {
84        eprintln!("[mms] {error}");
85    }
86    println!(
87        "[mms] {} intent(s) from vtuber-mirror-example.mms",
88        output.intents.len()
89    );
90    println!(
91        "[vtuber-mirror-example] expected XR-only views: 2 XR eye views plus mirror-derived views; no desktop scene view unless a Camera3D/Camera2D is added"
92    );
93
94    let world = engine::ecs::World::default();
95    let mut universe = engine::Universe::new(world);
96
97    let scope = engine::ecs::ComponentId::default();
98    for intent in output.intents {
99        universe.command_queue.push_intent_now(scope, intent);
100    }
101
102    universe.systems.process_commands(
103        &mut universe.world,
104        &mut universe.visuals,
105        &mut universe.render_assets,
106        &mut universe.command_queue,
107    );
108
109    let bg_root = universe.world.add_component(
110        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
111    );
112    universe.add(bg_root);
113
114    let cloud_params = example_util::CloudRingParams {
115        cloud_count: 10,
116        radius: 34.0,
117        center_y: 8.5,
118        puffs_per_cloud: 28,
119        angle_jitter: 0.30,
120        high_y_probability: 0.45,
121        high_y_multiplier: 1.28,
122        seed: 0x57_55_B0_0Au32,
123    };
124    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
125
126    for kind in [
127        SignalKind::DragStart,
128        SignalKind::DragMove,
129        SignalKind::DragEnd,
130        SignalKind::Click,
131    ] {
132        universe
133            .systems
134            .rx
135            .add_global_handler(kind, on_xr_pointer_event);
136    }
137
138    universe.enable_repl();
139    engine::Windowing::run_app(universe).expect("Windowing failed");
140}
More examples
Hide additional examples
examples/vtuber-editor-example.rs (line 111)
77fn main() {
78    mittens_engine::example_support::ensure_model_assets();
79    utils::logger::init();
80
81    let output = scripting::MeowMeowRunner::eval(include_str!("vtuber-editor-example.mms"));
82
83    for error in &output.errors {
84        eprintln!("[mms] {error}");
85    }
86    println!(
87        "[mms] {} intent(s) from vtuber-editor-example.mms",
88        output.intents.len()
89    );
90    println!(
91        "[vtuber-editor-example] expected XR-only views: 2 XR eye views plus mirror-derived views; no desktop scene view unless a Camera3D/Camera2D is added"
92    );
93
94    let world = engine::ecs::World::default();
95
96    let mut universe = engine::Universe::new(world);
97
98    let scope = engine::ecs::ComponentId::default();
99    for intent in output.intents {
100        universe.command_queue.push_intent_now(scope, intent);
101    }
102
103    universe.systems.process_commands(
104        &mut universe.world,
105        &mut universe.visuals,
106        &mut universe.render_assets,
107        &mut universe.command_queue,
108    );
109
110    let bg_root = universe.world.add_component(
111        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
112    );
113    universe.add(bg_root);
114
115    let cloud_params = example_util::CloudRingParams {
116        cloud_count: 10,
117        radius: 34.0,
118        center_y: 8.5,
119        puffs_per_cloud: 28,
120        angle_jitter: 0.30,
121        high_y_probability: 0.45,
122        high_y_multiplier: 1.28,
123        seed: 0x57_55_B0_0Au32,
124    };
125    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
126
127    for kind in [
128        SignalKind::DragStart,
129        SignalKind::DragMove,
130        SignalKind::DragEnd,
131        SignalKind::Click,
132    ] {
133        universe
134            .systems
135            .rx
136            .add_global_handler(kind, on_xr_pointer_event);
137    }
138
139    universe.enable_repl();
140    engine::Windowing::run_app(universe).expect("Windowing failed");
141}
examples/vtuber-example.rs (line 115)
11fn main() {
12    mittens_engine::example_support::ensure_model_assets();
13    utils::logger::init();
14
15    let world = engine::ecs::World::default();
16    let mut universe = engine::Universe::new(world);
17
18    // Light pink background.
19    let background = universe
20        .world
21        .add_component(BackgroundColorComponent::new());
22    let background_c = universe
23        .world
24        .add_component(ColorComponent::rgba(1.0, 0.82, 0.90, 1.0));
25    let _ = universe.world.add_child(background, background_c);
26    universe.add(background);
27
28    // Small ambient so shadowed areas aren't pure black.
29    let ambient = universe
30        .world
31        .add_component(AmbientLightComponent::rgb(0.10, 0.10, 0.12));
32    universe.add(ambient);
33
34    // --- Camera rig (WASD + mouse) ---
35    // InputComponent is the root, and it owns a Transform (the camera rig).
36    let input = universe
37        .world
38        .add_component(InputComponent::new().with_speed(1.5));
39    let input_mode = universe.world.add_component(
40        InputTransformModeComponent::forward_z()
41            .with_fps_rotation()
42            .with_roll_axis_y(),
43    );
44    let _ = universe.attach(input, input_mode);
45
46    // Start slightly pulled back looking towards the origin.
47    let rig_transform = universe
48        .world
49        .add_component(TransformComponent::new().with_position(0.0, 0.0, 6.0));
50    let _ = universe.attach(input, rig_transform);
51
52    let camera3d = universe.world.add_component(Camera3DComponent::new());
53    let _ = universe.attach(rig_transform, camera3d);
54
55    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
56    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
57
58    universe.add(input);
59
60    // --- lighting ---
61    // Directional key light (slightly down + forward Z).
62    let sun = universe.world.add_component(
63        DirectionalLightComponent::new()
64            .with_intensity(1.2)
65            .with_color(1.0, 0.98, 0.94),
66    );
67    let sun_dir = universe
68        .world
69        .add_component(TransformComponent::new().with_position(0.0, -0.35, 1.0));
70    let _ = universe.attach(sun_dir, sun);
71    universe.add(sun_dir);
72
73    let light_transform = universe.world.add_component(
74        TransformComponent::new()
75            .with_position(1.0, 6.0, 3.0)
76            .with_scale(0.1, 0.1, 0.1),
77    );
78    let light = universe.world.add_component(
79        engine::ecs::component::PointLightComponent::new()
80            .with_distance(120.0)
81            .with_color(1.0, 1.0, 1.0),
82    );
83    let _ = universe.attach(light_transform, light);
84    universe.add(light_transform);
85
86    // --- VTuber model ---
87    let model_root = universe.world.add_component(TransformComponent::new());
88    let model = universe
89        .world
90        .add_component(GLTFComponent::new("assets/models/pc-rei.hoodie.glb"));
91    // emissive for pc-rei
92    let emissive = universe
93        .world
94        .add_component(engine::ecs::component::EmissiveComponent::on());
95
96    let _ = universe.attach(model, emissive);
97
98    let xr_input = universe.world.add_component(InputXRComponent::on());
99    let xr_gamepad = universe
100        .world
101        .add_component(engine::ecs::component::InputXRGamepadComponent::new().speed(1.5));
102    let xr_head = universe.world.add_component(TransformComponent::new());
103    let xr_camera = universe.world.add_component(CameraXRComponent::on());
104    let _ = universe.attach(xr_input, xr_head);
105    let _ = universe.attach(xr_input, xr_gamepad);
106    let _ = universe.attach(xr_head, xr_camera);
107    let _ = universe.attach(xr_head, model_root);
108
109    let _ = universe.attach(model_root, model);
110    universe.add(xr_input);
111    universe.add(model_root);
112
113    // --- Background clouds (occluded + lit) ---
114    let bg_root = universe.world.add_component(
115        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
116    );
117    universe.add(bg_root);
118    let mut cloud_params = example_util::CloudRingParams::default();
119    cloud_params.cloud_count = 8; // +3 clusters
120    cloud_params.angle_jitter = 0.35;
121    cloud_params.high_y_probability = 0.5;
122    cloud_params.high_y_multiplier = 1.5;
123    cloud_params.seed = 0x57_55_B0_01u32;
124    example_util::spawn_cloud_ring(&mut universe, bg_root, cloud_params);
125
126    // --- Simple environment ---
127    let spawn_cube = |universe: &mut engine::Universe,
128                      position: (f32, f32, f32),
129                      scale: (f32, f32, f32),
130                      color: (f32, f32, f32, f32)| {
131        let transform = universe.world.add_component(
132            TransformComponent::new()
133                .with_position(position.0, position.1, position.2)
134                .with_scale(scale.0, scale.1, scale.2),
135        );
136        let renderable = universe.world.add_component(RenderableComponent::cube());
137        let color = universe
138            .world
139            .add_component(ColorComponent::rgba(color.0, color.1, color.2, color.3));
140
141        let _ = universe.attach(transform, renderable);
142        let _ = universe.attach(renderable, color);
143
144        universe.add(transform);
145    };
146
147    // floor
148    spawn_cube(
149        &mut universe,
150        (0.0, -0.05, 0.0),
151        (10.0, 0.1, 10.0),
152        (0.92, 0.92, 0.92, 1.0),
153    );
154
155    // back wall
156    spawn_cube(
157        &mut universe,
158        (0.0, 1.5, -5.0),
159        (10.0, 3.0, 1.0),
160        (0.95, 0.94, 0.96, 1.0),
161    );
162
163    // desk
164    spawn_cube(
165        &mut universe,
166        (0.0, 0.35, 1.0),
167        (1.0, 0.75, 0.5),
168        (0.75, 0.70, 0.65, 1.0),
169    );
170
171    let xr_root = universe
172        .world
173        .add_component(engine::ecs::component::XrComponent::on());
174    universe.add(xr_root);
175
176    universe.systems.process_commands(
177        &mut universe.world,
178        &mut universe.visuals,
179        &mut universe.render_assets,
180        &mut universe.command_queue,
181    );
182
183    universe.enable_repl();
184    engine::Windowing::run_app(universe).expect("Windowing failed");
185}
examples/gestures-and-gizmos.rs (line 69)
13fn build_gestures_and_gizmos_scene(universe: &mut engine::Universe) -> Scene {
14    use engine::ecs::component::{
15        BackgroundColorComponent, BackgroundComponent, Camera3DComponent, ColorComponent,
16        DirectionalLightComponent, InputComponent, InputTransformModeComponent, PointerComponent,
17        RaycastableComponent, RenderableComponent, TransformComponent, TransformGizmoComponent,
18    };
19    use engine::graphics::BuiltinMeshType;
20    use engine::graphics::primitives::{MaterialHandle, Renderable};
21
22    let tri_mesh = universe.render_assets.get_mesh(BuiltinMeshType::Triangle2D);
23    let cube_mesh = universe.render_assets.get_mesh(BuiltinMeshType::Cube);
24    let tetra_mesh = universe
25        .render_assets
26        .get_mesh(BuiltinMeshType::Tetrahedron);
27
28    // BackgroundColor { C.rgba }
29    let bg_color = universe
30        .world
31        .add_component(BackgroundColorComponent::new());
32    let bg_color_c = universe
33        .world
34        .add_component(ColorComponent::rgba(0.90, 0.90, 0.90, 1.0));
35    let _ = universe.world.add_child(bg_color, bg_color_c);
36    universe.add(bg_color);
37
38    // ambient light
39    let ambient = universe
40        .world
41        .add_component(AmbientLightComponent::rgb(0.25, 0.25, 0.25));
42    universe.add(ambient);
43
44    // ground plane
45    let ground_tx = universe.world.add_component(
46        TransformComponent::new()
47            .with_position(0.0, -2.5, 0.0)
48            .with_scale(20.0, 1.0, 20.0),
49    );
50    let ground_r = universe
51        .world
52        .add_component(RenderableComponent::new(Renderable::new(
53            universe.render_assets.get_mesh(BuiltinMeshType::Cube),
54            MaterialHandle::TOON_MESH,
55        )));
56    let ground_c = universe
57        .world
58        .add_component(ColorComponent::rgba(0.75, 0.75, 0.75, 1.0));
59    let _ = universe.attach(ground_tx, ground_r);
60    let _ = universe.attach(ground_r, ground_c);
61    let _ = universe.add(ground_tx);
62
63    // Background {
64    //     with_occlusion_and_lighting()
65    //     // using the example utils to add clouds to the background
66    // }
67    let bg_root = universe
68        .world
69        .add_component(BackgroundComponent::new().with_occlusion_and_lighting());
70    universe.add(bg_root);
71
72    // DirectionalLight {
73    //     T { translate [1, 1, 1] }
74    // }
75    // Directional lights encode their direction in the node's world position.
76    let sun_t = universe
77        .world
78        .add_component(TransformComponent::new().with_position(1.0, 1.0, 1.0));
79    let sun = universe
80        .world
81        .add_component(DirectionalLightComponent::new());
82    let _ = universe.attach(sun_t, sun);
83    universe.add(sun_t);
84
85    // i = input
86    // t = transform
87    // c3d = camera3d
88    //
89    // I {
90    //     T {
91    //         C3D { with_fps_rotation().with_roll_axis_y() }
92    //     }
93    // }
94    let input = universe
95        .world
96        .add_component(InputComponent::new().with_speed(2.5));
97    let input_mode = universe.world.add_component(
98        InputTransformModeComponent::forward_z()
99            .with_fps_rotation()
100            .with_roll_axis_y(),
101    );
102
103    let _ = universe.attach(input, input_mode);
104
105    // Forward is -Z, so put the camera at +Z looking toward the origin.
106    let rig_t = universe
107        .world
108        .add_component(TransformComponent::new().with_position(0.0, 0.0, 3.5));
109    let _ = universe.attach(input, rig_t);
110
111    let cam = universe
112        .world
113        .add_component(Camera3DComponent::new().with_far(600.0).with_fov(70.0));
114    let _ = universe.attach(rig_t, cam);
115
116    // Opt-in: treat this camera rig as a pointer source.
117    let pointer = universe.world.add_component(PointerComponent::new());
118    let _ = universe.attach(cam, pointer);
119
120    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
121    example_util::spawn_desktop_camera_controls_hint(universe, rig_t);
122
123    fn spawn_shape_with_gizmo(
124        universe: &mut engine::Universe,
125        mesh: engine::graphics::primitives::CpuMeshHandle,
126        pos: [f32; 3],
127        scale: [f32; 3],
128        rot_euler: [f32; 3],
129        color: [f32; 4],
130    ) {
131        let t = universe.world.add_component(
132            TransformComponent::new()
133                .with_position(pos[0], pos[1], pos[2])
134                .with_scale(scale[0], scale[1], scale[2])
135                .with_rotation_euler(rot_euler[0], rot_euler[1], rot_euler[2]),
136        );
137        let r = universe
138            .world
139            .add_component(RenderableComponent::new(Renderable::new(
140                mesh,
141                MaterialHandle::TOON_MESH,
142            )));
143        let c = universe
144            .world
145            .add_component(ColorComponent::rgba(color[0], color[1], color[2], color[3]));
146        let rc = universe
147            .world
148            .add_component(RaycastableComponent::enabled());
149        let g = universe.world.add_component(TransformGizmoComponent::new());
150
151        let _ = universe.attach(t, r);
152        let _ = universe.attach(r, c);
153        let _ = universe.attach(r, rc);
154        let _ = universe.attach(t, g);
155
156        universe.add(t);
157    }
158
159    fn spawn_shape_raycastable_no_gizmo(
160        universe: &mut engine::Universe,
161        mesh: engine::graphics::primitives::CpuMeshHandle,
162        pos: [f32; 3],
163        scale: [f32; 3],
164        rot_euler: [f32; 3],
165        color: [f32; 4],
166    ) {
167        let t = universe.world.add_component(
168            TransformComponent::new()
169                .with_position(pos[0], pos[1], pos[2])
170                .with_scale(scale[0], scale[1], scale[2])
171                .with_rotation_euler(rot_euler[0], rot_euler[1], rot_euler[2]),
172        );
173        let r = universe
174            .world
175            .add_component(RenderableComponent::new(Renderable::new(
176                mesh,
177                MaterialHandle::TOON_MESH,
178            )));
179        let c = universe
180            .world
181            .add_component(ColorComponent::rgba(color[0], color[1], color[2], color[3]));
182        let rc = universe
183            .world
184            .add_component(RaycastableComponent::enabled());
185
186        let _ = universe.attach(t, r);
187        let _ = universe.attach(r, c);
188        let _ = universe.attach(r, rc);
189
190        universe.add(t);
191    }
192
193    spawn_shape_with_gizmo(
194        universe,
195        tri_mesh,
196        [-1.2, 0.0, 0.0],
197        [0.65, 0.65, 0.65],
198        [0.0, 0.0, 0.0],
199        [0.2, 0.9, 0.25, 1.0],
200    );
201    spawn_shape_with_gizmo(
202        universe,
203        cube_mesh,
204        [0.0, 0.0, 0.0],
205        [0.55, 0.55, 0.55],
206        [0.0, 0.0, 0.0],
207        [0.95, 0.25, 0.2, 1.0],
208    );
209    spawn_shape_with_gizmo(
210        universe,
211        tetra_mesh,
212        [1.2, 0.0, 0.0],
213        [0.7, 0.7, 0.7],
214        [0.0, 0.0, 0.0],
215        [0.2, 0.55, 1.0, 1.0],
216    );
217
218    // Standalone tetrahedron: no gizmo, but explicitly raycastable.
219    // This helps isolate tetra picking vs gizmo-handle interception.
220    spawn_shape_raycastable_no_gizmo(
221        universe,
222        tetra_mesh,
223        [2.6, -0.6, 0.0],
224        [0.95, 0.95, 0.95],
225        [0.0, 0.0, 0.0],
226        [0.85, 0.85, 1.0, 1.0],
227    );
228
229    universe.add(input);
230
231    Scene { bg_root }
232}
examples/background-occlusion-example.rs (line 121)
19fn main() {
20    mittens_engine::example_support::ensure_model_assets();
21    utils::logger::init();
22
23    let world = engine::ecs::World::default();
24    let mut universe = engine::Universe::new(world);
25
26    // Light purple-red background so the occlusion reads.
27    let clear = universe
28        .world
29        .add_component(engine::ecs::component::BackgroundColorComponent::new());
30    let clear_c = universe
31        .world
32        .add_component(engine::ecs::component::ColorComponent::rgba(
33            0.62, 0.38, 0.56, 1.0,
34        ));
35    let _ = universe.world.add_child(clear, clear_c);
36    universe.add(clear);
37
38    // A bit of ambient so the cluster volume reads.
39    let ambient = universe
40        .world
41        .add_component(engine::ecs::component::AmbientLightComponent::rgb(
42            0.20, 0.15, 0.3,
43        ));
44    universe.add(ambient);
45
46    // --- Camera rig (WASD/QE) ---
47    let input = universe
48        .world
49        .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
50    let input_mode = universe.world.add_component(
51        engine::ecs::component::InputTransformModeComponent::forward_z().with_roll_axis_y(),
52    );
53    let _ = universe.attach(input, input_mode);
54
55    let rig_transform = universe.world.add_component(
56        engine::ecs::component::TransformComponent::new().with_position(0.0, 0.0, 6.0),
57    );
58    let _ = universe.attach(input, rig_transform);
59
60    let camera3d = universe.world.add_component(
61        engine::ecs::component::Camera3DComponent::new()
62            .with_far(200.0)
63            .with_fov(70.0),
64    );
65    let _ = universe.attach(rig_transform, camera3d);
66
67    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
68    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
69
70    // Key directional light toward the cloud volume.
71    //
72    // Directional lights encode their direction in the node's world position.
73    // The shader normalizes this vector.
74    let sun = universe.world.add_component(
75        engine::ecs::component::DirectionalLightComponent::new()
76            .with_intensity(1.6)
77            .with_color(1.0, 0.98, 0.92),
78    );
79    // Pointing from the clouds back toward the camera a bit (+Z), and slightly from above.
80    let sun_dir = universe.world.add_component(
81        engine::ecs::component::TransformComponent::new().with_position(0.15, 0.65, 0.75),
82    );
83    let _ = universe.attach(sun_dir, sun);
84
85    // A couple point lights to fill/shade the cloud volume.
86    let light_a = universe.world.add_component(
87        engine::ecs::component::PointLightComponent::new()
88            .with_distance(80.0)
89            .with_intensity(3.0)
90            .with_color(0.9, 0.95, 1.0),
91    );
92    let light_a_tx = universe.world.add_component(
93        engine::ecs::component::TransformComponent::new().with_position(8.0, 8.0, 5.0),
94    );
95    let _ = universe.attach(light_a_tx, light_a);
96
97    let light_b = universe.world.add_component(
98        engine::ecs::component::PointLightComponent::new()
99            .with_distance(80.0)
100            .with_intensity(2.2)
101            .with_color(1.0, 0.9, 0.85),
102    );
103    let light_b_tx = universe.world.add_component(
104        engine::ecs::component::TransformComponent::new().with_position(-10.0, 4.0, -6.0),
105    );
106    let _ = universe.attach(light_b_tx, light_b);
107
108    universe.add(input);
109    universe.add(sun_dir);
110    universe.add(light_a_tx);
111    universe.add(light_b_tx);
112
113    let cube_mesh = universe
114        .render_assets
115        .get_mesh(engine::graphics::BuiltinMeshType::Cube);
116
117    // --- Background occluded+lit world ---
118    // Renderables under this node participate in a background stage that depth-writes for
119    // self-occlusion + uses the normal lighting shader inputs.
120    let bg_root = universe.world.add_component(
121        engine::ecs::component::BackgroundComponent::new().with_occlusion_and_lighting(),
122    );
123    universe.add(bg_root);
124
125    // Create overlapping cube clusters like cloud puffs.
126    // Place them generally in front of the camera (negative Z).
127    // Spawn two groups on opposite X sides.
128    let cluster_count: u32 = 9;
129    for (group_i, group_x) in [-16.0_f32, 16.0_f32].into_iter().enumerate() {
130        let group_tx = universe.world.add_component(
131            engine::ecs::component::TransformComponent::new().with_position(group_x, 0.0, 0.0),
132        );
133        let _ = universe.attach(bg_root, group_tx);
134
135        for cluster_i in 0..cluster_count {
136            let seed = (0xC10u32 ^ (group_i as u32).wrapping_mul(0x9E37_79B9))
137                ^ (cluster_i.wrapping_mul(7919));
138
139            let cx = (rand01(seed ^ 0xA341_316C) - 0.5) * 18.0;
140            let cy = (rand01(seed ^ 0xC801_3EA4) - 0.5) * 10.0 + 2.0;
141            let cz = -18.0 - rand01(seed ^ 0xB529_7A4D) * 26.0;
142
143            let center_tx = universe.world.add_component(
144                engine::ecs::component::TransformComponent::new().with_position(cx, cy, cz),
145            );
146            let _ = universe.attach(group_tx, center_tx);
147
148            let puffs = 18u32;
149            for puff_i in 0..puffs {
150                let puff_seed = seed ^ puff_i.wrapping_mul(1_103_515_245);
151
152                // Slightly ellipsoidal distribution.
153                let ox = (rand01(puff_seed ^ 0x68bc_21eb) - 0.5) * 7.0;
154                let oy = (rand01(puff_seed ^ 0x02e5_be93) - 0.5) * 3.0;
155                let oz = (rand01(puff_seed ^ 0xa1d3_4f2b) - 0.5) * 7.0;
156
157                let base = 0.7 + rand01(puff_seed ^ 0x9e37_79b9) * 2.6;
158                let sx = base * (0.7 + rand01(puff_seed ^ 0x243f_6a88) * 0.8);
159                let sy = base * (0.6 + rand01(puff_seed ^ 0x85a3_08d3) * 0.9);
160                let sz = base * (0.7 + rand01(puff_seed ^ 0x1319_8a2e) * 0.8);
161
162                let tx = universe.world.add_component(
163                    engine::ecs::component::TransformComponent::new()
164                        .with_position(ox, oy, oz)
165                        .with_scale(sx, sy, sz),
166                );
167                let renderable =
168                    universe
169                        .world
170                        .add_component(engine::ecs::component::RenderableComponent::new(
171                            engine::graphics::primitives::Renderable::new(
172                                cube_mesh,
173                                engine::graphics::primitives::MaterialHandle::TOON_MESH,
174                            ),
175                        ));
176
177                // Slight blue-grey variation.
178                let t = rand01(puff_seed ^ 0x7f4a_7c15);
179                let r = 0.55 + 0.10 * t;
180                let g = 0.58 + 0.10 * t;
181                let b = 0.66 + 0.12 * t;
182                let color = universe
183                    .world
184                    .add_component(engine::ecs::component::ColorComponent::rgba(r, g, b, 1.0));
185
186                let _ = universe.attach(center_tx, tx);
187                let _ = universe.attach(tx, renderable);
188                let _ = universe.attach(renderable, color);
189            }
190        }
191    }
192
193    // Foreground reference cube (should never be occluded by background depth).
194    let fg_tx = universe.world.add_component(
195        engine::ecs::component::TransformComponent::new()
196            .with_position(0.0, -0.5, -4.0)
197            .with_scale(1.2, 0.8, 1.2),
198    );
199    let fg_renderable =
200        universe
201            .world
202            .add_component(engine::ecs::component::RenderableComponent::new(
203                engine::graphics::primitives::Renderable::new(
204                    cube_mesh,
205                    engine::graphics::primitives::MaterialHandle::TOON_MESH,
206                ),
207            ));
208    let fg_color = universe
209        .world
210        .add_component(engine::ecs::component::ColorComponent::rgba(
211            0.9, 0.2, 0.2, 1.0,
212        ));
213
214    universe.add(fg_tx);
215    let _ = universe.attach(fg_tx, fg_renderable);
216    let _ = universe.attach(fg_renderable, fg_color);
217
218    // Foreground opaque floor: 16x16 larger white cubes, 10 units below the reference cube.
219    let floor_root = universe.world.add_component(
220        engine::ecs::component::TransformComponent::new().with_position(0.0, -10.5, -10.0),
221    );
222    universe.add(floor_root);
223
224    let spacing = 10_f32;
225    let half = 5_f32;
226    for x in 0..16u32 {
227        for z in 0..64u32 {
228            let px = (x as f32 - half) * spacing;
229            let pz = (z as f32 * -1.0 + half) * spacing;
230            let tx = universe.world.add_component(
231                engine::ecs::component::TransformComponent::new()
232                    .with_position(px, -5.0, pz)
233                    .with_scale(5.0, 0.5, 5.0),
234            );
235            let renderable =
236                universe
237                    .world
238                    .add_component(engine::ecs::component::RenderableComponent::new(
239                        engine::graphics::primitives::Renderable::new(
240                            cube_mesh,
241                            engine::graphics::primitives::MaterialHandle::TOON_MESH,
242                        ),
243                    ));
244            let color = universe
245                .world
246                .add_component(engine::ecs::component::ColorComponent::rgba(
247                    1.0, 1.0, 1.0, 1.0,
248                ));
249
250            let _ = universe.attach(floor_root, tx);
251            let _ = universe.attach(tx, renderable);
252            let _ = universe.attach(renderable, color);
253        }
254    }
255
256    universe.systems.process_commands(
257        &mut universe.world,
258        &mut universe.visuals,
259        &mut universe.render_assets,
260        &mut universe.command_queue,
261    );
262
263    universe.enable_repl();
264    engine::Windowing::run_app(universe).expect("Windowing failed");
265}
examples/font-example.rs (line 52)
13fn main() {
14    mittens_engine::example_support::ensure_model_assets();
15    utils::logger::init();
16
17    let world = engine::ecs::World::default();
18    let mut universe = engine::Universe::new(world);
19
20    // Dark background so the font texture pops.
21    let background = universe
22        .world
23        .add_component(BackgroundColorComponent::new());
24    let background_c = universe
25        .world
26        .add_component(ColorComponent::rgba(0.20, 0.2, 0.20, 1.0));
27    let _ = universe.world.add_child(background, background_c);
28    universe.add(background);
29
30    // Ambient so text is readable even without explicit lights.
31    let ambient = universe
32        .world
33        .add_component(AmbientLightComponent::rgb(0.50, 0.50, 0.50));
34    universe.add(ambient);
35
36    let directional_tx = universe
37        .world
38        .add_component(TransformComponent::new().with_position(0.0, 0.5, 1.0));
39    let directional_light = universe.world.add_component(
40        engine::ecs::component::DirectionalLightComponent::new()
41            .with_color(1.0, 1.0, 1.0)
42            .with_intensity(0.8),
43    );
44    let _ = universe.attach(directional_tx, directional_light);
45    universe.add(directional_tx);
46
47    // --- background clouds ---
48    // Background stage (occluded + lit) so the cloud volume self-occludes but won't occlude
49    // the foreground text (renderer clears depth before foreground).
50    let bg_root = universe
51        .world
52        .add_component(BackgroundComponent::new().with_occlusion_and_lighting());
53    universe.add(bg_root);
54
55    let mut bg_cloud_params = example_util::CloudRingParams::default();
56    bg_cloud_params.cloud_count = 6;
57    bg_cloud_params.seed = 0xF0_17_C10u32;
58    example_util::spawn_cloud_ring(&mut universe, bg_root, bg_cloud_params);
59
60    // I {
61    //   // not fps rotation, just relative rotation
62    //   with_forward_z()
63    //   with_roll_axis_y()
64    //   C3D {}
65    // }
66    let input = universe
67        .world
68        .add_component(InputComponent::new().with_speed(2.0));
69    let input_mode = universe
70        .world
71        .add_component(InputTransformModeComponent::forward_z().with_roll_axis_y());
72    let _ = universe.attach(input, input_mode);
73
74    let rig_transform = universe
75        .world
76        .add_component(TransformComponent::new().with_position(1.8, -0.5, 2.5));
77    let _ = universe.attach(input, rig_transform);
78
79    let camera = universe.world.add_component(Camera3DComponent::new());
80    let _ = universe.attach(rig_transform, camera);
81
82    // Click-to-pick: treat this camera rig as a pointer source.
83    let pointer = universe.world.add_component(PointerComponent::new());
84    let _ = universe.attach(camera, pointer);
85
86    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
87    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
88
89    universe.add(input);
90
91    // --- foreground clouds ---
92    // Normal foreground renderables (not background stage).
93    // Offset the ring forward (negative Z) so several clusters are in view.
94    let fg_cloud_root = universe
95        .world
96        .add_component(TransformComponent::new().with_position(0.0, -6.0, -10.0));
97    universe.add(fg_cloud_root);
98
99    let mut fg_cloud_params = example_util::CloudRingParams::default();
100    fg_cloud_params.cloud_count = 4;
101    fg_cloud_params.radius = 9.0;
102    fg_cloud_params.center_y = 1.0;
103    fg_cloud_params.puffs_per_cloud = 22;
104    fg_cloud_params.angle_jitter = 0.35;
105    fg_cloud_params.high_y_probability = 0.35;
106    fg_cloud_params.high_y_multiplier = 1.4;
107    fg_cloud_params.seed = 0xF0_17_C102u32;
108    example_util::spawn_cloud_ring(&mut universe, fg_cloud_root, fg_cloud_params);
109
110    // T {
111    //   with_translation(0,0, -2)
112    //   TXT {
113    //     "ababaabbaabbaaabbbaaabbbaaaabbbbaaaaabbbbbababababa"
114    //     TextureComponent { assets/images/test.font_system.png }
115    //   }
116    // }
117    fn estimate_text_height_world(text: &str, scale: f32) -> f32 {
118        let line_count = text.lines().count().max(1) as f32;
119        // Text quads are ~1 unit tall per line in text-space.
120        // Add some padding so blocks don't feel cramped.
121        let pad_lines = 1.25;
122        (line_count + pad_lines) * scale
123    }
124
125    fn spawn_text_block(
126        universe: &mut engine::Universe,
127        position: (f32, f32, f32),
128        scale: f32,
129        text: &str,
130        font_texture_uri: Option<&str>,
131        text_color_rgba: Option<[f32; 4]>,
132        shadow: Option<TextShadowComponent>,
133        filtering: TextureFilteringComponent,
134    ) -> f32 {
135        // T_root { T_scale { [Color] { TXT { shadow, filtering } } } }
136        let text_root = universe.world.add_component(
137            TransformComponent::new().with_position(position.0, position.1, position.2),
138        );
139
140        let text_scale = universe
141            .world
142            .add_component(TransformComponent::new().with_scale(scale, scale, 1.0));
143        let _ = universe.attach(text_root, text_scale);
144
145        let text_parent = if let Some([r, g, b, a]) = text_color_rgba {
146            let color = universe
147                .world
148                .add_component(ColorComponent::rgba(r, g, b, a));
149            let _ = universe.attach(text_scale, color);
150            color
151        } else {
152            text_scale
153        };
154
155        let text_c = universe.world.add_component(TextComponent::new(text));
156        let _ = universe.attach(text_parent, text_c);
157
158        // Explicit opt-in: make the glyph renderables pickable.
159        // TextSystem will propagate this to all spawned glyph quads.
160        let raycastable = universe
161            .world
162            .add_component(RaycastableComponent::enabled());
163        let _ = universe.attach(text_c, raycastable);
164
165        // Route glyph quads into the alpha-to-coverage cutout pass.
166        let cutout = universe
167            .world
168            .add_component(TransparentCutoutComponent::new());
169        let _ = universe.attach(text_c, cutout);
170
171        if let Some(shadow) = shadow {
172            let shadow_id = universe.world.add_component(shadow);
173            let _ = universe.attach(text_c, shadow_id);
174        }
175
176        // Optional: override the font atlas for this text block.
177        // TextSystem will propagate this to all glyph renderables.
178        if let Some(uri) = font_texture_uri {
179            let tex = universe
180                .world
181                .add_component(TextureComponent::with_uri(uri));
182            let _ = universe.attach(text_c, tex);
183        }
184
185        let filtering_id = universe.world.add_component(filtering);
186        let _ = universe.attach(text_c, filtering_id);
187
188        universe.add(text_root);
189
190        estimate_text_height_world(text, scale)
191    }
192
193    // --- text blocks ---
194    // Multi-line samples at different scales.
195    // (Text literals omitted in the README/snippet; see constants below.)
196    const TEXT_BIG: &str = "CAT ENGINE\nfont example\nBIG TEXT";
197    const TEXT_MED: &str = "multi-line\ntext block\nmedium";
198    const TEXT_SMALL: &str = "small\ntext";
199    const TEXT_TINY: &str = "tiny\ntext\n(zoom in)";
200
201    // Stack vertically; advance by (measured height + gap) so big text gets more room.
202    let x = -1.2;
203    let z = -2.0;
204    let mut y = 1.2;
205    let gap = 0.15;
206
207    let shadow_crisp = Some(
208        TextShadowComponent::new()
209            .with_scale(1.35)
210            .with_offset([0.06, -0.06, 0.0015]),
211    );
212
213    y -= spawn_text_block(
214        &mut universe,
215        (x, y, z),
216        0.55,
217        TEXT_BIG,
218        None,
219        Some([1.0, 1.0, 1.0, 1.0]),
220        shadow_crisp,
221        TextureFilteringComponent::nearest_magnification(),
222    ) + gap;
223    y -= spawn_text_block(
224        &mut universe,
225        (x, y, z),
226        0.25,
227        TEXT_MED,
228        None,
229        Some([0.60, 0.95, 1.00, 1.0]),
230        Some(
231            TextShadowComponent::new()
232                .with_rgba([0.0, 0.0, 0.15, 1.0])
233                .with_scale(1.20)
234                .with_offset([0.05, -0.04, 0.0015]),
235        ),
236        TextureFilteringComponent::linear(),
237    ) + gap;
238    y -= spawn_text_block(
239        &mut universe,
240        (x, y, z),
241        0.14,
242        TEXT_SMALL,
243        None,
244        Some([1.0, 0.88, 0.35, 1.0]),
245        Some(
246            TextShadowComponent::new()
247                .with_rgba([0.15, 0.0, 0.0, 1.0])
248                .with_scale(1.55)
249                .with_offset([0.08, -0.08, 0.0015]),
250        ),
251        TextureFilteringComponent::nearest(),
252    ) + gap;
253    let _ = spawn_text_block(
254        &mut universe,
255        (x, y, z),
256        0.08,
257        TEXT_TINY,
258        None,
259        Some([0.90, 1.0, 0.70, 1.0]),
260        shadow_crisp,
261        TextureFilteringComponent::nearest_magnification(),
262    );
263
264    // Left block: explicit multi-line text using the default font_system atlas.
265    const TEXT_LEFT: &str = "even though there's hexes\nto the solar plexus in my lexus\ni'm feelin' reckless,\nwhen i'm eating breakfast";
266    let _ = spawn_text_block(
267        &mut universe,
268        (x - 8.1, 1.1, z),
269        0.22,
270        TEXT_LEFT,
271        Some("assets/textures/font_system.dds"),
272        Some([0.95, 0.95, 0.95, 1.0]),
273        Some(
274            TextShadowComponent::new()
275                .with_scale(1.25)
276                .with_offset([0.05, -0.05, 0.0015]),
277        ),
278        TextureFilteringComponent::nearest_magnification(),
279    );
280
281    // Alt atlas: put it *behind* the original stack (slightly farther from the camera)
282    // and tint it dark grey.
283    let alt_atlas = Some("assets/textures/font_system.0.0.dds");
284    let alt_z = z - 0.05;
285    let alt_grey = Some([0.25, 0.25, 0.25, 1.0]);
286
287    let mut y_alt = 1.2;
288    y_alt -= spawn_text_block(
289        &mut universe,
290        (x, y_alt, alt_z),
291        0.55,
292        TEXT_BIG,
293        alt_atlas,
294        alt_grey,
295        Some(
296            TextShadowComponent::new()
297                .with_rgba([0.0, 0.0, 0.0, 1.0])
298                .with_scale(1.15)
299                .with_offset([0.03, -0.03, 0.0015]),
300        ),
301        TextureFilteringComponent::linear(),
302    ) + gap;
303    y_alt -= spawn_text_block(
304        &mut universe,
305        (x, y_alt, alt_z),
306        0.25,
307        TEXT_MED,
308        alt_atlas,
309        alt_grey,
310        Some(
311            TextShadowComponent::new()
312                .with_rgba([0.0, 0.0, 0.0, 1.0])
313                .with_scale(1.15)
314                .with_offset([0.03, -0.03, 0.0015]),
315        ),
316        TextureFilteringComponent::linear(),
317    ) + gap;
318    y_alt -= spawn_text_block(
319        &mut universe,
320        (x, y_alt, alt_z),
321        0.14,
322        TEXT_SMALL,
323        alt_atlas,
324        alt_grey,
325        Some(
326            TextShadowComponent::new()
327                .with_rgba([0.0, 0.0, 0.0, 1.0])
328                .with_scale(1.15)
329                .with_offset([0.03, -0.03, 0.0015]),
330        ),
331        TextureFilteringComponent::linear(),
332    ) + gap;
333    let _ = spawn_text_block(
334        &mut universe,
335        (x, y_alt, alt_z),
336        0.08,
337        TEXT_TINY,
338        alt_atlas,
339        alt_grey,
340        Some(
341            TextShadowComponent::new()
342                .with_rgba([0.0, 0.0, 0.0, 1.0])
343                .with_scale(1.15)
344                .with_offset([0.03, -0.03, 0.0015]),
345        ),
346        TextureFilteringComponent::linear(),
347    );
348
349    universe.enable_repl();
350
351    let xr_input = universe.world.add_component(InputXRComponent::on());
352    let xr_gamepad = universe
353        .world
354        .add_component(engine::ecs::component::InputXRGamepadComponent::new().speed(1.5));
355    let xr_head = universe.world.add_component(TransformComponent::new());
356    let xr_camera = universe.world.add_component(CameraXRComponent::on());
357    let _ = universe.attach(xr_input, xr_head);
358    let _ = universe.attach(xr_input, xr_gamepad);
359    let _ = universe.attach(xr_head, xr_camera);
360    universe.add(xr_input);
361
362    // Add an OpenXR component so OpenXRSystem initializes and starts polling events.
363    let xr_root = universe
364        .world
365        .add_component(engine::ecs::component::XrComponent::on());
366    universe.add(xr_root);
367
368    // Process init-time registrations (Text expands into glyph subtrees here).
369    universe.systems.process_commands(
370        &mut universe.world,
371        &mut universe.visuals,
372        &mut universe.render_assets,
373        &mut universe.command_queue,
374    );
375
376    engine::Windowing::run_app(universe).expect("Windowing failed");
377}
Source

pub fn with_ray_casting(self) -> Self

Trait Implementations§

Source§

impl Clone for BackgroundComponent

Source§

fn clone(&self) -> BackgroundComponent

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Component for BackgroundComponent

Source§

fn as_any(&self) -> &dyn Any

Source§

fn as_any_mut(&mut self) -> &mut dyn Any

Source§

fn name(&self) -> &'static str

Short debug/type name for this component kind (e.g. “transform”, “camera”).
Source§

fn to_mms_ast(&self, _world: &World) -> ComponentExpression

Encode this component as an MMS Component Expression AST node. Read more
Source§

fn set_id(&mut self, _component: ComponentId)

Source§

fn init(&mut self, _emit: &mut dyn SignalEmitter, _component: ComponentId)

Called when component is added to the World
Source§

fn cleanup(&mut self, _emit: &mut dyn SignalEmitter, _component: ComponentId)

Called when component is removed from the World.
Source§

fn encode(&self) -> HashMap<String, Value>

Encode component data to a HashMap for serialization. Read more
Source§

fn decode(&mut self, _data: &HashMap<String, Value>) -> Result<(), String>

Decode component data from a HashMap after deserialization. Read more
Source§

impl Copy for BackgroundComponent

Source§

impl Debug for BackgroundComponent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for BackgroundComponent

Source§

fn default() -> BackgroundComponent

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more