diff --git a/examples/xr.rs b/examples/xr.rs index 68b7b5d..35b0800 100644 --- a/examples/xr.rs +++ b/examples/xr.rs @@ -5,8 +5,9 @@ use bevy_openxr::input::XrInput; use bevy_openxr::resources::{XrFrameState, XrInstance, XrSession}; use bevy_openxr::xr_input::debug_gizmos::OpenXrDebugRenderer; use bevy_openxr::xr_input::interactions::{ - interactions, draw_interaction_gizmos, update_interactable_states, InteractionEvent, - XRDirectInteractor, XRInteractable, XRInteractableState, XRInteractorState, XRRayInteractor, + draw_interaction_gizmos, draw_socket_gizmos, interactions, update_interactable_states, + InteractionEvent, XRDirectInteractor, XRInteractable, XRInteractableState, XRInteractorState, + XRRayInteractor, XRSocketInteractor, socket_interactions, }; use bevy_openxr::xr_input::oculus_touch::OculusController; use bevy_openxr::xr_input::prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}; @@ -33,7 +34,9 @@ fn main() { Update, draw_interaction_gizmos.after(update_interactable_states), ) + .add_systems(Update, draw_socket_gizmos.after(update_interactable_states)) .add_systems(Update, interactions) + .add_systems(Update, socket_interactions) .add_systems(Update, prototype_interaction_input) .add_systems(Update, update_interactable_states.after(interactions)) .add_systems(Update, update_grabbables.after(update_interactable_states)) @@ -60,13 +63,16 @@ fn setup( transform: Transform::from_xyz(0.0, 0.5, 0.0), ..default() }); - // cube - commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Cube { size: 0.1 })), - material: materials.add(Color::rgb(0.8, 0.0, 0.0).into()), - transform: Transform::from_xyz(0.0, 0.5, 1.0), - ..default() - }); + // socket + commands.spawn(( + SpatialBundle { + transform: Transform::from_xyz(0.0, 0.5, 1.0), + ..default() + }, + XRInteractorState::Selecting, + XRSocketInteractor, + )); + // light commands.spawn(PointLightBundle { point_light: PointLight { @@ -167,7 +173,11 @@ pub struct Grabbable; pub fn update_grabbables( mut events: EventReader, mut grabbable_query: Query<(&mut Transform, With, Without)>, - interactor_query: Query<(&GlobalTransform, With, Without)>, + interactor_query: Query<( + &GlobalTransform, + With, + Without, + )>, ) { //so basically the idea is to try all the events? for event in events.read() { diff --git a/src/xr_input/interactions.rs b/src/xr_input/interactions.rs index 86a35e5..db3dfc2 100644 --- a/src/xr_input/interactions.rs +++ b/src/xr_input/interactions.rs @@ -13,6 +13,9 @@ pub struct XRDirectInteractor; #[derive(Component)] pub struct XRRayInteractor; +#[derive(Component)] +pub struct XRSocketInteractor; + #[derive(Component, Clone, Copy)] pub enum XRInteractableState { Idle, @@ -40,6 +43,27 @@ impl Default for XRInteractorState { #[derive(Component)] pub struct XRInteractable; +//i guess really these should be seperate +pub fn draw_socket_gizmos( + mut gizmos: Gizmos, + interactor_query: Query<( + &GlobalTransform, + &XRInteractorState, + Entity, + &XRSocketInteractor, + )>, +) { + for (global, state, _entity, _socket) in interactor_query.iter() { + let mut transform = global.compute_transform().clone(); + transform.scale = Vec3::splat(0.1); + let color = match state { + XRInteractorState::Idle => Color::BLUE, + XRInteractorState::Selecting => Color::PURPLE, + }; + gizmos.cuboid(transform, color) + } +} + pub fn draw_interaction_gizmos( mut gizmos: Gizmos, interactable_query: Query< @@ -118,6 +142,59 @@ pub struct InteractionEvent { pub interactable_state: XRInteractableState, } +//yeah these need to be seperate somehow +pub fn socket_interactions( + mut interactable_query: Query< + (&GlobalTransform, &mut XRInteractableState, Entity), + (With, Without), + >, + interactor_query: Query< + ( + &GlobalTransform, + &XRInteractorState, + Entity, + &XRSocketInteractor, + ), + (Without), + >, + mut writer: EventWriter, +) { + for interactable in interactable_query.iter() { + //for the interactbles + for socket in interactor_query.iter() { + let interactor_global_transform = socket.0; + let xr_interactable_global_transform = interactable.0; + let interactor_state = socket.1; + //check for sphere overlaps + let size = 0.1; + if interactor_global_transform + .compute_transform() + .translation + .distance_squared( + xr_interactable_global_transform + .compute_transform() + .translation, + ) + < (size * size) * 2.0 + { + //check for selections first + match interactor_state { + XRInteractorState::Idle => (), //welp this wont work, + XRInteractorState::Selecting => { + //welp now I gota actually make things do stuff lol + let event = InteractionEvent { + interactor: socket.2, + interactable: interactable.2, + interactable_state: XRInteractableState::Select, + }; + writer.send(event); + } + } + } + } + } +} + pub fn interactions( mut interactable_query: Query< (&GlobalTransform, &mut XRInteractableState, Entity), @@ -235,8 +312,7 @@ pub fn update_interactable_states( Ok((_entity, mut entity_state)) => { *entity_state = event.interactable_state; } - Err(_) => { - } + Err(_) => {} } } }