mod events;
mod focus;
mod highlight;
mod mouse;
mod selection;
pub use crate::{
events::{event_debug_system, mesh_events_system, HoverEvent, PickingEvent, SelectionEvent},
focus::{mesh_focus, Hover},
highlight::{
get_initial_mesh_button_material, mesh_highlighting, MeshButtonMaterials, PickableButton,
},
mouse::update_pick_source_positions,
selection::{mesh_selection, NoDeselect, Selection},
};
pub use bevy_mod_raycast::{BoundVol, Primitive3d, RayCastSource};
use bevy::{prelude::*, ui::FocusPolicy};
pub mod pick_stage {
pub const PICKING: &str = "picking";
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)]
pub enum PickingSystem {
BuildRays,
UpdateRaycast,
Highlighting,
Selection,
Focus,
Events,
}
pub type PickableMesh = bevy_mod_raycast::RayCastMesh<PickingRaycastSet>;
pub type PickingCamera = bevy_mod_raycast::RayCastSource<PickingRaycastSet>;
pub type RayCastPluginState = bevy_mod_raycast::PluginState<PickingRaycastSet>;
pub struct PickingRaycastSet;
pub struct PickingPluginState {
pub enabled: bool,
paused_for_ui: bool,
}
impl Default for PickingPluginState {
fn default() -> Self {
PickingPluginState {
enabled: true,
paused_for_ui: false,
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum UpdatePicks {
EveryFrame(Vec2),
OnMouseEvent,
}
impl Default for UpdatePicks {
fn default() -> Self {
UpdatePicks::EveryFrame(Vec2::ZERO)
}
}
fn update_state(
mut raycast_state: ResMut<RayCastPluginState>,
picking_state: Res<PickingPluginState>,
) {
raycast_state.enabled = picking_state.enabled;
}
pub struct PickingPlugin;
impl Plugin for PickingPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<RayCastPluginState>()
.init_resource::<PickingPluginState>()
.add_system_to_stage(CoreStage::PostUpdate, update_state.system())
.add_system_to_stage(
CoreStage::PostUpdate,
bevy_mod_raycast::update_bound_sphere::<PickingRaycastSet>
.system()
.before(PickingSystem::UpdateRaycast),
)
.add_system_to_stage(
CoreStage::PostUpdate,
update_pick_source_positions
.system()
.before(PickingSystem::BuildRays),
)
.add_system_to_stage(
CoreStage::PostUpdate,
bevy_mod_raycast::build_rays::<PickingRaycastSet>
.system()
.label(PickingSystem::BuildRays)
.before(PickingSystem::UpdateRaycast),
)
.add_system_to_stage(
CoreStage::PostUpdate,
bevy_mod_raycast::update_raycast::<PickingRaycastSet>
.system()
.label(PickingSystem::UpdateRaycast),
);
}
}
pub struct InteractablePickingPlugin;
impl Plugin for InteractablePickingPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_event::<PickingEvent>()
.add_system_to_stage(
CoreStage::PostUpdate,
mesh_focus
.system()
.label(PickingSystem::Focus)
.after(PickingSystem::UpdateRaycast),
)
.add_system_to_stage(
CoreStage::PostUpdate,
mesh_selection
.system()
.label(PickingSystem::Selection)
.before(PickingSystem::Events)
.after(PickingSystem::Focus),
)
.add_system_to_stage(
CoreStage::PostUpdate,
mesh_events_system.system().label(PickingSystem::Events),
);
}
}
pub struct HighlightablePickingPlugin;
impl Plugin for HighlightablePickingPlugin {
fn build(&self, app: &mut AppBuilder) {
app.init_resource::<MeshButtonMaterials>()
.add_system_to_stage(
CoreStage::PostUpdate,
get_initial_mesh_button_material
.system()
.after(PickingSystem::UpdateRaycast)
.before(PickingSystem::Highlighting),
)
.add_system_to_stage(
CoreStage::PostUpdate,
mesh_highlighting
.system()
.label(PickingSystem::Highlighting)
.after(PickingSystem::Events),
);
}
}
pub struct DebugCursorPickingPlugin;
impl Plugin for DebugCursorPickingPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_system_to_stage(
CoreStage::PostUpdate,
bevy_mod_raycast::update_debug_cursor::<PickingRaycastSet>
.system()
.after(PickingSystem::UpdateRaycast),
);
}
}
pub struct DebugEventsPickingPlugin;
impl Plugin for DebugEventsPickingPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_system_to_stage(
CoreStage::PostUpdate,
event_debug_system.system().after(PickingSystem::Events),
);
}
}
#[derive(Bundle)]
pub struct PickingCameraBundle {
pub source: PickingCamera,
pub update: UpdatePicks,
}
impl Default for PickingCameraBundle {
fn default() -> Self {
PickingCameraBundle {
source: PickingCamera::new(),
update: UpdatePicks::default(),
}
}
}
#[derive(Bundle, Default)]
pub struct PickableBundle {
pub pickable_mesh: PickableMesh,
pub interaction: Interaction,
pub focus_policy: FocusPolicy,
pub pickable_button: PickableButton,
pub selection: Selection,
pub hover: Hover,
}