Skip to content

Commit

Permalink
Raycast Backend option for picking hidden meshes. (#282)
Browse files Browse the repository at this point in the history
* add: pick hidden with raycast backend

* Update changelog

---------

Co-authored-by: Aevyrie <[email protected]>
  • Loading branch information
dgriffith0 and aevyrie authored Feb 23, 2024
1 parent e26601c commit 085bf9d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# UNRELEASED

- Added: support for `bevy_ui` `UiScale`.
- Added: `RaycastBackendSettings::raycast_visibility` to support picking hidden meshes.

# 0.17.0

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ bevy = { version = "0.12", default-features = false, features = [
"bevy_gltf",
"bevy_scene",
"bevy_ui",
"bevy_gizmos",
"png",
"ktx2",
"zstd",
Expand Down
16 changes: 14 additions & 2 deletions backends/bevy_picking_raycast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,25 @@ pub mod prelude {
}

/// Runtime settings for the [`RaycastBackend`].
#[derive(Resource, Default, Reflect)]
#[derive(Resource, Reflect)]
#[reflect(Resource, Default)]
pub struct RaycastBackendSettings {
/// When set to `true` raycasting will only happen between cameras and entities marked with
/// [`RaycastPickable`]. Off by default. This setting is provided to give you fine-grained
/// control over which cameras and entities should be used by the raycast backend at runtime.
pub require_markers: bool,
/// When set to Ignore, hidden items can be raycasted against.
/// See [`RaycastSettings::visibility`] for more information.
pub raycast_visibility: RaycastVisibility,
}

impl Default for RaycastBackendSettings {
fn default() -> Self {
Self {
require_markers: false,
raycast_visibility: RaycastVisibility::MustBeVisibleAndInView,
}
}
}

/// Optional. Marks cameras and target entities that should be used in the raycast picking backend.
Expand Down Expand Up @@ -102,7 +114,7 @@ pub fn update_hits(
})
{
let settings = RaycastSettings {
visibility: RaycastVisibility::MustBeVisibleAndInView,
visibility: backend_settings.raycast_visibility,
filter: &|entity| {
let marker_requirement =
!backend_settings.require_markers || marked_targets.get(entity).is_ok();
Expand Down
70 changes: 70 additions & 0 deletions examples/hidden.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! An example of picking a hidden mesh in your bevy app.
use bevy::prelude::*;
use bevy_mod_picking::prelude::*;
use bevy_picking_raycast::{bevy_mod_raycast::prelude::RaycastVisibility, RaycastBackendSettings};

fn main() {
App::new()
.add_plugins(DefaultPlugins.set(low_latency_window_plugin()))
.add_plugins(DefaultPickingPlugins)
.insert_resource(RaycastBackendSettings {
raycast_visibility: RaycastVisibility::Ignore,
..Default::default()
})
.add_systems(Startup, setup)
.add_systems(Update, show)
.run();
}

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
},
PickableBundle::default(), // Optional: adds selection, highlighting, and helper components.
));
commands.spawn((
PbrBundle {
visibility: Visibility::Hidden,
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
},
On::<Pointer<Over>>::target_component_mut::<Visibility>(|_listener, visibility| {
*visibility = Visibility::Visible;
}),
On::<Pointer<Out>>::target_component_mut::<Visibility>(|_listener, visibility| {
*visibility = Visibility::Hidden;
}),
PickableBundle::default(), // Optional: adds selection, highlighting, and helper components.
));

commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, -4.0),
..default()
});
commands.spawn((Camera3dBundle {
transform: Transform::from_xyz(3.0, 3.0, 3.0).looking_at(Vec3::ZERO, Vec3::Y),
..default()
},));
}

pub fn show(mut gizmos: Gizmos) {
gizmos.cuboid(
Transform::from_translation(Vec3::new(0.0, 0.5, 0.0)),
Color::GREEN,
);
}

0 comments on commit 085bf9d

Please sign in to comment.