From f9cf277634cb5a9f91f58dcfb1e874c6ff1c92be Mon Sep 17 00:00:00 2001 From: Sorseg Date: Tue, 25 Mar 2025 21:15:20 +0200 Subject: [PATCH] Make RayMap map public (#18544) Migration guide: # Objective Currently there seems to be no way to enable picking through render-to-texture cameras ## Solution This PR allows casting rays from the game code quite easily. ## Testing - I've tested these in my game and it seems to work - I haven't tested edge cases --- ## Showcase
Click to view showcase ```rust fn cast_rays_from_additional_camera( cameras: Query<(&GlobalTransform, &Camera, Entity), With>, mut rays: ResMut, pointers: Query<(&PointerId, &PointerLocation)>, ) { for (camera_global_transform, camera, camera_entity) in &cameras { for (pointer_id, pointer_loc) in &pointers { let Some(viewport_pos) = pointer_loc.location() else { continue; }; // if camera result is transformed in any way, the reverse transformation // should be applied somewhere here let ray = camera .viewport_to_world(camera_global_transform, viewport_pos.position) .ok(); if let Some(r) = ray { rays.map.insert(RayId::new(camera_entity, *pointer_id), r); } } } } ```
## Migration Guide The `bevy_picking::backend::ray::RayMap::map` method is removed as redundant, In systems using `Res` replace `ray_map.map()` with `&ray_map.map` --- crates/bevy_picking/src/backend.rs | 10 ++++------ crates/bevy_picking/src/mesh_picking/mod.rs | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/bevy_picking/src/backend.rs b/crates/bevy_picking/src/backend.rs index 6c0db34e72..fb4f801d6e 100644 --- a/crates/bevy_picking/src/backend.rs +++ b/crates/bevy_picking/src/backend.rs @@ -178,7 +178,10 @@ pub mod ray { /// ``` #[derive(Clone, Debug, Default, Resource)] pub struct RayMap { - map: HashMap, + /// Cartesian product of all pointers and all cameras + /// Add your rays here to support picking through indirections, + /// e.g. rendered-to-texture cameras + pub map: HashMap, } impl RayMap { @@ -187,11 +190,6 @@ pub mod ray { self.map.iter() } - /// The hash map of all rays cast in the current frame. - pub fn map(&self) -> &HashMap { - &self.map - } - /// Clears the [`RayMap`] and re-populates it with one ray for each /// combination of pointer entity and camera entity where the pointer /// intersects the camera's viewport. diff --git a/crates/bevy_picking/src/mesh_picking/mod.rs b/crates/bevy_picking/src/mesh_picking/mod.rs index 42d704e772..1e7e45bc2d 100644 --- a/crates/bevy_picking/src/mesh_picking/mod.rs +++ b/crates/bevy_picking/src/mesh_picking/mod.rs @@ -86,7 +86,7 @@ pub fn update_hits( mut ray_cast: MeshRayCast, mut output: EventWriter, ) { - for (&ray_id, &ray) in ray_map.map().iter() { + for (&ray_id, &ray) in ray_map.iter() { let Ok((camera, cam_can_pick, cam_layers)) = picking_cameras.get(ray_id.camera) else { continue; };