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

<details>
  <summary>Click to view showcase</summary>

```rust

fn cast_rays_from_additional_camera(
    cameras: Query<(&GlobalTransform, &Camera, Entity), With<RenderToTextureCamera>>,
    mut rays: ResMut<RayMap>,
    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);
            }
        }
    }
}

```

</details>

## Migration Guide
The `bevy_picking::backend::ray::RayMap::map` method is removed as
redundant,
In systems using `Res<RayMap>` replace `ray_map.map()` with
`&ray_map.map`
This commit is contained in:
Sorseg 2025-03-25 21:15:20 +02:00 committed by François Mockers
parent af9fd4e939
commit 30a022feae
2 changed files with 5 additions and 7 deletions

View File

@ -178,7 +178,10 @@ pub mod ray {
/// ```
#[derive(Clone, Debug, Default, Resource)]
pub struct RayMap {
map: HashMap<RayId, Ray3d>,
/// 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<RayId, Ray3d>,
}
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<RayId, Ray3d> {
&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.

View File

@ -86,7 +86,7 @@ pub fn update_hits(
mut ray_cast: MeshRayCast,
mut output: EventWriter<PointerHits>,
) {
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;
};