diff --git a/src/main.rs b/src/main.rs index 6a7f524..772dbc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,6 +91,10 @@ struct CliArgs { #[clap(short, long, action)] flatscreen: bool, + /// Force Pipelined Rending, improving fps at the cost of latency + #[clap(short, long, action)] + pipelined_rendering: bool, + /// If monado insists on emulating them, set this flag...we want the raw input #[clap(long)] disable_controllers: bool, @@ -297,6 +301,10 @@ fn bevy_loop( .add(AudioPlugin::default()) .add(GizmoPlugin); + if args.pipelined_rendering { + base = base.add(PipelinedRenderingPlugin); + } + if args.flatscreen { bevy_app.add_plugins(base); } else { diff --git a/src/objects/input/sk_controller.rs b/src/objects/input/sk_controller.rs index 5b59ec3..97e82e1 100644 --- a/src/objects/input/sk_controller.rs +++ b/src/objects/input/sk_controller.rs @@ -17,13 +17,14 @@ use bevy::{ color::LinearRgba, gltf::GltfAssetLabel, pbr::MeshMaterial3d, - prelude::{Children, Commands, Component, Mesh, Query, Res, ResMut, Transform}, + prelude::{Children, Commands, Component, IntoSystemConfigs as _, Mesh, Query, Res, ResMut, Transform}, scene::SceneRoot, utils::default, }; use bevy_mod_openxr::{ helper_traits::{ToQuat, ToVec2, ToVec3}, - resources::OxrFrameState, + openxr_session_running, + resources::{OxrFrameState, Pipelined}, session::OxrSession, spaces::{OxrSpaceExt, OxrSpaceLocationFlags}, }; @@ -56,7 +57,10 @@ impl Plugin for StardustControllerPlugin { fn build(&self, app: &mut App) { embedded_asset!(app, "src/objects/input", "cursor.glb"); app.add_systems(XrSessionCreated, spawn_controllers); - app.add_systems(InputUpdate, update_controllers); + app.add_systems( + InputUpdate, + update_controllers.run_if(openxr_session_running), + ); } } @@ -66,14 +70,22 @@ fn update_controllers( time: Res, base_space: Res, session: ResMut, + pipelined: Option>, ) { for (mut controller, mut transform) in query.iter_mut() { let input_node = controller.input.spatial.node().unwrap(); + let time = if pipelined.is_some() { + openxr::Time::from_nanos( + time.predicted_display_time.as_nanos() + time.predicted_display_period.as_nanos(), + ) + } else { + time.predicted_display_time + }; let location = (|| { let location = match session.locate_space( &XrSpace::from_raw_openxr_space(controller.space.as_raw()), &base_space, - time.predicted_display_time, + time, ) { Err(err) => { error!("issues locating controller space: {err}"); diff --git a/src/objects/input/sk_hand.rs b/src/objects/input/sk_hand.rs index 212f0c9..c770fb0 100644 --- a/src/objects/input/sk_hand.rs +++ b/src/objects/input/sk_hand.rs @@ -17,7 +17,8 @@ use bevy::prelude::{ }; use bevy::utils::default; use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3}; -use bevy_mod_openxr::resources::OxrFrameState; +use bevy_mod_openxr::openxr_session_running; +use bevy_mod_openxr::resources::{OxrFrameState, Pipelined}; use bevy_mod_openxr::session::OxrSession; use bevy_mod_openxr::spaces::OxrSpaceLocationFlags; use bevy_mod_xr::hands::{HandBone, HandSide}; @@ -45,7 +46,14 @@ pub struct StardustHandPlugin; impl Plugin for StardustHandPlugin { fn build(&self, app: &mut bevy::prelude::App) { app.add_systems(XrSessionCreated, create_hands); - app.add_systems(InputUpdate, (update_hands,draw_hand_gizmos).chain()); + app.add_systems( + InputUpdate, + ( + update_hands.run_if(openxr_session_running), + draw_hand_gizmos, + ) + .chain(), + ); } } @@ -61,10 +69,18 @@ fn update_hands( time: Res, base_space: Res, session: ResMut, + pipelined: Option>, ) { + let time = if pipelined.is_some() { + openxr::Time::from_nanos( + time.predicted_display_time.as_nanos() + time.predicted_display_period.as_nanos(), + ) + } else { + time.predicted_display_time + }; for mut hand in &mut query { let joints = session - .locate_hand_joints(&hand.hand_tracker, &base_space, time.predicted_display_time) + .locate_hand_joints(&hand.hand_tracker, &base_space, time) .unwrap(); if let InputDataType::Hand(hand_input) = &mut *hand.input.data.lock() { let input_node = hand.input.spatial.node().unwrap();