1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use crate::{PickingCamera, UpdatePicks};
use bevy::{prelude::*, render::camera::Camera};
use bevy_mod_raycast::RayCastMethod;

/// Update Screenspace ray cast sources with the current mouse position
pub fn update_pick_source_positions(
    mut cursor: EventReader<CursorMoved>,
    mut pick_source_query: Query<(
        &mut PickingCamera,
        Option<&mut UpdatePicks>,
        Option<&Camera>,
    )>,
) {
    for (mut pick_source, option_update_picks, option_camera) in &mut pick_source_query.iter_mut() {
        let camera = match option_camera {
            Some(camera) => camera,
            None => panic!("The PickingCamera entity has no associated Camera component"),
        };
        let mut update_picks = match option_update_picks {
            Some(update_picks) => update_picks,
            None => panic!("The PickingCamera entity has no associated UpdatePicks component"),
        };
        let cursor_latest = match cursor.iter().last() {
            Some(cursor_moved) => {
                if cursor_moved.id == camera.window {
                    Some(cursor_moved)
                } else {
                    None
                }
            }
            None => None,
        };
        match *update_picks {
            UpdatePicks::EveryFrame(cached_cursor_pos) => {
                match cursor_latest {
                    Some(cursor_moved) => {
                        pick_source.cast_method = RayCastMethod::Screenspace(cursor_moved.position);
                        *update_picks = UpdatePicks::EveryFrame(cursor_moved.position);
                    }
                    None => pick_source.cast_method = RayCastMethod::Screenspace(cached_cursor_pos),
                };
            }
            UpdatePicks::OnMouseEvent => match cursor_latest {
                Some(cursor_moved) => {
                    pick_source.cast_method = RayCastMethod::Screenspace(cursor_moved.position)
                }
                None => continue,
            },
        };
    }
}