added initial interactions
This commit is contained in:
@@ -12,7 +12,7 @@ anyhow = "1.0.75"
|
||||
ash = "0.37.3"
|
||||
bevy = { git = "https://github.com/awtterpip/bevy", default-features = false, features = [
|
||||
"bevy_render",
|
||||
], rev = "ac28b11797c0a85b431ee4940c6afa434f712f7a" }
|
||||
] }
|
||||
openxr = { version = "0.17.1", features = ["mint"] }
|
||||
mint = "0.5.9"
|
||||
wgpu = "0.16.0"
|
||||
@@ -20,7 +20,7 @@ wgpu-core = { version = "0.16.0", features = ["vulkan"] }
|
||||
wgpu-hal = "0.16.0"
|
||||
|
||||
[dev-dependencies]
|
||||
bevy = { git = "https://github.com/awtterpip/bevy", rev = "ac28b11797c0a85b431ee4940c6afa434f712f7a" }
|
||||
bevy = { git = "https://github.com/awtterpip/bevy" }
|
||||
color-eyre = "0.6.2"
|
||||
|
||||
[[example]]
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
|
||||
use bevy::prelude::*;
|
||||
use bevy::transform::components::Transform;
|
||||
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::{
|
||||
draw_interaction_gizmos, hover_interaction, XRDirectInteractor, XRInteractable,
|
||||
XRInteractableState, XRInteractorState,
|
||||
};
|
||||
use bevy_openxr::xr_input::oculus_touch::OculusController;
|
||||
use bevy_openxr::xr_input::prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig};
|
||||
use bevy_openxr::xr_input::trackers::{
|
||||
OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker,
|
||||
};
|
||||
use bevy_openxr::xr_input::Hand;
|
||||
use bevy_openxr::DefaultXrPlugins;
|
||||
|
||||
fn main() {
|
||||
@@ -21,6 +29,9 @@ fn main() {
|
||||
.add_systems(Update, proto_locomotion)
|
||||
.add_systems(Startup, spawn_controllers_example)
|
||||
.insert_resource(PrototypeLocomotionConfig::default())
|
||||
.add_systems(Update, draw_interaction_gizmos)
|
||||
.add_systems(Update, hover_interaction)
|
||||
.add_systems(Update, prototype_interaction_input)
|
||||
.run();
|
||||
}
|
||||
|
||||
@@ -65,6 +76,15 @@ fn setup(
|
||||
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
..default()
|
||||
},));
|
||||
//simple interactable
|
||||
commands.spawn((
|
||||
SpatialBundle {
|
||||
transform: Transform::from_xyz(0.0, 1.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
XRInteractable,
|
||||
XRInteractableState::default(),
|
||||
));
|
||||
}
|
||||
|
||||
fn spawn_controllers_example(mut commands: Commands) {
|
||||
@@ -74,6 +94,8 @@ fn spawn_controllers_example(mut commands: Commands) {
|
||||
OpenXRController,
|
||||
OpenXRTracker,
|
||||
SpatialBundle::default(),
|
||||
XRDirectInteractor,
|
||||
XRInteractorState::default(),
|
||||
));
|
||||
//right hand
|
||||
commands.spawn((
|
||||
@@ -81,5 +103,52 @@ fn spawn_controllers_example(mut commands: Commands) {
|
||||
OpenXRController,
|
||||
OpenXRTracker,
|
||||
SpatialBundle::default(),
|
||||
XRDirectInteractor,
|
||||
XRInteractorState::default(),
|
||||
));
|
||||
}
|
||||
|
||||
fn prototype_interaction_input(
|
||||
oculus_controller: Res<OculusController>,
|
||||
frame_state: Res<XrFrameState>,
|
||||
xr_input: Res<XrInput>,
|
||||
instance: Res<XrInstance>,
|
||||
session: Res<XrSession>,
|
||||
mut right_interactor_query: Query<
|
||||
(&mut XRInteractorState),
|
||||
(
|
||||
With<XRDirectInteractor>,
|
||||
With<OpenXRRightController>,
|
||||
Without<OpenXRLeftController>,
|
||||
),
|
||||
>,
|
||||
mut left_interactor_query: Query<
|
||||
(&mut XRInteractorState),
|
||||
(
|
||||
With<XRDirectInteractor>,
|
||||
With<OpenXRLeftController>,
|
||||
Without<OpenXRRightController>,
|
||||
),
|
||||
>,
|
||||
) {
|
||||
//lock frame
|
||||
let frame_state = *frame_state.lock().unwrap();
|
||||
//get controller
|
||||
let controller = oculus_controller.get_ref(&instance, &session, &frame_state, &xr_input);
|
||||
//get controller triggers
|
||||
let left_trigger = controller.trigger(Hand::Left);
|
||||
let right_trigger = controller.trigger(Hand::Right);
|
||||
//get the interactors and do state stuff
|
||||
let mut left_state = left_interactor_query.single_mut();
|
||||
if left_trigger > 0.8 {
|
||||
*left_state = XRInteractorState::Selecting;
|
||||
} else {
|
||||
*left_state = XRInteractorState::Idle;
|
||||
}
|
||||
let mut right_state = right_interactor_query.single_mut();
|
||||
if right_trigger > 0.8 {
|
||||
*right_state = XRInteractorState::Selecting;
|
||||
} else {
|
||||
*right_state = XRInteractorState::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
123
src/xr_input/interactions.rs
Normal file
123
src/xr_input/interactions.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use std::f32::consts::PI;
|
||||
|
||||
use bevy::prelude::{
|
||||
info, Color, Component, Gizmos, GlobalTransform, Quat, Query, Vec3, With, Without,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct XRDirectInteractor;
|
||||
#[derive(Component)]
|
||||
pub enum XRInteractableState {
|
||||
Idle,
|
||||
Hover,
|
||||
Select,
|
||||
}
|
||||
|
||||
impl Default for XRInteractableState {
|
||||
fn default() -> Self {
|
||||
XRInteractableState::Idle
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub enum XRInteractorState {
|
||||
Idle,
|
||||
Selecting,
|
||||
}
|
||||
impl Default for XRInteractorState {
|
||||
fn default() -> Self {
|
||||
XRInteractorState::Idle
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct XRInteractable;
|
||||
|
||||
pub fn draw_interaction_gizmos(
|
||||
mut gizmos: Gizmos,
|
||||
interactable_query: Query<
|
||||
(&GlobalTransform, &XRInteractableState),
|
||||
(With<XRInteractable>, Without<XRDirectInteractor>),
|
||||
>,
|
||||
interactor_query: Query<
|
||||
(&GlobalTransform, &XRInteractorState),
|
||||
(With<XRDirectInteractor>, Without<XRInteractable>),
|
||||
>,
|
||||
) {
|
||||
for (global_transform, interactable_state) in interactable_query.iter() {
|
||||
let transform = global_transform.compute_transform();
|
||||
let color = match interactable_state {
|
||||
XRInteractableState::Idle => Color::RED,
|
||||
XRInteractableState::Hover => Color::YELLOW,
|
||||
XRInteractableState::Select => Color::GREEN,
|
||||
};
|
||||
gizmos.sphere(transform.translation, transform.rotation, 0.1, color);
|
||||
}
|
||||
|
||||
for (interactor_global_transform, interactor_state) in interactor_query.iter() {
|
||||
let mut transform = interactor_global_transform.compute_transform();
|
||||
transform.scale = Vec3::splat(0.1);
|
||||
let quat = Quat::from_euler(
|
||||
bevy::prelude::EulerRot::XYZ,
|
||||
45.0 * (PI / 180.0),
|
||||
0.0,
|
||||
45.0 * (PI / 180.0),
|
||||
);
|
||||
transform.rotation = quat;
|
||||
let color = match interactor_state {
|
||||
XRInteractorState::Idle => Color::BLUE,
|
||||
XRInteractorState::Selecting => Color::PURPLE,
|
||||
};
|
||||
gizmos.cuboid(transform, color);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hover_interaction(
|
||||
mut interactable_query: Query<
|
||||
(&GlobalTransform, &mut XRInteractableState),
|
||||
(With<XRInteractable>, Without<XRDirectInteractor>),
|
||||
>,
|
||||
interactor_query: Query<
|
||||
(&GlobalTransform, &XRInteractorState),
|
||||
(With<XRDirectInteractor>, Without<XRInteractable>),
|
||||
>,
|
||||
) {
|
||||
'interactable: for (xr_interactable_global_transform, mut state) in
|
||||
interactable_query.iter_mut()
|
||||
{
|
||||
let mut hovered = false;
|
||||
let mut selected = false;
|
||||
for (interactor_global_transform, interactor_state) in interactor_query.iter() {
|
||||
//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
|
||||
{
|
||||
info!("we overlapping");
|
||||
//check for selections first
|
||||
match interactor_state {
|
||||
XRInteractorState::Idle => hovered = true,
|
||||
XRInteractorState::Selecting => {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//check what we found
|
||||
//also i dont like this
|
||||
if selected {
|
||||
*state = XRInteractableState::Select;
|
||||
} else if hovered {
|
||||
*state = XRInteractableState::Hover;
|
||||
} else {
|
||||
*state = XRInteractableState::Idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod controllers;
|
||||
pub mod debug_gizmos;
|
||||
pub mod interactions;
|
||||
pub mod oculus_touch;
|
||||
pub mod prototype_locomotion;
|
||||
pub mod trackers;
|
||||
|
||||
Reference in New Issue
Block a user