diff --git a/src/backend/input.rs b/src/backend/input.rs index 5b50883..28a41f8 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -159,6 +159,7 @@ impl Default for InteractionState { pub struct Pointer { pub idx: usize, pub pose: Affine3A, + pub raw_pose: Affine3A, pub now: PointerState, pub before: PointerState, pub last_click: Instant, @@ -171,6 +172,7 @@ impl Pointer { Self { idx, pose: Affine3A::IDENTITY, + raw_pose: Affine3A::IDENTITY, now: Default::default(), before: Default::default(), last_click: Instant::now(), diff --git a/src/backend/openvr/input.rs b/src/backend/openvr/input.rs index 6ae7592..e690988 100644 --- a/src/backend/openvr/input.rs +++ b/src/backend/openvr/input.rs @@ -56,6 +56,7 @@ pub(super) struct OpenVrInputSource { pub(super) struct OpenVrHandSource { has_pose: bool, + device: Option, input_hnd: InputValueHandle, pose_hnd: ActionHandle, haptics_hnd: ActionHandle, @@ -91,6 +92,7 @@ impl OpenVrInputSource { let hands: [OpenVrHandSource; 2] = array::from_fn(|i| OpenVrHandSource { has_pose: false, + device: None, input_hnd: input_hnd[i], pose_hnd: pose_hnd[i], haptics_hnd: haptics_hnd[i], @@ -124,6 +126,7 @@ impl OpenVrInputSource { pub fn update( &mut self, + universe: ETrackingUniverseOrigin, input: &mut InputManager, system: &mut SystemManager, app: &mut AppState, @@ -138,12 +141,19 @@ impl OpenVrInputSource { let _ = input.update_actions(&mut [aas]); - let universe = ETrackingUniverseOrigin::TrackingUniverseStanding; + let devices = system.get_device_to_absolute_tracking_pose(universe.clone(), 0.005); + app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine(); for i in 0..2 { let hand = &mut self.hands[i]; let app_hand = &mut app.input_state.pointers[i]; + if let Some(device) = hand.device { + app_hand.raw_pose = devices[device.0 as usize] + .mDeviceToAbsoluteTracking + .to_affine(); + } + hand.has_pose = false; let _ = input @@ -198,14 +208,10 @@ impl OpenVrInputSource { .map(|x| x.0.y) .unwrap_or(0.0); } - - let devices = system.get_device_to_absolute_tracking_pose(universe, 0.005); - app.input_state.hmd = devices[0].mDeviceToAbsoluteTracking.to_affine(); } pub fn update_devices(&mut self, system: &mut SystemManager, app: &mut AppState) { app.input_state.devices.clear(); - for idx in 0..TrackedDeviceIndex::MAX { let device = TrackedDeviceIndex::new(idx as _).unwrap(); // safe if !system.is_tracked_device_connected(device) { @@ -220,9 +226,11 @@ impl OpenVrInputSource { let role = system.get_controller_role_for_tracked_device_index(device); match role { ETrackedControllerRole::TrackedControllerRole_LeftHand => { + self.hands[0].device = Some(device); TrackedDeviceRole::LeftHand } ETrackedControllerRole::TrackedControllerRole_RightHand => { + self.hands[1].device = Some(device); TrackedDeviceRole::RightHand } _ => continue, diff --git a/src/backend/openvr/mod.rs b/src/backend/openvr/mod.rs index cbb2e26..edcb449 100644 --- a/src/backend/openvr/mod.rs +++ b/src/backend/openvr/mod.rs @@ -100,8 +100,8 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { notifications.run_dbus(); notifications.run_udp(); - let mut space_mover = playspace::PlayspaceMover::new(); - space_mover.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr); + let mut playspace = playspace::PlayspaceMover::new(); + playspace.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr); #[cfg(feature = "osc")] let mut osc_sender = @@ -159,7 +159,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { EVREventType::VREvent_SeatedZeroPoseReset | EVREventType::VREvent_StandingZeroPoseReset | EVREventType::VREvent_ChaperoneUniverseHasChanged => { - space_mover.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr); + playspace.playspace_changed(&mut compositor_mgr, &mut chaperone_mgr); } _ => {} } @@ -210,17 +210,22 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { let _ = adjust_gain(&mut settings_mgr, channel, value); } SystemTask::FixFloor => { - space_mover.fix_floor(&mut chaperone_mgr, &state.input_state); + playspace.fix_floor(&mut chaperone_mgr, &state.input_state); } SystemTask::ResetPlayspace => { - space_mover.reset_offset(&mut chaperone_mgr); + playspace.reset_offset(&mut chaperone_mgr); } }, } } state.input_state.pre_update(); - input_source.update(&mut input_mgr, &mut system_mgr, &mut state); + input_source.update( + playspace.get_universe(), + &mut input_mgr, + &mut system_mgr, + &mut state, + ); state.input_state.post_update(); if state @@ -237,7 +242,7 @@ pub fn openvr_run(running: Arc) -> Result<(), BackendError> { .for_each(|o| o.state.auto_movement(&mut state)); watch_fade(&mut state, overlays.mut_by_id(watch_id).unwrap()); // want panic - space_mover.update(&mut chaperone_mgr, &mut overlays, &state); + playspace.update(&mut chaperone_mgr, &mut overlays, &state); let lengths_haptics = interact(&mut overlays, &mut state); for (idx, (len, haptics)) in lengths_haptics.iter().enumerate() { diff --git a/src/backend/openvr/playspace.rs b/src/backend/openvr/playspace.rs index 58bcbfa..1139121 100644 --- a/src/backend/openvr/playspace.rs +++ b/src/backend/openvr/playspace.rs @@ -14,7 +14,6 @@ use super::{helpers::Affine3AConvert, overlay::OpenVrOverlayData}; struct DragData { pose: Affine3A, - pose_inverse: Affine3A, hand: usize, hand_pos: Vec3A, } @@ -46,24 +45,27 @@ impl PlayspaceMover { log::info!("End space drag"); return; } - let new_hand = state.input_state.pointers[data.hand].pose.translation; - let new_hand_local = new_hand; - let relative_pos = data.pose.transform_vector3a(new_hand_local - data.hand_pos); - log::info!("Space drag: {:?}", relative_pos); + let new_hand = + state.input_state.pointers[data.hand].raw_pose.translation + data.pose.translation; + let relative_pos = data.pose.transform_vector3a(new_hand - data.hand_pos); + + if relative_pos.length_squared() > 1000.0 { + log::warn!("Space drag too fast, ignoring"); + return; + } overlays.iter_mut().for_each(|overlay| { if overlay.state.grabbable { overlay.state.dirty = true; - overlay.state.transform.translation += relative_pos * -1.0; + overlay.state.transform.translation -= relative_pos; } }); - let mut mat = data.pose.clone(); - mat.translation += relative_pos; - //data.hand_pos = data.pose.inverse().transform_point3a(new_hand); + data.pose.translation += relative_pos; + data.hand_pos = new_hand; - set_working_copy(&universe, chaperone_mgr, &mat); + set_working_copy(&universe, chaperone_mgr, &data.pose); chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live); } else { for (i, pointer) in state.input_state.pointers.iter().enumerate() { @@ -72,11 +74,9 @@ impl PlayspaceMover { log::warn!("Can't space drag - failed to get zero pose"); return; }; - let pose_inverse = mat.inverse(); - let hand_pos = pointer.pose.translation; + let hand_pos = pointer.raw_pose.translation + mat.translation; self.last = Some(DragData { pose: mat, - pose_inverse, hand: i, hand_pos, }); @@ -129,6 +129,10 @@ impl PlayspaceMover { self.last = None; } } + + pub fn get_universe(&self) -> ETrackingUniverseOrigin { + self.universe.clone() + } } fn universe_str(universe: &ETrackingUniverseOrigin) -> &'static str {