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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use super::*;
use bevy::prelude::*;

pub struct DebugPickingPlugin;
impl Plugin for DebugPickingPlugin {
    fn build(&self, app: &mut AppBuilder) {
        app.add_startup_system(setup_debug_cursor.system())
            .add_system(update_debug_cursor_position.system())
            .add_system(get_picks.system());
    }
}

fn get_picks(pick_state: Res<PickState>) {
    if cfg!(debug_assertions) {
        println!("Top entities:\n{:#?}", pick_state.top_all())
    }
}

struct DebugCursor;

struct DebugCursorMesh;

/// Updates the 3d cursor to be in the pointed world coordinates
fn update_debug_cursor_position(
    pick_state: Res<PickState>,
    mut query: Query<&mut Transform, With<DebugCursor>>,
    mut visibility_query: Query<&mut Visible, With<DebugCursorMesh>>,
) {
    // Set the cursor translation to the top pick's world coordinates
    match pick_state.top_all() {
        Some(top_list) => {
            for (_group, _entity, intersection) in top_list {
                let transform_new = intersection.normal.to_transform();
                for mut transform in &mut query.iter_mut() {
                    *transform = Transform::from_matrix(transform_new);
                }
                for mut visible in &mut visibility_query.iter_mut() {
                    visible.is_visible = true;
                }
            }
        }
        None => {
            for mut visible in &mut visibility_query.iter_mut() {
                visible.is_visible = false;
            }
        }
    }
}

/// Start up system to create 3d Debug cursor
fn setup_debug_cursor(
    commands: &mut Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let debug_matl = materials.add(StandardMaterial {
        albedo: Color::rgb(0.0, 1.0, 0.0),
        shaded: false,
        ..Default::default()
    });
    let cube_size = 0.04;
    let cube_tail_scale = 20.0;
    let ball_size = 0.08;
    commands
        // cursor
        .spawn(PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Icosphere {
                subdivisions: 4,
                radius: ball_size,
            })),
            material: debug_matl.clone(),
            ..Default::default()
        })
        .with_children(|parent| {
            let mut transform = Transform::from_translation(Vec3::new(
                0.0,
                (cube_size * cube_tail_scale) / 2.0,
                0.0,
            ));
            transform.apply_non_uniform_scale(Vec3::from([1.0, cube_tail_scale, 1.0]));

            // child cube
            parent
                .spawn(PbrBundle {
                    mesh: meshes.add(Mesh::from(shape::Cube { size: cube_size })),
                    material: debug_matl,
                    transform,
                    ..Default::default()
                })
                .with(DebugCursorMesh);
        })
        .with(DebugCursor)
        .with(DebugCursorMesh);
}