Skip to content
This repository was archived by the owner on Mar 4, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ categories = ["game-engines", "rendering"]
resolver = "2"

[dependencies]
bevy = { version = "0.9", default-features = false, features = ["render"] }
bevy = { version = "0.10.0", default-features = false, features = ["bevy_render"] }

bevy_mod_raycast = "0.7"
bevy_mod_raycast = {git = "https://github.com/soerenmeier/bevy_mod_raycast", branch = "bevy-0.10"}

[dev-dependencies]
bevy = { version = "0.9", default-features = false, features = [
bevy = { version = "0.10.0", default-features = false, features = [
"bevy_pbr",
"bevy_winit",
"bevy_ui",
Expand Down
6 changes: 3 additions & 3 deletions examples/deselection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use bevy_mod_picking::{DefaultPickingPlugins, NoDeselect, PickableBundle, Pickin
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, // Reduce input latency
..default()
},
}),
..default()
}))
.add_plugins(DefaultPickingPlugins) // <- Adds picking, interaction, and highlighting
Expand All @@ -26,7 +26,7 @@ fn setup(
// plane
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
},
Expand Down
4 changes: 2 additions & 2 deletions examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn main() {
.add_plugins(DefaultPlugins)
.add_plugins(DefaultPickingPlugins) // <- Adds picking, interaction, and highlighting
.add_startup_system(setup)
.add_system_to_stage(CoreStage::PostUpdate, print_events)
.add_system(print_events.in_base_set(CoreSet::PreUpdate))
.run();
}

Expand All @@ -28,7 +28,7 @@ fn setup(
) {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
},
Expand Down
6 changes: 3 additions & 3 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use bevy_mod_picking::{
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, // Reduce input latency
..default()
},
}),
..default()
}))
.add_plugins(DefaultPickingPlugins) // <- Adds picking, interaction, and highlighting
Expand All @@ -29,7 +29,7 @@ fn setup(
) {
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })),
mesh: meshes.add(Mesh::from(shape::Plane::from_size(5.0))),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..Default::default()
},
Expand Down
11 changes: 5 additions & 6 deletions examples/stress_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ use bevy_mod_picking::*;
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
window: WindowDescriptor {
primary_window: Some(Window {
title: "bevy_mod_picking stress test".to_string(),
width: 800.,
height: 600.,
resolution: (800., 600.).into(),
present_mode: PresentMode::AutoNoVsync, // Reduce input latency
..default()
},
}),
..default()
}))
.add_plugins(DefaultPickingPlugins) // <- Adds picking, interaction, and highlighting
Expand All @@ -36,10 +35,10 @@ fn setup(
let tris_total = tris_sphere * (half_width as usize * 2).pow(3);
info!("Total tris: {}, Tris per mesh: {}", tris_total, tris_sphere);

let mesh_handle = meshes.add(Mesh::from(shape::Icosphere {
let mesh_handle = meshes.add(Mesh::try_from(shape::Icosphere {
radius: 0.2,
subdivisions,
}));
}).unwrap());

let matl_handle = materials.add(StandardMaterial {
perceptual_roughness: 0.5,
Expand Down
18 changes: 6 additions & 12 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,12 @@ pub fn mesh_events_system(
mouse_button_input: Res<Input<MouseButton>>,
touches_input: Res<Touches>,
mut picking_events: EventWriter<PickingEvent>,
hover_query: Query<
(Entity, &Hover, ChangeTrackers<Hover>),
(Changed<Hover>, With<PickableMesh>),
>,
selection_query: Query<
(Entity, &Selection, ChangeTrackers<Selection>),
(Changed<Selection>, With<PickableMesh>),
>,
hover_query: Query<(Entity, Ref<Hover>), (Changed<Hover>, With<PickableMesh>)>,
selection_query: Query<(Entity, Ref<Selection>), (Changed<Selection>, With<PickableMesh>)>,
click_query: Query<(Entity, &Hover)>,
) {
for (entity, hover, hover_change) in hover_query.iter() {
if hover_change.is_added() {
for (entity, hover) in hover_query.iter() {
if hover.is_added() {
continue; // Avoid a false change detection when a component is added.
}
if hover.hovered() {
Expand All @@ -49,8 +43,8 @@ pub fn mesh_events_system(
picking_events.send(PickingEvent::Hover(HoverEvent::JustLeft(entity)));
}
}
for (entity, selection, selection_change) in selection_query.iter() {
if selection_change.is_added() {
for (entity, selection) in selection_query.iter() {
if selection.is_added() {
continue; // Avoid a false change detection when a component is added.
}
if selection.selected() {
Expand Down
143 changes: 52 additions & 91 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,14 @@ pub use crate::{
};
pub use bevy_mod_raycast::{Primitive3d, RaycastMesh, RaycastSource};

use bevy::{
app::PluginGroupBuilder, asset::Asset, ecs::schedule::ShouldRun, prelude::*, ui::FocusPolicy,
};
use bevy::{app::PluginGroupBuilder, asset::Asset, prelude::*, ui::FocusPolicy};
use highlight::{get_initial_mesh_highlight_asset, Highlight};

#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)]
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
pub enum PickingSystem {
UpdatePickSourcePositions,
BuildRays,
UpdateRaycast,
UpdateIntersections,
Highlighting,
Selection,
PauseForBlockers,
Focus,
Events,
MeshHighlighting,
}

/// A type alias for the concrete [RaycastMesh](bevy_mod_raycast::RaycastMesh) type used for Picking.
Expand Down Expand Up @@ -60,14 +52,6 @@ impl Default for PickingPluginsState {
}
}

fn simple_criteria(flag: bool) -> ShouldRun {
if flag {
ShouldRun::Yes
} else {
ShouldRun::No
}
}

#[derive(Default, Resource)]
pub struct PausedForBlockers(pub(crate) bool);
impl PausedForBlockers {
Expand Down Expand Up @@ -115,31 +99,20 @@ pub struct PickingPlugin;
impl Plugin for PickingPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<PickingPluginsState>()
.add_system_set_to_stage(
CoreStage::PreUpdate,
SystemSet::new()
.with_run_criteria(|state: Res<PickingPluginsState>| {
simple_criteria(state.enable_picking)
})
.with_system(
update_pick_source_positions
.label(PickingSystem::UpdatePickSourcePositions)
.before(PickingSystem::BuildRays),
)
.with_system(
bevy_mod_raycast::build_rays::<PickingRaycastSet>
.label(PickingSystem::BuildRays)
.before(PickingSystem::UpdateRaycast),
)
.with_system(
bevy_mod_raycast::update_raycast::<PickingRaycastSet>
.label(PickingSystem::UpdateRaycast)
.before(PickingSystem::UpdateIntersections),
)
.with_system(
bevy_mod_raycast::update_intersections::<PickingRaycastSet>
.label(PickingSystem::UpdateIntersections),
),
.add_systems(
(
update_pick_source_positions,
bevy_mod_raycast::build_rays::<PickingRaycastSet>,
bevy_mod_raycast::update_raycast::<PickingRaycastSet>,
bevy_mod_raycast::update_intersections::<PickingRaycastSet>,
)
.chain()
.in_set(PickingSystem::UpdateIntersections),
)
.configure_set(
PickingSystem::UpdateIntersections
.run_if(|state: Res<PickingPluginsState>| state.enable_picking)
.in_base_set(CoreSet::PreUpdate),
);
}
}
Expand All @@ -149,32 +122,21 @@ impl Plugin for InteractablePickingPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<PausedForBlockers>()
.add_event::<PickingEvent>()
.add_system_set_to_stage(
CoreStage::PreUpdate,
SystemSet::new()
.with_run_criteria(|state: Res<PickingPluginsState>| {
simple_criteria(state.enable_interacting)
})
.with_system(
pause_for_picking_blockers
.label(PickingSystem::PauseForBlockers)
.after(PickingSystem::UpdateIntersections),
)
.with_system(
mesh_focus
.label(PickingSystem::Focus)
.after(PickingSystem::PauseForBlockers),
)
.with_system(
mesh_selection
.label(PickingSystem::Selection)
.after(PickingSystem::Focus),
)
.with_system(
mesh_events_system
.label(PickingSystem::Events)
.after(PickingSystem::Selection),
),
.add_systems(
(
pause_for_picking_blockers,
mesh_focus,
mesh_selection,
mesh_events_system,
)
.chain()
.in_set(PickingSystem::Events),
)
.configure_set(
PickingSystem::Events
.run_if(|state: Res<PickingPluginsState>| state.enable_interacting)
.in_base_set(CoreSet::PreUpdate)
.after(PickingSystem::UpdateIntersections),
);
}
}
Expand All @@ -194,32 +156,30 @@ where
app.add_startup_system(move |mut commands: Commands, assets: ResMut<Assets<T>>| {
commands.insert_resource(highlighting_default(assets));
})
.add_system_set_to_stage(
CoreStage::PreUpdate,
SystemSet::new()
.with_run_criteria(|state: Res<PickingPluginsState>| {
simple_criteria(state.enable_highlighting)
})
.with_system(
get_initial_mesh_highlight_asset::<T>
.after(PickingSystem::UpdateIntersections)
.before(PickingSystem::Highlighting),
)
.with_system(
mesh_highlighting::<T>
.label(PickingSystem::Highlighting)
.before(PickingSystem::Events),
),
.add_systems(
(
get_initial_mesh_highlight_asset::<T>,
mesh_highlighting::<T>,
)
.chain()
.in_set(PickingSystem::MeshHighlighting),
)
.configure_set(
PickingSystem::MeshHighlighting
.run_if(|state: Res<PickingPluginsState>| state.enable_highlighting)
.in_base_set(CoreSet::PreUpdate)
.before(PickingSystem::Events)
.after(PickingSystem::UpdateIntersections),
);
}
}

pub struct DebugCursorPickingPlugin;
impl Plugin for DebugCursorPickingPlugin {
fn build(&self, app: &mut App) {
app.add_system_to_stage(
CoreStage::PreUpdate,
app.add_system(
bevy_mod_raycast::update_debug_cursor::<PickingRaycastSet>
.in_base_set(CoreSet::PreUpdate)
.after(PickingSystem::UpdateIntersections),
);
}
Expand All @@ -228,9 +188,10 @@ impl Plugin for DebugCursorPickingPlugin {
pub struct DebugEventsPickingPlugin;
impl Plugin for DebugEventsPickingPlugin {
fn build(&self, app: &mut App) {
app.add_system_to_stage(
CoreStage::PreUpdate,
event_debug_system.after(PickingSystem::Events),
app.add_system(
event_debug_system
.in_base_set(CoreSet::PreUpdate)
.after(PickingSystem::Events),
);
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{PickingCamera, UpdatePicks};
use bevy::{
prelude::*,
render::camera::{Camera, RenderTarget},
window::WindowRef,
};
use bevy_mod_raycast::RaycastMethod;

Expand Down Expand Up @@ -57,8 +58,12 @@ fn get_inputs<'a>(
let cursor_latest = match cursor.iter().last() {
Some(cursor_moved) => {
if let RenderTarget::Window(window) = camera.target {
if cursor_moved.id == window {
Some(cursor_moved.position)
if let WindowRef::Entity(camera_entity) = window {
if cursor_moved.window == camera_entity {
Some(cursor_moved.position)
} else {
None
}
} else {
None
}
Expand Down