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
|
use crate::math::Point;
use bevy::prelude::*;
use bevy::window::PrimaryWindow;
#[derive(Component)]
pub struct MainCamera;
#[derive(Default, Copy, Clone, Debug, Resource)]
pub struct SceneMouse {
#[cfg(feature = "dim2")]
pub point: Option<Point<f32>>,
#[cfg(feature = "dim3")]
pub ray: Option<(Point<f32>, crate::math::Vector<f32>)>,
}
pub fn track_mouse_state(
mut scene_mouse: ResMut<SceneMouse>,
windows: Query<&Window, With<PrimaryWindow>>,
camera: Query<(&GlobalTransform, &Camera), With<MainCamera>>,
) {
if let Ok(window) = windows.get_single() {
for (camera_transform, camera) in camera.iter() {
if let Some(cursor) = window.cursor_position() {
let ndc_cursor = ((cursor / Vec2::new(window.width(), window.height()) * 2.0)
- Vec2::ONE)
* Vec2::new(1.0, -1.0);
let ndc_to_world =
camera_transform.compute_matrix() * camera.clip_from_view().inverse();
let ray_pt1 =
ndc_to_world.project_point3(Vec3::new(ndc_cursor.x, ndc_cursor.y, -1.0));
#[cfg(feature = "dim2")]
{
scene_mouse.point = Some(Point::new(ray_pt1.x, ray_pt1.y));
}
#[cfg(feature = "dim3")]
{
let ray_pt2 =
ndc_to_world.project_point3(Vec3::new(ndc_cursor.x, ndc_cursor.y, 1.0));
let ray_dir = ray_pt2 - ray_pt1;
scene_mouse.ray = Some((na::Vector3::from(ray_pt1).into(), ray_dir.into()));
}
}
}
}
}
|