From 0141ec2074856c0bd405b36227b4601d85e73e27 Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Tue, 5 Sep 2023 18:46:04 +0800 Subject: [PATCH] feat: :sparkles: Add automatic button mapping system (internal) (#1817) --- alvr/client_core/src/lib.rs | 11 + alvr/client_openxr/src/interaction.rs | 418 +-------- alvr/client_openxr/src/lib.rs | 18 +- alvr/common/src/inputs.rs | 907 ++++++++++++++++++++ alvr/common/src/lib.rs | 4 +- alvr/common/src/paths.rs | 90 -- alvr/server/cpp/ALVR-common/packet_types.h | 34 - alvr/server/cpp/alvr_server/Controller.cpp | 856 ++++-------------- alvr/server/cpp/alvr_server/Controller.h | 24 +- alvr/server/cpp/alvr_server/Paths.cpp | 247 ++++-- alvr/server/cpp/alvr_server/Paths.h | 70 +- alvr/server/cpp/alvr_server/Settings.cpp | 6 +- alvr/server/cpp/alvr_server/Settings.h | 6 +- alvr/server/cpp/alvr_server/alvr_server.cpp | 26 +- alvr/server/cpp/alvr_server/bindings.h | 4 +- alvr/server/src/buttons.rs | 45 - alvr/server/src/connection.rs | 112 ++- alvr/server/src/input_mapping.rs | 636 ++++++++++++++ alvr/server/src/lib.rs | 3 +- alvr/server/src/openvr_props.rs | 88 +- alvr/session/src/lib.rs | 6 +- alvr/session/src/settings.rs | 53 +- 22 files changed, 2086 insertions(+), 1578 deletions(-) create mode 100644 alvr/common/src/inputs.rs delete mode 100644 alvr/common/src/paths.rs delete mode 100644 alvr/server/src/buttons.rs create mode 100644 alvr/server/src/input_mapping.rs diff --git a/alvr/client_core/src/lib.rs b/alvr/client_core/src/lib.rs index 3b68062b..a73e934e 100644 --- a/alvr/client_core/src/lib.rs +++ b/alvr/client_core/src/lib.rs @@ -167,6 +167,17 @@ pub fn send_playspace(area: Option) { } } +pub fn send_active_interaction_profile(device_id: u64, profile_id: u64) { + if let Some(sender) = &mut *CONTROL_SENDER.lock() { + sender + .send(&ClientControlPacket::ActiveInteractionProfile { + device_id, + profile_id, + }) + .ok(); + } +} + pub fn send_buttons(entries: Vec) { if let Some(sender) = &mut *CONTROL_SENDER.lock() { sender.send(&ClientControlPacket::Buttons(entries)).ok(); diff --git a/alvr/client_openxr/src/interaction.rs b/alvr/client_openxr/src/interaction.rs index 67a52a93..5f2f0ced 100644 --- a/alvr/client_openxr/src/interaction.rs +++ b/alvr/client_openxr/src/interaction.rs @@ -4,11 +4,6 @@ use alvr_packets::{ButtonEntry, ButtonValue}; use openxr as xr; use std::collections::HashMap; -enum BindingType { - Binary, - Scalar, -} - pub enum ButtonAction { Binary(xr::Action), Scalar(xr::Action), @@ -21,281 +16,8 @@ pub struct HandSource { pub vibration_action: xr::Action, } -pub struct ButtonBindingInfo { - name: String, - //note: this might be different than the path that generated the id - binding_path: String, - binding_type: BindingType, -} - -const QUEST_CONTROLLER_PROFILE: &str = "/interaction_profiles/oculus/touch_controller"; -const PICO_NEO3_CONTROLLER_PROFILE: &str = "/interaction_profiles/bytedance/pico_neo3_controller"; -const PICO4_CONTROLLER_PROFILE: &str = "/interaction_profiles/bytedance/pico4_controller"; -const FOCUS3_CONTROLLER_PROFILE: &str = "/interaction_profiles/htc/vive_focus3_controller"; -const YVR_CONTROLLER_PROFILE: &str = "/interaction_profiles/yvr/touch_controller"; - -fn get_button_bindings(platform: Platform) -> HashMap { - let mut map = HashMap::new(); - - // Baseline bindings for the Touch controller - map.insert( - *MENU_CLICK_ID, - ButtonBindingInfo { - name: "menu_click".into(), - binding_path: MENU_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *A_CLICK_ID, - ButtonBindingInfo { - name: "a_click".into(), - binding_path: A_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *A_TOUCH_ID, - ButtonBindingInfo { - name: "a_touch".into(), - binding_path: A_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *B_CLICK_ID, - ButtonBindingInfo { - name: "b_click".into(), - binding_path: B_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *B_TOUCH_ID, - ButtonBindingInfo { - name: "b_touch".into(), - binding_path: B_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *X_CLICK_ID, - ButtonBindingInfo { - name: "x_click".into(), - binding_path: X_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *X_TOUCH_ID, - ButtonBindingInfo { - name: "x_touch".into(), - binding_path: X_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *Y_CLICK_ID, - ButtonBindingInfo { - name: "y_click".into(), - binding_path: Y_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *Y_TOUCH_ID, - ButtonBindingInfo { - name: "y_touch".into(), - binding_path: Y_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_SQUEEZE_VALUE_ID, - ButtonBindingInfo { - name: "left_squeeze_value".into(), - binding_path: LEFT_SQUEEZE_VALUE_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *LEFT_SQUEEZE_CLICK_ID, - ButtonBindingInfo { - name: "left_squeeze_click".into(), - binding_path: "/user/hand/left/input/squeeze".into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_TRIGGER_VALUE_ID, - ButtonBindingInfo { - name: "left_trigger_value".into(), - binding_path: LEFT_TRIGGER_VALUE_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *LEFT_TRIGGER_CLICK_ID, - ButtonBindingInfo { - name: "left_trigger_click".into(), - binding_path: "/user/hand/left/input/trigger".into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_TRIGGER_TOUCH_ID, - ButtonBindingInfo { - name: "left_trigger_touch".into(), - binding_path: LEFT_TRIGGER_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_THUMBSTICK_X_ID, - ButtonBindingInfo { - name: "left_thumbstick_x".into(), - binding_path: LEFT_THUMBSTICK_X_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *LEFT_THUMBSTICK_Y_ID, - ButtonBindingInfo { - name: "left_thumbstick_y".into(), - binding_path: LEFT_THUMBSTICK_Y_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *LEFT_THUMBSTICK_CLICK_ID, - ButtonBindingInfo { - name: "left_thumbstick_click".into(), - binding_path: LEFT_THUMBSTICK_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_THUMBSTICK_TOUCH_ID, - ButtonBindingInfo { - name: "left_thumbstick_touch".into(), - binding_path: LEFT_THUMBSTICK_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *LEFT_THUMBREST_TOUCH_ID, - ButtonBindingInfo { - name: "left_thumbrest_touch".into(), - binding_path: LEFT_THUMBREST_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_SQUEEZE_VALUE_ID, - ButtonBindingInfo { - name: "right_squeeze_value".into(), - binding_path: RIGHT_SQUEEZE_VALUE_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *RIGHT_SQUEEZE_CLICK_ID, - ButtonBindingInfo { - name: "right_squeeze_click".into(), - binding_path: "/user/hand/right/input/squeeze".into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_TRIGGER_VALUE_ID, - ButtonBindingInfo { - name: "right_trigger_value".into(), - binding_path: RIGHT_TRIGGER_VALUE_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *RIGHT_TRIGGER_CLICK_ID, - ButtonBindingInfo { - name: "right_trigger_click".into(), - binding_path: "/user/hand/right/input/trigger".into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_TRIGGER_TOUCH_ID, - ButtonBindingInfo { - name: "right_trigger_touch".into(), - binding_path: RIGHT_TRIGGER_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_THUMBSTICK_X_ID, - ButtonBindingInfo { - name: "right_thumbstick_x".into(), - binding_path: RIGHT_THUMBSTICK_X_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *RIGHT_THUMBSTICK_Y_ID, - ButtonBindingInfo { - name: "right_thumbstick_y".into(), - binding_path: RIGHT_THUMBSTICK_Y_PATH.into(), - binding_type: BindingType::Scalar, - }, - ); - map.insert( - *RIGHT_THUMBSTICK_CLICK_ID, - ButtonBindingInfo { - name: "right_thumbstick_click".into(), - binding_path: RIGHT_THUMBSTICK_CLICK_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_THUMBSTICK_TOUCH_ID, - ButtonBindingInfo { - name: "right_thumbstick_touch".into(), - binding_path: RIGHT_THUMBSTICK_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - map.insert( - *RIGHT_THUMBREST_TOUCH_ID, - ButtonBindingInfo { - name: "right_thumbrest_touch".into(), - binding_path: RIGHT_THUMBREST_TOUCH_PATH.into(), - binding_type: BindingType::Binary, - }, - ); - - // Tweak bindings if other platforms - match platform { - Platform::Focus3 => { - map.remove(&*A_TOUCH_ID); - map.remove(&*B_TOUCH_ID); - map.remove(&*X_TOUCH_ID); - map.remove(&*Y_TOUCH_ID); - map.remove(&*LEFT_SQUEEZE_CLICK_ID); - map.remove(&*LEFT_TRIGGER_CLICK_ID); - map.remove(&*LEFT_THUMBREST_TOUCH_ID); - map.remove(&*RIGHT_SQUEEZE_CLICK_ID); - map.remove(&*RIGHT_TRIGGER_CLICK_ID); - map.remove(&*RIGHT_THUMBREST_TOUCH_ID); - } - Platform::Yvr => { - map.remove(&*LEFT_SQUEEZE_VALUE_ID); - map.remove(&*RIGHT_SQUEEZE_VALUE_ID); - } - _ => {} - } - - map -} - pub struct HandsInteractionContext { + pub interaction_profile_id: u64, pub action_set: xr::ActionSet, pub button_actions: HashMap, pub hand_sources: [HandSource; 2], @@ -317,31 +39,42 @@ pub fn initialize_hands_interaction( xr::Binding::new(action, action.instance().string_to_path(path).unwrap()) } - let bindings_info = get_button_bindings(platform); + let interaction_profile_path = match platform { + Platform::Quest => QUEST_CONTROLLER_PROFILE_PATH, + Platform::PicoNeo3 => PICO_NEO3_CONTROLLER_PROFILE_PATH, + Platform::Pico4 => PICO4_CONTROLLER_PROFILE_PATH, + Platform::Focus3 => FOCUS3_CONTROLLER_PROFILE_PATH, + Platform::Yvr => YVR_CONTROLLER_PROFILE_PATH, + Platform::Other => QUEST_CONTROLLER_PROFILE_PATH, + }; + let interaction_profile_id = alvr_common::hash_string(interaction_profile_path); // Create actions: let mut button_actions = HashMap::new(); - for (id, info) in &bindings_info { + for button_id in &CONTROLLER_PROFILE_INFO + .get(&interaction_profile_id) + .unwrap() + .button_set + { + let info = BUTTON_INFO.get(button_id).unwrap(); + + let name = info.path[1..].replace('/', "_"); let display_name = format!( "{}{}", - info.name[0..1].to_uppercase(), - info.name[1..].replace('_', " ") + name[0..1].to_uppercase(), + name[1..].replace('_', " ") ); - let action = match info.binding_type { - BindingType::Binary => ButtonAction::Binary( - action_set - .create_action(&info.name, &display_name, &[]) - .unwrap(), - ), - BindingType::Scalar => ButtonAction::Scalar( - action_set - .create_action(&info.name, &display_name, &[]) - .unwrap(), - ), + let action = match info.button_type { + ButtonType::Binary => { + ButtonAction::Binary(action_set.create_action(&name, &display_name, &[]).unwrap()) + } + ButtonType::Scalar => { + ButtonAction::Scalar(action_set.create_action(&name, &display_name, &[]).unwrap()) + } }; - button_actions.insert(*id, action); + button_actions.insert(*button_id, action); } let left_grip_action = action_set @@ -361,7 +94,7 @@ pub fn initialize_hands_interaction( // Create action bindings: for (id, action) in &button_actions { - let path = &bindings_info.get(id).unwrap().binding_path; + let path = &BUTTON_INFO.get(id).unwrap().path; match action { ButtonAction::Binary(action) => { bindings.push(binding(action, path)); @@ -391,19 +124,11 @@ pub fn initialize_hands_interaction( )); // Apply bindings: - - let controller_profile = match platform { - Platform::Quest => QUEST_CONTROLLER_PROFILE, - Platform::PicoNeo3 => PICO_NEO3_CONTROLLER_PROFILE, - Platform::Pico4 => PICO4_CONTROLLER_PROFILE, - Platform::Focus3 => FOCUS3_CONTROLLER_PROFILE, - Platform::Yvr => YVR_CONTROLLER_PROFILE, - Platform::Other => QUEST_CONTROLLER_PROFILE, - }; - xr_instance .suggest_interaction_profile_bindings( - xr_instance.string_to_path(controller_profile).unwrap(), + xr_instance + .string_to_path(interaction_profile_path) + .unwrap(), &bindings, ) .unwrap(); @@ -444,6 +169,7 @@ pub fn initialize_hands_interaction( ]; HandsInteractionContext { + interaction_profile_id, action_set, button_actions, hand_sources, @@ -528,73 +254,7 @@ pub fn get_hand_motion( (Some(hand_motion), None) } -// todo: move emulation to server -fn emulate_missing_button_value( - platform: Platform, - click_action_id: u64, - state: bool, -) -> Option { - let value = ButtonValue::Scalar(if state { 1_f32 } else { 0_f32 }); - - if platform == Platform::Yvr { - if click_action_id == *LEFT_SQUEEZE_CLICK_ID { - Some(ButtonEntry { - path_id: *LEFT_SQUEEZE_VALUE_ID, - value, - }) - } else if click_action_id == *RIGHT_SQUEEZE_CLICK_ID { - Some(ButtonEntry { - path_id: *RIGHT_SQUEEZE_VALUE_ID, - value, - }) - } else { - None - } - } else { - None - } -} - -// todo: use hysteresis -// todo: move emulation to server -fn emulate_missing_button_click( - platform: Platform, - value_action_id: u64, - state: f32, -) -> Option { - let value = ButtonValue::Binary(state > 0.5); - - if platform == Platform::Focus3 { - if value_action_id == *LEFT_SQUEEZE_VALUE_ID { - Some(ButtonEntry { - path_id: *LEFT_SQUEEZE_CLICK_ID, - value, - }) - } else if value_action_id == *LEFT_TRIGGER_VALUE_ID { - Some(ButtonEntry { - path_id: *LEFT_TRIGGER_CLICK_ID, - value, - }) - } else if value_action_id == *RIGHT_SQUEEZE_VALUE_ID { - Some(ButtonEntry { - path_id: *RIGHT_SQUEEZE_CLICK_ID, - value, - }) - } else if value_action_id == *RIGHT_TRIGGER_VALUE_ID { - Some(ButtonEntry { - path_id: *RIGHT_TRIGGER_CLICK_ID, - value, - }) - } else { - None - } - } else { - None - } -} - pub fn update_buttons( - platform: Platform, xr_session: &xr::Session, button_actions: &HashMap, ) -> Vec { @@ -611,12 +271,6 @@ pub fn update_buttons( path_id: *id, value: ButtonValue::Binary(state.current_state), }); - - if let Some(entry) = - emulate_missing_button_value(platform, *id, state.current_state) - { - button_entries.push(entry); - } } } ButtonAction::Scalar(action) => { @@ -629,12 +283,6 @@ pub fn update_buttons( path_id: *id, value: ButtonValue::Scalar(state.current_state), }); - - if let Some(entry) = - emulate_missing_button_click(platform, *id, state.current_state) - { - button_entries.push(entry); - } } } } diff --git a/alvr/client_openxr/src/lib.rs b/alvr/client_openxr/src/lib.rs index 68014ffc..5a1417b6 100644 --- a/alvr/client_openxr/src/lib.rs +++ b/alvr/client_openxr/src/lib.rs @@ -44,7 +44,6 @@ struct HistoryView { } struct StreamingInputContext { - platform: Platform, xr_instance: xr::Instance, xr_session: xr::Session, hands_context: Arc, @@ -341,11 +340,8 @@ fn update_streaming_input(ctx: &mut StreamingInputContext) { face_data, }); - let button_entries = interaction::update_buttons( - ctx.platform, - &ctx.xr_session, - &ctx.hands_context.button_actions, - ); + let button_entries = + interaction::update_buttons(&ctx.xr_session, &ctx.hands_context.button_actions); if !button_entries.is_empty() { alvr_client_core::send_buttons(button_entries); } @@ -691,7 +687,6 @@ pub fn entry_point() { }; let mut context = StreamingInputContext { - platform, xr_instance: xr_instance.clone(), xr_session: xr_session.clone().into_any_graphics(), hands_context: Arc::clone(&hands_context), @@ -797,6 +792,15 @@ pub fn entry_point() { .unwrap() .map(|a| Vec2::new(a.width, a.height)), ); + + alvr_client_core::send_active_interaction_profile( + *LEFT_HAND_ID, + hands_context.interaction_profile_id, + ); + alvr_client_core::send_active_interaction_profile( + *RIGHT_HAND_ID, + hands_context.interaction_profile_id, + ); } ClientCoreEvent::StreamingStopped => { stream_swapchains.take(); diff --git a/alvr/common/src/inputs.rs b/alvr/common/src/inputs.rs new file mode 100644 index 00000000..f512e4b1 --- /dev/null +++ b/alvr/common/src/inputs.rs @@ -0,0 +1,907 @@ +use crate::hash_string; +use once_cell::sync::Lazy; +use std::collections::{HashMap, HashSet}; + +// OpenXR interaction paths. They are used for the communication protocol and can also be used +// directly for OpenXR interop. +pub const HEAD_PATH: &str = "/user/head"; +pub const LEFT_HAND_PATH: &str = "/user/hand/left"; +pub const RIGHT_HAND_PATH: &str = "/user/hand/right"; + +pub const QUEST_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/oculus/touch_controller"; +pub const VIVE_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/htc/vive_controller"; +pub const INDEX_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/valve/index_controller"; +pub const PICO_NEO3_CONTROLLER_PROFILE_PATH: &str = + "/interaction_profiles/bytedance/pico_neo3_controller"; +pub const PICO4_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/bytedance/pico4_controller"; +pub const FOCUS3_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/htc/vive_focus3_controller"; +pub const YVR_CONTROLLER_PROFILE_PATH: &str = "/interaction_profiles/yvr/touch_controller"; + +pub const HEAD_ENTER_CLICK_PATH: &str = "/user/head/input/enter/click"; +pub const LEFT_SYSTEM_CLICK_PATH: &str = "/user/hand/left/input/system/click"; +pub const LEFT_SYSTEM_TOUCH_PATH: &str = "/user/hand/left/input/system/touch"; +pub const LEFT_MENU_CLICK_PATH: &str = "/user/hand/left/input/menu/click"; +pub const LEFT_BACK_CLICK_PATH: &str = "/user/hand/left/input/back/click"; +pub const LEFT_A_CLICK_PATH: &str = "/user/hand/left/input/a/click"; +pub const LEFT_A_TOUCH_PATH: &str = "/user/hand/left/input/a/touch"; +pub const LEFT_B_CLICK_PATH: &str = "/user/hand/left/input/b/click"; +pub const LEFT_B_TOUCH_PATH: &str = "/user/hand/left/input/b/touch"; +pub const LEFT_X_CLICK_PATH: &str = "/user/hand/left/input/x/click"; +pub const LEFT_X_TOUCH_PATH: &str = "/user/hand/left/input/x/touch"; +pub const LEFT_Y_CLICK_PATH: &str = "/user/hand/left/input/y/click"; +pub const LEFT_Y_TOUCH_PATH: &str = "/user/hand/left/input/y/touch"; +pub const LEFT_SQUEEZE_CLICK_PATH: &str = "/user/hand/left/input/squeeze/click"; +pub const LEFT_SQUEEZE_TOUCH_PATH: &str = "/user/hand/left/input/squeeze/touch"; +pub const LEFT_SQUEEZE_VALUE_PATH: &str = "/user/hand/left/input/squeeze/value"; +pub const LEFT_SQUEEZE_FORCE_PATH: &str = "/user/hand/left/input/squeeze/force"; +pub const LEFT_TRIGGER_CLICK_PATH: &str = "/user/hand/left/input/trigger/click"; +pub const LEFT_TRIGGER_TOUCH_PATH: &str = "/user/hand/left/input/trigger/touch"; +pub const LEFT_TRIGGER_VALUE_PATH: &str = "/user/hand/left/input/trigger/value"; +pub const LEFT_THUMBSTICK_X_PATH: &str = "/user/hand/left/input/thumbstick/x"; +pub const LEFT_THUMBSTICK_Y_PATH: &str = "/user/hand/left/input/thumbstick/y"; +pub const LEFT_THUMBSTICK_CLICK_PATH: &str = "/user/hand/left/input/thumbstick/click"; +pub const LEFT_THUMBSTICK_TOUCH_PATH: &str = "/user/hand/left/input/thumbstick/touch"; +pub const LEFT_TRACKPAD_X_PATH: &str = "/user/hand/left/input/trackpad/x"; +pub const LEFT_TRACKPAD_Y_PATH: &str = "/user/hand/left/input/trackpad/y"; +pub const LEFT_TRACKPAD_CLICK_PATH: &str = "/user/hand/left/input/trackpad/click"; +pub const LEFT_TRACKPAD_FORCE_PATH: &str = "/user/hand/left/input/trackpad/force"; +pub const LEFT_TRACKPAD_TOUCH_PATH: &str = "/user/hand/left/input/trackpad/touch"; +pub const LEFT_THUMBREST_TOUCH_PATH: &str = "/user/hand/left/input/thumbrest/touch"; + +pub const RIGHT_SYSTEM_CLICK_PATH: &str = "/user/hand/right/input/system/click"; +pub const RIGHT_SYSTEM_TOUCH_PATH: &str = "/user/hand/right/input/system/touch"; +pub const RIGHT_MENU_CLICK_PATH: &str = "/user/hand/right/input/menu/click"; +pub const RIGHT_BACK_CLICK_PATH: &str = "/user/hand/right/input/back/click"; +pub const RIGHT_A_CLICK_PATH: &str = "/user/hand/right/input/a/click"; +pub const RIGHT_A_TOUCH_PATH: &str = "/user/hand/right/input/a/touch"; +pub const RIGHT_B_CLICK_PATH: &str = "/user/hand/right/input/b/click"; +pub const RIGHT_B_TOUCH_PATH: &str = "/user/hand/right/input/b/touch"; +pub const RIGHT_SQUEEZE_CLICK_PATH: &str = "/user/hand/right/input/squeeze/click"; +pub const RIGHT_SQUEEZE_TOUCH_PATH: &str = "/user/hand/right/input/squeeze/touch"; +pub const RIGHT_SQUEEZE_VALUE_PATH: &str = "/user/hand/right/input/squeeze/value"; +pub const RIGHT_SQUEEZE_FORCE_PATH: &str = "/user/hand/right/input/squeeze/force"; +pub const RIGHT_TRIGGER_CLICK_PATH: &str = "/user/hand/right/input/trigger/click"; +pub const RIGHT_TRIGGER_VALUE_PATH: &str = "/user/hand/right/input/trigger/value"; +pub const RIGHT_TRIGGER_TOUCH_PATH: &str = "/user/hand/right/input/trigger/touch"; +pub const RIGHT_THUMBSTICK_X_PATH: &str = "/user/hand/right/input/thumbstick/x"; +pub const RIGHT_THUMBSTICK_Y_PATH: &str = "/user/hand/right/input/thumbstick/y"; +pub const RIGHT_THUMBSTICK_CLICK_PATH: &str = "/user/hand/right/input/thumbstick/click"; +pub const RIGHT_THUMBSTICK_TOUCH_PATH: &str = "/user/hand/right/input/thumbstick/touch"; +pub const RIGHT_TRACKPAD_X_PATH: &str = "/user/hand/right/input/trackpad/x"; +pub const RIGHT_TRACKPAD_Y_PATH: &str = "/user/hand/right/input/trackpad/y"; +pub const RIGHT_TRACKPAD_CLICK_PATH: &str = "/user/hand/right/input/trackpad/click"; +pub const RIGHT_TRACKPAD_FORCE_PATH: &str = "/user/hand/right/input/trackpad/force"; +pub const RIGHT_TRACKPAD_TOUCH_PATH: &str = "/user/hand/right/input/trackpad/touch"; +pub const RIGHT_THUMBREST_TOUCH_PATH: &str = "/user/hand/right/input/thumbrest/touch"; + +pub static HEAD_ID: Lazy = Lazy::new(|| hash_string(HEAD_PATH)); +pub static LEFT_HAND_ID: Lazy = Lazy::new(|| hash_string(LEFT_HAND_PATH)); +pub static RIGHT_HAND_ID: Lazy = Lazy::new(|| hash_string(RIGHT_HAND_PATH)); + +pub static QUEST_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(QUEST_CONTROLLER_PROFILE_PATH)); +pub static VIVE_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(VIVE_CONTROLLER_PROFILE_PATH)); +pub static INDEX_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(INDEX_CONTROLLER_PROFILE_PATH)); +pub static PICO_NEO3_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(PICO_NEO3_CONTROLLER_PROFILE_PATH)); +pub static PICO4_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(PICO4_CONTROLLER_PROFILE_PATH)); +pub static FOCUS3_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(FOCUS3_CONTROLLER_PROFILE_PATH)); +pub static YVR_CONTROLLER_PROFILE_ID: Lazy = + Lazy::new(|| hash_string(YVR_CONTROLLER_PROFILE_PATH)); + +pub static HEAD_ENTER_CLICK_ID: Lazy = Lazy::new(|| hash_string(HEAD_ENTER_CLICK_PATH)); +pub static LEFT_SYSTEM_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_SYSTEM_CLICK_PATH)); +pub static LEFT_SYSTEM_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_SYSTEM_TOUCH_PATH)); +pub static LEFT_MENU_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_MENU_CLICK_PATH)); +pub static LEFT_BACK_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_BACK_CLICK_PATH)); +pub static LEFT_A_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_A_CLICK_PATH)); +pub static LEFT_A_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_A_TOUCH_PATH)); +pub static LEFT_B_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_B_CLICK_PATH)); +pub static LEFT_B_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_B_TOUCH_PATH)); +pub static LEFT_X_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_X_CLICK_PATH)); +pub static LEFT_X_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_X_TOUCH_PATH)); +pub static LEFT_Y_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_Y_CLICK_PATH)); +pub static LEFT_Y_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_Y_TOUCH_PATH)); +pub static LEFT_SQUEEZE_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_CLICK_PATH)); +pub static LEFT_SQUEEZE_VALUE_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_VALUE_PATH)); +pub static LEFT_SQUEEZE_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_TOUCH_PATH)); +pub static LEFT_SQUEEZE_FORCE_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_FORCE_PATH)); +pub static LEFT_TRIGGER_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_CLICK_PATH)); +pub static LEFT_TRIGGER_VALUE_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_VALUE_PATH)); +pub static LEFT_TRIGGER_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_TOUCH_PATH)); +pub static LEFT_THUMBSTICK_X_ID: Lazy = Lazy::new(|| hash_string(LEFT_THUMBSTICK_X_PATH)); +pub static LEFT_THUMBSTICK_Y_ID: Lazy = Lazy::new(|| hash_string(LEFT_THUMBSTICK_Y_PATH)); +pub static LEFT_THUMBSTICK_CLICK_ID: Lazy = + Lazy::new(|| hash_string(LEFT_THUMBSTICK_CLICK_PATH)); +pub static LEFT_THUMBSTICK_TOUCH_ID: Lazy = + Lazy::new(|| hash_string(LEFT_THUMBSTICK_TOUCH_PATH)); +pub static LEFT_TRACKPAD_X_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRACKPAD_X_PATH)); +pub static LEFT_TRACKPAD_Y_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRACKPAD_Y_PATH)); +pub static LEFT_TRACKPAD_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRACKPAD_CLICK_PATH)); +pub static LEFT_TRACKPAD_FORCE_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRACKPAD_FORCE_PATH)); +pub static LEFT_TRACKPAD_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRACKPAD_TOUCH_PATH)); +pub static LEFT_THUMBREST_TOUCH_ID: Lazy = + Lazy::new(|| hash_string(LEFT_THUMBREST_TOUCH_PATH)); + +pub static RIGHT_SYSTEM_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SYSTEM_CLICK_PATH)); +pub static RIGHT_SYSTEM_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SYSTEM_TOUCH_PATH)); +pub static RIGHT_MENU_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_MENU_CLICK_PATH)); +pub static RIGHT_BACK_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_BACK_CLICK_PATH)); +pub static RIGHT_A_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_A_CLICK_PATH)); +pub static RIGHT_A_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_A_TOUCH_PATH)); +pub static RIGHT_B_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_B_CLICK_PATH)); +pub static RIGHT_B_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_B_TOUCH_PATH)); +pub static RIGHT_SQUEEZE_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_CLICK_PATH)); +pub static RIGHT_SQUEEZE_VALUE_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_VALUE_PATH)); +pub static RIGHT_SQUEEZE_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_TOUCH_PATH)); +pub static RIGHT_SQUEEZE_FORCE_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_FORCE_PATH)); +pub static RIGHT_TRIGGER_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_CLICK_PATH)); +pub static RIGHT_TRIGGER_VALUE_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_VALUE_PATH)); +pub static RIGHT_TRIGGER_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_TOUCH_PATH)); +pub static RIGHT_THUMBSTICK_X_ID: Lazy = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_X_PATH)); +pub static RIGHT_THUMBSTICK_Y_ID: Lazy = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_Y_PATH)); +pub static RIGHT_THUMBSTICK_CLICK_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_THUMBSTICK_CLICK_PATH)); +pub static RIGHT_THUMBSTICK_TOUCH_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_THUMBSTICK_TOUCH_PATH)); +pub static RIGHT_TRACKPAD_X_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRACKPAD_X_PATH)); +pub static RIGHT_TRACKPAD_Y_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRACKPAD_Y_PATH)); +pub static RIGHT_TRACKPAD_CLICK_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_TRACKPAD_CLICK_PATH)); +pub static RIGHT_TRACKPAD_FORCE_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_TRACKPAD_FORCE_PATH)); +pub static RIGHT_TRACKPAD_TOUCH_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_TRACKPAD_TOUCH_PATH)); +pub static RIGHT_THUMBREST_TOUCH_ID: Lazy = + Lazy::new(|| hash_string(RIGHT_THUMBREST_TOUCH_PATH)); + +pub static DEVICE_ID_TO_PATH: Lazy> = Lazy::new(|| { + [ + (*HEAD_ID, HEAD_PATH), + (*LEFT_HAND_ID, LEFT_HAND_PATH), + (*RIGHT_HAND_ID, RIGHT_HAND_PATH), + ] + .into_iter() + .collect() +}); + +pub enum ButtonType { + Binary, + Scalar, +} + +pub struct ButtonInfo { + pub path: &'static str, + pub button_type: ButtonType, + pub device_id: u64, +} + +pub static BUTTON_INFO: Lazy> = Lazy::new(|| { + [ + ( + *HEAD_ENTER_CLICK_ID, + ButtonInfo { + path: HEAD_ENTER_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *HEAD_ID, + }, + ), + ( + *LEFT_SYSTEM_CLICK_ID, + ButtonInfo { + path: LEFT_SYSTEM_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_SYSTEM_TOUCH_ID, + ButtonInfo { + path: LEFT_SYSTEM_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_MENU_CLICK_ID, + ButtonInfo { + path: LEFT_MENU_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_BACK_CLICK_ID, + ButtonInfo { + path: LEFT_BACK_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_A_CLICK_ID, + ButtonInfo { + path: LEFT_A_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_A_TOUCH_ID, + ButtonInfo { + path: LEFT_A_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_B_CLICK_ID, + ButtonInfo { + path: LEFT_B_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_B_TOUCH_ID, + ButtonInfo { + path: LEFT_B_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_X_CLICK_ID, + ButtonInfo { + path: LEFT_X_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_X_TOUCH_ID, + ButtonInfo { + path: LEFT_X_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_Y_CLICK_ID, + ButtonInfo { + path: LEFT_Y_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_Y_TOUCH_ID, + ButtonInfo { + path: LEFT_Y_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_SQUEEZE_CLICK_ID, + ButtonInfo { + path: LEFT_SQUEEZE_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_SQUEEZE_VALUE_ID, + ButtonInfo { + path: LEFT_SQUEEZE_VALUE_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_SQUEEZE_TOUCH_ID, + ButtonInfo { + path: LEFT_SQUEEZE_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_SQUEEZE_FORCE_ID, + ButtonInfo { + path: LEFT_SQUEEZE_FORCE_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRIGGER_CLICK_ID, + ButtonInfo { + path: LEFT_TRIGGER_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRIGGER_VALUE_ID, + ButtonInfo { + path: LEFT_TRIGGER_VALUE_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRIGGER_TOUCH_ID, + ButtonInfo { + path: LEFT_TRIGGER_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_THUMBSTICK_X_ID, + ButtonInfo { + path: LEFT_THUMBSTICK_X_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_THUMBSTICK_Y_ID, + ButtonInfo { + path: LEFT_THUMBSTICK_Y_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_THUMBSTICK_CLICK_ID, + ButtonInfo { + path: LEFT_THUMBSTICK_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_THUMBSTICK_TOUCH_ID, + ButtonInfo { + path: LEFT_THUMBSTICK_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRACKPAD_X_ID, + ButtonInfo { + path: LEFT_TRACKPAD_X_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRACKPAD_Y_ID, + ButtonInfo { + path: LEFT_TRACKPAD_Y_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRACKPAD_CLICK_ID, + ButtonInfo { + path: LEFT_TRACKPAD_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRACKPAD_FORCE_ID, + ButtonInfo { + path: LEFT_TRACKPAD_FORCE_PATH, + button_type: ButtonType::Scalar, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_TRACKPAD_TOUCH_ID, + ButtonInfo { + path: LEFT_TRACKPAD_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *LEFT_THUMBREST_TOUCH_ID, + ButtonInfo { + path: LEFT_THUMBREST_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *LEFT_HAND_ID, + }, + ), + ( + *RIGHT_SYSTEM_CLICK_ID, + ButtonInfo { + path: RIGHT_SYSTEM_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_SYSTEM_TOUCH_ID, + ButtonInfo { + path: RIGHT_SYSTEM_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_MENU_CLICK_ID, + ButtonInfo { + path: RIGHT_MENU_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_BACK_CLICK_ID, + ButtonInfo { + path: RIGHT_BACK_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_A_CLICK_ID, + ButtonInfo { + path: RIGHT_A_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_A_TOUCH_ID, + ButtonInfo { + path: RIGHT_A_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_B_CLICK_ID, + ButtonInfo { + path: RIGHT_B_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_B_TOUCH_ID, + ButtonInfo { + path: RIGHT_B_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_SQUEEZE_CLICK_ID, + ButtonInfo { + path: RIGHT_SQUEEZE_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_SQUEEZE_VALUE_ID, + ButtonInfo { + path: RIGHT_SQUEEZE_VALUE_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_SQUEEZE_TOUCH_ID, + ButtonInfo { + path: RIGHT_SQUEEZE_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_SQUEEZE_FORCE_ID, + ButtonInfo { + path: RIGHT_SQUEEZE_FORCE_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRIGGER_CLICK_ID, + ButtonInfo { + path: RIGHT_TRIGGER_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRIGGER_VALUE_ID, + ButtonInfo { + path: RIGHT_TRIGGER_VALUE_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRIGGER_TOUCH_ID, + ButtonInfo { + path: RIGHT_TRIGGER_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_THUMBSTICK_X_ID, + ButtonInfo { + path: RIGHT_THUMBSTICK_X_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_THUMBSTICK_Y_ID, + ButtonInfo { + path: RIGHT_THUMBSTICK_Y_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_THUMBSTICK_CLICK_ID, + ButtonInfo { + path: RIGHT_THUMBSTICK_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_THUMBSTICK_TOUCH_ID, + ButtonInfo { + path: RIGHT_THUMBSTICK_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRACKPAD_X_ID, + ButtonInfo { + path: RIGHT_TRACKPAD_X_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRACKPAD_Y_ID, + ButtonInfo { + path: RIGHT_TRACKPAD_Y_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRACKPAD_CLICK_ID, + ButtonInfo { + path: RIGHT_TRACKPAD_CLICK_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRACKPAD_FORCE_ID, + ButtonInfo { + path: RIGHT_TRACKPAD_FORCE_PATH, + button_type: ButtonType::Scalar, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_TRACKPAD_TOUCH_ID, + ButtonInfo { + path: RIGHT_TRACKPAD_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ( + *RIGHT_THUMBREST_TOUCH_ID, + ButtonInfo { + path: RIGHT_THUMBREST_TOUCH_PATH, + button_type: ButtonType::Binary, + device_id: *RIGHT_HAND_ID, + }, + ), + ] + .into_iter() + .collect() +}); + +pub struct InteractionProfileInfo { + pub path: &'static str, + pub button_set: HashSet, +} + +pub static CONTROLLER_PROFILE_INFO: Lazy> = Lazy::new(|| { + [ + ( + *QUEST_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: QUEST_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_X_CLICK_ID, + *LEFT_X_TOUCH_ID, + *LEFT_Y_CLICK_ID, + *LEFT_Y_TOUCH_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_THUMBREST_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_A_TOUCH_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_B_TOUCH_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_THUMBREST_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *VIVE_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: VIVE_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_SYSTEM_CLICK_ID, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_TRACKPAD_X_ID, + *LEFT_TRACKPAD_Y_ID, + *LEFT_TRACKPAD_CLICK_ID, + *LEFT_TRACKPAD_TOUCH_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_MENU_CLICK_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_TRACKPAD_X_ID, + *RIGHT_TRACKPAD_Y_ID, + *RIGHT_TRACKPAD_CLICK_ID, + *RIGHT_TRACKPAD_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *INDEX_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: INDEX_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_SYSTEM_CLICK_ID, + *LEFT_SYSTEM_TOUCH_ID, + *LEFT_A_CLICK_ID, + *LEFT_A_TOUCH_ID, + *LEFT_B_CLICK_ID, + *LEFT_B_TOUCH_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_SQUEEZE_FORCE_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_TRACKPAD_X_ID, + *LEFT_TRACKPAD_Y_ID, + *LEFT_TRACKPAD_FORCE_ID, + *LEFT_TRACKPAD_TOUCH_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_SYSTEM_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_A_TOUCH_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_B_TOUCH_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_SQUEEZE_FORCE_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_TRACKPAD_X_ID, + *RIGHT_TRACKPAD_Y_ID, + *RIGHT_TRACKPAD_FORCE_ID, + *RIGHT_TRACKPAD_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *PICO_NEO3_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: PICO_NEO3_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_X_CLICK_ID, + *LEFT_X_TOUCH_ID, + *LEFT_Y_CLICK_ID, + *LEFT_Y_TOUCH_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_SYSTEM_CLICK_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_THUMBREST_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_A_TOUCH_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_B_TOUCH_ID, + *RIGHT_MENU_CLICK_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_THUMBREST_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *PICO4_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: PICO4_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_X_CLICK_ID, + *LEFT_X_TOUCH_ID, + *LEFT_Y_CLICK_ID, + *LEFT_Y_TOUCH_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_SYSTEM_CLICK_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_THUMBREST_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_A_TOUCH_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_B_TOUCH_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_THUMBREST_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *FOCUS3_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: FOCUS3_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_X_CLICK_ID, + *LEFT_Y_CLICK_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_SQUEEZE_CLICK_ID, + // *LEFT_SQUEEZE_TOUCH_ID, // not actually working + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_THUMBREST_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_SQUEEZE_CLICK_ID, + // *RIGHT_SQUEEZE_TOUCH_ID, // not actually working + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_THUMBREST_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ( + *YVR_CONTROLLER_PROFILE_ID, + InteractionProfileInfo { + path: YVR_CONTROLLER_PROFILE_PATH, + button_set: [ + *LEFT_X_CLICK_ID, + *LEFT_Y_CLICK_ID, + *LEFT_MENU_CLICK_ID, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_TRIGGER_VALUE_ID, + *LEFT_THUMBSTICK_X_ID, + *LEFT_THUMBSTICK_Y_ID, + *LEFT_THUMBSTICK_CLICK_ID, + *LEFT_THUMBSTICK_TOUCH_ID, + *LEFT_THUMBREST_TOUCH_ID, + *RIGHT_A_CLICK_ID, + *RIGHT_B_CLICK_ID, + *RIGHT_SYSTEM_CLICK_ID, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_TRIGGER_VALUE_ID, + *RIGHT_THUMBSTICK_X_ID, + *RIGHT_THUMBSTICK_Y_ID, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + *RIGHT_THUMBREST_TOUCH_ID, + ] + .into_iter() + .collect(), + }, + ), + ] + .into_iter() + .collect() +}); diff --git a/alvr/common/src/lib.rs b/alvr/common/src/lib.rs index cafa4a75..9e752009 100644 --- a/alvr/common/src/lib.rs +++ b/alvr/common/src/lib.rs @@ -1,7 +1,7 @@ mod average; mod connection_result; +mod inputs; mod logging; -mod paths; mod primitives; mod version; @@ -18,9 +18,9 @@ pub use settings_schema; pub use average::*; pub use connection_result::*; +pub use inputs::*; pub use log::{debug, error, info, warn}; pub use logging::*; -pub use paths::*; pub use primitives::*; pub use version::*; diff --git a/alvr/common/src/paths.rs b/alvr/common/src/paths.rs deleted file mode 100644 index adeb21ef..00000000 --- a/alvr/common/src/paths.rs +++ /dev/null @@ -1,90 +0,0 @@ -use crate::hash_string; -use once_cell::sync::Lazy; -use std::collections::HashMap; - -pub const HEAD_PATH: &str = "/user/head"; -pub const LEFT_HAND_PATH: &str = "/user/hand/left"; -pub const RIGHT_HAND_PATH: &str = "/user/hand/right"; - -pub static HEAD_ID: Lazy = Lazy::new(|| hash_string(HEAD_PATH)); -pub static LEFT_HAND_ID: Lazy = Lazy::new(|| hash_string(LEFT_HAND_PATH)); -pub static RIGHT_HAND_ID: Lazy = Lazy::new(|| hash_string(RIGHT_HAND_PATH)); - -pub static DEVICE_ID_TO_PATH: Lazy> = Lazy::new(|| { - [ - (*HEAD_ID, HEAD_PATH), - (*LEFT_HAND_ID, LEFT_HAND_PATH), - (*RIGHT_HAND_ID, RIGHT_HAND_PATH), - ] - .into_iter() - .collect() -}); - -pub const HEAD_ENTER_CLICK_PATH: &str = "/user/head/input/enter/click"; -pub const BACK_CLICK_PATH: &str = "/user/hand/left/input/back/click"; -pub const MENU_CLICK_PATH: &str = "/user/hand/left/input/menu/click"; -pub const A_CLICK_PATH: &str = "/user/hand/right/input/a/click"; -pub const A_TOUCH_PATH: &str = "/user/hand/right/input/a/touch"; -pub const B_CLICK_PATH: &str = "/user/hand/right/input/b/click"; -pub const B_TOUCH_PATH: &str = "/user/hand/right/input/b/touch"; -pub const X_CLICK_PATH: &str = "/user/hand/left/input/x/click"; -pub const X_TOUCH_PATH: &str = "/user/hand/left/input/x/touch"; -pub const Y_CLICK_PATH: &str = "/user/hand/left/input/y/click"; -pub const Y_TOUCH_PATH: &str = "/user/hand/left/input/y/touch"; -pub const LEFT_SQUEEZE_CLICK_PATH: &str = "/user/hand/left/input/squeeze/click"; -pub const LEFT_SQUEEZE_VALUE_PATH: &str = "/user/hand/left/input/squeeze/value"; -pub const LEFT_TRIGGER_CLICK_PATH: &str = "/user/hand/left/input/trigger/click"; -pub const LEFT_TRIGGER_VALUE_PATH: &str = "/user/hand/left/input/trigger/value"; -pub const LEFT_TRIGGER_TOUCH_PATH: &str = "/user/hand/left/input/trigger/touch"; -pub const LEFT_THUMBSTICK_X_PATH: &str = "/user/hand/left/input/thumbstick/x"; -pub const LEFT_THUMBSTICK_Y_PATH: &str = "/user/hand/left/input/thumbstick/y"; -pub const LEFT_THUMBSTICK_CLICK_PATH: &str = "/user/hand/left/input/thumbstick/click"; -pub const LEFT_THUMBSTICK_TOUCH_PATH: &str = "/user/hand/left/input/thumbstick/touch"; -pub const LEFT_THUMBREST_TOUCH_PATH: &str = "/user/hand/left/input/thumbrest/touch"; -pub const RIGHT_SQUEEZE_CLICK_PATH: &str = "/user/hand/right/input/squeeze/click"; -pub const RIGHT_SQUEEZE_VALUE_PATH: &str = "/user/hand/right/input/squeeze/value"; -pub const RIGHT_TRIGGER_CLICK_PATH: &str = "/user/hand/right/input/trigger/click"; -pub const RIGHT_TRIGGER_VALUE_PATH: &str = "/user/hand/right/input/trigger/value"; -pub const RIGHT_TRIGGER_TOUCH_PATH: &str = "/user/hand/right/input/trigger/touch"; -pub const RIGHT_THUMBSTICK_X_PATH: &str = "/user/hand/right/input/thumbstick/x"; -pub const RIGHT_THUMBSTICK_Y_PATH: &str = "/user/hand/right/input/thumbstick/y"; -pub const RIGHT_THUMBSTICK_CLICK_PATH: &str = "/user/hand/right/input/thumbstick/click"; -pub const RIGHT_THUMBSTICK_TOUCH_PATH: &str = "/user/hand/right/input/thumbstick/touch"; -pub const RIGHT_THUMBREST_TOUCH_PATH: &str = "/user/hand/right/input/thumbrest/touch"; - -pub static HEAD_ENTER_CLICK_ID: Lazy = Lazy::new(|| hash_string(HEAD_ENTER_CLICK_PATH)); -pub static MENU_CLICK_ID: Lazy = Lazy::new(|| hash_string(MENU_CLICK_PATH)); -pub static A_CLICK_ID: Lazy = Lazy::new(|| hash_string(A_CLICK_PATH)); -pub static A_TOUCH_ID: Lazy = Lazy::new(|| hash_string(A_TOUCH_PATH)); -pub static B_CLICK_ID: Lazy = Lazy::new(|| hash_string(B_CLICK_PATH)); -pub static B_TOUCH_ID: Lazy = Lazy::new(|| hash_string(B_TOUCH_PATH)); -pub static X_CLICK_ID: Lazy = Lazy::new(|| hash_string(X_CLICK_PATH)); -pub static X_TOUCH_ID: Lazy = Lazy::new(|| hash_string(X_TOUCH_PATH)); -pub static Y_CLICK_ID: Lazy = Lazy::new(|| hash_string(Y_CLICK_PATH)); -pub static Y_TOUCH_ID: Lazy = Lazy::new(|| hash_string(Y_TOUCH_PATH)); -pub static LEFT_SQUEEZE_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_CLICK_PATH)); -pub static LEFT_SQUEEZE_VALUE_ID: Lazy = Lazy::new(|| hash_string(LEFT_SQUEEZE_VALUE_PATH)); -pub static LEFT_TRIGGER_CLICK_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_CLICK_PATH)); -pub static LEFT_TRIGGER_VALUE_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_VALUE_PATH)); -pub static LEFT_TRIGGER_TOUCH_ID: Lazy = Lazy::new(|| hash_string(LEFT_TRIGGER_TOUCH_PATH)); -pub static LEFT_THUMBSTICK_X_ID: Lazy = Lazy::new(|| hash_string(LEFT_THUMBSTICK_X_PATH)); -pub static LEFT_THUMBSTICK_Y_ID: Lazy = Lazy::new(|| hash_string(LEFT_THUMBSTICK_Y_PATH)); -pub static LEFT_THUMBSTICK_CLICK_ID: Lazy = - Lazy::new(|| hash_string(LEFT_THUMBSTICK_CLICK_PATH)); -pub static LEFT_THUMBSTICK_TOUCH_ID: Lazy = - Lazy::new(|| hash_string(LEFT_THUMBSTICK_TOUCH_PATH)); -pub static LEFT_THUMBREST_TOUCH_ID: Lazy = - Lazy::new(|| hash_string(LEFT_THUMBREST_TOUCH_PATH)); -pub static RIGHT_SQUEEZE_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_CLICK_PATH)); -pub static RIGHT_SQUEEZE_VALUE_ID: Lazy = Lazy::new(|| hash_string(RIGHT_SQUEEZE_VALUE_PATH)); -pub static RIGHT_TRIGGER_CLICK_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_CLICK_PATH)); -pub static RIGHT_TRIGGER_VALUE_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_VALUE_PATH)); -pub static RIGHT_TRIGGER_TOUCH_ID: Lazy = Lazy::new(|| hash_string(RIGHT_TRIGGER_TOUCH_PATH)); -pub static RIGHT_THUMBSTICK_X_ID: Lazy = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_X_PATH)); -pub static RIGHT_THUMBSTICK_Y_ID: Lazy = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_Y_PATH)); -pub static RIGHT_THUMBSTICK_CLICK_ID: Lazy = - Lazy::new(|| hash_string(RIGHT_THUMBSTICK_CLICK_PATH)); -pub static RIGHT_THUMBSTICK_TOUCH_ID: Lazy = - Lazy::new(|| hash_string(RIGHT_THUMBSTICK_TOUCH_PATH)); -pub static RIGHT_THUMBREST_TOUCH_ID: Lazy = - Lazy::new(|| hash_string(RIGHT_THUMBREST_TOUCH_PATH)); diff --git a/alvr/server/cpp/ALVR-common/packet_types.h b/alvr/server/cpp/ALVR-common/packet_types.h index 03abef37..5f8a0822 100644 --- a/alvr/server/cpp/ALVR-common/packet_types.h +++ b/alvr/server/cpp/ALVR-common/packet_types.h @@ -26,44 +26,10 @@ enum ALVR_ENCODER_QUALITY_PRESET { }; enum ALVR_INPUT { - ALVR_INPUT_SYSTEM_CLICK, - ALVR_INPUT_APPLICATION_MENU_CLICK, - ALVR_INPUT_GRIP_CLICK, - ALVR_INPUT_GRIP_VALUE, - ALVR_INPUT_GRIP_TOUCH, - ALVR_INPUT_A_CLICK, - ALVR_INPUT_A_TOUCH, - ALVR_INPUT_B_CLICK, - ALVR_INPUT_B_TOUCH, - ALVR_INPUT_X_CLICK, - ALVR_INPUT_X_TOUCH, - ALVR_INPUT_Y_CLICK, - ALVR_INPUT_Y_TOUCH, - ALVR_INPUT_JOYSTICK_CLICK, - ALVR_INPUT_JOYSTICK_X, - ALVR_INPUT_JOYSTICK_Y, - ALVR_INPUT_JOYSTICK_TOUCH, - ALVR_INPUT_BACK_CLICK, - ALVR_INPUT_GUIDE_CLICK, - ALVR_INPUT_START_CLICK, - ALVR_INPUT_TRIGGER_CLICK, - ALVR_INPUT_TRIGGER_VALUE, - ALVR_INPUT_TRIGGER_TOUCH, - ALVR_INPUT_TRACKPAD_X, - ALVR_INPUT_TRACKPAD_Y, - ALVR_INPUT_TRACKPAD_CLICK, - ALVR_INPUT_TRACKPAD_TOUCH, - ALVR_INPUT_THUMB_REST_TOUCH, - ALVR_INPUT_FINGER_INDEX, ALVR_INPUT_FINGER_MIDDLE, ALVR_INPUT_FINGER_RING, ALVR_INPUT_FINGER_PINKY, - ALVR_INPUT_GRIP_FORCE, - ALVR_INPUT_TRACKPAD_FORCE, - - ALVR_INPUT_MAX = ALVR_INPUT_TRACKPAD_FORCE, - ALVR_INPUT_COUNT = ALVR_INPUT_MAX + 1 }; #define ALVR_BUTTON_FLAG(input) (1ULL << input) diff --git a/alvr/server/cpp/alvr_server/Controller.cpp b/alvr/server/cpp/alvr_server/Controller.cpp index 45889605..9f44bea2 100644 --- a/alvr/server/cpp/alvr_server/Controller.cpp +++ b/alvr/server/cpp/alvr_server/Controller.cpp @@ -9,8 +9,7 @@ #include vr::ETrackedDeviceClass Controller::getControllerDeviceClass() { - // index == 8/9 == "HTCViveTracker.json" - if (Settings::Instance().m_controllerMode == 8 || Settings::Instance().m_controllerMode == 9) + if (Settings::Instance().m_controllerIsTracker) return vr::TrackedDeviceClass_GenericTracker; return vr::TrackedDeviceClass_Controller; } @@ -24,11 +23,6 @@ Controller::Controller(uint64_t deviceID) : TrackedDevice(deviceID) { m_pose.qDriverFromHeadRotation = HmdQuaternion_Init(1, 0, 0, 0); m_pose.qWorldFromDriverRotation = HmdQuaternion_Init(1, 0, 0, 0); m_pose.qRotation = HmdQuaternion_Init(1, 0, 0, 0); - - // init handles - for (int i = 0; i < ALVR_INPUT_COUNT; i++) { - m_handles[i] = vr::k_ulInvalidInputComponentHandle; - } } // @@ -41,284 +35,62 @@ vr::EVRInitError Controller::Activate(vr::TrackedDeviceIndex_t unObjectId) { auto vr_properties = vr::VRProperties(); auto vr_driver_input = vr::VRDriverInput(); - const bool isViveTracker = - Settings::Instance().m_controllerMode == 8 || Settings::Instance().m_controllerMode == 9; this->object_id = unObjectId; this->prop_container = vr_properties->TrackedDeviceToPropertyContainer(this->object_id); SetOpenvrProps(this->device_id); - switch (Settings::Instance().m_controllerMode) { - case 1: // Oculus Rift - case 7: // Oculus Quest + RegisterButtons(this->device_id); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/system/click", &m_handles[ALVR_INPUT_SYSTEM_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/system/touch", &m_handles[ALVR_INPUT_THUMB_REST_TOUCH]); - vr_driver_input->CreateBooleanComponent(this->prop_container, - "/input/application_menu/click", - &m_handles[ALVR_INPUT_APPLICATION_MENU_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/grip/click", &m_handles[ALVR_INPUT_GRIP_CLICK]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/grip/value", - &m_handles[ALVR_INPUT_GRIP_VALUE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/grip/touch", &m_handles[ALVR_INPUT_GRIP_TOUCH]); + vr_driver_input->CreateHapticComponent(this->prop_container, "/output/haptic", &m_compHaptic); - if (this->device_id == RIGHT_HAND_ID) { - // A,B for right hand. - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/a/click", &m_handles[ALVR_INPUT_A_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/a/touch", &m_handles[ALVR_INPUT_A_TOUCH]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/b/click", &m_handles[ALVR_INPUT_B_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/b/touch", &m_handles[ALVR_INPUT_B_TOUCH]); + vr_driver_input->CreateScalarComponent(this->prop_container, + "/input/finger/index", + &m_buttonHandles[ALVR_INPUT_FINGER_INDEX], + vr::VRScalarType_Absolute, + vr::VRScalarUnits_NormalizedOneSided); + vr_driver_input->CreateScalarComponent(this->prop_container, + "/input/finger/middle", + &m_buttonHandles[ALVR_INPUT_FINGER_MIDDLE], + vr::VRScalarType_Absolute, + vr::VRScalarUnits_NormalizedOneSided); + vr_driver_input->CreateScalarComponent(this->prop_container, + "/input/finger/ring", + &m_buttonHandles[ALVR_INPUT_FINGER_RING], + vr::VRScalarType_Absolute, + vr::VRScalarUnits_NormalizedOneSided); + vr_driver_input->CreateScalarComponent(this->prop_container, + "/input/finger/pinky", + &m_buttonHandles[ALVR_INPUT_FINGER_PINKY], + vr::VRScalarType_Absolute, + vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/right", - "/skeleton/hand/right", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - SKELETON_BONE_COUNT, - &m_compSkeleton); - - } else { - // X,Y for left hand. - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/x/click", &m_handles[ALVR_INPUT_X_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/x/touch", &m_handles[ALVR_INPUT_X_TOUCH]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/y/click", &m_handles[ALVR_INPUT_Y_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/y/touch", &m_handles[ALVR_INPUT_Y_TOUCH]); - - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/left", - "/skeleton/hand/left", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - SKELETON_BONE_COUNT, - &m_compSkeleton); - } - - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/joystick/click", &m_handles[ALVR_INPUT_JOYSTICK_CLICK]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/joystick/x", - &m_handles[ALVR_INPUT_JOYSTICK_X], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/joystick/y", - &m_handles[ALVR_INPUT_JOYSTICK_Y], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/joystick/touch", &m_handles[ALVR_INPUT_JOYSTICK_TOUCH]); - - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/back/click", &m_handles[ALVR_INPUT_BACK_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/guide/click", &m_handles[ALVR_INPUT_GUIDE_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/start/click", &m_handles[ALVR_INPUT_START_CLICK]); - - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trigger/click", &m_handles[ALVR_INPUT_TRIGGER_CLICK]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trigger/value", - &m_handles[ALVR_INPUT_TRIGGER_VALUE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trigger/touch", &m_handles[ALVR_INPUT_TRIGGER_TOUCH]); - - vr_driver_input->CreateHapticComponent( - this->prop_container, "/output/haptic", &m_compHaptic); - break; - case 3: // Index - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/system/click", &m_handles[ALVR_INPUT_SYSTEM_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/a/click", &m_handles[ALVR_INPUT_A_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/a/touch", &m_handles[ALVR_INPUT_A_TOUCH]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/b/click", &m_handles[ALVR_INPUT_B_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/b/touch", &m_handles[ALVR_INPUT_B_TOUCH]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trigger/click", &m_handles[ALVR_INPUT_TRIGGER_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trigger/touch", &m_handles[ALVR_INPUT_TRIGGER_TOUCH]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trigger/value", - &m_handles[ALVR_INPUT_TRIGGER_VALUE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trackpad/x", - &m_handles[ALVR_INPUT_TRACKPAD_X], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trackpad/y", - &m_handles[ALVR_INPUT_TRACKPAD_Y], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trackpad/force", - &m_handles[ALVR_INPUT_TRACKPAD_FORCE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trackpad/touch", &m_handles[ALVR_INPUT_TRACKPAD_TOUCH]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/grip/force", - &m_handles[ALVR_INPUT_GRIP_FORCE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/grip/value", - &m_handles[ALVR_INPUT_GRIP_VALUE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/grip/touch", &m_handles[ALVR_INPUT_GRIP_TOUCH]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/thumbstick/x", - &m_handles[ALVR_INPUT_JOYSTICK_X], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/thumbstick/y", - &m_handles[ALVR_INPUT_JOYSTICK_Y], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/thumbstick/click", &m_handles[ALVR_INPUT_JOYSTICK_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/thumbstick/touch", &m_handles[ALVR_INPUT_JOYSTICK_TOUCH]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/finger/index", - &m_handles[ALVR_INPUT_FINGER_INDEX], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/finger/middle", - &m_handles[ALVR_INPUT_FINGER_MIDDLE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/finger/ring", - &m_handles[ALVR_INPUT_FINGER_RING], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/finger/pinky", - &m_handles[ALVR_INPUT_FINGER_PINKY], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - if (this->device_id == LEFT_HAND_ID) { - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/left", - "/skeleton/hand/left", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - 0U, - &m_compSkeleton); - } else { - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/right", - "/skeleton/hand/right", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - 0U, - &m_compSkeleton); - } - vr_driver_input->CreateHapticComponent( - this->prop_container, "/output/haptic", &m_compHaptic); - break; - case 9: { // Vive Tracker - // yes we want to explicitly fallthrough to vive case!, vive trackers can have input when - // POGO pins are connected to a peripheral. the input bindings are only active when the - // tracker role is set to "vive_tracker_handed"/held_in_hand roles. - [[fallthrough]]; - } - case 5: // Vive - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trackpad/touch", &m_handles[ALVR_INPUT_TRACKPAD_TOUCH]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trackpad/click", &m_handles[ALVR_INPUT_TRACKPAD_CLICK]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trackpad/x", - &m_handles[ALVR_INPUT_TRACKPAD_X], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trackpad/y", - &m_handles[ALVR_INPUT_TRACKPAD_Y], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedTwoSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/trigger/click", &m_handles[ALVR_INPUT_TRIGGER_CLICK]); - vr_driver_input->CreateScalarComponent(this->prop_container, - "/input/trigger/value", - &m_handles[ALVR_INPUT_TRIGGER_VALUE], - vr::VRScalarType_Absolute, - vr::VRScalarUnits_NormalizedOneSided); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/grip/click", &m_handles[ALVR_INPUT_GRIP_CLICK]); - vr_driver_input->CreateBooleanComponent(this->prop_container, - "/input/application_menu/click", - &m_handles[ALVR_INPUT_APPLICATION_MENU_CLICK]); - vr_driver_input->CreateBooleanComponent( - this->prop_container, "/input/system/click", &m_handles[ALVR_INPUT_SYSTEM_CLICK]); - if (this->device_id == LEFT_HAND_ID) { - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/left", - "/skeleton/hand/left", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - 0U, - &m_compSkeleton); - } else { - vr_driver_input->CreateSkeletonComponent( - this->prop_container, - "/input/skeleton/right", - "/skeleton/hand/right", - "/pose/raw", - vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, - nullptr, - 0U, - &m_compSkeleton); - } - vr_driver_input->CreateHapticComponent( - this->prop_container, "/output/haptic", &m_compHaptic); - break; + if (this->device_id == LEFT_HAND_ID) { + vr_driver_input->CreateSkeletonComponent( + this->prop_container, + "/input/skeleton/left", + "/skeleton/hand/left", + "/pose/raw", + vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, + nullptr, + 0U, + &m_compSkeleton); + } else { + vr_driver_input->CreateSkeletonComponent( + this->prop_container, + "/input/skeleton/right", + "/skeleton/hand/right", + "/pose/raw", + vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, + nullptr, + 0U, + &m_compSkeleton); } // NB: here we set some initial values for the hand skeleton to fix the frozen hand bug { vr::VRBoneTransform_t boneTransforms[SKELETON_BONE_COUNT]; - GetBoneTransform(false, this->device_id == LEFT_HAND_ID, 0.0, 0.0, 0, boneTransforms); + GetBoneTransform(false, boneTransforms); vr_driver_input->UpdateSkeletonComponent(m_compSkeleton, vr::VRSkeletalMotionRange_WithController, @@ -360,275 +132,50 @@ vr::DriverPose_t Controller::GetPose() { return m_pose; } vr::VRInputComponentHandle_t Controller::getHapticComponent() { return m_compHaptic; } -void Controller::SetButton(uint64_t id, FfiButtonValue value) { - if (value.type == BUTTON_TYPE_BINARY) { - uint32_t flag; - if (id == MENU_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_SYSTEM_CLICK); - } else if (id == A_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_A_CLICK); - } else if (id == A_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH); - } else if (id == B_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_B_CLICK); - } else if (id == B_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH); - } else if (id == X_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_X_CLICK); - } else if (id == X_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH); - } else if (id == Y_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_Y_CLICK); - } else if (id == Y_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH); - } else if (id == LEFT_SQUEEZE_CLICK_ID || id == RIGHT_SQUEEZE_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_GRIP_CLICK); - } else if (id == LEFT_TRIGGER_CLICK_ID || id == RIGHT_TRIGGER_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK); - } else if (id == LEFT_TRIGGER_TOUCH_ID || id == RIGHT_TRIGGER_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH); - } else if (id == LEFT_THUMBSTICK_CLICK_ID || id == RIGHT_THUMBSTICK_CLICK_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_CLICK); - } else if (id == LEFT_THUMBSTICK_TOUCH_ID || id == RIGHT_THUMBSTICK_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH); - } else if (id == LEFT_THUMBREST_TOUCH_ID || id == RIGHT_THUMBREST_TOUCH_ID) { - flag = ALVR_BUTTON_FLAG(ALVR_INPUT_THUMB_REST_TOUCH); - } - m_buttons = value.binary ? m_buttons | flag : m_buttons & ~flag; - } else if (id == LEFT_SQUEEZE_VALUE_ID || id == RIGHT_SQUEEZE_VALUE_ID) { - m_gripValue = value.scalar; - } else if (id == LEFT_TRIGGER_VALUE_ID || id == RIGHT_TRIGGER_VALUE_ID) { - m_triggerValue = value.scalar; - } else if (id == LEFT_THUMBSTICK_X_ID || id == RIGHT_THUMBSTICK_X_ID) { - m_joystickX = value.scalar; - } else if (id == LEFT_THUMBSTICK_Y_ID || id == RIGHT_THUMBSTICK_Y_ID) { - m_joystickY = value.scalar; +void Controller::RegisterButton(uint64_t id) { + ButtonInfo buttonInfo; + if (device_id == LEFT_HAND_ID) { + buttonInfo = LEFT_CONTROLLER_BUTTON_MAPPING[id]; + } else { + buttonInfo = RIGHT_CONTROLLER_BUTTON_MAPPING[id]; } - auto vr_driver_input = vr::VRDriverInput(); + if (buttonInfo.type == ButtonType::Binary) { + vr::VRDriverInput()->CreateBooleanComponent( + this->prop_container, buttonInfo.steamvr_path, &m_buttonHandles[id]); + } else { + auto scalarType = buttonInfo.type == ButtonType::ScalarOneSided + ? vr::VRScalarUnits_NormalizedOneSided + : vr::VRScalarUnits_NormalizedTwoSided; + vr::VRDriverInput()->CreateScalarComponent(this->prop_container, + buttonInfo.steamvr_path, + &m_buttonHandles[id], + vr::VRScalarType_Absolute, + scalarType); + } +} - switch (Settings::Instance().m_controllerMode) { - case 3: // Valve Index - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_SYSTEM_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_SYSTEM_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_GRIP_TOUCH], m_gripValue > 0.7f, 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_GRIP_FORCE], (m_gripValue * 1.1f - 1.f) * 10.f, 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_GRIP_VALUE], m_gripValue * 1.1f, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_TRACKPAD_X], m_joystickX, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_TRACKPAD_Y], m_joystickY, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRACKPAD_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_THUMB_REST_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_JOYSTICK_X], m_joystickX, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_JOYSTICK_Y], m_joystickY, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_JOYSTICK_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_JOYSTICK_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0, - 0.0); - if (this->device_id == RIGHT_HAND_ID) { - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH)) != 0, - 0.0); - } else { - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH)) != 0, - 0.0); - } - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_CLICK], - Settings::Instance().m_overrideTriggerThreshold - ? m_triggerValue >= Settings::Instance().m_triggerThreshold - : (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_TRIGGER_VALUE], m_triggerValue, 0.0); +void Controller::SetButton(uint64_t id, FfiButtonValue value) { - break; - case 5: // Vive wand - case 9: // Vive Tracker - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRACKPAD_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRACKPAD_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_TRACKPAD_X], m_joystickX, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_TRACKPAD_Y], m_joystickY, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_CLICK], - Settings::Instance().m_overrideTriggerThreshold - ? m_triggerValue >= Settings::Instance().m_triggerThreshold - : (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_TRIGGER_VALUE], m_triggerValue, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_GRIP_CLICK], - Settings::Instance().m_overrideGripThreshold - ? m_gripValue >= Settings::Instance().m_gripThreshold - : (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_GRIP_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_SYSTEM_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_SYSTEM_CLICK)) != 0, - 0.0); + if (value.type == BUTTON_TYPE_BINARY) { + vr::VRDriverInput()->UpdateBooleanComponent(m_buttonHandles[id], (bool)value.binary, 0.0); + } else { + vr::VRDriverInput()->UpdateScalarComponent(m_buttonHandles[id], value.scalar, 0.0); + } - if (this->device_id == RIGHT_HAND_ID) { - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_APPLICATION_MENU_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_CLICK)) != 0, - 0.0); - } else { - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_APPLICATION_MENU_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_CLICK)) != 0, - 0.0); - } - break; - case 1: // Oculus Rift - case 7: // Oculus Quest - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_SYSTEM_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_SYSTEM_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_APPLICATION_MENU_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_APPLICATION_MENU_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_GRIP_CLICK], - Settings::Instance().m_overrideGripThreshold - ? m_gripValue >= Settings::Instance().m_gripThreshold - : (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_GRIP_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_GRIP_VALUE], m_gripValue, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_GRIP_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_GRIP_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_THUMB_REST_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_THUMB_REST_TOUCH)) != 0, - 0.0); - - if (this->device_id == RIGHT_HAND_ID) { - // A,B for right hand. - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_A_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_B_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH)) != 0, - 0.0); - - } else { - // X,Y for left hand. - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_X_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_X_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_Y_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_Y_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH)) != 0, - 0.0); - } - - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_JOYSTICK_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_JOYSTICK_X], m_joystickX, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_JOYSTICK_Y], m_joystickY, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_JOYSTICK_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0, - 0.0); - - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_BACK_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_BACK_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_GUIDE_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_GUIDE_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_START_CLICK], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_START_CLICK)) != 0, - 0.0); - - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_CLICK], - Settings::Instance().m_overrideTriggerThreshold - ? m_triggerValue >= Settings::Instance().m_triggerThreshold - : (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK)) != 0, - 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_TRIGGER_VALUE], m_triggerValue, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_TOUCH], - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH)) != 0, - 0.0); - break; + // todo: remove when moving inferred controller hand skeleton to rust + if (id == LEFT_A_TOUCH_ID || id == LEFT_B_TOUCH_ID || id == LEFT_X_TOUCH_ID || + id == LEFT_Y_TOUCH_ID || id == LEFT_TRACKPAD_TOUCH_ID || id == LEFT_THUMBSTICK_TOUCH_ID || + id == LEFT_THUMBREST_TOUCH_ID || id == RIGHT_A_TOUCH_ID || id == RIGHT_B_TOUCH_ID || + id == RIGHT_TRACKPAD_TOUCH_ID || id == RIGHT_THUMBSTICK_TOUCH_ID || + id == RIGHT_THUMBREST_TOUCH_ID) { + m_currentThumbTouch = value.binary; + } else if (id == LEFT_TRIGGER_TOUCH_ID || id == RIGHT_TRIGGER_TOUCH_ID) { + m_currentTriggerTouch = value.binary; + } else if (id == LEFT_TRIGGER_VALUE_ID || id == RIGHT_TRIGGER_VALUE_ID) { + m_triggerValue = value.scalar; + } else if (id == LEFT_SQUEEZE_VALUE_ID || id == RIGHT_SQUEEZE_VALUE_ID) { + m_gripValue = value.scalar; } } @@ -711,92 +258,77 @@ bool Controller::onPoseUpdate(float predictionS, handSkeleton->jointRotations[24].z) * 0.67f; - switch (Settings::Instance().m_controllerMode) { - case 1: - case 3: - case 7: - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_JOYSTICK_TOUCH], rotThumb > 0.7f, 0.0); - vr_driver_input->UpdateBooleanComponent( - m_handles[ALVR_INPUT_TRIGGER_TOUCH], rotIndex > 0.7f, 0.0); - } + // switch (Settings::Instance().m_controllerMode) { + // case 1: + // case 3: + // case 7: + // vr_driver_input->UpdateBooleanComponent( + // m_buttonHandles[LEFT_THUMBSTICK_TOUCH_ID], rotThumb > 0.7f, 0.0); + // vr_driver_input->UpdateBooleanComponent( + // m_buttonHandles[ALVR_INPUT_TRIGGER_TOUCH], rotIndex > 0.7f, 0.0); + // } - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_INDEX], rotIndex, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_MIDDLE], rotMiddle, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_RING], rotRing, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_PINKY], rotPinky, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_INDEX], rotIndex, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_MIDDLE], rotMiddle, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_RING], rotRing, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_PINKY], rotPinky, 0.0); } else { - uint64_t currentThumbTouch = - m_buttons & - (ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH) | ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH) | - ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH) | ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH) | - ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)); - if (m_lastThumbTouch != currentThumbTouch) { + if (m_lastThumbTouch != m_currentThumbTouch) { m_thumbTouchAnimationProgress += 1.f / ANIMATION_FRAME_COUNT; if (m_thumbTouchAnimationProgress > 1.f) { m_thumbTouchAnimationProgress = 0; - m_lastThumbTouch = currentThumbTouch; + m_lastThumbTouch = m_currentThumbTouch; } } else { m_thumbTouchAnimationProgress = 0; } - uint64_t currentIndexTouch = m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH); - if (m_lastIndexTouch != currentIndexTouch) { + if (m_lastTriggerTouch != m_currentTriggerTouch) { m_indexTouchAnimationProgress += 1.f / ANIMATION_FRAME_COUNT; if (m_indexTouchAnimationProgress > 1.f) { m_indexTouchAnimationProgress = 0; - m_lastIndexTouch = currentIndexTouch; + m_lastTriggerTouch = m_currentTriggerTouch; } } else { m_indexTouchAnimationProgress = 0; } - // Valve Index - if (Settings::Instance().m_controllerMode == 3) { - float indexCurl = 0.0; - if (m_triggerValue > 0.0) { - indexCurl = 0.5 + m_triggerValue * 0.5; - } else if (m_lastIndexTouch == 0) { - indexCurl = m_indexTouchAnimationProgress * 0.5; - } else { - indexCurl = 0.5 - m_indexTouchAnimationProgress * 0.5; - } - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_FINGER_INDEX], indexCurl, 0.0); - - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_FINGER_MIDDLE], m_gripValue, 0.0); - - // Ring and pinky fingers are not tracked. Infer a more natural pose. - if ((m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH)) != 0 || - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH)) != 0 || - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH)) != 0 || - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH)) != 0 || - (m_buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0) { - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_RING], 1, 0.0); - vr_driver_input->UpdateScalarComponent(m_handles[ALVR_INPUT_FINGER_PINKY], 1, 0.0); - } else { - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_FINGER_RING], m_gripValue, 0.0); - vr_driver_input->UpdateScalarComponent( - m_handles[ALVR_INPUT_FINGER_PINKY], m_gripValue, 0.0); - } + float indexCurl = 0.0; + if (m_triggerValue > 0.0) { + indexCurl = 0.5 + m_triggerValue * 0.5; + } else if (m_lastTriggerTouch == 0) { + indexCurl = m_indexTouchAnimationProgress * 0.5; + } else { + indexCurl = 0.5 - m_indexTouchAnimationProgress * 0.5; } + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_INDEX], indexCurl, 0.0); - uint64_t lastPoseTouch = m_lastThumbTouch + m_lastIndexTouch; + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_MIDDLE], m_gripValue, 0.0); + + // Ring and pinky fingers are not tracked. Infer a more natural pose. + if (m_currentThumbTouch) { + vr_driver_input->UpdateScalarComponent(m_buttonHandles[ALVR_INPUT_FINGER_RING], 1, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_PINKY], 1, 0.0); + } else { + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_RING], m_gripValue, 0.0); + vr_driver_input->UpdateScalarComponent( + m_buttonHandles[ALVR_INPUT_FINGER_PINKY], m_gripValue, 0.0); + } vr::VRBoneTransform_t boneTransforms[SKELETON_BONE_COUNT]; - // Perform whatever logic is necessary to convert your device's input into a skeletal - // pose, first to create a pose "With Controller", that is as close to the pose of the - // user's real hand as possible - GetBoneTransform(true, - this->device_id == LEFT_HAND_ID, - m_thumbTouchAnimationProgress, - m_indexTouchAnimationProgress, - lastPoseTouch, - boneTransforms); + // Perform whatever logic is necessary to convert your device's input into a + // skeletal pose, first to create a pose "With Controller", that is as close to the + // pose of the user's real hand as possible + GetBoneTransform(true, boneTransforms); // Then update the WithController pose on the component with those transforms vr::EVRInputError err = @@ -809,12 +341,7 @@ bool Controller::onPoseUpdate(float predictionS, Error("UpdateSkeletonComponentfailed. Error: %i\n", err); } - GetBoneTransform(false, - this->device_id == LEFT_HAND_ID, - m_thumbTouchAnimationProgress, - m_indexTouchAnimationProgress, - lastPoseTouch, - boneTransforms); + GetBoneTransform(false, boneTransforms); // Then update the WithoutController pose on the component err = vr_driver_input->UpdateSkeletonComponent(m_compSkeleton, @@ -835,11 +362,10 @@ bool Controller::onPoseUpdate(float predictionS, void GetThumbBoneTransform(bool withController, bool isLeftHand, - uint64_t buttons, + bool touch, vr::VRBoneTransform_t outBoneTransform[]) { if (isLeftHand) { - if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_Y_TOUCH)) != 0) { - // y touch + if (touch) { if (withController) { outBoneTransform[2] = {{-0.017303f, 0.032567f, 0.025281f, 1.f}, {0.317609f, 0.528344f, 0.213134f, 0.757991f}}; @@ -855,42 +381,7 @@ void GetThumbBoneTransform(bool withController, outBoneTransform[4] = {{0.032517f, 0.000000f, 0.000000f, 1.f}, {0.988590f, 0.143978f, 0.041520f, 0.015363f}}; } - } else if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_X_TOUCH)) != 0) { - // x touch - if (withController) { - outBoneTransform[2] = {{-0.017625f, 0.031098f, 0.022755f, 1}, - {0.388513f, 0.527438f, 0.249444f, 0.713193f}}; - outBoneTransform[3] = {{0.040406f, 0.000000f, -0.000000f, 1}, - {0.978341f, 0.085924f, 0.037765f, 0.184501f}}; - outBoneTransform[4] = {{0.032517f, -0.000000f, 0.000000f, 1}, - {0.894037f, -0.043820f, -0.048328f, 0.443217f}}; - } else { - outBoneTransform[2] = {{-0.017288f, 0.027151f, 0.021465f, 1}, - {0.502777f, 0.569978f, 0.147197f, 0.632988f}}; - outBoneTransform[3] = {{0.040406f, 0.000000f, -0.000000f, 1}, - {0.970397f, -0.048119f, 0.023261f, 0.235527f}}; - outBoneTransform[4] = {{0.032517f, 0.000000f, 0.000000f, 1}, - {0.794064f, 0.084451f, -0.037468f, 0.600772f}}; - } - } else if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0) { - // joy touch - if (withController) { - outBoneTransform[2] = {{-0.017914f, 0.029178f, 0.025298f, 1}, - {0.455126f, 0.591760f, 0.168152f, 0.643743f}}; - outBoneTransform[3] = {{0.040406f, 0.000000f, -0.000000f, 1}, - {0.969878f, 0.084444f, 0.045679f, 0.223873f}}; - outBoneTransform[4] = {{0.032517f, -0.000000f, 0.000000f, 1}, - {0.991257f, 0.014384f, -0.005602f, 0.131040f}}; - } else { - outBoneTransform[2] = {{-0.017914f, 0.029178f, 0.025298f, 1}, - {0.455126f, 0.591760f, 0.168152f, 0.643743f}}; - outBoneTransform[3] = {{0.040406f, 0.000000f, -0.000000f, 1}, - {0.969878f, 0.084444f, 0.045679f, 0.223873f}}; - outBoneTransform[4] = {{0.032517f, -0.000000f, 0.000000f, 1}, - {0.991257f, 0.014384f, -0.005602f, 0.131040f}}; - } } else { - // no touch outBoneTransform[2] = {{-0.012083f, 0.028070f, 0.025050f, 1}, {0.464112f, 0.567418f, 0.272106f, 0.623374f}}; outBoneTransform[3] = {{0.040406f, 0.000000f, -0.000000f, 1}, @@ -902,8 +393,7 @@ void GetThumbBoneTransform(bool withController, outBoneTransform[5] = {{0.030464f, -0.000000f, -0.000000f, 1}, {1.000000f, -0.000000f, 0.000000f, 0.000000f}}; } else { - if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_B_TOUCH)) != 0) { - // b touch + if (touch) { if (withController) { outBoneTransform[2] = {{0.017303f, 0.032567f, 0.025281f, 1}, {0.528344f, -0.317609f, 0.757991f, -0.213134f}}; @@ -919,42 +409,7 @@ void GetThumbBoneTransform(bool withController, outBoneTransform[4] = {{-0.032517f, -0.000000f, -0.000000f, 1}, {0.988590f, 0.143978f, 0.041520f, 0.015363f}}; } - } else if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_A_TOUCH)) != 0) { - // a touch - if (withController) { - outBoneTransform[2] = {{0.017625f, 0.031098f, 0.022755f, 1}, - {0.527438f, -0.388513f, 0.713193f, -0.249444f}}; - outBoneTransform[3] = {{-0.040406f, -0.000000f, 0.000000f, 1}, - {0.978341f, 0.085924f, 0.037765f, 0.184501f}}; - outBoneTransform[4] = {{-0.032517f, 0.000000f, -0.000000f, 1}, - {0.894037f, -0.043820f, -0.048328f, 0.443217f}}; - } else { - outBoneTransform[2] = {{0.017288f, 0.027151f, 0.021465f, 1}, - {0.569978f, -0.502777f, 0.632988f, -0.147197f}}; - outBoneTransform[3] = {{-0.040406f, -0.000000f, 0.000000f, 1}, - {0.970397f, -0.048119f, 0.023261f, 0.235527f}}; - outBoneTransform[4] = {{-0.032517f, -0.000000f, -0.000000f, 1}, - {0.794064f, 0.084451f, -0.037468f, 0.600772f}}; - } - } else if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_JOYSTICK_TOUCH)) != 0) { - // joy touch - if (withController) { - outBoneTransform[2] = {{0.017914f, 0.029178f, 0.025298f, 1}, - {0.591760f, -0.455126f, 0.643743f, -0.168152f}}; - outBoneTransform[3] = {{-0.040406f, -0.000000f, 0.000000f, 1}, - {0.969878f, 0.084444f, 0.045679f, 0.223873f}}; - outBoneTransform[4] = {{-0.032517f, 0.000000f, -0.000000f, 1}, - {0.991257f, 0.014384f, -0.005602f, 0.131040f}}; - } else { - outBoneTransform[2] = {{0.017914f, 0.029178f, 0.025298f, 1}, - {0.591760f, -0.455126f, 0.643743f, -0.168152f}}; - outBoneTransform[3] = {{-0.040406f, -0.000000f, 0.000000f, 1}, - {0.969878f, 0.084444f, 0.045679f, 0.223873f}}; - outBoneTransform[4] = {{-0.032517f, 0.000000f, -0.000000f, 1}, - {0.991257f, 0.014384f, -0.005602f, 0.131040f}}; - } } else { - // no touch outBoneTransform[2] = {{0.012330f, 0.028661f, 0.025049f, 1}, {0.571059f, -0.451277f, 0.630056f, -0.270685f}}; outBoneTransform[3] = {{-0.040406f, -0.000000f, 0.000000f, 1}, @@ -970,10 +425,10 @@ void GetThumbBoneTransform(bool withController, void GetTriggerBoneTransform(bool withController, bool isLeftHand, - uint64_t buttons, + bool touch, + float click, vr::VRBoneTransform_t outBoneTransform[]) { - if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK)) != 0) { - // click + if (click) { if (withController) { if (isLeftHand) { outBoneTransform[6] = {{-0.003925f, 0.027171f, 0.014640f, 1}, @@ -1183,8 +638,7 @@ void GetTriggerBoneTransform(bool withController, {-0.031423f, 0.791013f, 0.597190f, 0.129133f}}; } } - } else if ((buttons & ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH)) != 0) { - // touch + } else if (touch) { if (withController) { if (isLeftHand) { outBoneTransform[6] = {{-0.003925f, 0.027171f, 0.014640f, 1}, @@ -1665,12 +1119,8 @@ void GetGripClickBoneTransform(bool withController, } } -void Controller::GetBoneTransform(bool withController, - bool isLeftHand, - float thumbAnimationProgress, - float indexAnimationProgress, - uint64_t lastPoseButtons, - vr::VRBoneTransform_t outBoneTransform[]) { +void Controller::GetBoneTransform(bool withController, vr::VRBoneTransform_t outBoneTransform[]) { + auto isLeftHand = device_id == LEFT_HAND_ID; vr::VRBoneTransform_t boneTransform1[SKELETON_BONE_COUNT]; vr::VRBoneTransform_t boneTransform2[SKELETON_BONE_COUNT]; @@ -1687,23 +1137,21 @@ void Controller::GetBoneTransform(bool withController, } // thumb - GetThumbBoneTransform(withController, isLeftHand, lastPoseButtons, boneTransform1); - GetThumbBoneTransform(withController, isLeftHand, m_buttons, boneTransform2); + GetThumbBoneTransform(withController, isLeftHand, m_lastThumbTouch, boneTransform1); + GetThumbBoneTransform(withController, isLeftHand, m_currentThumbTouch, boneTransform2); for (int boneIdx = 2; boneIdx < 6; boneIdx++) { outBoneTransform[boneIdx].position = Lerp(boneTransform1[boneIdx].position, boneTransform2[boneIdx].position, - thumbAnimationProgress); + m_thumbTouchAnimationProgress); outBoneTransform[boneIdx].orientation = Slerp(boneTransform1[boneIdx].orientation, boneTransform2[boneIdx].orientation, - thumbAnimationProgress); + m_thumbTouchAnimationProgress); } // trigger (index to pinky) if (m_triggerValue > 0) { - GetTriggerBoneTransform( - withController, isLeftHand, ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_TOUCH), boneTransform1); - GetTriggerBoneTransform( - withController, isLeftHand, ALVR_BUTTON_FLAG(ALVR_INPUT_TRIGGER_CLICK), boneTransform2); + GetTriggerBoneTransform(withController, isLeftHand, true, false, boneTransform1); + GetTriggerBoneTransform(withController, isLeftHand, true, true, boneTransform2); for (int boneIdx = 6; boneIdx < SKELETON_BONE_COUNT; boneIdx++) { outBoneTransform[boneIdx].position = Lerp( boneTransform1[boneIdx].position, boneTransform2[boneIdx].position, m_triggerValue); @@ -1712,15 +1160,17 @@ void Controller::GetBoneTransform(bool withController, m_triggerValue); } } else { - GetTriggerBoneTransform(withController, isLeftHand, lastPoseButtons, boneTransform1); - GetTriggerBoneTransform(withController, isLeftHand, m_buttons, boneTransform2); + GetTriggerBoneTransform( + withController, isLeftHand, m_lastTriggerTouch, false, boneTransform1); + GetTriggerBoneTransform( + withController, isLeftHand, m_currentTriggerTouch, false, boneTransform2); for (int boneIdx = 6; boneIdx < SKELETON_BONE_COUNT; boneIdx++) { outBoneTransform[boneIdx].position = Lerp(boneTransform1[boneIdx].position, boneTransform2[boneIdx].position, - indexAnimationProgress); + m_indexTouchAnimationProgress); outBoneTransform[boneIdx].orientation = Slerp(boneTransform1[boneIdx].orientation, boneTransform2[boneIdx].orientation, - indexAnimationProgress); + m_indexTouchAnimationProgress); } } diff --git a/alvr/server/cpp/alvr_server/Controller.h b/alvr/server/cpp/alvr_server/Controller.h index e8128166..dc7892fb 100644 --- a/alvr/server/cpp/alvr_server/Controller.h +++ b/alvr/server/cpp/alvr_server/Controller.h @@ -33,6 +33,8 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { vr::VRInputComponentHandle_t getHapticComponent(); + void RegisterButton(uint64_t id); + void SetButton(uint64_t id, FfiButtonValue value); bool onPoseUpdate(float predictionS, @@ -40,12 +42,7 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { const FfiHandSkeleton *hand, unsigned int controllersTracked); - void GetBoneTransform(bool withController, - bool isLeftHand, - float thumbAnimationProgress, - float indexAnimationProgress, - uint64_t lastPoseTouch, - vr::VRBoneTransform_t outBoneTransform[]); + void GetBoneTransform(bool withController, vr::VRBoneTransform_t outBoneTransform[]); vr::ETrackedDeviceClass getControllerDeviceClass(); @@ -53,20 +50,21 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { static const int SKELETON_BONE_COUNT = 31; static const int ANIMATION_FRAME_COUNT = 15; - vr::VRInputComponentHandle_t m_handles[ALVR_INPUT_COUNT]; + std::map m_buttonHandles; + vr::VRInputComponentHandle_t m_compHaptic; vr::VRInputComponentHandle_t m_compSkeleton = vr::k_ulInvalidInputComponentHandle; vr::DriverPose_t m_pose; + // These variables are used for controller hand animation + // todo: move to rust float m_thumbTouchAnimationProgress = 0; float m_indexTouchAnimationProgress = 0; - uint64_t m_lastThumbTouch = 0; - uint64_t m_lastIndexTouch = 0; - - uint64_t m_buttons = 0; + bool m_currentThumbTouch = false; + bool m_lastThumbTouch = false; + bool m_currentTriggerTouch = false; + bool m_lastTriggerTouch = false; float m_triggerValue = 0; float m_gripValue = 0; - float m_joystickX = 0; - float m_joystickY = 0; }; diff --git a/alvr/server/cpp/alvr_server/Paths.cpp b/alvr/server/cpp/alvr_server/Paths.cpp index c6fe1843..368c997d 100644 --- a/alvr/server/cpp/alvr_server/Paths.cpp +++ b/alvr/server/cpp/alvr_server/Paths.cpp @@ -5,101 +5,182 @@ uint64_t HEAD_ID; uint64_t LEFT_HAND_ID; uint64_t RIGHT_HAND_ID; -uint64_t MENU_CLICK_ID; -uint64_t A_CLICK_ID; -uint64_t A_TOUCH_ID; -uint64_t B_CLICK_ID; -uint64_t B_TOUCH_ID; -uint64_t X_CLICK_ID; -uint64_t X_TOUCH_ID; -uint64_t Y_CLICK_ID; -uint64_t Y_TOUCH_ID; -uint64_t LEFT_SQUEEZE_CLICK_ID; -uint64_t LEFT_SQUEEZE_VALUE_ID; -uint64_t LEFT_TRIGGER_CLICK_ID; -uint64_t LEFT_TRIGGER_VALUE_ID; -uint64_t LEFT_TRIGGER_TOUCH_ID; -uint64_t LEFT_THUMBSTICK_X_ID; -uint64_t LEFT_THUMBSTICK_Y_ID; -uint64_t LEFT_THUMBSTICK_CLICK_ID; +std::map LEFT_CONTROLLER_BUTTON_MAPPING; +std::map RIGHT_CONTROLLER_BUTTON_MAPPING; + +uint64_t LEFT_A_TOUCH_ID; +uint64_t LEFT_B_TOUCH_ID; +uint64_t LEFT_X_TOUCH_ID; +uint64_t LEFT_Y_TOUCH_ID; +uint64_t LEFT_TRACKPAD_TOUCH_ID; uint64_t LEFT_THUMBSTICK_TOUCH_ID; uint64_t LEFT_THUMBREST_TOUCH_ID; -uint64_t RIGHT_SQUEEZE_CLICK_ID; -uint64_t RIGHT_SQUEEZE_VALUE_ID; -uint64_t RIGHT_TRIGGER_CLICK_ID; -uint64_t RIGHT_TRIGGER_VALUE_ID; -uint64_t RIGHT_TRIGGER_TOUCH_ID; -uint64_t RIGHT_THUMBSTICK_X_ID; -uint64_t RIGHT_THUMBSTICK_Y_ID; -uint64_t RIGHT_THUMBSTICK_CLICK_ID; +uint64_t LEFT_TRIGGER_TOUCH_ID; +uint64_t LEFT_TRIGGER_VALUE_ID; +uint64_t LEFT_SQUEEZE_TOUCH_ID; +uint64_t LEFT_SQUEEZE_VALUE_ID; +uint64_t RIGHT_A_TOUCH_ID; +uint64_t RIGHT_B_TOUCH_ID; +uint64_t RIGHT_TRACKPAD_TOUCH_ID; uint64_t RIGHT_THUMBSTICK_TOUCH_ID; uint64_t RIGHT_THUMBREST_TOUCH_ID; - -std::vector LEFT_CONTROLLER_BUTTON_IDS; -std::vector RIGHT_CONTROLLER_BUTTON_IDS; +uint64_t RIGHT_TRIGGER_TOUCH_ID; +uint64_t RIGHT_TRIGGER_VALUE_ID; +uint64_t RIGHT_SQUEEZE_TOUCH_ID; +uint64_t RIGHT_SQUEEZE_VALUE_ID; void init_paths() { HEAD_ID = PathStringToHash("/user/head"); LEFT_HAND_ID = PathStringToHash("/user/hand/left"); RIGHT_HAND_ID = PathStringToHash("/user/hand/right"); - MENU_CLICK_ID = PathStringToHash("/user/hand/left/input/menu/click"); - A_CLICK_ID = PathStringToHash("/user/hand/right/input/a/click"); - A_TOUCH_ID = PathStringToHash("/user/hand/right/input/a/touch"); - B_CLICK_ID = PathStringToHash("/user/hand/right/input/b/click"); - B_TOUCH_ID = PathStringToHash("/user/hand/right/input/b/touch"); - X_CLICK_ID = PathStringToHash("/user/hand/left/input/x/click"); - X_TOUCH_ID = PathStringToHash("/user/hand/left/input/x/touch"); - Y_CLICK_ID = PathStringToHash("/user/hand/left/input/y/click"); - Y_TOUCH_ID = PathStringToHash("/user/hand/left/input/y/touch"); - LEFT_SQUEEZE_CLICK_ID = PathStringToHash("/user/hand/left/input/squeeze/click"); - LEFT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/left/input/squeeze/value"); - LEFT_TRIGGER_CLICK_ID = PathStringToHash("/user/hand/left/input/trigger/click"); - LEFT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/left/input/trigger/value"); - LEFT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/left/input/trigger/touch"); - LEFT_THUMBSTICK_X_ID = PathStringToHash("/user/hand/left/input/thumbstick/x"); - LEFT_THUMBSTICK_Y_ID = PathStringToHash("/user/hand/left/input/thumbstick/y"); - LEFT_THUMBSTICK_CLICK_ID = PathStringToHash("/user/hand/left/input/thumbstick/click"); + HEAD_ID = PathStringToHash("/user/head"); + LEFT_HAND_ID = PathStringToHash("/user/hand/left"); + RIGHT_HAND_ID = PathStringToHash("/user/hand/right"); + + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/system/click"), + {"/input/system/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/system/touch"), + {"/input/system/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/menu/click"), + {"/input/application_menu/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/a/click"), + {"/input/a/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/a/touch"), + {"/input/a/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/b/click"), + {"/input/b/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/b/touch"), + {"/input/b/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/x/click"), + {"/input/x/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/x/touch"), + {"/input/x/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/y/click"), + {"/input/y/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/y/touch"), + {"/input/y/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/squeeze/click"), + {"/input/grip/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/squeeze/touch"), + {"/input/grip/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/squeeze/value"), + {"/input/grip/click", ButtonType::ScalarOneSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/squeeze/force"), + {"/input/grip/force", ButtonType::ScalarOneSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trigger/click"), + {"/input/trigger/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trigger/value"), + {"/input/trigger/value", ButtonType::ScalarOneSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trigger/touch"), + {"/input/trigger/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/thumbstick/x"), + {"/input/joystick/x", ButtonType::ScalarTwoSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/thumbstick/y"), + {"/input/joystick/y", ButtonType::ScalarTwoSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/left/input/thumbstick/click"), + {"/input/joystick/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/left/input/thumbstick/click"), + {"/input/joystick/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/left/input/thumbstick/touch"), + {"/input/joystick/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trackpad/x"), + {"/input/trackpad/x", ButtonType::ScalarTwoSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trackpad/y"), + {"/input/trackpad/y", ButtonType::ScalarTwoSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trackpad/click"), + {"/input/trackpad/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trackpad/force"), + {"/input/trackpad/force", ButtonType::ScalarOneSided}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/left/input/trackpad/touch"), + {"/input/trackpad/touch", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/left/input/thumbrest/touch"), + {"/input/thumbrest/touch", ButtonType::Binary}}); + + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/system/click"), + {"/input/system/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/system/touch"), + {"/input/system/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/menu/click"), + {"/input/application_menu/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/a/click"), + {"/input/a/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/a/touch"), + {"/input/a/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/b/click"), + {"/input/b/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/b/touch"), + {"/input/b/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/squeeze/click"), + {"/input/grip/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/squeeze/touch"), + {"/input/grip/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/squeeze/value"), + {"/input/grip/value", ButtonType::ScalarOneSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/squeeze/force"), + {"/input/grip/force", ButtonType::ScalarOneSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trigger/click"), + {"/input/trigger/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trigger/value"), + {"/input/trigger/value", ButtonType::ScalarOneSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trigger/touch"), + {"/input/trigger/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/thumbstick/x"), + {"/input/joystick/x", ButtonType::ScalarTwoSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/thumbstick/y"), + {"/input/joystick/y", ButtonType::ScalarTwoSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/thumbstick/click"), + {"/input/joystick/click", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/thumbstick/touch"), + {"/input/joystick/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/trackpad/x"), + {"/input/trackpad/x", ButtonType::ScalarTwoSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert({PathStringToHash("/user/hand/right/input/trackpad/y"), + {"/input/trackpad/y", ButtonType::ScalarTwoSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trackpad/click"), + {"/input/trackpad/click", ButtonType::Binary}}); + LEFT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trackpad/force"), + {"/input/trackpad/force", ButtonType::ScalarOneSided}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/trackpad/touch"), + {"/input/trackpad/touch", ButtonType::Binary}}); + RIGHT_CONTROLLER_BUTTON_MAPPING.insert( + {PathStringToHash("/user/hand/right/input/thumbrest/touch"), + {"/input/thumbrest/touch", ButtonType::Binary}}); + + LEFT_A_TOUCH_ID = PathStringToHash("/user/hand/left/input/a/touch"); + LEFT_B_TOUCH_ID = PathStringToHash("/user/hand/left/input/b/touch"); + LEFT_X_TOUCH_ID = PathStringToHash("/user/hand/left/input/x/touch"); + LEFT_Y_TOUCH_ID = PathStringToHash("/user/hand/left/input/y/touch"); + LEFT_TRACKPAD_TOUCH_ID = PathStringToHash("/user/hand/left/input/trackpad/touch"); LEFT_THUMBSTICK_TOUCH_ID = PathStringToHash("/user/hand/left/input/thumbstick/touch"); LEFT_THUMBREST_TOUCH_ID = PathStringToHash("/user/hand/left/input/thumbrest/touch"); - RIGHT_SQUEEZE_CLICK_ID = PathStringToHash("/user/hand/right/input/squeeze/click"); - RIGHT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/right/input/squeeze/value"); - RIGHT_TRIGGER_CLICK_ID = PathStringToHash("/user/hand/right/input/trigger/click"); - RIGHT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/right/input/trigger/value"); - RIGHT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/right/input/trigger/touch"); - RIGHT_THUMBSTICK_X_ID = PathStringToHash("/user/hand/right/input/thumbstick/x"); - RIGHT_THUMBSTICK_Y_ID = PathStringToHash("/user/hand/right/input/thumbstick/y"); - RIGHT_THUMBSTICK_CLICK_ID = PathStringToHash("/user/hand/right/input/thumbstick/click"); + LEFT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/left/input/trigger/touch"); + LEFT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/left/input/trigger/value"); + LEFT_SQUEEZE_TOUCH_ID = PathStringToHash("/user/hand/left/input/squeeze/touch"); + LEFT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/left/input/squeeze/value"); + RIGHT_A_TOUCH_ID = PathStringToHash("/user/hand/right/input/a/touch"); + RIGHT_B_TOUCH_ID = PathStringToHash("/user/hand/right/input/b/touch"); + RIGHT_TRACKPAD_TOUCH_ID = PathStringToHash("/user/hand/right/input/trackpad/touch"); RIGHT_THUMBSTICK_TOUCH_ID = PathStringToHash("/user/hand/right/input/thumbstick/touch"); RIGHT_THUMBREST_TOUCH_ID = PathStringToHash("/user/hand/right/input/thumbrest/touch"); - - LEFT_CONTROLLER_BUTTON_IDS.push_back(MENU_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(X_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(X_TOUCH_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(Y_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(Y_TOUCH_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_SQUEEZE_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_SQUEEZE_VALUE_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_TRIGGER_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_TRIGGER_VALUE_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_TRIGGER_TOUCH_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_THUMBSTICK_X_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_THUMBSTICK_Y_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_THUMBSTICK_CLICK_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_THUMBSTICK_TOUCH_ID); - LEFT_CONTROLLER_BUTTON_IDS.push_back(LEFT_THUMBREST_TOUCH_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(A_CLICK_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(A_TOUCH_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(B_CLICK_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(B_TOUCH_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_SQUEEZE_CLICK_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_SQUEEZE_VALUE_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_TRIGGER_CLICK_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_TRIGGER_VALUE_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_TRIGGER_TOUCH_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_THUMBSTICK_X_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_THUMBSTICK_Y_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_THUMBSTICK_CLICK_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_THUMBSTICK_TOUCH_ID); - RIGHT_CONTROLLER_BUTTON_IDS.push_back(RIGHT_THUMBREST_TOUCH_ID); + RIGHT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/right/input/trigger/touch"); + RIGHT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/right/input/trigger/value"); + RIGHT_SQUEEZE_TOUCH_ID = PathStringToHash("/user/hand/right/input/squeeze/touch"); + RIGHT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/right/input/squeeze/value"); } \ No newline at end of file diff --git a/alvr/server/cpp/alvr_server/Paths.h b/alvr/server/cpp/alvr_server/Paths.h index c4a5dc60..f0e9703b 100644 --- a/alvr/server/cpp/alvr_server/Paths.h +++ b/alvr/server/cpp/alvr_server/Paths.h @@ -1,43 +1,51 @@ #pragma once #include -#include +// #include +#include + +#include "openvr_driver.h" extern uint64_t HEAD_ID; extern uint64_t LEFT_HAND_ID; extern uint64_t RIGHT_HAND_ID; -extern uint64_t MENU_CLICK_ID; -extern uint64_t A_CLICK_ID; -extern uint64_t A_TOUCH_ID; -extern uint64_t B_CLICK_ID; -extern uint64_t B_TOUCH_ID; -extern uint64_t X_CLICK_ID; -extern uint64_t X_TOUCH_ID; -extern uint64_t Y_CLICK_ID; -extern uint64_t Y_TOUCH_ID; -extern uint64_t LEFT_SQUEEZE_CLICK_ID; -extern uint64_t LEFT_SQUEEZE_VALUE_ID; -extern uint64_t LEFT_TRIGGER_CLICK_ID; -extern uint64_t LEFT_TRIGGER_VALUE_ID; -extern uint64_t LEFT_TRIGGER_TOUCH_ID; -extern uint64_t LEFT_THUMBSTICK_X_ID; -extern uint64_t LEFT_THUMBSTICK_Y_ID; -extern uint64_t LEFT_THUMBSTICK_CLICK_ID; +enum class ButtonType { + Binary, + ScalarOneSided, + ScalarTwoSided, +}; + +struct ButtonInfo { + const char *steamvr_path; + ButtonType type; +}; + +// Map button ID to SteamVR button info +extern std::map LEFT_CONTROLLER_BUTTON_MAPPING; +extern std::map RIGHT_CONTROLLER_BUTTON_MAPPING; + +void init_paths(); + +// These values are needed to determine the hand skeleton when holding a controller. +// todo: move inferred hand skeleton to rust +extern uint64_t LEFT_A_TOUCH_ID; +extern uint64_t LEFT_B_TOUCH_ID; +extern uint64_t LEFT_X_TOUCH_ID; +extern uint64_t LEFT_Y_TOUCH_ID; +extern uint64_t LEFT_TRACKPAD_TOUCH_ID; extern uint64_t LEFT_THUMBSTICK_TOUCH_ID; extern uint64_t LEFT_THUMBREST_TOUCH_ID; -extern uint64_t RIGHT_SQUEEZE_CLICK_ID; -extern uint64_t RIGHT_SQUEEZE_VALUE_ID; -extern uint64_t RIGHT_TRIGGER_CLICK_ID; -extern uint64_t RIGHT_TRIGGER_VALUE_ID; -extern uint64_t RIGHT_TRIGGER_TOUCH_ID; -extern uint64_t RIGHT_THUMBSTICK_X_ID; -extern uint64_t RIGHT_THUMBSTICK_Y_ID; -extern uint64_t RIGHT_THUMBSTICK_CLICK_ID; +extern uint64_t LEFT_TRIGGER_TOUCH_ID; +extern uint64_t LEFT_TRIGGER_VALUE_ID; +extern uint64_t LEFT_SQUEEZE_TOUCH_ID; +extern uint64_t LEFT_SQUEEZE_VALUE_ID; +extern uint64_t RIGHT_A_TOUCH_ID; +extern uint64_t RIGHT_B_TOUCH_ID; +extern uint64_t RIGHT_TRACKPAD_TOUCH_ID; extern uint64_t RIGHT_THUMBSTICK_TOUCH_ID; extern uint64_t RIGHT_THUMBREST_TOUCH_ID; - -extern std::vector LEFT_CONTROLLER_BUTTON_IDS; -extern std::vector RIGHT_CONTROLLER_BUTTON_IDS; - -void init_paths(); \ No newline at end of file +extern uint64_t RIGHT_TRIGGER_TOUCH_ID; +extern uint64_t RIGHT_TRIGGER_VALUE_ID; +extern uint64_t RIGHT_SQUEEZE_TOUCH_ID; +extern uint64_t RIGHT_SQUEEZE_VALUE_ID; \ No newline at end of file diff --git a/alvr/server/cpp/alvr_server/Settings.cpp b/alvr/server/cpp/alvr_server/Settings.cpp index 0684135c..ef2393e2 100644 --- a/alvr/server/cpp/alvr_server/Settings.cpp +++ b/alvr/server/cpp/alvr_server/Settings.cpp @@ -102,11 +102,7 @@ void Settings::Load() { m_enableLinuxAsyncReprojection = config.get("linux_async_reprojection").get(); m_enableControllers = config.get("controllers_enabled").get(); - m_controllerMode = (int32_t)config.get("controllers_mode_idx").get(); - m_overrideTriggerThreshold = config.get("override_trigger_threshold").get(); - m_triggerThreshold = config.get("trigger_threshold").get(); - m_overrideGripThreshold = config.get("override_grip_threshold").get(); - m_gripThreshold = config.get("grip_threshold").get(); + m_controllerIsTracker = config.get("controller_is_tracker").get(); m_constantBitrate = v.get("session_settings") .get("video") diff --git a/alvr/server/cpp/alvr_server/Settings.h b/alvr/server/cpp/alvr_server/Settings.h index ea462605..76a36403 100644 --- a/alvr/server/cpp/alvr_server/Settings.h +++ b/alvr/server/cpp/alvr_server/Settings.h @@ -79,11 +79,7 @@ class Settings { bool m_enableLinuxAsyncReprojection; bool m_enableControllers; - int m_controllerMode = 0; - bool m_overrideTriggerThreshold; - float m_triggerThreshold; - bool m_overrideGripThreshold; - float m_gripThreshold; + int m_controllerIsTracker = false; bool m_constantBitrate; }; diff --git a/alvr/server/cpp/alvr_server/alvr_server.cpp b/alvr/server/cpp/alvr_server/alvr_server.cpp index 2a0d08dd..6083ae3a 100644 --- a/alvr/server/cpp/alvr_server/alvr_server.cpp +++ b/alvr/server/cpp/alvr_server/alvr_server.cpp @@ -193,6 +193,7 @@ void (*ReportComposed)(unsigned long long timestamp_ns, unsigned long long offse FfiDynamicEncoderParams (*GetDynamicEncoderParams)(); unsigned long long (*GetSerialNumber)(unsigned long long deviceID, char *outString); void (*SetOpenvrProps)(unsigned long long deviceID); +void (*RegisterButtons)(unsigned long long deviceID); void (*WaitForVSync)(); void *CppEntryPoint(const char *interface_name, int *return_code) { @@ -280,6 +281,17 @@ void SetOpenvrProperty(unsigned long long deviceID, FfiOpenvrProperty prop) { } } +void RegisterButton(unsigned long long buttonID) { + if (g_driver_provider.left_controller && + LEFT_CONTROLLER_BUTTON_MAPPING.find(buttonID) != LEFT_CONTROLLER_BUTTON_MAPPING.end()) { + g_driver_provider.left_controller->RegisterButton(buttonID); + } else if (g_driver_provider.right_controller && + RIGHT_CONTROLLER_BUTTON_MAPPING.find(buttonID) != + RIGHT_CONTROLLER_BUTTON_MAPPING.end()) { + g_driver_provider.right_controller->RegisterButton(buttonID); + } +} + void SetViewsConfig(FfiViewsConfig config) { if (g_driver_provider.hmd) { g_driver_provider.hmd->SetViewsConfig(config); @@ -297,16 +309,14 @@ void SetBattery(unsigned long long deviceID, float gauge_value, bool is_plugged) } } -void SetButton(unsigned long long path, FfiButtonValue value) { +void SetButton(unsigned long long buttonID, FfiButtonValue value) { if (g_driver_provider.left_controller && - std::find(LEFT_CONTROLLER_BUTTON_IDS.begin(), LEFT_CONTROLLER_BUTTON_IDS.end(), path) != - LEFT_CONTROLLER_BUTTON_IDS.end()) { - g_driver_provider.left_controller->SetButton(path, value); + LEFT_CONTROLLER_BUTTON_MAPPING.find(buttonID) != LEFT_CONTROLLER_BUTTON_MAPPING.end()) { + g_driver_provider.left_controller->SetButton(buttonID, value); } else if (g_driver_provider.right_controller && - std::find(RIGHT_CONTROLLER_BUTTON_IDS.begin(), - RIGHT_CONTROLLER_BUTTON_IDS.end(), - path) != RIGHT_CONTROLLER_BUTTON_IDS.end()) { - g_driver_provider.right_controller->SetButton(path, value); + RIGHT_CONTROLLER_BUTTON_MAPPING.find(buttonID) != + RIGHT_CONTROLLER_BUTTON_MAPPING.end()) { + g_driver_provider.right_controller->SetButton(buttonID, value); } } diff --git a/alvr/server/cpp/alvr_server/bindings.h b/alvr/server/cpp/alvr_server/bindings.h index 7de887e1..6f4049cf 100644 --- a/alvr/server/cpp/alvr_server/bindings.h +++ b/alvr/server/cpp/alvr_server/bindings.h @@ -122,6 +122,7 @@ extern "C" void (*ReportComposed)(unsigned long long timestamp_ns, unsigned long extern "C" FfiDynamicEncoderParams (*GetDynamicEncoderParams)(); extern "C" unsigned long long (*GetSerialNumber)(unsigned long long deviceID, char *outString); extern "C" void (*SetOpenvrProps)(unsigned long long deviceID); +extern "C" void (*RegisterButtons)(unsigned long long deviceID); extern "C" void (*WaitForVSync)(); extern "C" void *CppEntryPoint(const char *pInterfaceName, int *pReturnCode); @@ -140,10 +141,11 @@ extern "C" void VideoErrorReportReceive(); extern "C" void ShutdownSteamvr(); extern "C" void SetOpenvrProperty(unsigned long long deviceID, FfiOpenvrProperty prop); +extern "C" void RegisterButton(unsigned long long buttonID); extern "C" void SetChaperone(float areaWidth, float areaHeight); extern "C" void SetViewsConfig(FfiViewsConfig config); extern "C" void SetBattery(unsigned long long deviceID, float gauge_value, bool is_plugged); -extern "C" void SetButton(unsigned long long path, FfiButtonValue value); +extern "C" void SetButton(unsigned long long buttonID, FfiButtonValue value); extern "C" void CaptureFrame(); diff --git a/alvr/server/src/buttons.rs b/alvr/server/src/buttons.rs deleted file mode 100644 index a32e0678..00000000 --- a/alvr/server/src/buttons.rs +++ /dev/null @@ -1,45 +0,0 @@ -use alvr_common::{once_cell::sync::Lazy, *}; -use std::collections::HashMap; - -pub static BUTTON_PATH_FROM_ID: Lazy> = Lazy::new(|| { - [ - (*HEAD_ENTER_CLICK_ID, HEAD_ENTER_CLICK_PATH.into()), - (*MENU_CLICK_ID, MENU_CLICK_PATH.into()), - (*A_CLICK_ID, A_CLICK_PATH.into()), - (*A_TOUCH_ID, A_TOUCH_PATH.into()), - (*B_CLICK_ID, B_CLICK_PATH.into()), - (*B_TOUCH_ID, B_TOUCH_PATH.into()), - (*X_CLICK_ID, X_CLICK_PATH.into()), - (*X_TOUCH_ID, X_TOUCH_PATH.into()), - (*Y_CLICK_ID, Y_CLICK_PATH.into()), - (*Y_TOUCH_ID, Y_TOUCH_PATH.into()), - (*LEFT_SQUEEZE_CLICK_ID, LEFT_SQUEEZE_CLICK_PATH.into()), - (*LEFT_SQUEEZE_VALUE_ID, LEFT_SQUEEZE_VALUE_PATH.into()), - (*LEFT_TRIGGER_CLICK_ID, LEFT_TRIGGER_CLICK_PATH.into()), - (*LEFT_TRIGGER_VALUE_ID, LEFT_TRIGGER_VALUE_PATH.into()), - (*LEFT_TRIGGER_TOUCH_ID, LEFT_TRIGGER_TOUCH_PATH.into()), - (*LEFT_THUMBSTICK_X_ID, LEFT_THUMBSTICK_X_PATH.into()), - (*LEFT_THUMBSTICK_Y_ID, LEFT_THUMBSTICK_Y_PATH.into()), - (*LEFT_THUMBSTICK_CLICK_ID, LEFT_THUMBSTICK_CLICK_PATH.into()), - (*LEFT_THUMBSTICK_TOUCH_ID, LEFT_THUMBSTICK_TOUCH_PATH.into()), - (*LEFT_THUMBREST_TOUCH_ID, LEFT_THUMBREST_TOUCH_PATH.into()), - (*RIGHT_SQUEEZE_CLICK_ID, RIGHT_SQUEEZE_CLICK_PATH.into()), - (*RIGHT_SQUEEZE_VALUE_ID, RIGHT_SQUEEZE_VALUE_PATH.into()), - (*RIGHT_TRIGGER_CLICK_ID, RIGHT_TRIGGER_CLICK_PATH.into()), - (*RIGHT_TRIGGER_VALUE_ID, RIGHT_TRIGGER_VALUE_PATH.into()), - (*RIGHT_TRIGGER_TOUCH_ID, RIGHT_TRIGGER_TOUCH_PATH.into()), - (*RIGHT_THUMBSTICK_X_ID, RIGHT_THUMBSTICK_X_PATH.into()), - (*RIGHT_THUMBSTICK_Y_ID, RIGHT_THUMBSTICK_Y_PATH.into()), - ( - *RIGHT_THUMBSTICK_CLICK_ID, - RIGHT_THUMBSTICK_CLICK_PATH.into(), - ), - ( - *RIGHT_THUMBSTICK_TOUCH_ID, - RIGHT_THUMBSTICK_TOUCH_PATH.into(), - ), - (*RIGHT_THUMBREST_TOUCH_ID, RIGHT_THUMBREST_TOUCH_PATH.into()), - ] - .into_iter() - .collect() -}); diff --git a/alvr/server/src/connection.rs b/alvr/server/src/connection.rs index f944a4f9..942ca2f2 100644 --- a/alvr/server/src/connection.rs +++ b/alvr/server/src/connection.rs @@ -1,14 +1,13 @@ use crate::{ bitrate::BitrateManager, - buttons::BUTTON_PATH_FROM_ID, - create_recording_file, face_tracking::FaceTrackingSink, haptics, + input_mapping::ButtonMappingManager, sockets::WelcomeSocket, statistics::StatisticsManager, tracking::{self, TrackingManager}, - FfiButtonValue, FfiFov, FfiViewsConfig, VideoPacket, BITRATE_MANAGER, DECODER_CONFIG, - SERVER_DATA_MANAGER, STATISTICS_MANAGER, VIDEO_MIRROR_SENDER, VIDEO_RECORDING_FILE, + FfiFov, FfiViewsConfig, VideoPacket, BITRATE_MANAGER, DECODER_CONFIG, SERVER_DATA_MANAGER, + STATISTICS_MANAGER, VIDEO_MIRROR_SENDER, VIDEO_RECORDING_FILE, }; use alvr_audio::AudioDevice; use alvr_common::{ @@ -18,13 +17,14 @@ use alvr_common::{ once_cell::sync::Lazy, parking_lot::Mutex, settings_schema::Switch, - warn, AnyhowToCon, ConResult, ConnectionError, LazyMutOpt, RelaxedAtomic, ToCon, - DEVICE_ID_TO_PATH, HEAD_ID, LEFT_HAND_ID, RIGHT_HAND_ID, + warn, AnyhowToCon, ConResult, ConnectionError, LazyMutOpt, RelaxedAtomic, ToCon, BUTTON_INFO, + CONTROLLER_PROFILE_INFO, DEVICE_ID_TO_PATH, HEAD_ID, LEFT_HAND_ID, + QUEST_CONTROLLER_PROFILE_PATH, RIGHT_HAND_ID, }; use alvr_events::{ButtonEvent, EventType, HapticsEvent, TrackingEvent}; use alvr_packets::{ - ButtonValue, ClientConnectionResult, ClientControlPacket, ClientListAction, ClientStatistics, - Haptics, ServerControlPacket, StreamConfigPacket, Tracking, VideoPacketHeader, AUDIO, HAPTICS, + ClientConnectionResult, ClientControlPacket, ClientListAction, ClientStatistics, Haptics, + ServerControlPacket, StreamConfigPacket, Tracking, VideoPacketHeader, AUDIO, HAPTICS, STATISTICS, TRACKING, VIDEO, }; use alvr_session::{CodecType, ConnectionState, ControllersEmulationMode, FrameSize, OpenvrConfig}; @@ -78,32 +78,11 @@ pub fn contruct_openvr_config() -> OpenvrConfig { let old_config = data_manager_lock.session().openvr_config.clone(); let settings = data_manager_lock.settings().clone(); - let mut controllers_mode_idx = 0; - let mut override_trigger_threshold = false; - let mut trigger_threshold = 0.0; - let mut override_grip_threshold = false; - let mut grip_threshold = 0.0; + let mut controller_is_tracker = false; let controllers_enabled = if let Switch::Enabled(config) = settings.headset.controllers { - controllers_mode_idx = match config.emulation_mode { - ControllersEmulationMode::RiftSTouch => 1, - ControllersEmulationMode::ValveIndex => 3, - ControllersEmulationMode::ViveWand => 5, - ControllersEmulationMode::Quest2Touch => 7, - ControllersEmulationMode::ViveTracker => 9, - }; - override_trigger_threshold = - if let Switch::Enabled(value) = config.trigger_threshold_override { - trigger_threshold = value; - true - } else { - false - }; - override_grip_threshold = if let Switch::Enabled(value) = config.grip_threshold_override { - grip_threshold = value; - true - } else { - false - }; + controller_is_tracker = + matches!(config.emulation_mode, ControllersEmulationMode::ViveTracker); + true } else { false @@ -171,11 +150,7 @@ pub fn contruct_openvr_config() -> OpenvrConfig { .force_software_encoding, sw_thread_count: settings.video.encoder_config.software.thread_count, controllers_enabled, - controllers_mode_idx, - override_trigger_threshold, - trigger_threshold, - override_grip_threshold, - grip_threshold, + controller_is_tracker, enable_foveated_rendering, foveation_center_size_x, foveation_center_size_y, @@ -852,6 +827,21 @@ fn try_connect(mut client_ips: HashMap) -> ConResult { }); let control_receive_thread = thread::spawn({ + let mut controller_button_mapping_manager = if let Switch::Enabled(config) = + &SERVER_DATA_MANAGER.read().settings().headset.controllers + { + Some(ButtonMappingManager::new_automatic( + &CONTROLLER_PROFILE_INFO + .get(&alvr_common::hash_string(QUEST_CONTROLLER_PROFILE_PATH)) + .unwrap() + .button_set, + &config.button_mapping_config, + )) + } else { + None + }; + // todo: gestures_button_mapping_manager... + let control_sender = Arc::clone(&control_sender); let client_hostname = client_hostname.clone(); move || { @@ -897,6 +887,7 @@ fn try_connect(mut client_ips: HashMap) -> ConResult { unsafe { crate::RequestIDR() } } ClientControlPacket::VideoErrorReport => { + // legacy endpoint. todo: remove if let Some(stats) = &mut *STATISTICS_MANAGER.lock() { stats.report_packet_loss(); } @@ -940,9 +931,9 @@ fn try_connect(mut client_ips: HashMap) -> ConResult { entries .iter() .map(|e| ButtonEvent { - path: BUTTON_PATH_FROM_ID + path: BUTTON_INFO .get(&e.path_id) - .cloned() + .map(|info| info.path.to_owned()) .unwrap_or_else(|| { format!("Unknown (ID: {:#16x})", e.path_id) }), @@ -953,25 +944,28 @@ fn try_connect(mut client_ips: HashMap) -> ConResult { } } - for entry in entries { - let value = match entry.value { - ButtonValue::Binary(value) => FfiButtonValue { - type_: crate::FfiButtonType_BUTTON_TYPE_BINARY, - __bindgen_anon_1: crate::FfiButtonValue__bindgen_ty_1 { - binary: value.into(), - }, - }, - - ButtonValue::Scalar(value) => FfiButtonValue { - type_: crate::FfiButtonType_BUTTON_TYPE_SCALAR, - __bindgen_anon_1: crate::FfiButtonValue__bindgen_ty_1 { - scalar: value, - }, - }, + if let Some(manager) = &mut controller_button_mapping_manager { + for entry in entries { + manager.report_button(entry.path_id, entry.value); + } + }; + } + ClientControlPacket::ActiveInteractionProfile { + device_id: _, + profile_id, + } => { + controller_button_mapping_manager = + if let (Switch::Enabled(config), Some(profile_info)) = ( + &SERVER_DATA_MANAGER.read().settings().headset.controllers, + CONTROLLER_PROFILE_INFO.get(&profile_id), + ) { + Some(ButtonMappingManager::new_automatic( + &profile_info.button_set, + &config.button_mapping_config, + )) + } else { + None }; - - unsafe { crate::SetButton(entry.path_id, value) }; - } } ClientControlPacket::Log { level, message } => { info!("Client {client_hostname}: [{level:?}] {message}") @@ -1130,7 +1124,7 @@ pub extern "C" fn send_video(timestamp_ns: u64, buffer_ptr: *mut u8, len: i32, i unsafe { crate::RequestIDR() }; if is_idr { - create_recording_file(); + crate::create_recording_file(); *LAST_IDR_INSTANT.lock() = Instant::now(); } } diff --git a/alvr/server/src/input_mapping.rs b/alvr/server/src/input_mapping.rs new file mode 100644 index 00000000..659fcd63 --- /dev/null +++ b/alvr/server/src/input_mapping.rs @@ -0,0 +1,636 @@ +use crate::{bindings::FfiButtonValue, SERVER_DATA_MANAGER}; +use alvr_common::{once_cell::sync::Lazy, settings_schema::Switch, *}; +use alvr_packets::ButtonValue; +use alvr_session::{AutomaticButtonMappingConfig, ControllersEmulationMode, HysteresisThreshold}; +use std::{ + collections::{HashMap, HashSet}, + ops::Range, +}; + +pub static REGISTERED_BUTTON_SET: Lazy> = Lazy::new(|| { + let data_manager_lock = SERVER_DATA_MANAGER.read(); + let Switch::Enabled(controllers_config) = &data_manager_lock.settings().headset.controllers + else { + return HashSet::new(); + }; + + let profile = match &controllers_config.emulation_mode { + ControllersEmulationMode::Quest2Touch => &QUEST_CONTROLLER_PROFILE_ID, + ControllersEmulationMode::ValveIndex => &INDEX_CONTROLLER_PROFILE_ID, + ControllersEmulationMode::ViveWand => &VIVE_CONTROLLER_PROFILE_ID, + ControllersEmulationMode::ViveTracker => return HashSet::new(), + }; + CONTROLLER_PROFILE_INFO + .get(profile) + .unwrap() + .button_set + .clone() +}); + +pub struct BinaryToScalarStates { + off: f32, + on: f32, +} + +pub enum MappingType { + Passthrough, + HysteresisThreshold(HysteresisThreshold), + BinaryToScalar(BinaryToScalarStates), + Remap(Range), // remaps 0..1 to custom range +} + +pub struct BindingTarget { + destination: u64, + mapping_type: MappingType, + binary_conditions: Vec, +} + +// Inputs relative to the same physical button +#[derive(Clone, Copy)] +pub struct ButtonInputs { + click: Option, + touch: Option, + value: Option, + force: Option, +} + +fn click(click: u64) -> ButtonInputs { + ButtonInputs { + click: Some(click), + touch: None, + value: None, + force: None, + } +} + +fn ct(set: &HashSet, click: u64, touch: u64) -> ButtonInputs { + ButtonInputs { + click: Some(click), + touch: set.contains(&touch).then_some(touch), + value: None, + force: None, + } +} + +fn value(value: u64) -> ButtonInputs { + ButtonInputs { + click: None, + touch: None, + value: Some(value), + force: None, + } +} + +fn ctv(set: &HashSet, click: u64, touch: u64, value: u64) -> ButtonInputs { + ButtonInputs { + click: set.contains(&click).then_some(click), + touch: set.contains(&touch).then_some(touch), + value: set.contains(&value).then_some(value), + force: None, + } +} + +fn ctvf(set: &HashSet, click: u64, touch: u64, value: u64, force: u64) -> ButtonInputs { + ButtonInputs { + click: set.contains(&click).then_some(click), + touch: set.contains(&touch).then_some(touch), + value: set.contains(&value).then_some(value), + force: set.contains(&force).then_some(force), + } +} + +fn passthrough(target: u64) -> BindingTarget { + BindingTarget { + destination: target, + mapping_type: MappingType::Passthrough, + binary_conditions: vec![], + } +} + +fn binary_to_scalar(target: u64, map: BinaryToScalarStates) -> BindingTarget { + BindingTarget { + destination: target, + mapping_type: MappingType::BinaryToScalar(map), + binary_conditions: vec![], + } +} + +fn hysteresis_threshold(target: u64, map: HysteresisThreshold) -> BindingTarget { + BindingTarget { + destination: target, + mapping_type: MappingType::HysteresisThreshold(map), + binary_conditions: vec![], + } +} + +fn remap(target: u64, map: Range) -> BindingTarget { + BindingTarget { + destination: target, + mapping_type: MappingType::Remap(map), + binary_conditions: vec![], + } +} + +// Map two buttons with eterogeneous inputs +fn map_button_pair_automatic( + source: ButtonInputs, + destination: ButtonInputs, + config: &AutomaticButtonMappingConfig, +) -> impl Iterator)> { + let click_to_value = BinaryToScalarStates { off: 0.0, on: 1.0 }; + + let mut entries = vec![]; + if let Some(source_click) = source.click { + let mut targets = vec![]; + + if let Some(destination_click) = destination.click { + targets.push(passthrough(destination_click)); + } + if source.touch.is_none() { + if let Some(destination_touch) = destination.touch { + targets.push(passthrough(destination_touch)); + } + } + if source.value.is_none() { + if let Some(destination_value) = destination.value { + targets.push(binary_to_scalar(destination_value, click_to_value)); + } + } + + entries.push((source_click, targets)); + } + if let Some(source_touch) = source.touch { + let mut targets = vec![]; + if let Some(destination_touch) = destination.touch { + targets.push(passthrough(destination_touch)); + } + entries.push((source_touch, targets)); + } + if let Some(source_value) = source.value { + let mut targets = vec![]; + let mut remap_for_touch = false; + let mut remap_for_force = false; + + if source.click.is_none() { + if let Some(destination_click) = destination.click { + targets.push(hysteresis_threshold( + destination_click, + config.click_threshold, + )); + } + } + if source.touch.is_none() { + if let Some(destination_touch) = destination.touch { + targets.push(hysteresis_threshold( + destination_touch, + config.touch_threshold, + )); + remap_for_touch = true; + } + } + if source.force.is_none() { + if let Some(destination_force) = destination.force { + targets.push(remap(destination_force, config.force_threshold..1.0)); + remap_for_force = true; + } + } + if let Some(destination_value) = destination.value { + if !remap_for_touch && !remap_for_force { + targets.push(passthrough(destination_value)); + } else { + let low = if remap_for_touch { + config.touch_threshold.value + } else { + 0.0 + }; + let high = if remap_for_force { + config.force_threshold + } else { + 1.0 + }; + targets.push(remap(destination_value, low..high)); + } + } + + entries.push((source_value, targets)); + } + + entries.into_iter() +} + +pub fn automatic_bindings( + source_set: &HashSet, + destination_set: &HashSet, + config: &AutomaticButtonMappingConfig, +) -> HashMap> { + let s_set = source_set; + let d_set = destination_set; + + let mut bindings = HashMap::new(); + + // Menu buttons + if s_set.contains(&*LEFT_MENU_CLICK_ID) { + let click = click(*LEFT_MENU_CLICK_ID); + if d_set.contains(&*LEFT_MENU_CLICK_ID) { + bindings.extend(map_button_pair_automatic(click, click, config)); + } else if d_set.contains(&*LEFT_SYSTEM_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + click, + ct(s_set, *LEFT_SYSTEM_CLICK_ID, *LEFT_SYSTEM_TOUCH_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_MENU_CLICK_ID) { + let click = click(*RIGHT_MENU_CLICK_ID); + if d_set.contains(&*RIGHT_MENU_CLICK_ID) { + bindings.extend(map_button_pair_automatic(click, click, config)); + } else if d_set.contains(&*RIGHT_SYSTEM_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + click, + ct(s_set, *RIGHT_SYSTEM_CLICK_ID, *RIGHT_SYSTEM_TOUCH_ID), + config, + )); + } + } + + // A/X buttons + if s_set.contains(&*LEFT_X_CLICK_ID) { + let source = ct(s_set, *LEFT_X_CLICK_ID, *LEFT_X_TOUCH_ID); + if d_set.contains(&*LEFT_X_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_X_CLICK_ID, *LEFT_X_TOUCH_ID), + config, + )); + } else if d_set.contains(&*LEFT_A_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_A_CLICK_ID, *LEFT_A_TOUCH_ID), + config, + )); + } else if d_set.contains(&*LEFT_TRACKPAD_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_TRACKPAD_CLICK_ID, *LEFT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_A_CLICK_ID) { + let source = ct(s_set, *RIGHT_A_CLICK_ID, *RIGHT_A_TOUCH_ID); + if d_set.contains(&*RIGHT_A_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *RIGHT_A_CLICK_ID, *RIGHT_A_TOUCH_ID), + config, + )); + } else if d_set.contains(&*RIGHT_TRACKPAD_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *RIGHT_TRACKPAD_CLICK_ID, *RIGHT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + + // B/Y buttons + if s_set.contains(&*LEFT_Y_CLICK_ID) { + let source = ct(s_set, *LEFT_Y_CLICK_ID, *LEFT_Y_TOUCH_ID); + if d_set.contains(&*LEFT_Y_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_Y_CLICK_ID, *LEFT_Y_TOUCH_ID), + config, + )); + } else if d_set.contains(&*LEFT_B_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_B_CLICK_ID, *LEFT_B_TOUCH_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_B_CLICK_ID) && d_set.contains(&*RIGHT_B_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + ct(s_set, *RIGHT_B_CLICK_ID, *RIGHT_B_TOUCH_ID), + ct(d_set, *RIGHT_B_CLICK_ID, *RIGHT_B_TOUCH_ID), + config, + )); + } + + // Squeeze buttons + if (s_set.contains(&*LEFT_SQUEEZE_CLICK_ID) || s_set.contains(&*LEFT_SQUEEZE_VALUE_ID)) + && (d_set.contains(&*LEFT_SQUEEZE_CLICK_ID) || d_set.contains(&*LEFT_SQUEEZE_VALUE_ID)) + { + bindings.extend(map_button_pair_automatic( + ctvf( + s_set, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_SQUEEZE_TOUCH_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_SQUEEZE_FORCE_ID, + ), + ctvf( + d_set, + *LEFT_SQUEEZE_CLICK_ID, + *LEFT_SQUEEZE_TOUCH_ID, + *LEFT_SQUEEZE_VALUE_ID, + *LEFT_SQUEEZE_FORCE_ID, + ), + config, + )); + } + if (s_set.contains(&*RIGHT_SQUEEZE_CLICK_ID) || s_set.contains(&*RIGHT_SQUEEZE_VALUE_ID)) + && (d_set.contains(&*RIGHT_SQUEEZE_CLICK_ID) || d_set.contains(&*RIGHT_SQUEEZE_VALUE_ID)) + { + bindings.extend(map_button_pair_automatic( + ctvf( + s_set, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_SQUEEZE_TOUCH_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_SQUEEZE_FORCE_ID, + ), + ctvf( + d_set, + *RIGHT_SQUEEZE_CLICK_ID, + *RIGHT_SQUEEZE_TOUCH_ID, + *RIGHT_SQUEEZE_VALUE_ID, + *RIGHT_SQUEEZE_FORCE_ID, + ), + config, + )); + } + + // Trigger buttons + if (s_set.contains(&*LEFT_TRIGGER_CLICK_ID) || s_set.contains(&*LEFT_TRIGGER_VALUE_ID)) + && (d_set.contains(&*LEFT_TRIGGER_CLICK_ID) || d_set.contains(&*LEFT_TRIGGER_VALUE_ID)) + { + bindings.extend(map_button_pair_automatic( + ctv( + s_set, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_TRIGGER_VALUE_ID, + ), + ctv( + d_set, + *LEFT_TRIGGER_CLICK_ID, + *LEFT_TRIGGER_TOUCH_ID, + *LEFT_TRIGGER_VALUE_ID, + ), + config, + )); + } + if (s_set.contains(&*RIGHT_TRIGGER_CLICK_ID) || s_set.contains(&*RIGHT_TRIGGER_VALUE_ID)) + && (d_set.contains(&*RIGHT_TRIGGER_CLICK_ID) || d_set.contains(&*RIGHT_TRIGGER_VALUE_ID)) + { + bindings.extend(map_button_pair_automatic( + ctv( + s_set, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_TRIGGER_VALUE_ID, + ), + ctv( + d_set, + *RIGHT_TRIGGER_CLICK_ID, + *RIGHT_TRIGGER_TOUCH_ID, + *RIGHT_TRIGGER_VALUE_ID, + ), + config, + )); + } + + // Thumbsticks + if s_set.contains(&*LEFT_THUMBSTICK_X_ID) { + let x = value(*LEFT_THUMBSTICK_X_ID); + let y = value(*LEFT_THUMBSTICK_Y_ID); + if d_set.contains(&*LEFT_THUMBSTICK_X_ID) { + bindings.extend(map_button_pair_automatic(x, x, config)); + bindings.extend(map_button_pair_automatic(y, y, config)); + } else if d_set.contains(&*LEFT_TRACKPAD_X_ID) { + bindings.extend(map_button_pair_automatic( + x, + value(*LEFT_TRACKPAD_X_ID), + config, + )); + bindings.extend(map_button_pair_automatic( + y, + value(*LEFT_TRACKPAD_Y_ID), + config, + )); + } + } + if s_set.contains(&*LEFT_THUMBSTICK_CLICK_ID) { + let source = ct(s_set, *LEFT_THUMBSTICK_CLICK_ID, *LEFT_THUMBSTICK_TOUCH_ID); + if d_set.contains(&*LEFT_THUMBSTICK_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_THUMBSTICK_CLICK_ID, *LEFT_THUMBSTICK_TOUCH_ID), + config, + )); + } else if d_set.contains(&*LEFT_TRACKPAD_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *LEFT_TRACKPAD_CLICK_ID, *LEFT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_THUMBSTICK_X_ID) { + let x = value(*RIGHT_THUMBSTICK_X_ID); + let y = value(*RIGHT_THUMBSTICK_Y_ID); + if d_set.contains(&*RIGHT_THUMBSTICK_X_ID) { + bindings.extend(map_button_pair_automatic(x, x, config)); + bindings.extend(map_button_pair_automatic(y, y, config)); + } else if d_set.contains(&*RIGHT_TRACKPAD_X_ID) { + bindings.extend(map_button_pair_automatic( + x, + value(*RIGHT_TRACKPAD_X_ID), + config, + )); + bindings.extend(map_button_pair_automatic( + y, + value(*RIGHT_TRACKPAD_Y_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_THUMBSTICK_CLICK_ID) { + let source = ct( + s_set, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + ); + if d_set.contains(&*RIGHT_THUMBSTICK_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct( + d_set, + *RIGHT_THUMBSTICK_CLICK_ID, + *RIGHT_THUMBSTICK_TOUCH_ID, + ), + config, + )); + } else if d_set.contains(&*RIGHT_TRACKPAD_CLICK_ID) { + bindings.extend(map_button_pair_automatic( + source, + ct(d_set, *RIGHT_TRACKPAD_CLICK_ID, *RIGHT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + + // Thumbrests + if s_set.contains(&*LEFT_THUMBREST_TOUCH_ID) { + let source = value(*LEFT_THUMBREST_TOUCH_ID); + if d_set.contains(&*LEFT_THUMBREST_TOUCH_ID) { + bindings.extend(map_button_pair_automatic(source, source, config)); + } else if d_set.contains(&*LEFT_TRACKPAD_TOUCH_ID) { + bindings.extend(map_button_pair_automatic( + source, + value(*LEFT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + if s_set.contains(&*RIGHT_THUMBREST_TOUCH_ID) { + let source = value(*RIGHT_THUMBREST_TOUCH_ID); + if d_set.contains(&*RIGHT_THUMBREST_TOUCH_ID) { + bindings.extend(map_button_pair_automatic(source, source, config)); + } else if d_set.contains(&*RIGHT_TRACKPAD_TOUCH_ID) { + bindings.extend(map_button_pair_automatic( + source, + value(*RIGHT_TRACKPAD_TOUCH_ID), + config, + )); + } + } + + bindings +} + +pub extern "C" fn register_buttons(device_id: u64) { + for id in &*REGISTERED_BUTTON_SET { + if let Some(info) = BUTTON_INFO.get(id) { + if info.device_id == device_id { + unsafe { crate::RegisterButton(*id) }; + } + } else { + error!("Cannot register unrecognized button ID {id}"); + } + } +} + +pub struct ButtonMappingManager { + mappings: HashMap>, + binary_source_states: HashMap, + hysteresis_states: HashMap>, +} + +impl ButtonMappingManager { + pub fn new_automatic(source: &HashSet, config: &AutomaticButtonMappingConfig) -> Self { + Self { + mappings: automatic_bindings(source, ®ISTERED_BUTTON_SET, config), + binary_source_states: HashMap::new(), + hysteresis_states: HashMap::new(), + } + } + + // pub fn new_manual(mappings: HashMap>) -> Self { + // Self { + // mappings, + // binary_source_states: HashMap::new(), + // hysteresis_states: HashMap::new(), + // } + // } + + // Apply any button changes that are mapped to this specific button + pub fn report_button(&mut self, source_id: u64, source_value: ButtonValue) { + if let ButtonValue::Binary(value) = source_value { + let val_ref = self.binary_source_states.entry(source_id).or_default(); + + if value != *val_ref { + *val_ref = value; + } else { + return; + } + } + + if let Some(mappings) = self.mappings.get(&source_id) { + for mapping in mappings { + let destination_value = match (&mapping.mapping_type, source_value) { + (MappingType::Passthrough, value) => value, + (MappingType::HysteresisThreshold(threshold), ButtonValue::Scalar(value)) => { + let state = self + .hysteresis_states + .entry(source_id) + .or_default() + .entry(mapping.destination) + .or_default(); + + if *state && value < threshold.value - threshold.deviation { + *state = false; + } else if !*state && value > threshold.value + threshold.deviation { + *state = true; + } else { + // No change needed + return; + } + + ButtonValue::Binary(*state) + } + (MappingType::BinaryToScalar(levels), ButtonValue::Binary(value)) => { + if value { + ButtonValue::Scalar(levels.on) + } else { + ButtonValue::Scalar(levels.off) + } + } + (MappingType::Remap(range), ButtonValue::Scalar(value)) => { + let value = (value - range.start) / (range.end - range.start); + ButtonValue::Scalar(value.clamp(0.0, 1.0)) + } + _ => { + error!("Failed to map button!"); + return; + } + }; + + for source_id in &mapping.binary_conditions { + if !self + .binary_source_states + .get(source_id) + .copied() + .unwrap_or(false) + { + return; + } + } + + let destination_value = match destination_value { + ButtonValue::Binary(value) => FfiButtonValue { + type_: crate::FfiButtonType_BUTTON_TYPE_BINARY, + __bindgen_anon_1: crate::FfiButtonValue__bindgen_ty_1 { + binary: value.into(), + }, + }, + + ButtonValue::Scalar(value) => FfiButtonValue { + type_: crate::FfiButtonType_BUTTON_TYPE_SCALAR, + __bindgen_anon_1: crate::FfiButtonValue__bindgen_ty_1 { scalar: value }, + }, + }; + unsafe { crate::SetButton(mapping.destination, destination_value) }; + } + } else { + let button_name = BUTTON_INFO + .get(&source_id) + .map(|info| info.path) + .unwrap_or("Unknown"); + info!("Received button not mapped: {button_name}"); + } + } +} diff --git a/alvr/server/src/lib.rs b/alvr/server/src/lib.rs index 08acd6de..6a86516d 100644 --- a/alvr/server/src/lib.rs +++ b/alvr/server/src/lib.rs @@ -1,8 +1,8 @@ mod bitrate; -mod buttons; mod connection; mod face_tracking; mod haptics; +mod input_mapping; mod logging_backend; mod openvr_props; mod sockets; @@ -442,6 +442,7 @@ pub unsafe extern "C" fn HmdDriverFactory( ReportComposed = Some(report_composed); GetSerialNumber = Some(openvr_props::get_serial_number); SetOpenvrProps = Some(openvr_props::set_device_openvr_props); + RegisterButtons = Some(input_mapping::register_buttons); GetDynamicEncoderParams = Some(get_dynamic_encoder_params); WaitForVSync = Some(wait_for_vsync); diff --git a/alvr/server/src/openvr_props.rs b/alvr/server/src/openvr_props.rs index 11c89adc..c1292f45 100644 --- a/alvr/server/src/openvr_props.rs +++ b/alvr/server/src/openvr_props.rs @@ -70,7 +70,6 @@ fn serial_number(device_id: u64) -> String { } else if device_id == *LEFT_HAND_ID || device_id == *RIGHT_HAND_ID { if let Switch::Enabled(controllers) = &settings.headset.controllers { let serial_number = match &controllers.emulation_mode { - ControllersEmulationMode::RiftSTouch => "1WMGH000XX0000_Controller", ControllersEmulationMode::ValveIndex => "ALVR Remote Controller", ControllersEmulationMode::ViveWand => "ALVR Remote Controller", ControllersEmulationMode::Quest2Touch => "1WMHH000X00000_Controller", @@ -231,22 +230,22 @@ pub extern "C" fn set_device_openvr_props(device_id: u64) { }; match config.emulation_mode { - ControllersEmulationMode::RiftSTouch => { + ControllersEmulationMode::Quest2Touch => { set_string(TrackingSystemName, "oculus"); set_string(ManufacturerName, "Oculus"); if device_id == *LEFT_HAND_ID { - set_string(ModelNumber, "Oculus Rift S (Left Controller)"); - set_string(RenderModelName, "oculus_rifts_controller_left"); + set_string(ModelNumber, "Miramar (Left Controller)"); + set_string(RenderModelName, "oculus_quest2_controller_left"); set_string( RegisteredDeviceType, - "oculus/1WMGH000XX0000_Controller_Left", + "oculus/1WMHH000X00000_Controller_Left", ); } else if device_id == *RIGHT_HAND_ID { - set_string(ModelNumber, "Oculus Rift S (Right Controller)"); - set_string(RenderModelName, "oculus_rifts_controller_right"); + set_string(ModelNumber, "Miramar (Right Controller)"); + set_string(RenderModelName, "oculus_quest2_controller_right"); set_string( RegisteredDeviceType, - "oculus/1WMGH000XX0000_Controller_Right", + "oculus/1WMHH000X00000_Controller_Right", ); } set_string(ControllerType, "oculus_touch"); @@ -348,79 +347,6 @@ pub extern "C" fn set_device_openvr_props(device_id: u64) { set_string(ControllerType, "vive_controller"); set_string(InputProfilePath, "{oculus}/input/touch_profile.json"); } - ControllersEmulationMode::Quest2Touch => { - set_string(TrackingSystemName, "oculus"); - set_string(ManufacturerName, "Oculus"); - if device_id == *LEFT_HAND_ID { - set_string(ModelNumber, "Miramar (Left Controller)"); - set_string(RenderModelName, "oculus_quest2_controller_left"); - set_string( - RegisteredDeviceType, - "oculus/1WMHH000X00000_Controller_Left", - ); - } else if device_id == *RIGHT_HAND_ID { - set_string(ModelNumber, "Miramar (Right Controller)"); - set_string(RenderModelName, "oculus_quest2_controller_right"); - set_string( - RegisteredDeviceType, - "oculus/1WMHH000X00000_Controller_Right", - ); - } - set_string(ControllerType, "oculus_touch"); - set_string(InputProfilePath, "{oculus}/input/touch_profile.json"); - - if device_id == *LEFT_HAND_ID { - set_string( - NamedIconPathDeviceOff, - "{oculus}/icons/rifts_left_controller_off.png", - ); - set_string( - NamedIconPathDeviceSearching, - "{oculus}/icons/rifts_left_controller_searching.gif", - ); - set_string( - NamedIconPathDeviceSearchingAlert, - "{oculus}/icons/rifts_left_controller_searching_alert.gif", - ); - set_string( - NamedIconPathDeviceReady, - "{oculus}/icons/rifts_left_controller_ready.png", - ); - set_string( - NamedIconPathDeviceReadyAlert, - "{oculus}/icons/rifts_left_controller_ready_alert.png", - ); - set_string( - NamedIconPathDeviceAlertLow, - "{oculus}/icons/rifts_left_controller_ready_low.png", - ); - } else if device_id == *RIGHT_HAND_ID { - set_string( - NamedIconPathDeviceOff, - "{oculus}/icons/rifts_right_controller_off.png", - ); - set_string( - NamedIconPathDeviceSearching, - "{oculus}/icons/rifts_right_controller_searching.gif", - ); - set_string( - NamedIconPathDeviceSearchingAlert, - "{oculus}/icons/rifts_right_controller_searching_alert.gif", - ); - set_string( - NamedIconPathDeviceReady, - "{oculus}/icons/rifts_right_controller_ready.png", - ); - set_string( - NamedIconPathDeviceReadyAlert, - "{oculus}/icons/rifts_right_controller_ready_alert.png", - ); - set_string( - NamedIconPathDeviceAlertLow, - "{oculus}/icons/rifts_right_controller_ready_low.png", - ); - } - } ControllersEmulationMode::ViveTracker => { set_string(TrackingSystemName, "lighthouse"); set_string(RenderModelName, "{htc}vr_tracker_vive_1_0"); diff --git a/alvr/session/src/lib.rs b/alvr/session/src/lib.rs index 52d01a76..13481c6e 100644 --- a/alvr/session/src/lib.rs +++ b/alvr/session/src/lib.rs @@ -58,12 +58,8 @@ pub struct OpenvrConfig { pub entropy_coding: u32, pub force_sw_encoding: bool, pub sw_thread_count: u32, - pub controllers_mode_idx: i32, + pub controller_is_tracker: bool, pub controllers_enabled: bool, - pub override_trigger_threshold: bool, - pub trigger_threshold: f32, - pub override_grip_threshold: bool, - pub grip_threshold: f32, pub enable_foveated_rendering: bool, pub foveation_center_size_x: f32, pub foveation_center_size_y: f32, diff --git a/alvr/session/src/settings.rs b/alvr/session/src/settings.rs index d7232284..9c0c5cd4 100644 --- a/alvr/session/src/settings.rs +++ b/alvr/session/src/settings.rs @@ -600,16 +600,29 @@ pub struct FaceTrackingConfig { #[derive(SettingsSchema, Serialize, Deserialize, Clone)] pub enum ControllersEmulationMode { - #[schema(strings(display_name = "Rift S Touch"))] - RiftSTouch, + #[schema(strings(display_name = "Quest 2 Touch"))] + Quest2Touch, #[schema(strings(display_name = "Valve Index"))] ValveIndex, ViveWand, - #[schema(strings(display_name = "Quest 2 Touch"))] - Quest2Touch, ViveTracker, } +#[derive(SettingsSchema, Serialize, Deserialize, Clone, Copy)] +pub struct HysteresisThreshold { + #[schema(gui(slider(min = 0.0, max = 1.0, step = 0.01)))] + pub value: f32, + #[schema(gui(slider(min = 0.0, max = 1.0, step = 0.01)))] + pub deviation: f32, +} + +#[derive(SettingsSchema, Serialize, Deserialize, Clone)] +pub struct AutomaticButtonMappingConfig { + pub click_threshold: HysteresisThreshold, + pub touch_threshold: HysteresisThreshold, + pub force_threshold: f32, +} + #[derive(SettingsSchema, Serialize, Deserialize, Clone)] pub struct HapticsConfig { #[schema(flag = "real-time")] @@ -639,6 +652,8 @@ pub struct ControllersConfig { #[schema(flag = "steamvr-restart")] pub extra_openvr_props: Vec, + pub button_mapping_config: AutomaticButtonMappingConfig, + #[schema(strings( display_name = "Prediction", help = r"Higher values make the controllers track smoother. @@ -676,14 +691,6 @@ Currently this cannot be reliably estimated automatically. The correct value sho #[schema(gui(slider(min = -180.0, max = 180.0, step = 1.0)), suffix = "°")] pub left_hand_tracking_rotation_offset: [f32; 3], - #[schema(flag = "steamvr-restart")] - #[schema(gui(slider(min = 0.01, max = 1.0, step = 0.01)))] - pub trigger_threshold_override: Switch, - - #[schema(flag = "steamvr-restart")] - #[schema(gui(slider(min = 0.01, max = 1.0, step = 0.01)))] - pub grip_threshold_override: Switch, - #[schema(flag = "real-time")] pub haptics: Switch, } @@ -1228,6 +1235,20 @@ pub fn session_settings_default() -> SettingsDefault { }, tracked: true, extra_openvr_props: default_custom_openvr_props, + button_mapping_config: AutomaticButtonMappingConfigDefault { + gui_collapsed: true, + click_threshold: HysteresisThresholdDefault { + gui_collapsed: false, + value: 0.5, + deviation: 0.05, + }, + touch_threshold: HysteresisThresholdDefault { + gui_collapsed: false, + value: 0.1, + deviation: 0.05, + }, + force_threshold: 0.2, + }, steamvr_pipeline_frames: 3.0, linear_velocity_cutoff: 0.05, angular_velocity_cutoff: 10.0, @@ -1235,14 +1256,6 @@ pub fn session_settings_default() -> SettingsDefault { left_controller_rotation_offset: [-20.0, 0.0, 0.0], left_hand_tracking_position_offset: [0.04, -0.02, -0.13], left_hand_tracking_rotation_offset: [0.0, -45.0, -90.0], - trigger_threshold_override: SwitchDefault { - enabled: false, - content: 0.1, - }, - grip_threshold_override: SwitchDefault { - enabled: false, - content: 0.1, - }, haptics: SwitchDefault { enabled: true, content: HapticsConfigDefault {