Skip to main content

RayCastComponent

Struct RayCastComponent 

Source
pub struct RayCastComponent {
    pub mode: RayCastMode,
    pub max_distance: f32,
    pub cast_requests: u32,
    /* private fields */
}
Expand description

Ray casting request/behavior.

Semantics:

  • Attach this anywhere (commonly under a camera rig transform).
  • The RayCastSystem resolves the actual ray source from surrounding topology.
  • EventDriven means the raycaster casts only when explicitly requested, except for desktop cursor-through-camera pointers which currently auto-cast from desktop mouse input.

Fields§

§mode: RayCastMode§max_distance: f32

Max ray distance in world units.

§cast_requests: u32

Incremented by IntentValue::RequestRaycast to request a cast on this frame.

This is intentionally not serialized; it is a transient runtime signal.

Implementations§

Source§

impl RayCastComponent

Source

pub fn new(mode: RayCastMode) -> Self

Source

pub fn continuous() -> Self

Source

pub fn event_driven() -> Self

Examples found in repository?
examples/raycast-topology-animation.rs (line 284)
111fn main() {
112    mittens_engine::example_support::ensure_model_assets();
113    utils::logger::init();
114
115    let world = engine::ecs::World::default();
116    let mut universe = engine::Universe::new(world);
117
118    // Background.
119    let bg_color = universe
120        .world
121        .add_component(engine::ecs::component::BackgroundColorComponent::new());
122    let bg_color_c = universe
123        .world
124        .add_component(engine::ecs::component::ColorComponent::rgba(
125            0.1, 0.1, 0.1, 1.0,
126        ));
127    let _ = universe.world.add_child(bg_color, bg_color_c);
128    universe.add(bg_color);
129
130    // Camera rig so we can see the scene.
131    let input = universe
132        .world
133        .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
134
135    let rig_transform = universe.world.add_component(
136        engine::ecs::component::TransformComponent::new()
137            .with_position(0.0, 2.0, 8.0)
138            .with_rotation_euler(-0.25, 0.0, 0.0),
139    );
140
141    let camera3d = universe
142        .world
143        .add_component(engine::ecs::component::Camera3DComponent::new());
144
145    let input_mode = universe.world.add_component(
146        engine::ecs::component::InputTransformModeComponent::forward_z()
147            .with_roll_axis_y()
148            .with_fps_rotation(),
149    );
150
151    let _ = universe.attach(input, input_mode);
152    let _ = universe.attach(input, rig_transform);
153    let _ = universe.attach(rig_transform, camera3d);
154
155    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
156    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
157    universe.add(input);
158
159    // Two rotating anchor transforms that the raycaster will be reparented under.
160    // Each ring has its own anchor at a different height.
161    let anchor_a = universe.world.add_component(
162        engine::ecs::component::TransformComponent::new().with_position(0.0, 1.0, 0.0),
163    );
164    let anchor_b = universe.world.add_component(
165        engine::ecs::component::TransformComponent::new().with_position(0.0, 2.2, 0.0),
166    );
167
168    // Visual markers for A/B.
169    fn marker(universe: &mut engine::Universe, parent: engine::ecs::ComponentId, rgba: [f32; 4]) {
170        let r = universe
171            .world
172            .add_component(engine::ecs::component::RenderableComponent::cube());
173        let rc = universe
174            .world
175            .add_component(engine::ecs::component::RaycastableComponent::disabled());
176        let c = universe
177            .world
178            .add_component(engine::ecs::component::ColorComponent::rgba(
179                rgba[0], rgba[1], rgba[2], rgba[3],
180            ));
181        let e = universe
182            .world
183            .add_component(engine::ecs::component::EmissiveComponent::on());
184        let t = universe.world.add_component(
185            engine::ecs::component::TransformComponent::new().with_scale(0.15, 0.15, 0.15),
186        );
187        let _ = universe.attach(parent, t);
188        let _ = universe.attach(t, r);
189        let _ = universe.attach(r, rc);
190        let _ = universe.attach(r, c);
191        let _ = universe.attach(r, e);
192    }
193
194    marker(&mut universe, anchor_a, [0.9, 0.2, 0.2, 1.0]);
195    marker(&mut universe, anchor_b, [0.2, 0.2, 0.9, 1.0]);
196
197    universe.add(anchor_a);
198    universe.add(anchor_b);
199
200    // A ring of cubes around the origin to see which one gets hit.
201    fn ring_cube(
202        universe: &mut engine::Universe,
203        ring_root: engine::ecs::ComponentId,
204        x: f32,
205        y: f32,
206        z: f32,
207        rgba: [f32; 4],
208    ) {
209        let t = universe.world.add_component(
210            engine::ecs::component::TransformComponent::new()
211                .with_position(x, y, z)
212                .with_scale(0.35, 0.35, 0.35),
213        );
214        let r = universe
215            .world
216            .add_component(engine::ecs::component::RenderableComponent::cube());
217        let rc = universe
218            .world
219            .add_component(engine::ecs::component::RaycastableComponent::enabled());
220        let c = universe
221            .world
222            .add_component(engine::ecs::component::ColorComponent::rgba(
223                rgba[0], rgba[1], rgba[2], rgba[3],
224            ));
225        let _ = universe.attach(ring_root, t);
226        let _ = universe.attach(t, r);
227        let _ = universe.attach(r, rc);
228        let _ = universe.attach(r, c);
229    }
230
231    // Two rings: one per anchor height.
232    let n = 28;
233    let (radius_a, y_a) = (4.0, 1.0);
234    let (radius_b, y_b) = (2.6, 2.2);
235
236    let ring_a_root = universe
237        .world
238        .add_component(engine::ecs::component::TransformComponent::new());
239    let ring_b_root = universe
240        .world
241        .add_component(engine::ecs::component::TransformComponent::new());
242
243    for i in 0..n {
244        let a = (i as f32) * (std::f32::consts::TAU / (n as f32));
245        let (x, z) = (radius_a * a.cos(), radius_a * a.sin());
246        let color = if i % 2 == 0 {
247            [0.55, 0.20, 0.20, 1.0]
248        } else {
249            [0.20, 0.55, 0.20, 1.0]
250        };
251        ring_cube(&mut universe, ring_a_root, x, y_a, z, color);
252    }
253
254    for i in 0..n {
255        let a = (i as f32) * (std::f32::consts::TAU / (n as f32));
256        let (x, z) = (radius_b * a.cos(), radius_b * a.sin());
257        let color = if i % 2 == 0 {
258            [0.20, 0.25, 0.60, 1.0]
259        } else {
260            [0.20, 0.55, 0.55, 1.0]
261        };
262        ring_cube(&mut universe, ring_b_root, x, y_b, z, color);
263    }
264
265    // Init rings and attach scoped interaction handlers.
266    universe.add(ring_a_root);
267    universe.add(ring_b_root);
268    universe.add_signal_handler(
269        engine::ecs::SignalKind::RayIntersected,
270        ring_a_root,
271        ring_a_handler,
272    );
273    universe.add_signal_handler(
274        engine::ecs::SignalKind::RayIntersected,
275        ring_b_root,
276        ring_b_handler,
277    );
278
279    // The raycaster component we will move between parents.
280    // Source is inferred from topology:
281    // - Under transforms A/B (no camera child) => parent-forward (-Z)
282    // - Under camera rig transform (has camera child) => cursor-through-camera
283    let raycaster = universe.world.add_component(
284        engine::ecs::component::RayCastComponent::event_driven().with_max_distance(25.0),
285    );
286
287    // Global animation: move the raycaster between anchors.
288    // Loop length is 8 beats (we include a noop keyframe at beat 7.0 to force loop_len=8).
289    let anim_global = universe
290        .world
291        .add_component(engine::ecs::component::AnimationComponent::new());
292    {
293        // beat 0: attach to A.
294        let kf0 = universe
295            .world
296            .add_component(engine::ecs::component::KeyframeComponent::new(0.0));
297        let act0 = universe
298            .world
299            .add_component(engine::ecs::component::ActionComponent::new(
300                engine::ecs::IntentValue::Attach {
301                    parents: vec![anchor_a],
302                    child: raycaster,
303                },
304            ));
305        let _ = universe.attach(kf0, act0);
306        let _ = universe.attach(anim_global, kf0);
307
308        // beat 4: attach to B.
309        let kf4 = universe
310            .world
311            .add_component(engine::ecs::component::KeyframeComponent::new(4.0));
312        let act4 = universe
313            .world
314            .add_component(engine::ecs::component::ActionComponent::new(
315                engine::ecs::IntentValue::Attach {
316                    parents: vec![anchor_b],
317                    child: raycaster,
318                },
319            ));
320        let _ = universe.attach(kf4, act4);
321        let _ = universe.attach(anim_global, kf4);
322
323        // beat 7: noop to make loop_len=8.
324        let kf7 = universe
325            .world
326            .add_component(engine::ecs::component::KeyframeComponent::new(7.0));
327        let noop = universe
328            .world
329            .add_component(engine::ecs::component::ActionComponent::new(
330                engine::ecs::IntentValue::Noop,
331            ));
332        let _ = universe.attach(kf7, noop);
333        let _ = universe.attach(anim_global, kf7);
334    }
335    universe.add(anim_global);
336
337    // Ring A animation: rotate anchor A around Y (1 rev / 8 beats).
338    // Also triggers Action::raycast(raycaster) on downbeats in the first half: beats 0,1,2,3.
339    let anim_a = universe
340        .world
341        .add_component(engine::ecs::component::AnimationComponent::new());
342
343    // Ring B animation: rotate anchor B differently (yaw + pitch).
344    // Also triggers Action::raycast(raycaster) on offbeats in the second half: beats 4.5,5.5,6.5,7.5.
345    let anim_b = universe
346        .world
347        .add_component(engine::ecs::component::AnimationComponent::new());
348
349    let loop_beats = 8.0;
350    let steps = 64;
351
352    for step in 0..=steps {
353        let t = (step as f32) / (steps as f32);
354        let beat = (t as f64) * (loop_beats as f64);
355
356        // Keyframe beats are per-animation local beats.
357        let kf_a = universe
358            .world
359            .add_component(engine::ecs::component::KeyframeComponent::new(beat));
360        let kf_b = universe
361            .world
362            .add_component(engine::ecs::component::KeyframeComponent::new(beat));
363
364        // Anchor A rotation: smooth yaw.
365        let yaw_a = t * std::f32::consts::TAU;
366        let a_set = engine::ecs::component::ActionComponent::new(
367            engine::ecs::IntentValue::UpdateTransform {
368                component_ids: vec![anchor_a],
369                translation: [0.0, 1.0, 0.0],
370                rotation_quat_xyzw: quat_from_yaw(yaw_a),
371                scale: [1.0, 1.0, 1.0],
372            },
373        );
374        let a_set_id = universe.world.add_component(a_set);
375        let _ = universe.attach(kf_a, a_set_id);
376
377        // Anchor B rotation: yaw + pitch (different pattern).
378        let yaw_b = -t * std::f32::consts::TAU * 1.5;
379        let pitch_b = (t * std::f32::consts::TAU).sin() * 0.35;
380        let rot_b = quat_mul(quat_from_yaw(yaw_b), quat_from_pitch(pitch_b));
381        let b_set = engine::ecs::component::ActionComponent::new(
382            engine::ecs::IntentValue::UpdateTransform {
383                component_ids: vec![anchor_b],
384                translation: [0.0, 2.2, 0.0],
385                rotation_quat_xyzw: rot_b,
386                scale: [1.0, 1.0, 1.0],
387            },
388        );
389        let b_set_id = universe.world.add_component(b_set);
390        let _ = universe.attach(kf_b, b_set_id);
391
392        // Per-ring raycast patterns.
393        // A: downbeats in first half (0..4): step % 8 == 0 -> beats 0,1,2,3,4.
394        if beat < 4.0 && step % 8 == 0 {
395            let act = universe
396                .world
397                .add_component(engine::ecs::component::ActionComponent::new(
398                    engine::ecs::IntentValue::RequestRaycast {
399                        component_ids: vec![raycaster],
400                    },
401                ));
402            let _ = universe.attach(kf_a, act);
403        }
404
405        // B: offbeats in second half (4..8): step % 8 == 4 -> beats 0.5,1.5,...,7.5.
406        if beat >= 4.0 && step % 8 == 4 {
407            let act = universe
408                .world
409                .add_component(engine::ecs::component::ActionComponent::new(
410                    engine::ecs::IntentValue::RequestRaycast {
411                        component_ids: vec![raycaster],
412                    },
413                ));
414            let _ = universe.attach(kf_b, act);
415        }
416
417        let _ = universe.attach(anim_a, kf_a);
418        let _ = universe.attach(anim_b, kf_b);
419    }
420
421    universe.add(anim_a);
422    universe.add(anim_b);
423
424    // Process init-time registrations.
425    universe.systems.process_commands(
426        &mut universe.world,
427        &mut universe.visuals,
428        &mut universe.render_assets,
429        &mut universe.command_queue,
430    );
431
432    engine::Windowing::run_app(universe).expect("Windowing failed");
433}
Source

pub fn with_max_distance(self, max_distance: f32) -> Self

Examples found in repository?
examples/raycast-topology-animation.rs (line 284)
111fn main() {
112    mittens_engine::example_support::ensure_model_assets();
113    utils::logger::init();
114
115    let world = engine::ecs::World::default();
116    let mut universe = engine::Universe::new(world);
117
118    // Background.
119    let bg_color = universe
120        .world
121        .add_component(engine::ecs::component::BackgroundColorComponent::new());
122    let bg_color_c = universe
123        .world
124        .add_component(engine::ecs::component::ColorComponent::rgba(
125            0.1, 0.1, 0.1, 1.0,
126        ));
127    let _ = universe.world.add_child(bg_color, bg_color_c);
128    universe.add(bg_color);
129
130    // Camera rig so we can see the scene.
131    let input = universe
132        .world
133        .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
134
135    let rig_transform = universe.world.add_component(
136        engine::ecs::component::TransformComponent::new()
137            .with_position(0.0, 2.0, 8.0)
138            .with_rotation_euler(-0.25, 0.0, 0.0),
139    );
140
141    let camera3d = universe
142        .world
143        .add_component(engine::ecs::component::Camera3DComponent::new());
144
145    let input_mode = universe.world.add_component(
146        engine::ecs::component::InputTransformModeComponent::forward_z()
147            .with_roll_axis_y()
148            .with_fps_rotation(),
149    );
150
151    let _ = universe.attach(input, input_mode);
152    let _ = universe.attach(input, rig_transform);
153    let _ = universe.attach(rig_transform, camera3d);
154
155    // Topology: I { T { C3D } } — add a small camera-attached controls hint.
156    example_util::spawn_desktop_camera_controls_hint(&mut universe, rig_transform);
157    universe.add(input);
158
159    // Two rotating anchor transforms that the raycaster will be reparented under.
160    // Each ring has its own anchor at a different height.
161    let anchor_a = universe.world.add_component(
162        engine::ecs::component::TransformComponent::new().with_position(0.0, 1.0, 0.0),
163    );
164    let anchor_b = universe.world.add_component(
165        engine::ecs::component::TransformComponent::new().with_position(0.0, 2.2, 0.0),
166    );
167
168    // Visual markers for A/B.
169    fn marker(universe: &mut engine::Universe, parent: engine::ecs::ComponentId, rgba: [f32; 4]) {
170        let r = universe
171            .world
172            .add_component(engine::ecs::component::RenderableComponent::cube());
173        let rc = universe
174            .world
175            .add_component(engine::ecs::component::RaycastableComponent::disabled());
176        let c = universe
177            .world
178            .add_component(engine::ecs::component::ColorComponent::rgba(
179                rgba[0], rgba[1], rgba[2], rgba[3],
180            ));
181        let e = universe
182            .world
183            .add_component(engine::ecs::component::EmissiveComponent::on());
184        let t = universe.world.add_component(
185            engine::ecs::component::TransformComponent::new().with_scale(0.15, 0.15, 0.15),
186        );
187        let _ = universe.attach(parent, t);
188        let _ = universe.attach(t, r);
189        let _ = universe.attach(r, rc);
190        let _ = universe.attach(r, c);
191        let _ = universe.attach(r, e);
192    }
193
194    marker(&mut universe, anchor_a, [0.9, 0.2, 0.2, 1.0]);
195    marker(&mut universe, anchor_b, [0.2, 0.2, 0.9, 1.0]);
196
197    universe.add(anchor_a);
198    universe.add(anchor_b);
199
200    // A ring of cubes around the origin to see which one gets hit.
201    fn ring_cube(
202        universe: &mut engine::Universe,
203        ring_root: engine::ecs::ComponentId,
204        x: f32,
205        y: f32,
206        z: f32,
207        rgba: [f32; 4],
208    ) {
209        let t = universe.world.add_component(
210            engine::ecs::component::TransformComponent::new()
211                .with_position(x, y, z)
212                .with_scale(0.35, 0.35, 0.35),
213        );
214        let r = universe
215            .world
216            .add_component(engine::ecs::component::RenderableComponent::cube());
217        let rc = universe
218            .world
219            .add_component(engine::ecs::component::RaycastableComponent::enabled());
220        let c = universe
221            .world
222            .add_component(engine::ecs::component::ColorComponent::rgba(
223                rgba[0], rgba[1], rgba[2], rgba[3],
224            ));
225        let _ = universe.attach(ring_root, t);
226        let _ = universe.attach(t, r);
227        let _ = universe.attach(r, rc);
228        let _ = universe.attach(r, c);
229    }
230
231    // Two rings: one per anchor height.
232    let n = 28;
233    let (radius_a, y_a) = (4.0, 1.0);
234    let (radius_b, y_b) = (2.6, 2.2);
235
236    let ring_a_root = universe
237        .world
238        .add_component(engine::ecs::component::TransformComponent::new());
239    let ring_b_root = universe
240        .world
241        .add_component(engine::ecs::component::TransformComponent::new());
242
243    for i in 0..n {
244        let a = (i as f32) * (std::f32::consts::TAU / (n as f32));
245        let (x, z) = (radius_a * a.cos(), radius_a * a.sin());
246        let color = if i % 2 == 0 {
247            [0.55, 0.20, 0.20, 1.0]
248        } else {
249            [0.20, 0.55, 0.20, 1.0]
250        };
251        ring_cube(&mut universe, ring_a_root, x, y_a, z, color);
252    }
253
254    for i in 0..n {
255        let a = (i as f32) * (std::f32::consts::TAU / (n as f32));
256        let (x, z) = (radius_b * a.cos(), radius_b * a.sin());
257        let color = if i % 2 == 0 {
258            [0.20, 0.25, 0.60, 1.0]
259        } else {
260            [0.20, 0.55, 0.55, 1.0]
261        };
262        ring_cube(&mut universe, ring_b_root, x, y_b, z, color);
263    }
264
265    // Init rings and attach scoped interaction handlers.
266    universe.add(ring_a_root);
267    universe.add(ring_b_root);
268    universe.add_signal_handler(
269        engine::ecs::SignalKind::RayIntersected,
270        ring_a_root,
271        ring_a_handler,
272    );
273    universe.add_signal_handler(
274        engine::ecs::SignalKind::RayIntersected,
275        ring_b_root,
276        ring_b_handler,
277    );
278
279    // The raycaster component we will move between parents.
280    // Source is inferred from topology:
281    // - Under transforms A/B (no camera child) => parent-forward (-Z)
282    // - Under camera rig transform (has camera child) => cursor-through-camera
283    let raycaster = universe.world.add_component(
284        engine::ecs::component::RayCastComponent::event_driven().with_max_distance(25.0),
285    );
286
287    // Global animation: move the raycaster between anchors.
288    // Loop length is 8 beats (we include a noop keyframe at beat 7.0 to force loop_len=8).
289    let anim_global = universe
290        .world
291        .add_component(engine::ecs::component::AnimationComponent::new());
292    {
293        // beat 0: attach to A.
294        let kf0 = universe
295            .world
296            .add_component(engine::ecs::component::KeyframeComponent::new(0.0));
297        let act0 = universe
298            .world
299            .add_component(engine::ecs::component::ActionComponent::new(
300                engine::ecs::IntentValue::Attach {
301                    parents: vec![anchor_a],
302                    child: raycaster,
303                },
304            ));
305        let _ = universe.attach(kf0, act0);
306        let _ = universe.attach(anim_global, kf0);
307
308        // beat 4: attach to B.
309        let kf4 = universe
310            .world
311            .add_component(engine::ecs::component::KeyframeComponent::new(4.0));
312        let act4 = universe
313            .world
314            .add_component(engine::ecs::component::ActionComponent::new(
315                engine::ecs::IntentValue::Attach {
316                    parents: vec![anchor_b],
317                    child: raycaster,
318                },
319            ));
320        let _ = universe.attach(kf4, act4);
321        let _ = universe.attach(anim_global, kf4);
322
323        // beat 7: noop to make loop_len=8.
324        let kf7 = universe
325            .world
326            .add_component(engine::ecs::component::KeyframeComponent::new(7.0));
327        let noop = universe
328            .world
329            .add_component(engine::ecs::component::ActionComponent::new(
330                engine::ecs::IntentValue::Noop,
331            ));
332        let _ = universe.attach(kf7, noop);
333        let _ = universe.attach(anim_global, kf7);
334    }
335    universe.add(anim_global);
336
337    // Ring A animation: rotate anchor A around Y (1 rev / 8 beats).
338    // Also triggers Action::raycast(raycaster) on downbeats in the first half: beats 0,1,2,3.
339    let anim_a = universe
340        .world
341        .add_component(engine::ecs::component::AnimationComponent::new());
342
343    // Ring B animation: rotate anchor B differently (yaw + pitch).
344    // Also triggers Action::raycast(raycaster) on offbeats in the second half: beats 4.5,5.5,6.5,7.5.
345    let anim_b = universe
346        .world
347        .add_component(engine::ecs::component::AnimationComponent::new());
348
349    let loop_beats = 8.0;
350    let steps = 64;
351
352    for step in 0..=steps {
353        let t = (step as f32) / (steps as f32);
354        let beat = (t as f64) * (loop_beats as f64);
355
356        // Keyframe beats are per-animation local beats.
357        let kf_a = universe
358            .world
359            .add_component(engine::ecs::component::KeyframeComponent::new(beat));
360        let kf_b = universe
361            .world
362            .add_component(engine::ecs::component::KeyframeComponent::new(beat));
363
364        // Anchor A rotation: smooth yaw.
365        let yaw_a = t * std::f32::consts::TAU;
366        let a_set = engine::ecs::component::ActionComponent::new(
367            engine::ecs::IntentValue::UpdateTransform {
368                component_ids: vec![anchor_a],
369                translation: [0.0, 1.0, 0.0],
370                rotation_quat_xyzw: quat_from_yaw(yaw_a),
371                scale: [1.0, 1.0, 1.0],
372            },
373        );
374        let a_set_id = universe.world.add_component(a_set);
375        let _ = universe.attach(kf_a, a_set_id);
376
377        // Anchor B rotation: yaw + pitch (different pattern).
378        let yaw_b = -t * std::f32::consts::TAU * 1.5;
379        let pitch_b = (t * std::f32::consts::TAU).sin() * 0.35;
380        let rot_b = quat_mul(quat_from_yaw(yaw_b), quat_from_pitch(pitch_b));
381        let b_set = engine::ecs::component::ActionComponent::new(
382            engine::ecs::IntentValue::UpdateTransform {
383                component_ids: vec![anchor_b],
384                translation: [0.0, 2.2, 0.0],
385                rotation_quat_xyzw: rot_b,
386                scale: [1.0, 1.0, 1.0],
387            },
388        );
389        let b_set_id = universe.world.add_component(b_set);
390        let _ = universe.attach(kf_b, b_set_id);
391
392        // Per-ring raycast patterns.
393        // A: downbeats in first half (0..4): step % 8 == 0 -> beats 0,1,2,3,4.
394        if beat < 4.0 && step % 8 == 0 {
395            let act = universe
396                .world
397                .add_component(engine::ecs::component::ActionComponent::new(
398                    engine::ecs::IntentValue::RequestRaycast {
399                        component_ids: vec![raycaster],
400                    },
401                ));
402            let _ = universe.attach(kf_a, act);
403        }
404
405        // B: offbeats in second half (4..8): step % 8 == 4 -> beats 0.5,1.5,...,7.5.
406        if beat >= 4.0 && step % 8 == 4 {
407            let act = universe
408                .world
409                .add_component(engine::ecs::component::ActionComponent::new(
410                    engine::ecs::IntentValue::RequestRaycast {
411                        component_ids: vec![raycaster],
412                    },
413                ));
414            let _ = universe.attach(kf_b, act);
415        }
416
417        let _ = universe.attach(anim_a, kf_a);
418        let _ = universe.attach(anim_b, kf_b);
419    }
420
421    universe.add(anim_a);
422    universe.add(anim_b);
423
424    // Process init-time registrations.
425    universe.systems.process_commands(
426        &mut universe.world,
427        &mut universe.visuals,
428        &mut universe.render_assets,
429        &mut universe.command_queue,
430    );
431
432    engine::Windowing::run_app(universe).expect("Windowing failed");
433}

Trait Implementations§

Source§

impl Clone for RayCastComponent

Source§

fn clone(&self) -> RayCastComponent

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 RayCastComponent

Source§

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

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

fn set_id(&mut self, component: ComponentId)

Source§

fn as_any(&self) -> &dyn Any

Source§

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

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 to_mms_ast(&self, _world: &World) -> ComponentExpression

Encode this component as an MMS Component Expression AST node. Read more
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 RayCastComponent

Source§

impl Debug for RayCastComponent

Source§

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

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

impl Default for RayCastComponent

Source§

fn default() -> Self

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