diff --git a/alvr/server_openvr/cpp/alvr_server/Controller.cpp b/alvr/server_openvr/cpp/alvr_server/Controller.cpp index 23f4fee9a4..c0eff15f60 100644 --- a/alvr/server_openvr/cpp/alvr_server/Controller.cpp +++ b/alvr/server_openvr/cpp/alvr_server/Controller.cpp @@ -14,7 +14,7 @@ vr::ETrackedDeviceClass Controller::getControllerDeviceClass() { return vr::TrackedDeviceClass_Controller; } -Controller::Controller(uint64_t deviceID) +Controller::Controller(uint64_t deviceID, DEVICE_DESCRIPTION_TYPE deviceType) : TrackedDevice(deviceID) { m_pose = vr::DriverPose_t {}; m_pose.poseIsValid = false; @@ -24,6 +24,8 @@ Controller::Controller(uint64_t deviceID) m_pose.qDriverFromHeadRotation = HmdQuaternion_Init(1, 0, 0, 0); m_pose.qWorldFromDriverRotation = HmdQuaternion_Init(1, 0, 0, 0); m_pose.qRotation = HmdQuaternion_Init(1, 0, 0, 0); + + m_deviceType = deviceType; } // @@ -39,9 +41,9 @@ vr::EVRInitError Controller::Activate(vr::TrackedDeviceIndex_t unObjectId) { this->object_id = unObjectId; this->prop_container = vr_properties->TrackedDeviceToPropertyContainer(this->object_id); - SetOpenvrProps(this->device_id); + SetOpenVRProps(); - RegisterButtons(this->device_id); + RegisterButtonAll(); vr_driver_input->CreateHapticComponent(this->prop_container, "/output/haptic", &m_compHaptic); @@ -80,6 +82,7 @@ vr::EVRInitError Controller::Activate(vr::TrackedDeviceIndex_t unObjectId) { "/input/skeleton/left", "/skeleton/hand/left", "/pose/raw", + // m_fullSkeletal ? vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Full : vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, nullptr, 0U, @@ -91,6 +94,7 @@ vr::EVRInitError Controller::Activate(vr::TrackedDeviceIndex_t unObjectId) { "/input/skeleton/right", "/skeleton/hand/right", "/pose/raw", + // m_fullSkeletal ? vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Full : vr::EVRSkeletalTrackingLevel::VRSkeletalTracking_Partial, nullptr, 0U, @@ -120,6 +124,24 @@ vr::EVRInitError Controller::Activate(vr::TrackedDeviceIndex_t unObjectId) { return vr::VRInitError_None; } +void Controller::RegisterButtonAll() { + int buttonLen = 0; + auto buttons = GetRegisterButtons(m_deviceType, &buttonLen); + for (int i = 0; buttonLen > i; i++) { + RegisterButton(buttons[i]); + } + FreeRegisterButtonArray(buttons, buttonLen); +} + +void Controller::SetOpenVRProps() { + int propLen = 0; + auto props = GetOpenVrProps(m_deviceType, &propLen); + for (int i = 0; propLen > i; i++) { + set_prop(props[i]); + } + FreePropArray(props, propLen); +} + void Controller::Deactivate() { Debug("RemoteController::Deactivate\n"); this->object_id = vr::k_unTrackedDeviceIndexInvalid; @@ -149,7 +171,7 @@ vr::VRInputComponentHandle_t Controller::getHapticComponent() { return m_compHap void Controller::RegisterButton(uint64_t id) { ButtonInfo buttonInfo; - if (device_id == HAND_LEFT_ID) { + if (m_deviceType == DEVICE_DESCRIPTION_TYPE::LEFT_HAND) { buttonInfo = LEFT_CONTROLLER_BUTTON_MAPPING[id]; } else { buttonInfo = RIGHT_CONTROLLER_BUTTON_MAPPING[id]; diff --git a/alvr/server_openvr/cpp/alvr_server/Controller.h b/alvr/server_openvr/cpp/alvr_server/Controller.h index 836ea660c4..ebb542d2d4 100644 --- a/alvr/server_openvr/cpp/alvr_server/Controller.h +++ b/alvr/server_openvr/cpp/alvr_server/Controller.h @@ -7,7 +7,7 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { public: - Controller(uint64_t deviceID); + Controller(uint64_t deviceID, DEVICE_DESCRIPTION_TYPE deviceType); virtual ~Controller() {}; @@ -49,6 +49,9 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { vr::ETrackedDeviceClass getControllerDeviceClass(); private: + void SetOpenVRProps(); + void RegisterButtonAll(); + static const int SKELETON_BONE_COUNT = 31; static const int ANIMATION_FRAME_COUNT = 15; @@ -59,6 +62,8 @@ class Controller : public TrackedDevice, public vr::ITrackedDeviceServerDriver { vr::DriverPose_t m_pose; + DEVICE_DESCRIPTION_TYPE m_deviceType; + // These variables are used for controller hand animation // todo: move to rust float m_thumbTouchAnimationProgress = 0; diff --git a/alvr/server_openvr/cpp/alvr_server/HMD.cpp b/alvr/server_openvr/cpp/alvr_server/HMD.cpp index 12d1680da1..f6255b3e28 100644 --- a/alvr/server_openvr/cpp/alvr_server/HMD.cpp +++ b/alvr/server_openvr/cpp/alvr_server/HMD.cpp @@ -95,7 +95,7 @@ vr::EVRInitError Hmd::Activate(vr::TrackedDeviceIndex_t unObjectId) { this->object_id = unObjectId; this->prop_container = vr_properties->TrackedDeviceToPropertyContainer(this->object_id); - SetOpenvrProps(this->device_id); + SetOpenVRProps(); vr_properties->SetFloatProperty( this->prop_container, @@ -181,6 +181,15 @@ vr::EVRInitError Hmd::Activate(vr::TrackedDeviceIndex_t unObjectId) { return vr::VRInitError_None; } +void Hmd::SetOpenVRProps() { + int propLen = 0; + auto props = GetOpenVrProps(DEVICE_DESCRIPTION_TYPE::HMD, &propLen); + for (int i = 0; propLen > i; i++) { + set_prop(props[i]); + } + FreePropArray(props, propLen); +} + void Hmd::Deactivate() { this->object_id = vr::k_unTrackedDeviceIndexInvalid; this->prop_container = vr::k_ulInvalidPropertyContainer; diff --git a/alvr/server_openvr/cpp/alvr_server/HMD.h b/alvr/server_openvr/cpp/alvr_server/HMD.h index 9395386ad1..cd5dfdfbe6 100644 --- a/alvr/server_openvr/cpp/alvr_server/HMD.h +++ b/alvr/server_openvr/cpp/alvr_server/HMD.h @@ -62,6 +62,8 @@ class Hmd : public TrackedDevice, public vr::ITrackedDeviceServerDriver, vr::IVR std::shared_ptr m_poseHistory; private: + void SetOpenVRProps(); + FfiViewsConfig views_config; bool m_baseComponentsInitialized; diff --git a/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp b/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp index fb9e0b64f7..d3e317a511 100644 --- a/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp +++ b/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp @@ -100,8 +100,10 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { } if (Settings::Instance().m_enableControllers) { - this->left_controller = std::make_unique(HAND_LEFT_ID); - this->right_controller = std::make_unique(HAND_RIGHT_ID); + this->left_controller + = std::make_unique(HAND_LEFT_ID, DEVICE_DESCRIPTION_TYPE::LEFT_HAND); + this->right_controller + = std::make_unique(HAND_RIGHT_ID, DEVICE_DESCRIPTION_TYPE::RIGHT_HAND); this->tracked_devices.insert({ HAND_LEFT_ID, (TrackedDevice*)this->left_controller.get() }); @@ -310,10 +312,14 @@ void (*ReportPresent)(unsigned long long timestamp_ns, unsigned long long offset void (*ReportComposed)(unsigned long long timestamp_ns, unsigned long long offset_ns); 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)(); +FfiOpenvrProperty* (*GetOpenVrProps)(DEVICE_DESCRIPTION_TYPE deviceType, int* count); +void (*FreePropArray)(FfiOpenvrProperty* ptr, int count); + +uint64_t* (*GetRegisterButtons)(DEVICE_DESCRIPTION_TYPE deviceType, int* count); +void (*FreeRegisterButtonArray)(uint64_t* ptr, int count); + void CppInit() { HookCrashHandler(); diff --git a/alvr/server_openvr/cpp/alvr_server/bindings.h b/alvr/server_openvr/cpp/alvr_server/bindings.h index f70bd7d6d9..451bb41412 100644 --- a/alvr/server_openvr/cpp/alvr_server/bindings.h +++ b/alvr/server_openvr/cpp/alvr_server/bindings.h @@ -84,6 +84,13 @@ struct FfiDynamicEncoderParams { float framerate; }; +enum DEVICE_DESCRIPTION_TYPE { + HMD, + LEFT_HAND, + RIGHT_HAND, + OTHER, +}; + extern "C" const unsigned char* FRAME_RENDER_VS_CSO_PTR; extern "C" unsigned int FRAME_RENDER_VS_CSO_LEN; extern "C" const unsigned char* FRAME_RENDER_PS_CSO_PTR; @@ -128,10 +135,14 @@ extern "C" void (*ReportPresent)(unsigned long long timestamp_ns, unsigned long extern "C" void (*ReportComposed)(unsigned long long timestamp_ns, unsigned long long offset_ns); 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 (*FreePropArray)(FfiOpenvrProperty* ptr, int count); +extern "C" FfiOpenvrProperty* (*GetOpenVrProps)(DEVICE_DESCRIPTION_TYPE deviceType, int* count); + +extern "C" unsigned long long* (*GetRegisterButtons)(DEVICE_DESCRIPTION_TYPE deviceType, int* count); +extern "C" void (*FreeRegisterButtonArray)(unsigned long long* ptr, int count); + extern "C" void CppInit(); extern "C" void* CppOpenvrEntryPoint(const char* pInterfaceName, int* pReturnCode); extern "C" void InitializeStreaming(); diff --git a/alvr/server_openvr/src/lib.rs b/alvr/server_openvr/src/lib.rs index c8a693d191..71aea2c108 100644 --- a/alvr/server_openvr/src/lib.rs +++ b/alvr/server_openvr/src/lib.rs @@ -26,7 +26,7 @@ use alvr_server_core::{ServerCoreContext, ServerCoreEvent, REGISTERED_BUTTON_SET use alvr_session::CodecType; use std::{ ffi::{c_char, c_void, CString}, - ptr, + mem, ptr, thread, sync::{mpsc, Once}, thread, time::{Duration, Instant}, @@ -253,6 +253,53 @@ pub extern "C" fn register_buttons(device_id: u64) { } } +pub unsafe extern "C" fn get_register_buttons( + device_type: DEVICE_DESCRIPTION_TYPE, + button_id_len: *mut std::os::raw::c_int, +) -> *mut u64 { + let device_id = if device_type == DEVICE_DESCRIPTION_TYPE_LEFT_HAND { + *HAND_LEFT_ID + } else { + *HAND_RIGHT_ID + }; + let mut button_id_vec: Vec = REGISTERED_BUTTON_SET + .iter() + .filter_map(|id| { + if let Some(info) = BUTTON_INFO.get(id) { + if info.device_id == device_id { + Some(*id) + } else { + None + } + } else { + error!("Cannot register unrecognized button ID {id}"); + None + } + }) + .collect(); + + button_id_vec.shrink_to_fit(); + assert!(button_id_vec.len() == button_id_vec.capacity()); + + let len = button_id_vec.len(); + let ptr = button_id_vec.as_mut_ptr(); + + mem::forget(button_id_vec); + ptr::write(button_id_len, len as std::os::raw::c_int); + + ptr +} + +#[no_mangle] +pub unsafe extern "C" fn free_register_button_array( + button_id_array: *mut u64, + id_len: std::os::raw::c_int, +) { + let len = id_len as usize; + let vec = Vec::from_raw_parts(button_id_array, len, len); + mem::drop(vec); +} + extern "C" fn send_haptics(device_id: u64, duration_s: f32, frequency: f32, amplitude: f32) { if let Some(context) = &*SERVER_CORE_CONTEXT.read() { let haptics = Haptics { @@ -383,8 +430,10 @@ pub unsafe extern "C" fn HmdDriverFactory( LogPeriodically = Some(alvr_server_core::alvr_log_periodically); PathStringToHash = Some(alvr_server_core::alvr_path_to_id); GetSerialNumber = Some(props::get_serial_number); - SetOpenvrProps = Some(props::set_device_openvr_props); - RegisterButtons = Some(register_buttons); + GetOpenVrProps = Some(props::get_device_openvr_props); + FreePropArray = Some(props::free_prop_array); + GetRegisterButtons = Some(get_register_buttons); + FreeRegisterButtonArray = Some(free_register_button_array); DriverReadyIdle = Some(driver_ready_idle); HapticsSend = Some(send_haptics); SetVideoConfigNals = Some(set_video_config_nals); diff --git a/alvr/server_openvr/src/props.rs b/alvr/server_openvr/src/props.rs index 57fef8b9d5..01c30624f7 100644 --- a/alvr/server_openvr/src/props.rs +++ b/alvr/server_openvr/src/props.rs @@ -3,17 +3,18 @@ // todo: add more emulation modes use crate::{ - FfiOpenvrProperty, FfiOpenvrPropertyType_Bool, FfiOpenvrPropertyType_Double, - FfiOpenvrPropertyType_Float, FfiOpenvrPropertyType_Int32, FfiOpenvrPropertyType_String, - FfiOpenvrPropertyType_Uint64, FfiOpenvrPropertyType_Vector3, FfiOpenvrPropertyValue, + DEVICE_DESCRIPTION_TYPE, DEVICE_DESCRIPTION_TYPE_HMD, DEVICE_DESCRIPTION_TYPE_LEFT_HAND, DEVICE_DESCRIPTION_TYPE_RIGHT_HAND, FfiOpenvrProperty, + FfiOpenvrPropertyType_Bool, FfiOpenvrPropertyType_Double, FfiOpenvrPropertyType_Float, + FfiOpenvrPropertyType_Int32, FfiOpenvrPropertyType_String, FfiOpenvrPropertyType_Uint64, + FfiOpenvrPropertyType_Vector3, FfiOpenvrPropertyValue, }; use alvr_common::{info, settings_schema::Switch, HAND_LEFT_ID, HAND_RIGHT_ID, HEAD_ID}; use alvr_session::{ ControllersEmulationMode, HeadsetEmulationMode, OpenvrPropValue, OpenvrProperty, }; use std::{ - ffi::{c_char, CString}, - ptr, + ffi::{c_char, c_int, CString}, + mem, ptr, }; pub fn to_ffi_openvr_prop(prop: OpenvrProperty) -> FfiOpenvrProperty { @@ -108,473 +109,512 @@ pub extern "C" fn get_serial_number(device_id: u64, out_str: *mut c_char) -> u64 } #[no_mangle] -pub extern "C" fn set_device_openvr_props(device_id: u64) { +pub unsafe extern "C" fn get_device_openvr_props( + device_type: DEVICE_DESCRIPTION_TYPE, + prop_count: *mut c_int, +) -> *mut FfiOpenvrProperty { + let mut prop_vec; + prop_vec = match device_type { + DEVICE_DESCRIPTION_TYPE_HMD => get_hmd_openvr_prop(), + DEVICE_DESCRIPTION_TYPE_LEFT_HAND => get_hand_openvr_prop(true), + DEVICE_DESCRIPTION_TYPE_RIGHT_HAND => get_hand_openvr_prop(false), + _ => Vec::::new(), + }; + + prop_vec.shrink_to_fit(); + assert!(prop_vec.len() == prop_vec.capacity()); + + let len = prop_vec.len(); + let ptr = prop_vec.as_mut_ptr(); + + mem::forget(prop_vec); + ptr::write(prop_count, len as c_int); + + ptr +} + +#[no_mangle] +pub unsafe extern "C" fn free_prop_array(prop_array: *mut FfiOpenvrProperty, prop_count: c_int) { + let len = prop_count as usize; + let vec = Vec::from_raw_parts(prop_array, len, len); + mem::drop(vec); +} + + +fn get_hmd_openvr_prop() -> Vec { use OpenvrProperty::*; + let mut props = Vec::new(); let settings = alvr_server_core::settings(); - if device_id == *HEAD_ID { - fn set_prop(prop: OpenvrProperty) { - info!("Setting head OpenVR prop: {prop:?}"); - unsafe { - crate::SetOpenvrProperty(*HEAD_ID, to_ffi_openvr_prop(prop)); - } - } + let mut set_prop = |prop| { + info!("Setting head OpenVR prop: {prop:?}"); - match &settings.headset.emulation_mode { - HeadsetEmulationMode::RiftS => { - set_prop(TrackingSystemName("oculus".into())); - set_prop(ModelNumber("Oculus Rift S".into())); - set_prop(ManufacturerName("Oculus".into())); - set_prop(RenderModelName("generic_hmd".into())); - set_prop(RegisteredDeviceType("oculus/1WMGH000XX0000".into())); - set_prop(DriverVersion("1.42.0".into())); - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_headset_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_headset_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_headset_alert_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_headset_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_headset_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceStandby( - "{oculus}/icons/rifts_headset_standby.png".into(), - )); - } - HeadsetEmulationMode::Quest2 => { - set_prop(TrackingSystemName("oculus".into())); - set_prop(ModelNumber("Miramar".into())); - set_prop(ManufacturerName("Oculus".into())); - set_prop(RenderModelName("generic_hmd".into())); - set_prop(RegisteredDeviceType("oculus/1WMHH000X00000".into())); - set_prop(DriverVersion("1.55.0".into())); - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/quest_headset_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/quest_headset_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/quest_headset_alert_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/quest_headset_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/quest_headset_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceStandby( - "{oculus}/icons/quest_headset_standby.png".into(), - )); - } - HeadsetEmulationMode::Vive => { - set_prop(TrackingSystemName("Vive Tracker".into())); - set_prop(ModelNumber("ALVR driver server".into())); - set_prop(ManufacturerName("HTC".into())); - set_prop(RenderModelName("generic_hmd".into())); - set_prop(RegisteredDeviceType("vive".into())); - set_prop(DriverVersion("".into())); - set_prop(NamedIconPathDeviceOff( - "{htc}/icons/vive_headset_status_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{htc}/icons/vive_headset_status_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{htc}/icons/vive_headset_status_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{htc}/icons/vive_headset_status_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{htc}/icons/vive_headset_status_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceStandby( - "{htc}/icons/vive_headset_status_standby.png".into(), - )); - } - HeadsetEmulationMode::Custom { .. } => (), + props.push(to_ffi_openvr_prop(prop)); + }; + + match &settings.headset.emulation_mode { + HeadsetEmulationMode::RiftS => { + set_prop(TrackingSystemName("oculus".into())); + set_prop(ModelNumber("Oculus Rift S".into())); + set_prop(ManufacturerName("Oculus".into())); + set_prop(RenderModelName("generic_hmd".into())); + set_prop(RegisteredDeviceType("oculus/1WMGH000XX0000".into())); + set_prop(DriverVersion("1.42.0".into())); + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_headset_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_headset_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_headset_alert_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_headset_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_headset_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceStandby( + "{oculus}/icons/rifts_headset_standby.png".into(), + )); } + HeadsetEmulationMode::Quest2 => { + set_prop(TrackingSystemName("oculus".into())); + set_prop(ModelNumber("Miramar".into())); + set_prop(ManufacturerName("Oculus".into())); + set_prop(RenderModelName("generic_hmd".into())); + set_prop(RegisteredDeviceType("oculus/1WMHH000X00000".into())); + set_prop(DriverVersion("1.55.0".into())); + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/quest_headset_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/quest_headset_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/quest_headset_alert_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/quest_headset_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/quest_headset_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceStandby( + "{oculus}/icons/quest_headset_standby.png".into(), + )); + } + HeadsetEmulationMode::Vive => { + set_prop(TrackingSystemName("Vive Tracker".into())); + set_prop(ModelNumber("ALVR driver server".into())); + set_prop(ManufacturerName("HTC".into())); + set_prop(RenderModelName("generic_hmd".into())); + set_prop(RegisteredDeviceType("vive".into())); + set_prop(DriverVersion("".into())); + set_prop(NamedIconPathDeviceOff( + "{htc}/icons/vive_headset_status_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{htc}/icons/vive_headset_status_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{htc}/icons/vive_headset_status_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{htc}/icons/vive_headset_status_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{htc}/icons/vive_headset_status_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceStandby( + "{htc}/icons/vive_headset_status_standby.png".into(), + )); + } + HeadsetEmulationMode::Custom { .. } => (), + } - set_prop(UserIpdMeters(0.063)); - set_prop(UserHeadToEyeDepthMeters(0.0)); - set_prop(SecondsFromVsyncToPhotons(0.0)); + set_prop(UserIpdMeters(0.063)); + set_prop(UserHeadToEyeDepthMeters(0.0)); + set_prop(SecondsFromVsyncToPhotons(0.0)); - // return a constant that's not 0 (invalid) or 1 (reserved for Oculus) - set_prop(CurrentUniverseId(2)); + // return a constant that's not 0 (invalid) or 1 (reserved for Oculus) + set_prop(CurrentUniverseId(2)); - if cfg!(windows) { - // avoid "not fullscreen" warnings from vrmonitor - set_prop(IsOnDesktop(false)); + if cfg!(windows) { + // avoid "not fullscreen" warnings from vrmonitor + set_prop(IsOnDesktop(false)); - // We let SteamVR handle VSyncs. We just wait in PostPresent(). - set_prop(DriverDirectModeSendsVsyncEvents(false)); - } - set_prop(DeviceProvidesBatteryStatus(true)); - set_prop(ContainsProximitySensor(true)); + // We let SteamVR handle VSyncs. We just wait in PostPresent(). + set_prop(DriverDirectModeSendsVsyncEvents(false)); + } + set_prop(DeviceProvidesBatteryStatus(true)); + set_prop(ContainsProximitySensor(true)); - for prop in &settings.headset.extra_openvr_props { - set_prop(prop.clone()); - } - } else if device_id == *HAND_LEFT_ID || device_id == *HAND_RIGHT_ID { - if let Switch::Enabled(config) = &settings.headset.controllers { - let set_prop = |prop| { - info!( - "Setting {} controller OpenVR prop: {prop:?}", - if device_id == *HAND_LEFT_ID { - "left" - } else { - "right" - } - ); - unsafe { - crate::SetOpenvrProperty(device_id, to_ffi_openvr_prop(prop)); - } - }; + for prop in &settings.headset.extra_openvr_props { + set_prop(prop.clone()); + } - match config.emulation_mode { - ControllersEmulationMode::Quest2Touch => { - set_prop(TrackingSystemName("oculus".into())); - set_prop(ManufacturerName("Oculus".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber("Miramar (Left Controller)".into())); - set_prop(RenderModelName("oculus_quest2_controller_left".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMHH000X00000_Controller_Left".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber("Miramar (Right Controller)".into())); - set_prop(RenderModelName("oculus_quest2_controller_right".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMHH000X00000_Controller_Right".into(), - )); - } - set_prop(ControllerType("oculus_touch".into())); - set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); - - if device_id == *HAND_LEFT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_left_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_left_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_left_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_left_controller_ready_low.png".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_right_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_right_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_right_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_right_controller_ready_low.png".into(), - )); - } + props +} + +fn get_hand_openvr_prop(left_hand: bool) -> Vec { + use OpenvrProperty::*; + + let mut props: Vec = Vec::new(); + let settings = alvr_server_core::settings(); + + if let Switch::Enabled(config) = &settings.headset.controllers { + let mut set_prop = |prop| { + info!( + "Setting {} controller OpenVR prop: {prop:?}", + if left_hand { "left" } else { "right" } + ); + props.push(to_ffi_openvr_prop(prop)); + }; + + match config.emulation_mode { + ControllersEmulationMode::Quest2Touch => { + set_prop(TrackingSystemName("oculus".into())); + set_prop(ManufacturerName("Oculus".into())); + if left_hand { + set_prop(ModelNumber("Miramar (Left Controller)".into())); + set_prop(RenderModelName("oculus_quest2_controller_left".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMHH000X00000_Controller_Left".into(), + )); + } else { + set_prop(ModelNumber("Miramar (Right Controller)".into())); + set_prop(RenderModelName("oculus_quest2_controller_right".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMHH000X00000_Controller_Right".into(), + )); } - ControllersEmulationMode::Quest3Plus => { - set_prop(TrackingSystemName("oculus".into())); - set_prop(ManufacturerName("Oculus".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber("Meta Quest 3 (Left Controller)".into())); - set_prop(RenderModelName("oculus_quest_plus_controller_left".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMHH000X00000_Controller_Left".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber("Meta Quest 3 (Right Controller)".into())); - set_prop(RenderModelName("oculus_quest_plus_controller_right".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMHH000X00000_Controller_Right".into(), - )); - } - set_prop(ControllerType("oculus_touch".into())); - set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); - - if device_id == *HAND_LEFT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_left_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_left_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_left_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_left_controller_ready_low.png".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_right_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_right_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_right_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_right_controller_ready_low.png".into(), - )); - } + set_prop(ControllerType("oculus_touch".into())); + set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); + + if left_hand { + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_left_controller_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_left_controller_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_left_controller_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceAlertLow( + "{oculus}/icons/rifts_left_controller_ready_low.png".into(), + )); + } else { + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_right_controller_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_right_controller_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_right_controller_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceAlertLow( + "{oculus}/icons/rifts_right_controller_ready_low.png".into(), + )); } - ControllersEmulationMode::RiftSTouch => { - set_prop(TrackingSystemName("oculus".into())); - set_prop(ManufacturerName("Oculus".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber("Oculus Rift S (Left Controller)".into())); - set_prop(RenderModelName("oculus_rifts_controller_left".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMGH000XX0000_Controller_Left".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber("Oculus Rift S (Right Controller)".into())); - set_prop(RenderModelName("oculus_rifts_controller_right".into())); - set_prop(RegisteredDeviceType( - "oculus/1WMGH000XX0000_Controller_Right".into(), - )); - } - set_prop(ControllerType("oculus_touch".into())); - set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); - - if device_id == *HAND_LEFT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_left_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_left_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_left_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_left_controller_ready_low.png".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(NamedIconPathDeviceOff( - "{oculus}/icons/rifts_right_controller_off.png".into(), - )); - set_prop(NamedIconPathDeviceSearching( - "{oculus}/icons/rifts_right_controller_searching.gif".into(), - )); - set_prop(NamedIconPathDeviceSearchingAlert( - "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), - )); - set_prop(NamedIconPathDeviceReady( - "{oculus}/icons/rifts_right_controller_ready.png".into(), - )); - set_prop(NamedIconPathDeviceReadyAlert( - "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), - )); - set_prop(NamedIconPathDeviceAlertLow( - "{oculus}/icons/rifts_right_controller_ready_low.png".into(), - )); - } + } + ControllersEmulationMode::Quest3Plus => { + set_prop(TrackingSystemName("oculus".into())); + set_prop(ManufacturerName("Oculus".into())); + if left_hand { + set_prop(ModelNumber("Meta Quest 3 (Left Controller)".into())); + set_prop(RenderModelName("oculus_quest_plus_controller_left".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMHH000X00000_Controller_Left".into(), + )); + } else { + set_prop(ModelNumber("Meta Quest 3 (Right Controller)".into())); + set_prop(RenderModelName("oculus_quest_plus_controller_right".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMHH000X00000_Controller_Right".into(), + )); } - ControllersEmulationMode::ValveIndex => { - set_prop(TrackingSystemName("indexcontroller".into())); - set_prop(ManufacturerName("Valve".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber("Knuckles (Left Controller)".into())); - set_prop(RenderModelName( - "{indexcontroller}valve_controller_knu_1_0_left".into(), - )); - set_prop(RegisteredDeviceType( - "valve/index_controllerLHR-E217CD00_Left".into(), - )); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber("Knuckles (Right Controller)".into())); - set_prop(RenderModelName( - "{indexcontroller}valve_controller_knu_1_0_right".into(), - )); - set_prop(RegisteredDeviceType( - "valve/index_controllerLHR-E217CD00_Right".into(), - )); - } - set_prop(ControllerType("knuckles".into())); - set_prop(InputProfilePath( - "{indexcontroller}/input/index_controller_profile.json".into(), + set_prop(ControllerType("oculus_touch".into())); + set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); + + if left_hand { + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_left_controller_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_left_controller_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_left_controller_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceAlertLow( + "{oculus}/icons/rifts_left_controller_ready_low.png".into(), + )); + } else { + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_right_controller_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_right_controller_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_right_controller_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceAlertLow( + "{oculus}/icons/rifts_right_controller_ready_low.png".into(), )); } - ControllersEmulationMode::ViveWand => { - set_prop(TrackingSystemName("htc".into())); - set_prop(ManufacturerName("HTC".into())); - set_prop(RenderModelName("vr_controller_vive_1_5".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber( - "ALVR Remote Controller (Left Controller)".into(), - )); - set_prop(RegisteredDeviceType("vive_controller_Left".into())); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber( - "ALVR Remote Controller (Right Controller)".into(), - )); - set_prop(RegisteredDeviceType("oculus/vive_controller_Right".into())); - } - set_prop(ControllerType("vive_controller".into())); - set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); + } + ControllersEmulationMode::RiftSTouch => { + set_prop(TrackingSystemName("oculus".into())); + set_prop(ManufacturerName("Oculus".into())); + if left_hand { + set_prop(ModelNumber("Oculus Rift S (Left Controller)".into())); + set_prop(RenderModelName("oculus_rifts_controller_left".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMGH000XX0000_Controller_Left".into(), + )); + } else { + set_prop(ModelNumber("Oculus Rift S (Right Controller)".into())); + set_prop(RenderModelName("oculus_rifts_controller_right".into())); + set_prop(RegisteredDeviceType( + "oculus/1WMGH000XX0000_Controller_Right".into(), + )); } - ControllersEmulationMode::ViveTracker => { - set_prop(TrackingSystemName("lighthouse".into())); - set_prop(RenderModelName("{htc}vr_tracker_vive_1_0".into())); - if device_id == *HAND_LEFT_ID { - set_prop(ModelNumber("Vive Tracker Pro MV (Left Controller)".into())); - set_prop(RegisteredDeviceType("ALVR/tracker/left_foot".into())); - set_prop(ControllerType("vive_tracker_left_foot".into())); - } else if device_id == *HAND_RIGHT_ID { - set_prop(ModelNumber("Vive Tracker Pro MV (Right Controller)".into())); - set_prop(RegisteredDeviceType("ALVR/tracker/right_foot".into())); - set_prop(ControllerType("vive_tracker_right_foot".into())); - } - set_prop(InputProfilePath( - "{htc}/input/vive_tracker_profile.json".into(), - )); - - // All of these property values were dumped from real a vive tracker via - // https://github.com/SDraw/openvr_dumper and were copied from - // https://github.com/SDraw/driver_kinectV2 - set_prop(ResourceRoot("htc".into())); - set_prop(WillDriftInYaw(false)); - set_prop(TrackingFirmwareVersion( - "1541800000 RUNNER-WATCHMAN$runner-watchman@runner-watchman 2018-01-01 FPGA 512(2.56/0/0) BL 0 VRC 1541800000 Radio 1518800000".into(), - )); - set_prop(HardwareRevisionString( - "product 128 rev 2.5.6 lot 2000/0/0 0".into(), - )); - set_prop(ConnectedWirelessDongle("D0000BE000".into())); - set_prop(DeviceIsWireless(true)); - set_prop(DeviceIsCharging(false)); - set_prop(ControllerHandSelectionPriority(-1)); - // vr::HmdMatrix34_t l_transform = { - // {{-1.f, 0.f, 0.f, 0.f}, {0.f, 0.f, -1.f, 0.f}, {0.f, -1.f, 0.f, 0.f}}}; - // vr_properties->SetProperty(this->prop_container, - // vr::Prop_StatusDisplayTransform_Matrix34, - // &l_transform, - // sizeof(vr::HmdMatrix34_t), - // vr::k_unHmdMatrix34PropertyTag); - set_prop(FirmwareUpdateAvailable(false)); - set_prop(FirmwareManualUpdate(false)); - set_prop(FirmwareManualUpdateURL( - "https://developer.valvesoftware.com/wiki/SteamVR/HowTo_Update_Firmware" - .into(), - )); - set_prop(HardwareRevisionUint64(2214720000)); - set_prop(FirmwareVersion(1541800000)); - set_prop(FPGAVersion(512)); - set_prop(VRCVersion(1514800000)); - set_prop(RadioVersion(1518800000)); - set_prop(DongleVersion(8933539758)); - set_prop(DeviceCanPowerOff(true)); - // vr_properties->SetStringProperty(this->prop_container, - // vr::Prop_Firmware_ProgrammingTarget_String, - // GetSerialNumber().c_str()); - set_prop(FirmwareForceUpdateRequired(false)); - set_prop(FirmwareRemindUpdate(false)); - set_prop(HasDisplayComponent(false)); - set_prop(HasCameraComponent(false)); - set_prop(HasDriverDirectModeComponent(false)); - set_prop(HasVirtualDisplayComponent(false)); - - // icons + set_prop(ControllerType("oculus_touch".into())); + set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); + + if left_hand { set_prop(NamedIconPathDeviceOff( - "{htc}/icons/tracker_status_off.png".into(), + "{oculus}/icons/rifts_left_controller_off.png".into(), )); set_prop(NamedIconPathDeviceSearching( - "{htc}/icons/tracker_status_searching.gif".into(), + "{oculus}/icons/rifts_left_controller_searching.gif".into(), )); set_prop(NamedIconPathDeviceSearchingAlert( - "{htc}/icons/tracker_status_searching_alert.gif".into(), + "{oculus}/icons/rifts_left_controller_searching_alert.gif".into(), )); set_prop(NamedIconPathDeviceReady( - "{htc}/icons/tracker_status_ready.png".into(), + "{oculus}/icons/rifts_left_controller_ready.png".into(), )); set_prop(NamedIconPathDeviceReadyAlert( - "{htc}/icons/tracker_status_ready_alert.png".into(), + "{oculus}/icons/rifts_left_controller_ready_alert.png".into(), )); - set_prop(NamedIconPathDeviceNotReady( - "{htc}/icons/tracker_status_error.png".into(), + set_prop(NamedIconPathDeviceAlertLow( + "{oculus}/icons/rifts_left_controller_ready_low.png".into(), )); - set_prop(NamedIconPathDeviceStandby( - "{htc}/icons/tracker_status_standby.png".into(), + } else { + set_prop(NamedIconPathDeviceOff( + "{oculus}/icons/rifts_right_controller_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{oculus}/icons/rifts_right_controller_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{oculus}/icons/rifts_right_controller_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{oculus}/icons/rifts_right_controller_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{oculus}/icons/rifts_right_controller_ready_alert.png".into(), )); set_prop(NamedIconPathDeviceAlertLow( - "{htc}/icons/tracker_status_ready_low.png".into(), + "{oculus}/icons/rifts_right_controller_ready_low.png".into(), + )); + } + } + ControllersEmulationMode::ValveIndex => { + set_prop(TrackingSystemName("indexcontroller".into())); + set_prop(ManufacturerName("Valve".into())); + if left_hand { + set_prop(ModelNumber("Knuckles (Left Controller)".into())); + set_prop(RenderModelName( + "{indexcontroller}valve_controller_knu_1_0_left".into(), + )); + set_prop(RegisteredDeviceType( + "valve/index_controllerLHR-E217CD00_Left".into(), + )); + } else { + set_prop(ModelNumber("Knuckles (Right Controller)".into())); + set_prop(RenderModelName( + "{indexcontroller}valve_controller_knu_1_0_right".into(), )); + set_prop(RegisteredDeviceType( + "valve/index_controllerLHR-E217CD00_Right".into(), + )); + } + set_prop(ControllerType("knuckles".into())); + set_prop(InputProfilePath( + "{indexcontroller}/input/index_controller_profile.json".into(), + )); + } + ControllersEmulationMode::ViveWand => { + set_prop(TrackingSystemName("htc".into())); + set_prop(ManufacturerName("HTC".into())); + set_prop(RenderModelName("vr_controller_vive_1_5".into())); + if left_hand { + set_prop(ModelNumber( + "ALVR Remote Controller (Left Controller)".into(), + )); + set_prop(RegisteredDeviceType("vive_controller_Left".into())); + } else { + set_prop(ModelNumber( + "ALVR Remote Controller (Right Controller)".into(), + )); + set_prop(RegisteredDeviceType("oculus/vive_controller_Right".into())); + } + set_prop(ControllerType("vive_controller".into())); + set_prop(InputProfilePath("{oculus}/input/touch_profile.json".into())); + } + ControllersEmulationMode::ViveTracker => { + set_prop(TrackingSystemName("lighthouse".into())); + set_prop(RenderModelName("{htc}vr_tracker_vive_1_0".into())); + if left_hand { + set_prop(ModelNumber("Vive Tracker Pro MV (Left Controller)".into())); + set_prop(RegisteredDeviceType("ALVR/tracker/left_foot".into())); + set_prop(ControllerType("vive_tracker_left_foot".into())); + } else { + set_prop(ModelNumber("Vive Tracker Pro MV (Right Controller)".into())); + set_prop(RegisteredDeviceType("ALVR/tracker/right_foot".into())); + set_prop(ControllerType("vive_tracker_right_foot".into())); } - ControllersEmulationMode::Custom { .. } => todo!(), + set_prop(InputProfilePath( + "{htc}/input/vive_tracker_profile.json".into(), + )); + + // All of these property values were dumped from real a vive tracker via + // https://github.com/SDraw/openvr_dumper and were copied from + // https://github.com/SDraw/driver_kinectV2 + set_prop(ResourceRoot("htc".into())); + set_prop(WillDriftInYaw(false)); + set_prop(TrackingFirmwareVersion( + "1541800000 RUNNER-WATCHMAN$runner-watchman@runner-watchman 2018-01-01 FPGA 512(2.56/0/0) BL 0 VRC 1541800000 Radio 1518800000".into(), + )); + set_prop(HardwareRevisionString( + "product 128 rev 2.5.6 lot 2000/0/0 0".into(), + )); + set_prop(ConnectedWirelessDongle("D0000BE000".into())); + set_prop(DeviceIsWireless(true)); + set_prop(DeviceIsCharging(false)); + set_prop(ControllerHandSelectionPriority(-1)); + // vr::HmdMatrix34_t l_transform = { + // {{-1.f, 0.f, 0.f, 0.f}, {0.f, 0.f, -1.f, 0.f}, {0.f, -1.f, 0.f, 0.f}}}; + // vr_properties->SetProperty(this->prop_container, + // vr::Prop_StatusDisplayTransform_Matrix34, + // &l_transform, + // sizeof(vr::HmdMatrix34_t), + // vr::k_unHmdMatrix34PropertyTag); + set_prop(FirmwareUpdateAvailable(false)); + set_prop(FirmwareManualUpdate(false)); + set_prop(FirmwareManualUpdateURL( + "https://developer.valvesoftware.com/wiki/SteamVR/HowTo_Update_Firmware".into(), + )); + set_prop(HardwareRevisionUint64(2214720000)); + set_prop(FirmwareVersion(1541800000)); + set_prop(FPGAVersion(512)); + set_prop(VRCVersion(1514800000)); + set_prop(RadioVersion(1518800000)); + set_prop(DongleVersion(8933539758)); + set_prop(DeviceCanPowerOff(true)); + // vr_properties->SetStringProperty(this->prop_container, + // vr::Prop_Firmware_ProgrammingTarget_String, + // GetSerialNumber().c_str()); + set_prop(FirmwareForceUpdateRequired(false)); + set_prop(FirmwareRemindUpdate(false)); + set_prop(HasDisplayComponent(false)); + set_prop(HasCameraComponent(false)); + set_prop(HasDriverDirectModeComponent(false)); + set_prop(HasVirtualDisplayComponent(false)); + + // icons + set_prop(NamedIconPathDeviceOff( + "{htc}/icons/tracker_status_off.png".into(), + )); + set_prop(NamedIconPathDeviceSearching( + "{htc}/icons/tracker_status_searching.gif".into(), + )); + set_prop(NamedIconPathDeviceSearchingAlert( + "{htc}/icons/tracker_status_searching_alert.gif".into(), + )); + set_prop(NamedIconPathDeviceReady( + "{htc}/icons/tracker_status_ready.png".into(), + )); + set_prop(NamedIconPathDeviceReadyAlert( + "{htc}/icons/tracker_status_ready_alert.png".into(), + )); + set_prop(NamedIconPathDeviceNotReady( + "{htc}/icons/tracker_status_error.png".into(), + )); + set_prop(NamedIconPathDeviceStandby( + "{htc}/icons/tracker_status_standby.png".into(), + )); + set_prop(NamedIconPathDeviceAlertLow( + "{htc}/icons/tracker_status_ready_low.png".into(), + )); } + ControllersEmulationMode::Custom { .. } => todo!(), + } + let device_id = if left_hand { + *HAND_LEFT_ID + } else { + *HAND_RIGHT_ID + }; - set_prop(SerialNumber(serial_number(device_id))); - set_prop(AttachedDeviceId(serial_number(device_id))); + set_prop(SerialNumber(serial_number(device_id))); + set_prop(AttachedDeviceId(serial_number(device_id))); - set_prop(SupportedButtons(0xFFFFFFFFFFFFFFFF)); + set_prop(SupportedButtons(0xFFFFFFFFFFFFFFFF)); - // OpenXR does not support controller battery - set_prop(DeviceProvidesBatteryStatus(false)); + // OpenXR does not support controller battery + set_prop(DeviceProvidesBatteryStatus(false)); - // k_eControllerAxis_Joystick = 2 - set_prop(Axis0Type(2)); + // k_eControllerAxis_Joystick = 2 + set_prop(Axis0Type(2)); - if matches!(config.emulation_mode, ControllersEmulationMode::ViveTracker) { - // TrackedControllerRole_Invalid - set_prop(ControllerRoleHint(0)); - } else if device_id == *HAND_LEFT_ID { - // TrackedControllerRole_LeftHand - set_prop(ControllerRoleHint(1)); - } else if device_id == *HAND_RIGHT_ID { - // TrackedControllerRole_RightHand - set_prop(ControllerRoleHint(2)); - } + if matches!(config.emulation_mode, ControllersEmulationMode::ViveTracker) { + // TrackedControllerRole_Invalid + set_prop(ControllerRoleHint(0)); + } else if left_hand { + // TrackedControllerRole_LeftHand + set_prop(ControllerRoleHint(1)); + } else { + // TrackedControllerRole_RightHand + set_prop(ControllerRoleHint(2)); + } - for prop in &config.extra_openvr_props { - set_prop(prop.clone()); - } + for prop in &config.extra_openvr_props { + set_prop(prop.clone()); } } + + props }