nightshade_api/
picking.rs1use crate::input::{mouse_clicked, mouse_position};
4use crate::scene::is_reserved;
5use nightshade::ecs::gpu_picking::{GpuPickResult, surface_pick_coords};
6use nightshade::prelude::*;
7use nightshade::render::config::ViewportRect;
8use std::collections::HashSet;
9
10pub fn entity_under_cursor(world: &World) -> Option<Entity> {
13 pick_entities(world, mouse_position(world), PickingOptions::default())
14 .into_iter()
15 .map(|result| result.entity)
16 .find(|&entity| !is_reserved(world, entity))
17}
18
19pub fn clicked_entity(world: &World) -> Option<Entity> {
21 if !mouse_clicked(world, MouseButton::Left) {
22 return None;
23 }
24 entity_under_cursor(world)
25}
26
27pub fn cursor_on_ground(world: &World) -> Option<Vec3> {
29 get_ground_position_from_screen(world, mouse_position(world), 0.0)
30}
31
32pub fn pick_excluding(
36 world: &World,
37 screen_pos: Vec2,
38 exclude: &HashSet<Entity>,
39) -> Option<Entity> {
40 pick_entities(world, screen_pos, PickingOptions::default())
41 .into_iter()
42 .map(|result| result.entity)
43 .find(|entity| !is_reserved(world, *entity) && !exclude.contains(entity))
44}
45
46pub fn request_surface_pick(world: &mut World, screen_pos: Vec2) {
54 let rect = world
55 .res::<nightshade::ecs::window::resources::Window>()
56 .active_viewport_rect
57 .or_else(|| {
58 world
59 .res::<nightshade::ecs::window::resources::Window>()
60 .cached_viewport_size
61 .map(|(width, height)| ViewportRect {
62 x: 0.0,
63 y: 0.0,
64 width: width as f32,
65 height: height as f32,
66 })
67 });
68 let render_scale = world
69 .res::<nightshade::render::config::RenderSettings>()
70 .render_scale
71 .clamp(0.25, 4.0);
72 let surface_size = rect
73 .map(|rect| {
74 (
75 ((rect.width * render_scale).round() as u32).max(1),
76 ((rect.height * render_scale).round() as u32).max(1),
77 )
78 })
79 .unwrap_or((1, 1));
80 if let Some((pick_x, pick_y)) = surface_pick_coords(screen_pos, rect, surface_size) {
81 world
82 .res_mut::<nightshade::ecs::gpu_picking::GpuPicking>()
83 .request_pick(pick_x, pick_y);
84 }
85}
86
87pub fn take_surface_pick(world: &mut World) -> Option<GpuPickResult> {
91 world
92 .res_mut::<nightshade::ecs::gpu_picking::GpuPicking>()
93 .take_result()
94}