From 3803968b7c7725a88fed4abb99dbc8cda910666e Mon Sep 17 00:00:00 2001 From: Schmarni Date: Mon, 12 Feb 2024 09:05:44 +0100 Subject: [PATCH] clean up passthrough, change hand entity behavior and add cleanup steps to some plugins --- examples/android/Cargo.toml | 8 +- examples/android/src/lib.rs | 36 +++++--- examples/demo/src/lib.rs | 4 +- examples/globe.rs | 3 +- examples/xr.rs | 3 +- src/lib.rs | 23 +++-- src/passthrough.rs | 61 ++++++------- src/xr_init/mod.rs | 3 +- src/xr_input/actions.rs | 18 +++- src/xr_input/hands/common.rs | 133 +++++++++++----------------- src/xr_input/hands/emulated.rs | 10 +-- src/xr_input/hands/hand_tracking.rs | 9 +- src/xr_input/hands/mod.rs | 62 +++++++------ 13 files changed, 178 insertions(+), 195 deletions(-) diff --git a/examples/android/Cargo.toml b/examples/android/Cargo.toml index bea6cb3..1c412bc 100644 --- a/examples/android/Cargo.toml +++ b/examples/android/Cargo.toml @@ -16,10 +16,10 @@ bevy_oxr.path = "../.." bevy = "0.12" openxr = { git = "https://github.com/Ralith/openxrs", rev = "0177d2d", features = ["mint"] } -[profile.release] -lto = "fat" -codegen-units = 1 -panic = "abort" +# [profile.release] +# lto = "fat" +# codegen-units = 1 +# panic = "abort" # This metadata is used by `cargo-apk` - `xbuild` uses the `manifest.yaml` instead. [package.metadata.android] diff --git a/examples/android/src/lib.rs b/examples/android/src/lib.rs index efb835a..ba0f411 100644 --- a/examples/android/src/lib.rs +++ b/examples/android/src/lib.rs @@ -3,10 +3,10 @@ use bevy::prelude::*; use bevy::transform::components::Transform; use bevy_oxr::graphics::extensions::XrExtensions; use bevy_oxr::graphics::XrAppInfo; -use bevy_oxr::graphics::XrPreferdBlendMode::AlphaBlend; -use bevy_oxr::passthrough::{passthrough_layer_pause, passthrough_layer_resume}; -use bevy_oxr::xr_init::XrRenderData; +use bevy_oxr::passthrough::{PausePassthrough, ResumePassthrough, XrPassthroughState}; +use bevy_oxr::xr_init::xr_only; use bevy_oxr::xr_input::debug_gizmos::OpenXrDebugRenderer; +use bevy_oxr::xr_input::hands::HandBone; use bevy_oxr::xr_input::prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}; use bevy_oxr::xr_input::trackers::{ OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker, @@ -25,16 +25,23 @@ fn main() { }, prefered_blend_mode: bevy_oxr::graphics::XrPreferdBlendMode::Opaque, }) - .add_plugins(OpenXrDebugRenderer) + // .add_plugins(OpenXrDebugRenderer) .add_plugins(LogDiagnosticsPlugin::default()) .add_plugins(FrameTimeDiagnosticsPlugin) .add_systems(Startup, setup) - .add_systems(Update, (proto_locomotion, toggle_passthrough)) + .add_systems(Update, (proto_locomotion, toggle_passthrough).run_if(xr_only())) + .add_systems(Update, debug_hand_render.run_if(xr_only())) .add_systems(Startup, spawn_controllers_example) .insert_resource(PrototypeLocomotionConfig::default()) .run(); } +fn debug_hand_render(query: Query<&GlobalTransform, With>, mut gizmos: Gizmos) { + for transform in &query { + gizmos.sphere(transform.translation(), Quat::IDENTITY, 0.01, Color::RED); + } +} + /// set up a simple 3D scene fn setup( mut commands: Commands, @@ -90,15 +97,18 @@ fn spawn_controllers_example(mut commands: Commands) { )); } -// Does this work? Not getting logs -fn toggle_passthrough(keys: Res>, mut xr_data: ResMut) { +// TODO: make this a vr button +fn toggle_passthrough( + keys: Res>, + passthrough_state: Res, + mut resume: EventWriter, + mut pause: EventWriter, +) { if keys.just_pressed(KeyCode::Space) { - if xr_data.xr_passthrough_active { - passthrough_layer_pause(xr_data); - bevy::log::info!("Passthrough paused"); - } else { - passthrough_layer_resume(xr_data); - bevy::log::info!("Passthrough resumed"); + match *passthrough_state { + XrPassthroughState::Unsupported => {} + XrPassthroughState::Running => pause.send_default(), + XrPassthroughState::Paused => resume.send_default(), } } } diff --git a/examples/demo/src/lib.rs b/examples/demo/src/lib.rs index d55db1a..8f369f9 100644 --- a/examples/demo/src/lib.rs +++ b/examples/demo/src/lib.rs @@ -23,7 +23,7 @@ use bevy_oxr::{ xr_input::{ actions::XrActionSets, debug_gizmos::OpenXrDebugRenderer, - hands::common::{HandInputDebugRenderer, HandResource, HandsResource, OpenXrHandInput}, + hands::common::{HandInputDebugRenderer, HandResource, HandsResource}, hands::HandBone, interactions::{ draw_interaction_gizmos, draw_socket_gizmos, interactions, socket_interactions, @@ -120,7 +120,7 @@ pub fn main() { //test capsule .add_systems(Startup, spawn_capsule) //physics hands - .add_plugins(OpenXrHandInput) + // .add_plugins(OpenXrHandInput) .add_plugins(HandInputDebugRenderer) .add_systems(Startup, spawn_physics_hands) .add_systems( diff --git a/examples/globe.rs b/examples/globe.rs index 192916b..3f439be 100644 --- a/examples/globe.rs +++ b/examples/globe.rs @@ -3,7 +3,7 @@ use bevy::prelude::*; use bevy::transform::components::Transform; use bevy_oxr::graphics::XrAppInfo; use bevy_oxr::resources::XrViews; -use bevy_oxr::xr_input::hands::common::{HandInputDebugRenderer, OpenXrHandInput}; +use bevy_oxr::xr_input::hands::common::HandInputDebugRenderer; use bevy_oxr::xr_input::interactions::{ InteractionEvent, XRDirectInteractor, XRInteractorState, XRRayInteractor, XRSocketInteractor, }; @@ -31,7 +31,6 @@ fn main() { .add_systems(Update, (proto_locomotion, pull_to_ground).chain()) .insert_resource(PrototypeLocomotionConfig::default()) .add_systems(Startup, spawn_controllers_example) - .add_plugins(OpenXrHandInput) .add_plugins(HandInputDebugRenderer) .add_event::() .run(); diff --git a/examples/xr.rs b/examples/xr.rs index 6f8d2de..68104d9 100644 --- a/examples/xr.rs +++ b/examples/xr.rs @@ -7,7 +7,7 @@ use bevy_oxr::input::XrInput; use bevy_oxr::resources::{XrFrameState, XrSession}; use bevy_oxr::xr_input::actions::XrActionSets; -use bevy_oxr::xr_input::hands::common::{HandInputDebugRenderer, OpenXrHandInput}; +use bevy_oxr::xr_input::hands::common::HandInputDebugRenderer; use bevy_oxr::xr_input::interactions::{ draw_interaction_gizmos, draw_socket_gizmos, interactions, socket_interactions, update_interactable_states, InteractionEvent, Touched, XRDirectInteractor, XRInteractable, @@ -39,7 +39,6 @@ fn main() { .add_systems(Update, proto_locomotion) .insert_resource(PrototypeLocomotionConfig::default()) .add_systems(Startup, spawn_controllers_example) - .add_plugins(OpenXrHandInput) .add_plugins(HandInputDebugRenderer) .add_systems( Update, diff --git a/src/lib.rs b/src/lib.rs index ae0a5a4..17c5e6c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,11 +31,13 @@ use openxr as xr; use passthrough::{PassthroughPlugin, XrPassthroughLayer, XrPassthroughState}; use resources::*; use xr_init::{ - xr_after_wait_only, xr_only, xr_render_only, CleanupXrData, XrEarlyInitPlugin, XrHasWaited, - XrShouldRender, XrStatus, + xr_after_wait_only, xr_only, xr_render_only, CleanupXrData, SetupXrData, XrEarlyInitPlugin, + XrHasWaited, XrShouldRender, XrStatus, }; use xr_input::controllers::XrControllerType; -use xr_input::hands::XrHandPlugins; +use xr_input::hands::emulated::HandEmulationPlugin; +use xr_input::hands::hand_tracking::HandTrackingPlugin; +use xr_input::hands::HandPlugin; use xr_input::OpenXrInput; const VIEW_TYPE: xr::ViewConfigurationType = xr::ViewConfigurationType::PRIMARY_STEREO; @@ -51,11 +53,6 @@ pub struct OpenXrPlugin { app_info: XrAppInfo, } -fn mr_test(mut commands: Commands, mut resume: EventWriter) { - commands.insert_resource(ClearColor(Color::rgba(0.0, 0.0, 0.0, 0.0))); - resume.send_default(); -} - impl Plugin for OpenXrPlugin { fn build(&self, app: &mut App) { app.insert_resource(XrSessionRunning::new(AtomicBool::new(false))); @@ -114,7 +111,6 @@ impl Plugin for OpenXrPlugin { app.add_plugins(RenderPlugin::default()); app.insert_resource(XrStatus::Disabled); } - app.add_systems(Update, mr_test.run_if(xr_only())); app.add_systems( PreUpdate, xr_poll_events.run_if(|status: Res| *status != XrStatus::NoInstance), @@ -146,8 +142,6 @@ impl Plugin for OpenXrPlugin { .run_if(xr_only()) .run_if(xr_after_wait_only()) .run_if(xr_render_only()) - // Do NOT touch this ordering! idk why but you can NOT just put in a RenderSet - // right before rendering .before(render_system) .after(RenderSet::ExtractCommands), // .in_set(RenderSet::Prepare), @@ -224,7 +218,9 @@ impl PluginGroup for DefaultXrPlugins { .add_after::(OpenXrInput::new(XrControllerType::OculusTouch)) .add_after::(XrInitPlugin) .add_before::(XrEarlyInitPlugin) - .add(XrHandPlugins) + .add(HandPlugin) + .add(HandTrackingPlugin) + .add(HandEmulationPlugin) .add(PassthroughPlugin) .add(XrResourcePlugin) .set(WindowPlugin { @@ -259,6 +255,7 @@ fn xr_poll_events( session: Option>, session_running: Res, mut app_exit: EventWriter, + mut setup_xr: EventWriter, mut cleanup_xr: EventWriter, ) { if let (Some(instance), Some(session)) = (instance, session) { @@ -274,6 +271,7 @@ fn xr_poll_events( xr::SessionState::READY => { info!("Calling Session begin :3"); session.begin(VIEW_TYPE).unwrap(); + setup_xr.send_default(); session_running.store(true, std::sync::atomic::Ordering::Relaxed); } xr::SessionState::STOPPING => { @@ -283,7 +281,6 @@ fn xr_poll_events( } xr::SessionState::EXITING | xr::SessionState::LOSS_PENDING => { // app_exit.send(AppExit); - return; } _ => {} diff --git a/src/passthrough.rs b/src/passthrough.rs index 51256e7..e6eb1e5 100644 --- a/src/passthrough.rs +++ b/src/passthrough.rs @@ -25,10 +25,11 @@ pub enum XrPassthroughState { Paused, } -pub struct PassthroughPlugin; xr_arc_resource_wrapper!(XrPassthrough, xr::Passthrough); xr_arc_resource_wrapper!(XrPassthroughLayer, xr::PassthroughLayer); +pub struct PassthroughPlugin; + impl Plugin for PassthroughPlugin { fn build(&self, app: &mut App) { app.add_event::(); @@ -78,20 +79,31 @@ fn check_passthrough_support(mut cmds: Commands, instance: Option, mut state: ResMut) { +fn resume_passthrough( + layer: Res, + mut state: ResMut, + mut clear_color: ResMut, +) { if let Err(e) = layer.resume() { warn!("Unable to resume Passthrough: {}", e); return; } - info!("<=> Resume Passthrough"); + clear_color.set_a(0.0); + clear_color.set_r(0.0); + clear_color.set_g(0.0); + clear_color.set_b(0.0); *state = XrPassthroughState::Running; } -fn pause_passthrough(layer: Res, mut state: ResMut) { +fn pause_passthrough( + layer: Res, + mut state: ResMut, + mut clear_color: ResMut, +) { if let Err(e) = layer.pause() { warn!("Unable to resume Passthrough: {}", e); return; } - info!("<=> Pausing Passthrough"); + clear_color.set_a(1.0); *state = XrPassthroughState::Paused; } @@ -100,8 +112,8 @@ fn cleanup_passthrough(mut cmds: Commands) { cmds.remove_resource::(); } -fn setup_passthrough(mut cmds: Commands, instance: Res, session: Res) { - match create_passthrough(&instance, &session) { +fn setup_passthrough(mut cmds: Commands, session: Res) { + match create_passthrough(&session) { Ok((passthrough, layer)) => { cmds.insert_resource(XrPassthrough::from(passthrough)); cmds.insert_resource(XrPassthroughLayer::from(layer)); @@ -181,7 +193,6 @@ pub fn supports_passthrough(instance: &XrInstance, system: xr::SystemId) -> xr:: #[inline] pub fn create_passthrough( - instance: &XrInstance, xr_session: &XrSession, ) -> xr::Result<(xr::Passthrough, xr::PassthroughLayer)> { let passthrough = match xr_session { @@ -199,28 +210,14 @@ pub fn create_passthrough( Ok((passthrough, passthrough_layer)) } -// #[inline] -// pub fn passthrough_layer_resume(mut layer: ResMut, mut passthrough: ResMut) -> xr::Result<()> { -// layer.resume() -// } +/// Enable Passthrough on xr startup +/// just sends the [`ResumePassthrough`] event in [`XrSetup`] +pub struct EnablePassthroughStartup; -// #[inline] -// pub fn passthrough_layer_pause(mut xr_data_resource: ResMut) -> xr::Result<()> { -// unsafe { -// let passthrough_layer = &xr_data_resource.xr_passthrough_layer; -// { -// let passthrough_layer_locked = passthrough_layer.lock().unwrap(); -// cvt((xr_data_resource -// .xr_instance -// .exts() -// .fb_passthrough -// .unwrap() -// .passthrough_layer_pause)( -// *passthrough_layer_locked -// ))?; -// } -// xr_data_resource.xr_passthrough_active = false; -// bevy::log::info!("Paused passthrough layer"); -// Ok(()) -// } -// } +impl Plugin for EnablePassthroughStartup { + fn build(&self, app: &mut App) { + app.add_systems(XrSetup, |mut e: EventWriter| { + e.send_default(); + }); + } +} diff --git a/src/xr_init/mod.rs b/src/xr_init/mod.rs index 06d9578..bd17a04 100644 --- a/src/xr_init/mod.rs +++ b/src/xr_init/mod.rs @@ -126,7 +126,7 @@ pub struct StartXrSession; pub struct EndXrSession; #[derive(Event, Clone, Copy, Default)] -struct SetupXrData; +pub(crate) struct SetupXrData; #[derive(Event, Clone, Copy, Default)] pub(crate) struct CleanupXrData; @@ -192,7 +192,6 @@ fn start_xr_session( commands.insert_resource(xr_views); commands.insert_resource(xr_frame_state); *status = XrStatus::Enabling; - setup_xr.send_default(); } fn stop_xr_session(session: ResMut, mut status: ResMut) { diff --git a/src/xr_input/actions.rs b/src/xr_input/actions.rs index 748968d..b9d8c2d 100644 --- a/src/xr_input/actions.rs +++ b/src/xr_input/actions.rs @@ -6,7 +6,7 @@ use xr::{Action, Binding, Haptic, Posef, Vector2f}; use crate::{ resources::{XrInstance, XrSession}, - xr_init::XrPrePostSetup, + xr_init::{XrCleanup, XrPrePostSetup, XrPreSetup}, }; use super::oculus_touch::ActionSets; @@ -16,13 +16,23 @@ pub use xr::sys::NULL_PATH; pub struct OpenXrActionsPlugin; impl Plugin for OpenXrActionsPlugin { fn build(&self, app: &mut App) { - app.insert_resource(SetupActionSets { - sets: HashMap::new(), - }); + app.add_systems(XrPreSetup, insert_setup_action_sets); app.add_systems(XrPrePostSetup, setup_oxr_actions); + app.add_systems(XrCleanup, clean_actions); } } +fn insert_setup_action_sets(mut cmds: Commands) { + cmds.insert_resource(SetupActionSets { + sets: HashMap::new(), + }); +} + +fn clean_actions(mut cmds: Commands) { + cmds.remove_resource::(); + cmds.remove_resource::(); +} + #[inline(always)] fn create_action( action: &SetupAction, diff --git a/src/xr_input/hands/common.rs b/src/xr_input/hands/common.rs index 104c6b3..f080613 100644 --- a/src/xr_input/hands/common.rs +++ b/src/xr_input/hands/common.rs @@ -1,6 +1,10 @@ -use bevy::prelude::{ - default, Color, Commands, Component, Deref, DerefMut, Entity, Gizmos, Plugin, PostUpdate, - Query, Resource, SpatialBundle, Startup, Transform, +use bevy::{ + core::Name, + prelude::{ + default, Color, Commands, Component, Deref, DerefMut, Entity, Gizmos, Plugin, PostUpdate, + Query, Resource, SpatialBundle, Startup, Transform, + }, + transform::components::GlobalTransform, }; use crate::xr_input::{trackers::OpenXRTracker, Hand}; @@ -8,14 +12,14 @@ use crate::xr_input::{trackers::OpenXRTracker, Hand}; use super::{BoneTrackingStatus, HandBone}; /// add debug renderer for controllers -#[derive(Default)] -pub struct OpenXrHandInput; - -impl Plugin for OpenXrHandInput { - fn build(&self, app: &mut bevy::prelude::App) { - app.add_systems(Startup, spawn_hand_entities); - } -} +// #[derive(Default)] +// pub struct OpenXrHandInput; +// +// impl Plugin for OpenXrHandInput { +// fn build(&self, app: &mut bevy::prelude::App) { +// app.add_systems(Startup, spawn_hand_entities); +// } +// } /// add debug renderer for controllers #[derive(Default)] @@ -161,75 +165,46 @@ pub fn spawn_hand_entities(mut commands: Commands) { for bone in bones.iter() { let boneid = commands .spawn(( + Name::new(format!("{:?} {:?}", hand, bone)), SpatialBundle::default(), - bone.clone(), + *bone, OpenXRTracker, - hand.clone(), + *hand, BoneTrackingStatus::Emulated, HandBoneRadius(0.1), )) .id(); - match hand { - Hand::Left => match bone { - HandBone::Palm => hand_resource.left.palm = boneid, - HandBone::Wrist => hand_resource.left.wrist = boneid, - HandBone::ThumbMetacarpal => hand_resource.left.thumb.metacarpal = boneid, - HandBone::ThumbProximal => hand_resource.left.thumb.proximal = boneid, - HandBone::ThumbDistal => hand_resource.left.thumb.distal = boneid, - HandBone::ThumbTip => hand_resource.left.thumb.tip = boneid, - HandBone::IndexMetacarpal => hand_resource.left.index.metacarpal = boneid, - HandBone::IndexProximal => hand_resource.left.index.proximal = boneid, - HandBone::IndexIntermediate => hand_resource.left.index.intermediate = boneid, - HandBone::IndexDistal => hand_resource.left.index.distal = boneid, - HandBone::IndexTip => hand_resource.left.index.tip = boneid, - HandBone::MiddleMetacarpal => hand_resource.left.middle.metacarpal = boneid, - HandBone::MiddleProximal => hand_resource.left.middle.proximal = boneid, - HandBone::MiddleIntermediate => hand_resource.left.middle.intermediate = boneid, - HandBone::MiddleDistal => hand_resource.left.middle.distal = boneid, - HandBone::MiddleTip => hand_resource.left.middle.tip = boneid, - HandBone::RingMetacarpal => hand_resource.left.ring.metacarpal = boneid, - HandBone::RingProximal => hand_resource.left.ring.proximal = boneid, - HandBone::RingIntermediate => hand_resource.left.ring.intermediate = boneid, - HandBone::RingDistal => hand_resource.left.ring.distal = boneid, - HandBone::RingTip => hand_resource.left.ring.tip = boneid, - HandBone::LittleMetacarpal => hand_resource.left.little.metacarpal = boneid, - HandBone::LittleProximal => hand_resource.left.little.proximal = boneid, - HandBone::LittleIntermediate => hand_resource.left.little.intermediate = boneid, - HandBone::LittleDistal => hand_resource.left.little.distal = boneid, - HandBone::LittleTip => hand_resource.left.little.tip = boneid, - }, - Hand::Right => match bone { - HandBone::Palm => hand_resource.right.palm = boneid, - HandBone::Wrist => hand_resource.right.wrist = boneid, - HandBone::ThumbMetacarpal => hand_resource.right.thumb.metacarpal = boneid, - HandBone::ThumbProximal => hand_resource.right.thumb.proximal = boneid, - HandBone::ThumbDistal => hand_resource.right.thumb.distal = boneid, - HandBone::ThumbTip => hand_resource.right.thumb.tip = boneid, - HandBone::IndexMetacarpal => hand_resource.right.index.metacarpal = boneid, - HandBone::IndexProximal => hand_resource.right.index.proximal = boneid, - HandBone::IndexIntermediate => hand_resource.right.index.intermediate = boneid, - HandBone::IndexDistal => hand_resource.right.index.distal = boneid, - HandBone::IndexTip => hand_resource.right.index.tip = boneid, - HandBone::MiddleMetacarpal => hand_resource.right.middle.metacarpal = boneid, - HandBone::MiddleProximal => hand_resource.right.middle.proximal = boneid, - HandBone::MiddleIntermediate => { - hand_resource.right.middle.intermediate = boneid - } - HandBone::MiddleDistal => hand_resource.right.middle.distal = boneid, - HandBone::MiddleTip => hand_resource.right.middle.tip = boneid, - HandBone::RingMetacarpal => hand_resource.right.ring.metacarpal = boneid, - HandBone::RingProximal => hand_resource.right.ring.proximal = boneid, - HandBone::RingIntermediate => hand_resource.right.ring.intermediate = boneid, - HandBone::RingDistal => hand_resource.right.ring.distal = boneid, - HandBone::RingTip => hand_resource.right.ring.tip = boneid, - HandBone::LittleMetacarpal => hand_resource.right.little.metacarpal = boneid, - HandBone::LittleProximal => hand_resource.right.little.proximal = boneid, - HandBone::LittleIntermediate => { - hand_resource.right.little.intermediate = boneid - } - HandBone::LittleDistal => hand_resource.right.little.distal = boneid, - HandBone::LittleTip => hand_resource.right.little.tip = boneid, - }, + let hand_res = match hand { + Hand::Left => &mut hand_resource.left, + Hand::Right => &mut hand_resource.right, + }; + match bone { + HandBone::Palm => hand_res.palm = boneid, + HandBone::Wrist => hand_res.wrist = boneid, + HandBone::ThumbMetacarpal => hand_res.thumb.metacarpal = boneid, + HandBone::ThumbProximal => hand_res.thumb.proximal = boneid, + HandBone::ThumbDistal => hand_res.thumb.distal = boneid, + HandBone::ThumbTip => hand_res.thumb.tip = boneid, + HandBone::IndexMetacarpal => hand_res.index.metacarpal = boneid, + HandBone::IndexProximal => hand_res.index.proximal = boneid, + HandBone::IndexIntermediate => hand_res.index.intermediate = boneid, + HandBone::IndexDistal => hand_res.index.distal = boneid, + HandBone::IndexTip => hand_res.index.tip = boneid, + HandBone::MiddleMetacarpal => hand_res.middle.metacarpal = boneid, + HandBone::MiddleProximal => hand_res.middle.proximal = boneid, + HandBone::MiddleIntermediate => hand_res.middle.intermediate = boneid, + HandBone::MiddleDistal => hand_res.middle.distal = boneid, + HandBone::MiddleTip => hand_res.middle.tip = boneid, + HandBone::RingMetacarpal => hand_res.ring.metacarpal = boneid, + HandBone::RingProximal => hand_res.ring.proximal = boneid, + HandBone::RingIntermediate => hand_res.ring.intermediate = boneid, + HandBone::RingDistal => hand_res.ring.distal = boneid, + HandBone::RingTip => hand_res.ring.tip = boneid, + HandBone::LittleMetacarpal => hand_res.little.metacarpal = boneid, + HandBone::LittleProximal => hand_res.little.proximal = boneid, + HandBone::LittleIntermediate => hand_res.little.intermediate = boneid, + HandBone::LittleDistal => hand_res.little.distal = boneid, + HandBone::LittleTip => hand_res.little.tip = boneid, } } } @@ -241,16 +216,12 @@ pub struct HandBoneRadius(pub f32); pub fn draw_hand_entities( mut gizmos: Gizmos, - query: Query<(&Transform, &HandBone, &HandBoneRadius)>, + query: Query<(&GlobalTransform, &HandBone, &HandBoneRadius)>, ) { for (transform, hand_bone, hand_bone_radius) in query.iter() { let (_, color) = get_bone_gizmo_style(hand_bone); - gizmos.sphere( - transform.translation, - transform.rotation, - hand_bone_radius.0, - color, - ); + let (_, rotation, translation) = transform.to_scale_rotation_translation(); + gizmos.sphere(translation, rotation, hand_bone_radius.0, color); } } diff --git a/src/xr_input/hands/emulated.rs b/src/xr_input/hands/emulated.rs index ab1e627..9ebbc73 100644 --- a/src/xr_input/hands/emulated.rs +++ b/src/xr_input/hands/emulated.rs @@ -92,8 +92,6 @@ fn setup_hand_emulation_action_set(mut action_sets: ResMut) { suggest_oculus_touch_profile(action_set); } -pub struct EmulatedHandPoseData {} - fn suggest_oculus_touch_profile(action_set: &mut SetupActionSet) { action_set.suggest_binding( "/interaction_profiles/oculus/touch_controller", @@ -131,7 +129,6 @@ pub(crate) fn update_hand_skeleton_from_emulated( action_sets: Res, left_controller_transform: Query<&Transform, With>, right_controller_transform: Query<&Transform, With>, - tracking_root_transform: Query<&Transform, With>, mut bones: Query< ( &mut Transform, @@ -226,7 +223,6 @@ pub(crate) fn update_hand_skeleton_from_emulated( }, } } - let trt = tracking_root_transform.single(); for (mut t, bone, hand, status, mut radius) in bones.iter_mut() { match status { BoneTrackingStatus::Emulated => {} @@ -238,9 +234,9 @@ pub(crate) fn update_hand_skeleton_from_emulated( Hand::Left => 0, Hand::Right => 1, }][bone.get_index_from_bone()]; - *t = t.with_scale(trt.scale); - *t = t.with_rotation(trt.rotation * t.rotation); - *t = t.with_translation(trt.transform_point(t.translation)); + // *t = t.with_scale(trt.scale); + // *t = t.with_rotation(trt.rotation * t.rotation); + // *t = t.with_translation(trt.transform_point(t.translation)); } } pub fn update_hand_bones_emulated( diff --git a/src/xr_input/hands/hand_tracking.rs b/src/xr_input/hands/hand_tracking.rs index fd8c920..e2326a1 100644 --- a/src/xr_input/hands/hand_tracking.rs +++ b/src/xr_input/hands/hand_tracking.rs @@ -6,7 +6,7 @@ use crate::{ input::XrInput, resources::{XrFrameState, XrSession}, xr_init::xr_only, - xr_input::{hands::HandBone, trackers::OpenXRTrackingRoot, Hand, QuatConv, Vec3Conv}, + xr_input::{hands::HandBone, Hand, QuatConv, Vec3Conv}, }; use super::BoneTrackingStatus; @@ -158,7 +158,6 @@ pub fn update_hand_bones( hand_tracking: Option>, xr_input: Res, xr_frame_state: Res, - root_query: Query<(&Transform, With, Without)>, mut bones: Query<( &mut Transform, &Hand, @@ -174,7 +173,6 @@ pub fn update_hand_bones( return; } }; - let (root_transform, _, _) = root_query.get_single().unwrap(); let left_hand_data = hand_ref.get_poses(Hand::Left); let right_hand_data = hand_ref.get_poses(Hand::Right); bones @@ -203,8 +201,7 @@ pub fn update_hand_bones( *status = BoneTrackingStatus::Tracked; } radius.0 = bone_data.radius; - *transform = transform - .with_translation(root_transform.transform_point(bone_data.position)) - .with_rotation(root_transform.rotation * bone_data.orientation) + transform.translation = bone_data.position; + transform.rotation = bone_data.orientation; }); } diff --git a/src/xr_input/hands/mod.rs b/src/xr_input/hands/mod.rs index fa85cf8..8ab17d8 100644 --- a/src/xr_input/hands/mod.rs +++ b/src/xr_input/hands/mod.rs @@ -1,38 +1,50 @@ -use bevy::{app::PluginGroupBuilder, prelude::*}; +use bevy::prelude::*; use openxr::FormFactor; use crate::{ resources::{XrInstance, XrSession}, - xr_init::XrPreSetup, + xr_init::{XrCleanup, XrPreSetup, XrSetup}, }; use self::{ - emulated::HandEmulationPlugin, - hand_tracking::{DisableHandTracking, HandTrackingData, HandTrackingPlugin}, + common::{spawn_hand_entities, HandBoneRadius, HandsResource}, + hand_tracking::{DisableHandTracking, HandTrackingData}, }; +use super::{trackers::OpenXRTracker, Hand}; + pub mod common; pub mod emulated; pub mod hand_tracking; -pub struct XrHandPlugins; - -impl Plugin for XrHandPlugins { - fn build(&self, app: &mut App) { - app.add_plugins(HandTrackingPlugin) - .add_plugins(HandPlugin) - .add_plugins(HandEmulationPlugin); - } -} - pub struct HandPlugin; impl Plugin for HandPlugin { fn build(&self, app: &mut App) { app.add_systems(XrPreSetup, check_for_handtracking); + app.add_systems(XrSetup, spawn_hand_entities); + app.add_systems(XrCleanup, despawn_hand_entities); } } +#[allow(clippy::type_complexity)] +fn despawn_hand_entities( + mut commands: Commands, + hand_entities: Query< + Entity, + ( + With, + With, + With, + ), + >, +) { + for e in &hand_entities { + commands.entity(e).despawn_recursive(); + } + commands.remove_resource::() +} + fn check_for_handtracking( mut commands: Commands, instance: Res, @@ -86,21 +98,17 @@ pub enum HandBone { } impl HandBone { pub fn is_finger(&self) -> bool { - match &self { - HandBone::Wrist => false, - HandBone::Palm => false, - _ => true, - } + !matches!(self, HandBone::Wrist | HandBone::Palm) } pub fn is_metacarpal(&self) -> bool { - match &self { - HandBone::ThumbMetacarpal => true, - HandBone::IndexMetacarpal => true, - HandBone::MiddleMetacarpal => true, - HandBone::RingMetacarpal => true, - HandBone::LittleTip => true, - _ => false, - } + matches!( + self, + HandBone::ThumbMetacarpal + | HandBone::IndexMetacarpal + | HandBone::MiddleMetacarpal + | HandBone::RingMetacarpal + | HandBone::LittleTip + ) } pub const fn get_all_bones() -> [HandBone; 26] { [