@@ -2,9 +2,9 @@ use bevy::diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin};
|
||||
use bevy::prelude::*;
|
||||
use bevy::transform::components::Transform;
|
||||
use bevy_openxr::input::XrInput;
|
||||
use bevy_openxr::resources::XrFrameState;
|
||||
use bevy_openxr::resources::{XrFrameState, XrInstance, XrSession};
|
||||
use bevy_openxr::xr_input::oculus_touch::OculusController;
|
||||
use bevy_openxr::xr_input::{QuatConv, Vec3Conv};
|
||||
use bevy_openxr::xr_input::{Hand, QuatConv, Vec3Conv};
|
||||
use bevy_openxr::DefaultXrPlugins;
|
||||
|
||||
fn main() {
|
||||
@@ -61,29 +61,43 @@ fn hands(
|
||||
oculus_controller: Res<OculusController>,
|
||||
frame_state: Res<XrFrameState>,
|
||||
xr_input: Res<XrInput>,
|
||||
instance: Res<XrInstance>,
|
||||
session: Res<XrSession>,
|
||||
) {
|
||||
let mut func = || -> color_eyre::Result<()> {
|
||||
let frame_state = *frame_state.lock().unwrap();
|
||||
|
||||
let right_controller = oculus_controller
|
||||
.grip_space
|
||||
.right
|
||||
.relate(&xr_input.stage, frame_state.predicted_display_time)?;
|
||||
let left_controller = oculus_controller
|
||||
.grip_space
|
||||
.left
|
||||
.relate(&xr_input.stage, frame_state.predicted_display_time)?;
|
||||
let controller = oculus_controller.get_ref(&instance, &session, &frame_state, &xr_input);
|
||||
|
||||
let right_controller = controller.grip_space(Hand::Right);
|
||||
let left_controller = controller.grip_space(Hand::Left);
|
||||
|
||||
let mut color = Color::YELLOW_GREEN;
|
||||
if controller.a_button() {
|
||||
color = Color::BLUE;
|
||||
}
|
||||
if controller.b_button() {
|
||||
color = Color::RED;
|
||||
}
|
||||
if controller.trigger(Hand::Right) != 0.0 {
|
||||
color = Color::rgb(
|
||||
controller.trigger(Hand::Right),
|
||||
0.5,
|
||||
controller.trigger(Hand::Right),
|
||||
);
|
||||
}
|
||||
|
||||
gizmos.rect(
|
||||
right_controller.0.pose.position.to_vec3(),
|
||||
right_controller.0.pose.orientation.to_quat(),
|
||||
Vec2::new(0.05, 0.2),
|
||||
Color::YELLOW_GREEN,
|
||||
color,
|
||||
);
|
||||
gizmos.rect(
|
||||
left_controller.0.pose.position.to_vec3(),
|
||||
left_controller.0.pose.orientation.to_quat(),
|
||||
Vec2::new(0.05, 0.2),
|
||||
Color::YELLOW_GREEN,
|
||||
color,
|
||||
);
|
||||
Ok(())
|
||||
};
|
||||
|
||||
@@ -6,8 +6,8 @@ use wgpu::Instance;
|
||||
|
||||
use crate::input::XrInput;
|
||||
use crate::resources::{
|
||||
XrEnvironmentBlendMode, XrFrameState, XrFrameWaiter, XrInstance, XrSession, XrSessionRunning,
|
||||
XrSwapchain, XrViews, XrResolution, XrFormat,
|
||||
XrEnvironmentBlendMode, XrFormat, XrFrameState, XrFrameWaiter, XrInstance, XrResolution,
|
||||
XrSession, XrSessionRunning, XrSwapchain, XrViews,
|
||||
};
|
||||
|
||||
use openxr as xr;
|
||||
|
||||
@@ -13,8 +13,8 @@ use wgpu::Instance;
|
||||
|
||||
use crate::input::XrInput;
|
||||
use crate::resources::{
|
||||
Swapchain, SwapchainInner, XrEnvironmentBlendMode, XrFrameState, XrFrameWaiter, XrInstance,
|
||||
XrSession, XrSessionRunning, XrSwapchain, XrViews, XrResolution, XrFormat,
|
||||
Swapchain, SwapchainInner, XrEnvironmentBlendMode, XrFormat, XrFrameState, XrFrameWaiter,
|
||||
XrInstance, XrResolution, XrSession, XrSessionRunning, XrSwapchain, XrViews,
|
||||
};
|
||||
use crate::VIEW_TYPE;
|
||||
|
||||
@@ -386,7 +386,8 @@ pub fn initialize_xr_graphics(
|
||||
predicted_display_time: xr::Time::from_nanos(1),
|
||||
predicted_display_period: xr::Duration::from_nanos(1),
|
||||
should_render: true,
|
||||
}).into(),
|
||||
})
|
||||
.into(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ impl XrInput {
|
||||
// )?;
|
||||
let stage =
|
||||
session.create_reference_space(xr::ReferenceSpaceType::STAGE, xr::Posef::IDENTITY)?;
|
||||
let head =
|
||||
session.create_reference_space(xr::ReferenceSpaceType::VIEW, xr::Posef::IDENTITY)
|
||||
let head = session
|
||||
.create_reference_space(xr::ReferenceSpaceType::VIEW, xr::Posef::IDENTITY)
|
||||
.unwrap();
|
||||
//session.attach_action_sets(&[&action_set])?;
|
||||
//session.attach_action_sets(&[])?;
|
||||
|
||||
@@ -136,7 +136,7 @@ impl<G: xr::Graphics> SwapchainInner<G> {
|
||||
let swapchain = self.handle.lock().unwrap();
|
||||
if views.len() == 0 {
|
||||
warn!("views are len of 0");
|
||||
return Ok(())
|
||||
return Ok(());
|
||||
}
|
||||
self.stream.lock().unwrap().end(
|
||||
predicted_display_time,
|
||||
|
||||
@@ -6,15 +6,11 @@ use crate::resources::XrSession;
|
||||
use crate::xr_begin_frame;
|
||||
use crate::xr_input::controllers::XrControllerType;
|
||||
use crate::xr_input::oculus_touch::{setup_oculus_controller, ActionSets};
|
||||
use crate::xr_input::xr_camera::{
|
||||
xr_camera_head_sync, Eye, XRProjection, XrCameraBundle,
|
||||
};
|
||||
use crate::xr_input::xr_camera::{xr_camera_head_sync, Eye, XRProjection, XrCameraBundle};
|
||||
use bevy::app::{App, PostUpdate, Startup};
|
||||
use bevy::log::warn;
|
||||
use bevy::prelude::IntoSystemConfigs;
|
||||
use bevy::prelude::{
|
||||
Commands, Plugin, PreUpdate, Quat, Res, Vec3,
|
||||
};
|
||||
use bevy::prelude::{Commands, Plugin, PreUpdate, Quat, Res, Vec3};
|
||||
use bevy::render::camera::CameraProjectionPlugin;
|
||||
use bevy::render::view::{update_frusta, VisibilitySystems};
|
||||
use bevy::transform::TransformSystem;
|
||||
@@ -23,6 +19,11 @@ use bevy::transform::TransformSystem;
|
||||
pub struct OpenXrInput {
|
||||
pub controller_type: XrControllerType,
|
||||
}
|
||||
#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum Hand {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
impl OpenXrInput {
|
||||
pub fn new(controller_type: XrControllerType) -> Self {
|
||||
Self { controller_type }
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
use crate::input::XrInput;
|
||||
use crate::resources::{XrInstance, XrSession};
|
||||
use crate::xr_input::controllers::{Handed, Touchable};
|
||||
use crate::xr_input::Hand;
|
||||
use bevy::prelude::{Commands, Res, Resource};
|
||||
use openxr::{Action, ActionSet, AnyGraphics, Binding, Haptic, Instance, Posef, Session, Space};
|
||||
use openxr::{
|
||||
Action, ActionSet, AnyGraphics, Binding, FrameState, Haptic, Instance, Path, Posef, Session,
|
||||
Space, SpaceLocation, SpaceVelocity,
|
||||
};
|
||||
|
||||
use std::sync::OnceLock;
|
||||
|
||||
pub fn setup_oculus_controller(
|
||||
mut commands: Commands,
|
||||
@@ -25,6 +32,213 @@ pub fn setup_oculus_controller(
|
||||
#[derive(Resource, Clone)]
|
||||
pub struct ActionSets(pub Vec<ActionSet>);
|
||||
|
||||
pub struct OculusControllerRef<'a> {
|
||||
oculus_controller: &'a OculusController,
|
||||
instance: &'a Instance,
|
||||
session: &'a Session<AnyGraphics>,
|
||||
frame_state: &'a FrameState,
|
||||
xr_input: &'a XrInput,
|
||||
}
|
||||
|
||||
static RIGHT_SUBACTION_PATH: OnceLock<Path> = OnceLock::new();
|
||||
static LEFT_SUBACTION_PATH: OnceLock<Path> = OnceLock::new();
|
||||
|
||||
pub fn init_subaction_path(instance: &Instance) {
|
||||
let _ = LEFT_SUBACTION_PATH.set(instance.string_to_path("/user/hand/left").unwrap());
|
||||
let _ = RIGHT_SUBACTION_PATH.set(instance.string_to_path("/user/hand/right").unwrap());
|
||||
}
|
||||
|
||||
pub fn subaction_path(hand: Hand) -> Path {
|
||||
*match hand {
|
||||
Hand::Left => LEFT_SUBACTION_PATH.get().unwrap(),
|
||||
Hand::Right => RIGHT_SUBACTION_PATH.get().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
impl OculusControllerRef<'_> {
|
||||
pub fn grip_space(&self, hand: Hand) -> (SpaceLocation, SpaceVelocity) {
|
||||
match hand {
|
||||
Hand::Left => self.oculus_controller.grip_space.left.relate(
|
||||
&self.xr_input.stage,
|
||||
self.frame_state.predicted_display_time,
|
||||
),
|
||||
Hand::Right => self.oculus_controller.grip_space.right.relate(
|
||||
&self.xr_input.stage,
|
||||
self.frame_state.predicted_display_time,
|
||||
),
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
pub fn aim_space(&self, hand: Hand) -> (SpaceLocation, SpaceVelocity) {
|
||||
match hand {
|
||||
Hand::Left => self.oculus_controller.aim_space.left.relate(
|
||||
&self.xr_input.stage,
|
||||
self.frame_state.predicted_display_time,
|
||||
),
|
||||
Hand::Right => self.oculus_controller.aim_space.left.relate(
|
||||
&self.xr_input.stage,
|
||||
self.frame_state.predicted_display_time,
|
||||
),
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
pub fn squeeze(&self, hand: Hand) -> f32 {
|
||||
let action = &self.oculus_controller.squeeze;
|
||||
action
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn trigger(&self, hand: Hand) -> f32 {
|
||||
self.oculus_controller
|
||||
.trigger
|
||||
.inner
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn trigger_touched(&self, hand: Hand) -> bool {
|
||||
self.oculus_controller
|
||||
.trigger
|
||||
.touch
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn x_button(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.x_button
|
||||
.inner
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn x_button_touched(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.x_button
|
||||
.touch
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn y_button(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.y_button
|
||||
.inner
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn y_button_touched(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.y_button
|
||||
.touch
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn menu_button(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.menu_button
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn a_button(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.a_button
|
||||
.inner
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn a_button_touched(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.a_button
|
||||
.touch
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn b_button(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.b_button
|
||||
.inner
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn b_button_touched(&self) -> bool {
|
||||
self.oculus_controller
|
||||
.b_button
|
||||
.touch
|
||||
.state(&self.session, Path::NULL)
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn thumbstick_touch(&self, hand: Hand) -> bool {
|
||||
self.oculus_controller
|
||||
.thumbstick_touch
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
pub fn thumbstick(&self, hand: Hand) -> Thumbstick {
|
||||
Thumbstick {
|
||||
x: self
|
||||
.oculus_controller
|
||||
.thumbstick_x
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state,
|
||||
y: self
|
||||
.oculus_controller
|
||||
.thumbstick_y
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state,
|
||||
click: self
|
||||
.oculus_controller
|
||||
.thumbstick_click
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state,
|
||||
}
|
||||
}
|
||||
pub fn thumbrest_touch(&self, hand: Hand) -> bool {
|
||||
self.oculus_controller
|
||||
.thumbrest_touch
|
||||
.state(&self.session, subaction_path(hand))
|
||||
.unwrap()
|
||||
.current_state
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Thumbstick {
|
||||
x: f32,
|
||||
y: f32,
|
||||
click: bool,
|
||||
}
|
||||
|
||||
impl OculusController {
|
||||
pub fn get_ref<'a>(
|
||||
&'a self,
|
||||
instance: &'a Instance,
|
||||
session: &'a Session<AnyGraphics>,
|
||||
frame_state: &'a FrameState,
|
||||
xr_input: &'a XrInput,
|
||||
) -> OculusControllerRef {
|
||||
OculusControllerRef {
|
||||
oculus_controller: self,
|
||||
instance,
|
||||
session,
|
||||
frame_state,
|
||||
xr_input,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct OculusController {
|
||||
pub grip_space: Handed<Space>,
|
||||
@@ -53,6 +267,7 @@ impl OculusController {
|
||||
) -> anyhow::Result<Self> {
|
||||
let action_set =
|
||||
instance.create_action_set("oculus_input", "Oculus Touch Controller Input", 0)?;
|
||||
init_subaction_path(&instance);
|
||||
let left_path = instance.string_to_path("/user/hand/left").unwrap();
|
||||
let right_path = instance.string_to_path("/user/hand/right").unwrap();
|
||||
let hands = [left_path, right_path];
|
||||
|
||||
Reference in New Issue
Block a user