From 797c444911f1fa9da7826e39760bf8a0ae578599 Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Fri, 18 Oct 2024 21:19:47 +0200 Subject: [PATCH] refactor(server_openvr): :recycle: Use TrackedDevice for FakeViveTracker --- .../cpp/alvr_server/FakeViveTracker.cpp | 177 ++++++++++-------- .../cpp/alvr_server/FakeViveTracker.h | 42 +---- alvr/server_openvr/cpp/alvr_server/Paths.cpp | 72 ++++--- alvr/server_openvr/cpp/alvr_server/Paths.h | 45 +++-- .../cpp/alvr_server/alvr_server.cpp | 128 +++++-------- alvr/server_openvr/cpp/alvr_server/bindings.h | 11 +- alvr/server_openvr/src/lib.rs | 33 ++-- alvr/server_openvr/src/props.rs | 36 ++-- alvr/server_openvr/src/tracking.rs | 61 ++---- 9 files changed, 287 insertions(+), 318 deletions(-) diff --git a/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.cpp b/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.cpp index becff10c4e..33c6b7b524 100644 --- a/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.cpp +++ b/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.cpp @@ -1,27 +1,20 @@ #include "FakeViveTracker.h" -#include "Settings.h" #include "Logger.h" +#include "Paths.h" +#include "Settings.h" #include "Utils.h" #include "bindings.h" #include -FakeViveTracker::FakeViveTracker(std::string name) - : m_unObjectId(vr::k_unTrackedDeviceIndexInvalid) - , m_name("ALVR/tracker/" + name) - , m_serialNumber("ALVR Tracker (" + name + ")") { } +FakeViveTracker::FakeViveTracker(uint64_t deviceID) + : TrackedDevice(deviceID, vr::TrackedDeviceClass_GenericTracker) { } -vr::DriverPose_t FakeViveTracker::GetPose() { return m_pose; } - -vr::EVRInitError FakeViveTracker::Activate(vr::TrackedDeviceIndex_t unObjectId) { +bool FakeViveTracker::activate() { Debug("FakeViveTracker::Activate"); auto vr_properties = vr::VRProperties(); - m_unObjectId = unObjectId; - assert(m_unObjectId != vr::k_unTrackedDeviceIndexInvalid); - const auto propertyContainer = vr_properties->TrackedDeviceToPropertyContainer(m_unObjectId); - // Normally a vive tracker emulator would (logically) always set the tracking system to // "lighthouse" but in order to do space calibration with existing tools such as OpenVR Space // calibrator and be able to calibrate to/from ALVR HMD (and the proxy tracker) space to/from a @@ -29,41 +22,43 @@ vr::EVRInitError FakeViveTracker::Activate(vr::TrackedDeviceIndex_t unObjectId) // proxy tracker needs to be in a different tracking system to treat them differently and // prevent those tools doing the same space transform to the proxy tracker. vr_properties->SetStringProperty( - propertyContainer, vr::Prop_TrackingSystemName_String, "ALVRTrackerCustom" + this->prop_container, vr::Prop_TrackingSystemName_String, "ALVRTrackerCustom" ); //"lighthouse"); vr_properties->SetStringProperty( - propertyContainer, vr::Prop_ModelNumber_String, "Vive Tracker Pro MV" + this->prop_container, vr::Prop_ModelNumber_String, "Vive Tracker Pro MV" ); vr_properties->SetStringProperty( - propertyContainer, vr::Prop_SerialNumber_String, GetSerialNumber() + this->prop_container, vr::Prop_SerialNumber_String, this->get_serial_number().c_str() ); // Changed vr_properties->SetStringProperty( - propertyContainer, vr::Prop_RenderModelName_String, "{htc}vr_tracker_vive_1_0" + this->prop_container, vr::Prop_RenderModelName_String, "{htc}vr_tracker_vive_1_0" ); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_WillDriftInYaw_Bool, false); - vr_properties->SetStringProperty(propertyContainer, vr::Prop_ManufacturerName_String, "HTC"); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_WillDriftInYaw_Bool, false); + vr_properties->SetStringProperty(this->prop_container, vr::Prop_ManufacturerName_String, "HTC"); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_TrackingFirmwareVersion_String, "1541800000 RUNNER-WATCHMAN$runner-watchman@runner-watchman 2018-01-01 FPGA 512(2.56/0/0) " "BL 0 VRC 1541800000 Radio 1518800000" ); // Changed vr_properties->SetStringProperty( - propertyContainer, vr::Prop_HardwareRevision_String, "product 128 rev 2.5.6 lot 2000/0/0 0" + this->prop_container, + vr::Prop_HardwareRevision_String, + "product 128 rev 2.5.6 lot 2000/0/0 0" ); // Changed vr_properties->SetStringProperty( - propertyContainer, vr::Prop_ConnectedWirelessDongle_String, "D0000BE000" + this->prop_container, vr::Prop_ConnectedWirelessDongle_String, "D0000BE000" ); // Changed - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_DeviceIsWireless_Bool, true); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_DeviceIsCharging_Bool, false); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_DeviceIsWireless_Bool, true); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_DeviceIsCharging_Bool, false); vr_properties->SetFloatProperty( - propertyContainer, vr::Prop_DeviceBatteryPercentage_Float, 1.f + this->prop_container, vr::Prop_DeviceBatteryPercentage_Float, 1.f ); // Always charged 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( - propertyContainer, + this->prop_container, vr::Prop_StatusDisplayTransform_Matrix34, &l_transform, sizeof(vr::HmdMatrix34_t), @@ -71,138 +66,166 @@ vr::EVRInitError FakeViveTracker::Activate(vr::TrackedDeviceIndex_t unObjectId) ); vr_properties->SetBoolProperty( - propertyContainer, vr::Prop_Firmware_UpdateAvailable_Bool, false + this->prop_container, vr::Prop_Firmware_UpdateAvailable_Bool, false + ); + vr_properties->SetBoolProperty( + this->prop_container, vr::Prop_Firmware_ManualUpdate_Bool, false ); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_Firmware_ManualUpdate_Bool, false); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_Firmware_ManualUpdateURL_String, "https://developer.valvesoftware.com/wiki/SteamVR/HowTo_Update_Firmware" ); vr_properties->SetUint64Property( - propertyContainer, vr::Prop_HardwareRevision_Uint64, 2214720000 + this->prop_container, vr::Prop_HardwareRevision_Uint64, 2214720000 ); // Changed vr_properties->SetUint64Property( - propertyContainer, vr::Prop_FirmwareVersion_Uint64, 1541800000 + this->prop_container, vr::Prop_FirmwareVersion_Uint64, 1541800000 ); // Changed vr_properties->SetUint64Property( - propertyContainer, vr::Prop_FPGAVersion_Uint64, 512 + this->prop_container, vr::Prop_FPGAVersion_Uint64, 512 ); // Changed vr_properties->SetUint64Property( - propertyContainer, vr::Prop_VRCVersion_Uint64, 1514800000 + this->prop_container, vr::Prop_VRCVersion_Uint64, 1514800000 ); // Changed vr_properties->SetUint64Property( - propertyContainer, vr::Prop_RadioVersion_Uint64, 1518800000 + this->prop_container, vr::Prop_RadioVersion_Uint64, 1518800000 ); // Changed vr_properties->SetUint64Property( - propertyContainer, vr::Prop_DongleVersion_Uint64, 8933539758 + this->prop_container, vr::Prop_DongleVersion_Uint64, 8933539758 ); // Changed, based on vr::Prop_ConnectedWirelessDongle_String above vr_properties->SetBoolProperty( - propertyContainer, vr::Prop_DeviceProvidesBatteryStatus_Bool, true + this->prop_container, vr::Prop_DeviceProvidesBatteryStatus_Bool, true ); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_DeviceCanPowerOff_Bool, true); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_DeviceCanPowerOff_Bool, true); vr_properties->SetStringProperty( - propertyContainer, vr::Prop_Firmware_ProgrammingTarget_String, GetSerialNumber() + this->prop_container, + vr::Prop_Firmware_ProgrammingTarget_String, + this->get_serial_number().c_str() ); vr_properties->SetInt32Property( - propertyContainer, vr::Prop_DeviceClass_Int32, vr::TrackedDeviceClass_GenericTracker + this->prop_container, vr::Prop_DeviceClass_Int32, vr::TrackedDeviceClass_GenericTracker ); vr_properties->SetBoolProperty( - propertyContainer, vr::Prop_Firmware_ForceUpdateRequired_Bool, false + this->prop_container, vr::Prop_Firmware_ForceUpdateRequired_Bool, false ); - vr_properties->SetStringProperty(propertyContainer, vr::Prop_ResourceRoot_String, "htc"); + vr_properties->SetStringProperty(this->prop_container, vr::Prop_ResourceRoot_String, "htc"); + + const char* name; + if (this->device_id == BODY_CHEST_ID) { + name = "ALVR/tracker/chest"; + } else if (this->device_id == BODY_HIPS_ID) { + name = "ALVR/tracker/waist"; + } else if (this->device_id == BODY_LEFT_FOOT_ID) { + name = "ALVR/tracker/left_foot"; + } else if (this->device_id == BODY_RIGHT_FOOT_ID) { + name = "ALVR/tracker/right_foot"; + } else if (this->device_id == BODY_LEFT_KNEE_ID) { + name = "ALVR/tracker/left_knee"; + } else if (this->device_id == BODY_RIGHT_KNEE_ID) { + name = "ALVR/tracker/right_knee"; + } else { + name = "ALVR/tracker/unknown"; + } vr_properties->SetStringProperty( - propertyContainer, vr::Prop_RegisteredDeviceType_String, GetName() + this->prop_container, vr::Prop_RegisteredDeviceType_String, name ); vr_properties->SetStringProperty( - propertyContainer, vr::Prop_InputProfilePath_String, "{htc}/input/vive_tracker_profile.json" + this->prop_container, + vr::Prop_InputProfilePath_String, + "{htc}/input/vive_tracker_profile.json" + ); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_Identifiable_Bool, false); + vr_properties->SetBoolProperty( + this->prop_container, vr::Prop_Firmware_RemindUpdate_Bool, false ); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_Identifiable_Bool, false); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_Firmware_RemindUpdate_Bool, false); vr_properties->SetInt32Property( - propertyContainer, vr::Prop_ControllerRoleHint_Int32, vr::TrackedControllerRole_Invalid + this->prop_container, vr::Prop_ControllerRoleHint_Int32, vr::TrackedControllerRole_Invalid ); vr_properties->SetStringProperty( - propertyContainer, vr::Prop_ControllerType_String, "vive_tracker_waist" + this->prop_container, vr::Prop_ControllerType_String, "vive_tracker_waist" ); vr_properties->SetInt32Property( - propertyContainer, vr::Prop_ControllerHandSelectionPriority_Int32, -1 + this->prop_container, vr::Prop_ControllerHandSelectionPriority_Int32, -1 ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceOff_String, "{htc}/icons/tracker_status_off.png" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceSearching_String, "{htc}/icons/tracker_status_searching.gif" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceSearchingAlert_String, "{htc}/icons/tracker_status_searching_alert.gif" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceReady_String, "{htc}/icons/tracker_status_ready.png" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceReadyAlert_String, "{htc}/icons/tracker_status_ready_alert.png" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceNotReady_String, "{htc}/icons/tracker_status_error.png" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceStandby_String, "{htc}/icons/tracker_status_standby.png" ); vr_properties->SetStringProperty( - propertyContainer, + this->prop_container, vr::Prop_NamedIconPathDeviceAlertLow_String, "{htc}/icons/tracker_status_ready_low.png" ); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_HasDisplayComponent_Bool, false); - vr_properties->SetBoolProperty(propertyContainer, vr::Prop_HasCameraComponent_Bool, false); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_HasDisplayComponent_Bool, false); + vr_properties->SetBoolProperty(this->prop_container, vr::Prop_HasCameraComponent_Bool, false); vr_properties->SetBoolProperty( - propertyContainer, vr::Prop_HasDriverDirectModeComponent_Bool, false + this->prop_container, vr::Prop_HasDriverDirectModeComponent_Bool, false ); vr_properties->SetBoolProperty( - propertyContainer, vr::Prop_HasVirtualDisplayComponent_Bool, false + this->prop_container, vr::Prop_HasVirtualDisplayComponent_Bool, false ); - return vr::VRInitError_None; + return true; } -void FakeViveTracker::OnPoseUpdated(uint64_t targetTimestampNs, FfiBodyTracker tracker) { - if (this->m_unObjectId == vr::k_unTrackedDeviceIndexInvalid) { +void FakeViveTracker::OnPoseUpdated(uint64_t targetTimestampNs, const FfiDeviceMotion* motion) { + if (this->object_id == vr::k_unTrackedDeviceIndexInvalid) { return; } + + bool tracked = motion != nullptr; + auto pose = vr::DriverPose_t {}; - pose.poseIsValid = tracker.tracking; - pose.deviceIsConnected = tracker.tracking; - pose.result - = tracker.tracking ? vr::TrackingResult_Running_OK : vr::TrackingResult_Uninitialized; + pose.poseIsValid = tracked; + pose.deviceIsConnected = tracked; + pose.result = tracked ? vr::TrackingResult_Running_OK : vr::TrackingResult_Uninitialized; pose.qWorldFromDriverRotation = HmdQuaternion_Init(1, 0, 0, 0); pose.qDriverFromHeadRotation = HmdQuaternion_Init(1, 0, 0, 0); - pose.qRotation = HmdQuaternion_Init( - tracker.orientation.w, tracker.orientation.x, tracker.orientation.y, tracker.orientation.z - ); - - pose.vecPosition[0] = tracker.position[0]; - pose.vecPosition[1] = tracker.position[1]; - pose.vecPosition[2] = tracker.position[2]; + if (motion != nullptr) { + pose.qRotation = HmdQuaternion_Init( + motion->orientation.w, + motion->orientation.x, + motion->orientation.y, + motion->orientation.z + ); - m_pose = pose; + pose.vecPosition[0] = motion->position[0]; + pose.vecPosition[1] = motion->position[1]; + pose.vecPosition[2] = motion->position[2]; + } - vr::VRServerDriverHost()->TrackedDevicePoseUpdated( - this->m_unObjectId, pose, sizeof(vr::DriverPose_t) - ); + this->submit_pose(pose); } diff --git a/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h b/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h index 5f643c3513..a48b31d926 100644 --- a/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h +++ b/alvr/server_openvr/cpp/alvr_server/FakeViveTracker.h @@ -1,42 +1,16 @@ #pragma once +#include "TrackedDevice.h" #include "bindings.h" #include -class FakeViveTracker final : public vr::ITrackedDeviceServerDriver { - vr::TrackedDeviceIndex_t m_unObjectId; - std::string m_name; - std::string m_serialNumber; - vr::DriverPose_t m_pose = {}; - +class FakeViveTracker : public TrackedDevice { public: - FakeViveTracker(std::string name); - - FakeViveTracker(const FakeViveTracker&) = delete; - FakeViveTracker& operator=(const FakeViveTracker&) = delete; - - inline const char* GetSerialNumber() const { return m_serialNumber.c_str(); } - - inline const char* GetName() const { return m_name.c_str(); } - - virtual vr::EVRInitError Activate(vr::TrackedDeviceIndex_t unObjectId) override; - - virtual inline void Deactivate() override { m_unObjectId = vr::k_unTrackedDeviceIndexInvalid; } - - virtual inline void EnterStandby() override { } - virtual inline void* GetComponent(const char* /*pchComponentNameAndVersion*/) override { - // override this to add a component to a driver - return nullptr; - } - - virtual inline void DebugRequest( - const char* /*pchRequest*/, char* pchResponseBuffer, uint32_t unResponseBufferSize - ) override { - if (unResponseBufferSize >= 1) - pchResponseBuffer[0] = 0; - } - - virtual vr::DriverPose_t GetPose() override; + FakeViveTracker(uint64_t deviceID); + void OnPoseUpdated(uint64_t targetTimestampNs, const FfiDeviceMotion* motion); - void OnPoseUpdated(uint64_t targetTimestampNs, FfiBodyTracker tracker); +private: + // TrackedDevice + bool activate() final; + void* get_component(const char*) final { return nullptr; } }; diff --git a/alvr/server_openvr/cpp/alvr_server/Paths.cpp b/alvr/server_openvr/cpp/alvr_server/Paths.cpp index 643d96d4f3..6cd4b56930 100644 --- a/alvr/server_openvr/cpp/alvr_server/Paths.cpp +++ b/alvr/server_openvr/cpp/alvr_server/Paths.cpp @@ -6,10 +6,14 @@ uint64_t HAND_LEFT_ID; uint64_t HAND_RIGHT_ID; uint64_t HAND_TRACKER_LEFT_ID; uint64_t HAND_TRACKER_RIGHT_ID; - -std::map LEFT_CONTROLLER_BUTTON_MAPPING; -std::map RIGHT_CONTROLLER_BUTTON_MAPPING; -std::map> ALVR_TO_STEAMVR_PATH_IDS; +uint64_t BODY_CHEST_ID; +uint64_t BODY_HIPS_ID; +uint64_t BODY_LEFT_ELBOW_ID; +uint64_t BODY_RIGHT_ELBOW_ID; +uint64_t BODY_LEFT_KNEE_ID; +uint64_t BODY_LEFT_FOOT_ID; +uint64_t BODY_RIGHT_KNEE_ID; +uint64_t BODY_RIGHT_FOOT_ID; uint64_t LEFT_A_TOUCH_ID; uint64_t LEFT_B_TOUCH_ID; @@ -30,12 +34,53 @@ uint64_t RIGHT_TRIGGER_TOUCH_ID; uint64_t RIGHT_TRIGGER_VALUE_ID; uint64_t RIGHT_SQUEEZE_VALUE_ID; +std::set BODY_IDS; +std::map LEFT_CONTROLLER_BUTTON_MAPPING; +std::map RIGHT_CONTROLLER_BUTTON_MAPPING; +std::map> ALVR_TO_STEAMVR_PATH_IDS; + void init_paths() { HEAD_ID = PathStringToHash("/user/head"); HAND_LEFT_ID = PathStringToHash("/user/hand/left"); HAND_RIGHT_ID = PathStringToHash("/user/hand/right"); HAND_TRACKER_LEFT_ID = PathStringToHash("/user/hand_tracker/left"); HAND_TRACKER_RIGHT_ID = PathStringToHash("/user/hand_tracker/right"); + BODY_CHEST_ID = PathStringToHash("/user/body/chest"); + BODY_HIPS_ID = PathStringToHash("/user/body/waist"); + BODY_LEFT_ELBOW_ID = PathStringToHash("/user/body/left_elbow"); + BODY_RIGHT_ELBOW_ID = PathStringToHash("/user/body/right_elbow"); + BODY_LEFT_KNEE_ID = PathStringToHash("/user/body/left_knee"); + BODY_LEFT_FOOT_ID = PathStringToHash("/user/body/left_foot"); + BODY_RIGHT_KNEE_ID = PathStringToHash("/user/body/right_knee"); + BODY_RIGHT_FOOT_ID = PathStringToHash("/user/body/right_foot"); + + 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"); + LEFT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/left/input/trigger/touch"); + LEFT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/left/input/trigger/value"); + 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"); + RIGHT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/right/input/trigger/touch"); + RIGHT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/right/input/trigger/value"); + RIGHT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/right/input/squeeze/value"); + + BODY_IDS.insert(BODY_CHEST_ID); + BODY_IDS.insert(BODY_HIPS_ID); + BODY_IDS.insert(BODY_LEFT_ELBOW_ID); + BODY_IDS.insert(BODY_RIGHT_ELBOW_ID); + BODY_IDS.insert(BODY_LEFT_KNEE_ID); + BODY_IDS.insert(BODY_LEFT_FOOT_ID); + BODY_IDS.insert(BODY_RIGHT_KNEE_ID); + BODY_IDS.insert(BODY_RIGHT_FOOT_ID); LEFT_CONTROLLER_BUTTON_MAPPING.insert({ PathStringToHash("/user/hand/left/input/system/click"), { { "/input/system/click" }, ButtonType::Binary } }); @@ -202,23 +247,4 @@ void init_paths() { ALVR_TO_STEAMVR_PATH_IDS.insert({ info.first, ids }); } } - - 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"); - LEFT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/left/input/trigger/touch"); - LEFT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/left/input/trigger/value"); - 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"); - RIGHT_TRIGGER_TOUCH_ID = PathStringToHash("/user/hand/right/input/trigger/touch"); - RIGHT_TRIGGER_VALUE_ID = PathStringToHash("/user/hand/right/input/trigger/value"); - RIGHT_SQUEEZE_VALUE_ID = PathStringToHash("/user/hand/right/input/squeeze/value"); } diff --git a/alvr/server_openvr/cpp/alvr_server/Paths.h b/alvr/server_openvr/cpp/alvr_server/Paths.h index 2297f3c5b4..65a70c35bc 100644 --- a/alvr/server_openvr/cpp/alvr_server/Paths.h +++ b/alvr/server_openvr/cpp/alvr_server/Paths.h @@ -2,6 +2,7 @@ #include #include +#include #include #include "openvr_driver.h" @@ -11,24 +12,14 @@ extern uint64_t HAND_LEFT_ID; extern uint64_t HAND_RIGHT_ID; extern uint64_t HAND_TRACKER_LEFT_ID; extern uint64_t HAND_TRACKER_RIGHT_ID; - -enum class ButtonType { - Binary, - ScalarOneSided, - ScalarTwoSided, -}; - -struct ButtonInfo { - std::vector steamvr_paths; - ButtonType type; -}; - -// Map button ID to SteamVR button info -extern std::map LEFT_CONTROLLER_BUTTON_MAPPING; -extern std::map RIGHT_CONTROLLER_BUTTON_MAPPING; -extern std::map> ALVR_TO_STEAMVR_PATH_IDS; - -void init_paths(); +extern uint64_t BODY_CHEST_ID; +extern uint64_t BODY_HIPS_ID; +extern uint64_t BODY_LEFT_ELBOW_ID; +extern uint64_t BODY_RIGHT_ELBOW_ID; +extern uint64_t BODY_LEFT_KNEE_ID; +extern uint64_t BODY_LEFT_FOOT_ID; +extern uint64_t BODY_RIGHT_KNEE_ID; +extern uint64_t BODY_RIGHT_FOOT_ID; // These values are needed to determine the hand skeleton when holding a controller. // todo: move inferred hand skeleton to rust @@ -52,3 +43,21 @@ 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; + +enum class ButtonType { + Binary, + ScalarOneSided, + ScalarTwoSided, +}; + +struct ButtonInfo { + std::vector steamvr_paths; + ButtonType type; +}; + +extern std::set BODY_IDS; +extern std::map LEFT_CONTROLLER_BUTTON_MAPPING; +extern std::map RIGHT_CONTROLLER_BUTTON_MAPPING; +extern std::map> ALVR_TO_STEAMVR_PATH_IDS; + +void init_paths(); diff --git a/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp b/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp index eb73b64abc..86bdbf1453 100644 --- a/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp +++ b/alvr/server_openvr/cpp/alvr_server/alvr_server.cpp @@ -94,7 +94,7 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { InitDriverLog(vr::VRDriverLog()); this->hmd = std::make_unique(); - this->tracked_devices.insert({ HEAD_ID, (TrackedDevice*)this->hmd.get() }); + this->tracked_devices.insert({ HEAD_ID, this->hmd.get() }); this->hmd->register_device(); if (Settings::Instance().m_enableControllers) { @@ -106,10 +106,8 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { this->right_controller = std::make_unique(HAND_RIGHT_ID, controllerSkeletonLevel); - this->tracked_devices.insert({ HAND_LEFT_ID, - (TrackedDevice*)this->left_controller.get() }); - this->tracked_devices.insert({ HAND_RIGHT_ID, - (TrackedDevice*)this->right_controller.get() }); + this->tracked_devices.insert({ HAND_LEFT_ID, this->left_controller.get() }); + this->tracked_devices.insert({ HAND_RIGHT_ID, this->right_controller.get() }); this->left_controller->register_device(); this->right_controller->register_device(); @@ -122,10 +120,10 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { HAND_TRACKER_RIGHT_ID, vr::VRSkeletalTracking_Full ); - this->tracked_devices.insert({ HAND_TRACKER_LEFT_ID, - (TrackedDevice*)this->left_hand_tracker.get() }); + this->tracked_devices.insert({ HAND_TRACKER_LEFT_ID, this->left_hand_tracker.get() } + ); this->tracked_devices.insert({ HAND_TRACKER_RIGHT_ID, - (TrackedDevice*)this->right_hand_tracker.get() }); + this->right_hand_tracker.get() }); this->left_hand_tracker->register_device(); this->right_hand_tracker->register_device(); @@ -133,85 +131,45 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { } if (Settings::Instance().m_enableBodyTrackingFakeVive) { - auto waistTracker = std::make_unique("waist"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - waistTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - waistTracker.get() - )) { - Warn("Failed to register Vive tracker (waist)"); - } - generic_trackers.push_back(std::move(waistTracker)); - - auto chestTracker = std::make_unique("chest"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - chestTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - chestTracker.get() - )) { - Warn("Failed to register Vive tracker (chest)"); - } + auto chestTracker = std::make_unique(BODY_CHEST_ID); + tracked_devices.insert({ BODY_CHEST_ID, chestTracker.get() }); + chestTracker->register_device(); generic_trackers.push_back(std::move(chestTracker)); - auto leftElbowTracker = std::make_unique("left_elbow"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - leftElbowTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - leftElbowTracker.get() - )) { - Warn("Failed to register Vive tracker (left_elbow)"); - } + auto waistTracker = std::make_unique(BODY_HIPS_ID); + tracked_devices.insert({ BODY_HIPS_ID, waistTracker.get() }); + waistTracker->register_device(); + generic_trackers.push_back(std::move(waistTracker)); + + auto leftElbowTracker = std::make_unique(BODY_LEFT_ELBOW_ID); + tracked_devices.insert({ BODY_LEFT_ELBOW_ID, leftElbowTracker.get() }); + leftElbowTracker->register_device(); generic_trackers.push_back(std::move(leftElbowTracker)); - auto rightElbowTracker = std::make_unique("right_elbow"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - rightElbowTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - rightElbowTracker.get() - )) { - Warn("Failed to register Vive tracker (right_elbow)"); - } + auto rightElbowTracker = std::make_unique(BODY_RIGHT_ELBOW_ID); + tracked_devices.insert({ BODY_RIGHT_ELBOW_ID, rightElbowTracker.get() }); + rightElbowTracker->register_device(); generic_trackers.push_back(std::move(rightElbowTracker)); if (Settings::Instance().m_bodyTrackingHasLegs) { - auto leftKneeTracker = std::make_unique("left_knee"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - leftKneeTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - leftKneeTracker.get() - )) { - Warn("Failed to register Vive tracker (left_knee)"); - } + auto leftKneeTracker = std::make_unique(BODY_LEFT_KNEE_ID); + tracked_devices.insert({ BODY_LEFT_KNEE_ID, leftKneeTracker.get() }); + leftKneeTracker->register_device(); generic_trackers.push_back(std::move(leftKneeTracker)); - auto leftFootTracker = std::make_unique("left_foot"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - leftFootTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - leftFootTracker.get() - )) { - Warn("Failed to register Vive tracker (left_foot)"); - } + auto leftFootTracker = std::make_unique(BODY_LEFT_FOOT_ID); + tracked_devices.insert({ BODY_LEFT_FOOT_ID, leftFootTracker.get() }); + leftFootTracker->register_device(); generic_trackers.push_back(std::move(leftFootTracker)); - auto rightKneeTracker = std::make_unique("right_knee"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - rightKneeTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - rightKneeTracker.get() - )) { - Warn("Failed to register Vive tracker (right_knee)"); - } + auto rightKneeTracker = std::make_unique(BODY_RIGHT_KNEE_ID); + tracked_devices.insert({ BODY_RIGHT_KNEE_ID, rightKneeTracker.get() }); + rightKneeTracker->register_device(); generic_trackers.push_back(std::move(rightKneeTracker)); - auto rightFootTracker = std::make_unique("right_foot"); - if (!vr::VRServerDriverHost()->TrackedDeviceAdded( - rightFootTracker->GetSerialNumber(), - vr::TrackedDeviceClass_GenericTracker, - rightFootTracker.get() - )) { - Warn("Failed to register Vive tracker (right_foot)"); - } + auto rightFootTracker = std::make_unique(BODY_RIGHT_FOOT_ID); + tracked_devices.insert({ BODY_RIGHT_FOOT_ID, rightFootTracker.get() }); + rightFootTracker->register_device(); generic_trackers.push_back(std::move(rightFootTracker)); } } @@ -226,6 +184,7 @@ class DriverProvider : public vr::IServerTrackedDeviceProvider { this->left_controller.reset(); this->right_controller.reset(); this->hmd.reset(); + // this->generic_trackers.clear(); CleanupDriverLog(); @@ -380,8 +339,8 @@ void SetTracking( FfiDeviceMotion headMotion, FfiHandData leftHandData, FfiHandData rightHandData, - const FfiBodyTracker* bodyTrackers, - int bodyTrackersCount + const FfiDeviceMotion* bodyTrackerMotions, + int bodyTrackerMotionCount ) { if (g_driver_provider.hmd) { g_driver_provider.hmd->OnPoseUpdated(targetTimestampNs, headMotion); @@ -412,9 +371,20 @@ void SetTracking( } if (Settings::Instance().m_enableBodyTrackingFakeVive) { - for (int i = 0; i < bodyTrackersCount; i++) { - g_driver_provider.generic_trackers.at(bodyTrackers[i].trackerID) - ->OnPoseUpdated(targetTimestampNs, bodyTrackers[i]); + std::map motionsMap; + for (int i = 0; i < bodyTrackerMotionCount; i++) { + auto m = bodyTrackerMotions[i]; + motionsMap.insert({ m.deviceID, m }); + } + + for (auto id : BODY_IDS) { + auto* maybeTracker = (FakeViveTracker*)g_driver_provider.tracked_devices.at(id); + if (maybeTracker) { + auto res = motionsMap.find(id); + auto* maybeMotion = res != motionsMap.end() ? &res->second : nullptr; + + maybeTracker->OnPoseUpdated(targetTimestampNs, maybeMotion); + } } } } diff --git a/alvr/server_openvr/cpp/alvr_server/bindings.h b/alvr/server_openvr/cpp/alvr_server/bindings.h index 97bcd95fe5..0f507011ac 100644 --- a/alvr/server_openvr/cpp/alvr_server/bindings.h +++ b/alvr/server_openvr/cpp/alvr_server/bindings.h @@ -33,13 +33,6 @@ struct FfiHandData { bool isHandTracker; }; -struct FfiBodyTracker { - unsigned int trackerID; - FfiQuat orientation; - float position[3]; - unsigned int tracking; -}; - enum FfiOpenvrPropertyType { Bool, Float, @@ -151,8 +144,8 @@ extern "C" void SetTracking( FfiDeviceMotion headMotion, FfiHandData leftHandData, FfiHandData rightHandData, - const FfiBodyTracker* bodyTrackers, - int bodyTrackersCount + const FfiDeviceMotion* bodyTrackerMotions, + int bodyTrackerMotionCount ); extern "C" void VideoErrorReportReceive(); extern "C" void RequestDriverResync(); diff --git a/alvr/server_openvr/src/lib.rs b/alvr/server_openvr/src/lib.rs index 915402091e..6445d588cc 100644 --- a/alvr/server_openvr/src/lib.rs +++ b/alvr/server_openvr/src/lib.rs @@ -202,14 +202,19 @@ extern "C" fn driver_ready_idle(set_default_chap: bool) { && ffi_right_hand_skeleton.is_some(), }; - let body_motions = tracking::BODY_TRACKER_ID_MAP - .keys() - .filter_map(|id| { - Some((*id, context.get_device_motion(*id, sample_timestamp)?)) - }) - .collect::>(); - let ffi_body_trackers = - tracking::to_ffi_body_trackers(&body_motions, track_body); + let ffi_body_tracker_motions = if track_body { + tracking::BODY_TRACKER_IDS + .iter() + .filter_map(|id| { + Some(tracking::to_ffi_motion( + *id, + context.get_device_motion(*id, sample_timestamp)?, + )) + }) + .collect::>() + } else { + vec![] + }; // There are two pairs of controllers/hand tracking devices registered in // OpenVR, two lefts and two rights. If enabled with use_separate_hand_trackers, @@ -222,16 +227,8 @@ extern "C" fn driver_ready_idle(set_default_chap: bool) { ffi_head_motion, ffi_left_hand_data, ffi_right_hand_data, - if let Some(body_trackers) = &ffi_body_trackers { - body_trackers.as_ptr() - } else { - ptr::null() - }, - if let Some(body_trackers) = &ffi_body_trackers { - body_trackers.len() as _ - } else { - 0 - }, + ffi_body_tracker_motions.as_ptr(), + ffi_body_tracker_motions.len() as i32, ) }; } diff --git a/alvr/server_openvr/src/props.rs b/alvr/server_openvr/src/props.rs index 9e1c6324dd..04df89b1bc 100644 --- a/alvr/server_openvr/src/props.rs +++ b/alvr/server_openvr/src/props.rs @@ -8,8 +8,10 @@ use crate::{ FfiOpenvrPropertyType_Uint64, FfiOpenvrPropertyType_Vector3, FfiOpenvrPropertyValue, }; use alvr_common::{ - info, settings_schema::Switch, HAND_LEFT_ID, HAND_RIGHT_ID, HAND_TRACKER_LEFT_ID, - HAND_TRACKER_RIGHT_ID, HEAD_ID, + info, settings_schema::Switch, BODY_CHEST_ID, BODY_HIPS_ID, BODY_LEFT_ELBOW_ID, + BODY_LEFT_FOOT_ID, BODY_LEFT_KNEE_ID, BODY_RIGHT_ELBOW_ID, BODY_RIGHT_FOOT_ID, + BODY_RIGHT_KNEE_ID, HAND_LEFT_ID, HAND_RIGHT_ID, HAND_TRACKER_LEFT_ID, HAND_TRACKER_RIGHT_ID, + HEAD_ID, }; use alvr_session::{ ControllersEmulationMode, HeadsetEmulationMode, OpenvrPropValue, OpenvrProperty, @@ -90,16 +92,26 @@ fn serial_number(device_id: u64) -> String { } else { "Unknown".into() } - } else if device_id == *HAND_TRACKER_LEFT_ID || device_id == *HAND_TRACKER_RIGHT_ID { - if let Switch::Enabled(_) = &settings.headset.controllers { - if device_id == *HAND_TRACKER_LEFT_ID { - "ALVR_Left_Hand_Full_Skeletal".into() - } else { - "ALVR_Right_Hand_Full_Skeletal".into() - } - } else { - "Unknown".into() - } + } else if device_id == *HAND_TRACKER_LEFT_ID { + "ALVR_Left_Hand_Full_Skeletal".into() + } else if device_id == *HAND_TRACKER_RIGHT_ID { + "ALVR_Right_Hand_Full_Skeletal".into() + } else if device_id == *BODY_CHEST_ID { + "ALVR Tracker (chest)".into() + } else if device_id == *BODY_HIPS_ID { + "ALVR Tracker (waist)".into() + } else if device_id == *BODY_LEFT_ELBOW_ID { + "ALVR Tracker (left elbow)".into() + } else if device_id == *BODY_RIGHT_ELBOW_ID { + "ALVR Tracker (right elbow)".into() + } else if device_id == *BODY_LEFT_KNEE_ID { + "ALVR Tracker (left knee)".into() + } else if device_id == *BODY_RIGHT_KNEE_ID { + "ALVR Tracker (right knee)".into() + } else if device_id == *BODY_LEFT_FOOT_ID { + "ALVR Tracker (left foot)".into() + } else if device_id == *BODY_RIGHT_FOOT_ID { + "ALVR Tracker (right foot)".into() } else { "Unknown".into() } diff --git a/alvr/server_openvr/src/tracking.rs b/alvr/server_openvr/src/tracking.rs index 9691f72673..2d11022254 100644 --- a/alvr/server_openvr/src/tracking.rs +++ b/alvr/server_openvr/src/tracking.rs @@ -1,4 +1,4 @@ -use crate::{FfiBodyTracker, FfiDeviceMotion, FfiHandSkeleton, FfiQuat}; +use crate::{FfiDeviceMotion, FfiHandSkeleton, FfiQuat}; use alvr_common::{ glam::{EulerRot, Quat, Vec3}, once_cell::sync::Lazy, @@ -7,27 +7,23 @@ use alvr_common::{ BODY_LEFT_KNEE_ID, BODY_RIGHT_ELBOW_ID, BODY_RIGHT_FOOT_ID, BODY_RIGHT_KNEE_ID, HAND_LEFT_ID, }; use alvr_session::HeadsetConfig; -use std::{ - collections::HashMap, - f32::consts::{FRAC_PI_2, PI}, -}; +use std::f32::consts::{FRAC_PI_2, PI}; const DEG_TO_RAD: f32 = PI / 180.0; -// todo: remove the need for staging indices -pub static BODY_TRACKER_ID_MAP: Lazy> = Lazy::new(|| { - HashMap::from([ +pub static BODY_TRACKER_IDS: Lazy<[u64; 8]> = Lazy::new(|| { + [ // Upper body - (*BODY_CHEST_ID, 0), - (*BODY_HIPS_ID, 1), - (*BODY_LEFT_ELBOW_ID, 2), - (*BODY_RIGHT_ELBOW_ID, 3), + *BODY_CHEST_ID, + *BODY_HIPS_ID, + *BODY_LEFT_ELBOW_ID, + *BODY_RIGHT_ELBOW_ID, // Legs - (*BODY_LEFT_KNEE_ID, 4), - (*BODY_LEFT_FOOT_ID, 5), - (*BODY_RIGHT_KNEE_ID, 6), - (*BODY_RIGHT_FOOT_ID, 7), - ]) + *BODY_LEFT_KNEE_ID, + *BODY_LEFT_FOOT_ID, + *BODY_RIGHT_KNEE_ID, + *BODY_RIGHT_FOOT_ID, + ] }); fn to_ffi_quat(quat: Quat) -> FfiQuat { @@ -241,34 +237,3 @@ pub fn to_openvr_ffi_hand_skeleton( to_ffi_skeleton(skeleton) } - -pub fn to_ffi_body_trackers( - device_motions: &[(u64, DeviceMotion)], - tracking: bool, -) -> Option> { - let mut trackers = vec![]; - for i in 0..8 { - if let Some((id, motion)) = device_motions.iter().find(|(id, _)| { - BODY_TRACKER_ID_MAP - .get(id) - .map(|id| *id == i) - .unwrap_or(false) - }) { - trackers.push(FfiBodyTracker { - trackerID: *BODY_TRACKER_ID_MAP.get(id).unwrap(), - orientation: to_ffi_quat(motion.pose.orientation), - position: motion.pose.position.to_array(), - tracking: tracking.into(), - }); - } else { - trackers.push(FfiBodyTracker { - trackerID: i, - orientation: to_ffi_quat(Quat::IDENTITY), - position: [0_f32; 3], - tracking: 0, - }); - } - } - - Some(trackers) -}