feat: ✨ Add automatic button mapping system (internal) (#1817)
This commit is contained in:
parent
79eff14c25
commit
0141ec2074
|
@ -167,6 +167,17 @@ pub fn send_playspace(area: Option<Vec2>) {
|
|||
}
|
||||
}
|
||||
|
||||
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<ButtonEntry>) {
|
||||
if let Some(sender) = &mut *CONTROL_SENDER.lock() {
|
||||
sender.send(&ClientControlPacket::Buttons(entries)).ok();
|
||||
|
|
|
@ -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<bool>),
|
||||
Scalar(xr::Action<f32>),
|
||||
|
@ -21,281 +16,8 @@ pub struct HandSource {
|
|||
pub vibration_action: xr::Action<xr::Haptic>,
|
||||
}
|
||||
|
||||
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<u64, ButtonBindingInfo> {
|
||||
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<u64, ButtonAction>,
|
||||
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<ButtonEntry> {
|
||||
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<ButtonEntry> {
|
||||
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<xr::AnyGraphics>,
|
||||
button_actions: &HashMap<u64, ButtonAction>,
|
||||
) -> Vec<ButtonEntry> {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ struct HistoryView {
|
|||
}
|
||||
|
||||
struct StreamingInputContext {
|
||||
platform: Platform,
|
||||
xr_instance: xr::Instance,
|
||||
xr_session: xr::Session<xr::AnyGraphics>,
|
||||
hands_context: Arc<HandsInteractionContext>,
|
||||
|
@ -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();
|
||||
|
|
|
@ -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<u64> = Lazy::new(|| hash_string(HEAD_PATH));
|
||||
pub static LEFT_HAND_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_HAND_PATH));
|
||||
pub static RIGHT_HAND_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_HAND_PATH));
|
||||
|
||||
pub static QUEST_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(QUEST_CONTROLLER_PROFILE_PATH));
|
||||
pub static VIVE_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(VIVE_CONTROLLER_PROFILE_PATH));
|
||||
pub static INDEX_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(INDEX_CONTROLLER_PROFILE_PATH));
|
||||
pub static PICO_NEO3_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(PICO_NEO3_CONTROLLER_PROFILE_PATH));
|
||||
pub static PICO4_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(PICO4_CONTROLLER_PROFILE_PATH));
|
||||
pub static FOCUS3_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(FOCUS3_CONTROLLER_PROFILE_PATH));
|
||||
pub static YVR_CONTROLLER_PROFILE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(YVR_CONTROLLER_PROFILE_PATH));
|
||||
|
||||
pub static HEAD_ENTER_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(HEAD_ENTER_CLICK_PATH));
|
||||
pub static LEFT_SYSTEM_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SYSTEM_CLICK_PATH));
|
||||
pub static LEFT_SYSTEM_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SYSTEM_TOUCH_PATH));
|
||||
pub static LEFT_MENU_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_MENU_CLICK_PATH));
|
||||
pub static LEFT_BACK_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_BACK_CLICK_PATH));
|
||||
pub static LEFT_A_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_A_CLICK_PATH));
|
||||
pub static LEFT_A_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_A_TOUCH_PATH));
|
||||
pub static LEFT_B_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_B_CLICK_PATH));
|
||||
pub static LEFT_B_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_B_TOUCH_PATH));
|
||||
pub static LEFT_X_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_X_CLICK_PATH));
|
||||
pub static LEFT_X_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_X_TOUCH_PATH));
|
||||
pub static LEFT_Y_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_Y_CLICK_PATH));
|
||||
pub static LEFT_Y_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_Y_TOUCH_PATH));
|
||||
pub static LEFT_SQUEEZE_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_CLICK_PATH));
|
||||
pub static LEFT_SQUEEZE_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_VALUE_PATH));
|
||||
pub static LEFT_SQUEEZE_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_TOUCH_PATH));
|
||||
pub static LEFT_SQUEEZE_FORCE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_FORCE_PATH));
|
||||
pub static LEFT_TRIGGER_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_CLICK_PATH));
|
||||
pub static LEFT_TRIGGER_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_VALUE_PATH));
|
||||
pub static LEFT_TRIGGER_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_TOUCH_PATH));
|
||||
pub static LEFT_THUMBSTICK_X_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_THUMBSTICK_X_PATH));
|
||||
pub static LEFT_THUMBSTICK_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_THUMBSTICK_Y_PATH));
|
||||
pub static LEFT_THUMBSTICK_CLICK_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBSTICK_CLICK_PATH));
|
||||
pub static LEFT_THUMBSTICK_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBSTICK_TOUCH_PATH));
|
||||
pub static LEFT_TRACKPAD_X_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRACKPAD_X_PATH));
|
||||
pub static LEFT_TRACKPAD_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRACKPAD_Y_PATH));
|
||||
pub static LEFT_TRACKPAD_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRACKPAD_CLICK_PATH));
|
||||
pub static LEFT_TRACKPAD_FORCE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRACKPAD_FORCE_PATH));
|
||||
pub static LEFT_TRACKPAD_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRACKPAD_TOUCH_PATH));
|
||||
pub static LEFT_THUMBREST_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBREST_TOUCH_PATH));
|
||||
|
||||
pub static RIGHT_SYSTEM_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SYSTEM_CLICK_PATH));
|
||||
pub static RIGHT_SYSTEM_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SYSTEM_TOUCH_PATH));
|
||||
pub static RIGHT_MENU_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_MENU_CLICK_PATH));
|
||||
pub static RIGHT_BACK_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_BACK_CLICK_PATH));
|
||||
pub static RIGHT_A_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_A_CLICK_PATH));
|
||||
pub static RIGHT_A_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_A_TOUCH_PATH));
|
||||
pub static RIGHT_B_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_B_CLICK_PATH));
|
||||
pub static RIGHT_B_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_B_TOUCH_PATH));
|
||||
pub static RIGHT_SQUEEZE_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_CLICK_PATH));
|
||||
pub static RIGHT_SQUEEZE_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_VALUE_PATH));
|
||||
pub static RIGHT_SQUEEZE_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_TOUCH_PATH));
|
||||
pub static RIGHT_SQUEEZE_FORCE_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_FORCE_PATH));
|
||||
pub static RIGHT_TRIGGER_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_CLICK_PATH));
|
||||
pub static RIGHT_TRIGGER_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_VALUE_PATH));
|
||||
pub static RIGHT_TRIGGER_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_TOUCH_PATH));
|
||||
pub static RIGHT_THUMBSTICK_X_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_X_PATH));
|
||||
pub static RIGHT_THUMBSTICK_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_Y_PATH));
|
||||
pub static RIGHT_THUMBSTICK_CLICK_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBSTICK_CLICK_PATH));
|
||||
pub static RIGHT_THUMBSTICK_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBSTICK_TOUCH_PATH));
|
||||
pub static RIGHT_TRACKPAD_X_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRACKPAD_X_PATH));
|
||||
pub static RIGHT_TRACKPAD_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRACKPAD_Y_PATH));
|
||||
pub static RIGHT_TRACKPAD_CLICK_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_TRACKPAD_CLICK_PATH));
|
||||
pub static RIGHT_TRACKPAD_FORCE_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_TRACKPAD_FORCE_PATH));
|
||||
pub static RIGHT_TRACKPAD_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_TRACKPAD_TOUCH_PATH));
|
||||
pub static RIGHT_THUMBREST_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBREST_TOUCH_PATH));
|
||||
|
||||
pub static DEVICE_ID_TO_PATH: Lazy<HashMap<u64, &str>> = 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<HashMap<u64, ButtonInfo>> = 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<u64>,
|
||||
}
|
||||
|
||||
pub static CONTROLLER_PROFILE_INFO: Lazy<HashMap<u64, InteractionProfileInfo>> = 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()
|
||||
});
|
|
@ -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::*;
|
||||
|
||||
|
|
|
@ -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<u64> = Lazy::new(|| hash_string(HEAD_PATH));
|
||||
pub static LEFT_HAND_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_HAND_PATH));
|
||||
pub static RIGHT_HAND_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_HAND_PATH));
|
||||
|
||||
pub static DEVICE_ID_TO_PATH: Lazy<HashMap<u64, &str>> = 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<u64> = Lazy::new(|| hash_string(HEAD_ENTER_CLICK_PATH));
|
||||
pub static MENU_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(MENU_CLICK_PATH));
|
||||
pub static A_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(A_CLICK_PATH));
|
||||
pub static A_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(A_TOUCH_PATH));
|
||||
pub static B_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(B_CLICK_PATH));
|
||||
pub static B_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(B_TOUCH_PATH));
|
||||
pub static X_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(X_CLICK_PATH));
|
||||
pub static X_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(X_TOUCH_PATH));
|
||||
pub static Y_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(Y_CLICK_PATH));
|
||||
pub static Y_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(Y_TOUCH_PATH));
|
||||
pub static LEFT_SQUEEZE_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_CLICK_PATH));
|
||||
pub static LEFT_SQUEEZE_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_SQUEEZE_VALUE_PATH));
|
||||
pub static LEFT_TRIGGER_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_CLICK_PATH));
|
||||
pub static LEFT_TRIGGER_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_VALUE_PATH));
|
||||
pub static LEFT_TRIGGER_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_TRIGGER_TOUCH_PATH));
|
||||
pub static LEFT_THUMBSTICK_X_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_THUMBSTICK_X_PATH));
|
||||
pub static LEFT_THUMBSTICK_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(LEFT_THUMBSTICK_Y_PATH));
|
||||
pub static LEFT_THUMBSTICK_CLICK_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBSTICK_CLICK_PATH));
|
||||
pub static LEFT_THUMBSTICK_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBSTICK_TOUCH_PATH));
|
||||
pub static LEFT_THUMBREST_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(LEFT_THUMBREST_TOUCH_PATH));
|
||||
pub static RIGHT_SQUEEZE_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_CLICK_PATH));
|
||||
pub static RIGHT_SQUEEZE_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_SQUEEZE_VALUE_PATH));
|
||||
pub static RIGHT_TRIGGER_CLICK_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_CLICK_PATH));
|
||||
pub static RIGHT_TRIGGER_VALUE_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_VALUE_PATH));
|
||||
pub static RIGHT_TRIGGER_TOUCH_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_TRIGGER_TOUCH_PATH));
|
||||
pub static RIGHT_THUMBSTICK_X_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_X_PATH));
|
||||
pub static RIGHT_THUMBSTICK_Y_ID: Lazy<u64> = Lazy::new(|| hash_string(RIGHT_THUMBSTICK_Y_PATH));
|
||||
pub static RIGHT_THUMBSTICK_CLICK_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBSTICK_CLICK_PATH));
|
||||
pub static RIGHT_THUMBSTICK_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBSTICK_TOUCH_PATH));
|
||||
pub static RIGHT_THUMBREST_TOUCH_ID: Lazy<u64> =
|
||||
Lazy::new(|| hash_string(RIGHT_THUMBREST_TOUCH_PATH));
|
|
@ -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)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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<uint64_t, vr::VRInputComponentHandle_t> 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;
|
||||
};
|
||||
|
|
|
@ -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<uint64_t, ButtonInfo> LEFT_CONTROLLER_BUTTON_MAPPING;
|
||||
std::map<uint64_t, ButtonInfo> 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<uint64_t> LEFT_CONTROLLER_BUTTON_IDS;
|
||||
std::vector<uint64_t> 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");
|
||||
}
|
|
@ -1,43 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
// #include <vector>
|
||||
#include <map>
|
||||
|
||||
#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<uint64_t, ButtonInfo> LEFT_CONTROLLER_BUTTON_MAPPING;
|
||||
extern std::map<uint64_t, ButtonInfo> 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<uint64_t> LEFT_CONTROLLER_BUTTON_IDS;
|
||||
extern std::vector<uint64_t> RIGHT_CONTROLLER_BUTTON_IDS;
|
||||
|
||||
void init_paths();
|
||||
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;
|
|
@ -102,11 +102,7 @@ void Settings::Load() {
|
|||
m_enableLinuxAsyncReprojection = config.get("linux_async_reprojection").get<bool>();
|
||||
|
||||
m_enableControllers = config.get("controllers_enabled").get<bool>();
|
||||
m_controllerMode = (int32_t)config.get("controllers_mode_idx").get<int64_t>();
|
||||
m_overrideTriggerThreshold = config.get("override_trigger_threshold").get<bool>();
|
||||
m_triggerThreshold = config.get("trigger_threshold").get<double>();
|
||||
m_overrideGripThreshold = config.get("override_grip_threshold").get<bool>();
|
||||
m_gripThreshold = config.get("grip_threshold").get<double>();
|
||||
m_controllerIsTracker = config.get("controller_is_tracker").get<bool>();
|
||||
|
||||
m_constantBitrate = v.get("session_settings")
|
||||
.get("video")
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
use alvr_common::{once_cell::sync::Lazy, *};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub static BUTTON_PATH_FROM_ID: Lazy<HashMap<u64, String>> = 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()
|
||||
});
|
|
@ -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<IpAddr, String>) -> 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<IpAddr, String>) -> 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<IpAddr, String>) -> 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<IpAddr, String>) -> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<HashSet<u64>> = 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<f32>), // remaps 0..1 to custom range
|
||||
}
|
||||
|
||||
pub struct BindingTarget {
|
||||
destination: u64,
|
||||
mapping_type: MappingType,
|
||||
binary_conditions: Vec<u64>,
|
||||
}
|
||||
|
||||
// Inputs relative to the same physical button
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ButtonInputs {
|
||||
click: Option<u64>,
|
||||
touch: Option<u64>,
|
||||
value: Option<u64>,
|
||||
force: Option<u64>,
|
||||
}
|
||||
|
||||
fn click(click: u64) -> ButtonInputs {
|
||||
ButtonInputs {
|
||||
click: Some(click),
|
||||
touch: None,
|
||||
value: None,
|
||||
force: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn ct(set: &HashSet<u64>, 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<u64>, 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<u64>, 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<f32>) -> 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<Item = (u64, Vec<BindingTarget>)> {
|
||||
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<u64>,
|
||||
destination_set: &HashSet<u64>,
|
||||
config: &AutomaticButtonMappingConfig,
|
||||
) -> HashMap<u64, Vec<BindingTarget>> {
|
||||
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<u64, Vec<BindingTarget>>,
|
||||
binary_source_states: HashMap<u64, bool>,
|
||||
hysteresis_states: HashMap<u64, HashMap<u64, bool>>,
|
||||
}
|
||||
|
||||
impl ButtonMappingManager {
|
||||
pub fn new_automatic(source: &HashSet<u64>, 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<u64, Vec<BindingTarget>>) -> 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}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<OpenvrPropEntry>,
|
||||
|
||||
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<f32>,
|
||||
|
||||
#[schema(flag = "steamvr-restart")]
|
||||
#[schema(gui(slider(min = 0.01, max = 1.0, step = 0.01)))]
|
||||
pub grip_threshold_override: Switch<f32>,
|
||||
|
||||
#[schema(flag = "real-time")]
|
||||
pub haptics: Switch<HapticsConfig>,
|
||||
}
|
||||
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue