From f51cb7ce0c8b847e27e7d017fb1dd5e392fe5abf Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 10:34:32 -0700 Subject: [PATCH] trying to add duration support for vive --- plugins/oculus/src/OculusControllerManager.h | 2 - plugins/openvr/src/ViveControllerManager.cpp | 46 +++++++++++++++++--- plugins/openvr/src/ViveControllerManager.h | 17 +++++++- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 20e5726dff..e62c5f45ea 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -72,8 +72,6 @@ private: private: void stopHapticPulse(bool leftHand); - - private: void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); int _trackedControllers { 0 }; friend class OculusControllerManager; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 6b19646512..7d66429ed6 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -126,6 +126,11 @@ bool ViveControllerManager::activate() { userInputMapper->registerDevice(_inputDevice); _registeredWithInputMapper = true; + _leftHapticTimer.setSingleShot(true); + _rightHapticTimer.setSingleShot(true); + connect(&_leftHapticTimer, SIGNAL(timeout()), this, SLOT(hapticPulseHelper(true))); + connect(&_rightHapticTimer, SIGNAL(timeout()), this, SLOT(hapticPulseHelper(false))); + return true; } @@ -442,7 +447,20 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const _poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar); } -// Vive Controllers do not support duration +void ViveControllerManager::hapticPulseHelper(bool leftHand) { + if (_inputDevice) { + _inputDevice->hapticPulseHelper(leftHand); + } +} + +void ViveControllerManager::InputDevice::hapticPulseHelper(bool leftHand) { + if (leftHand) { + triggerHapticPulse(prevLeftHapticStrength, prevLeftHapticDuration, leftHand); + } else { + triggerHapticPulse(prevRightHapticStrength, prevRightHapticDuration, leftHand); + } +} + bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, bool leftHand) { auto handRole = leftHand ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_RightHand; auto deviceIndex = _system->GetTrackedDeviceIndexForControllerRole(handRole); @@ -450,11 +468,29 @@ bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, floa if (_system->IsTrackedDeviceConnected(deviceIndex) && _system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_Controller && _trackedDevicePose[deviceIndex].bPoseIsValid) { - // the documentation says the third argument to TriggerHapticPulse is duration - // but it seems to instead be strength, and is between 0 and 3999 + // Vive Controllers only support duration up to 4 ms, which is short enough that any variation feels more like strength + const float MAX_HAPTIC_TIME = 3999.0f; // in microseconds + float hapticTime = strength*MAX_HAPTIC_TIME; + if (hapticTime < duration*1000.0f) { + _system->TriggerHapticPulse(deviceIndex, 0, hapticTime); + } + + // Must wait 5 ms before triggering another pulse on this controller // https://github.com/ValveSoftware/openvr/wiki/IVRSystem::TriggerHapticPulse - const float MAX_HAPTIC_STRENGTH = 3999.0f; - _system->TriggerHapticPulse(deviceIndex, 0, strength*MAX_HAPTIC_STRENGTH); + const float HAPTIC_RESET_TIME = 5.0f; + float remainingHapticTime = duration - (hapticTime / 1000.0f + HAPTIC_RESET_TIME); // in milliseconds + if (remainingHapticTime > 0.0f) { + if (leftHand) { + prevLeftHapticStrength = strength; + prevLeftHapticDuration = remainingHapticTime; + _parent._leftHapticTimer.start(remainingHapticTime); + } + else { + prevRightHapticStrength = strength; + prevRightHapticDuration = remainingHapticTime; + _parent._rightHapticTimer.start(remainingHapticTime); + } + } return true; } return false; diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index c108d3087f..67fe43c15a 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -13,6 +13,7 @@ #define hifi__ViveControllerManager #include +#include #include #include @@ -45,10 +46,13 @@ public: void setRenderControllers(bool renderControllers) { _renderControllers = renderControllers; } +private slots: + void hapticPulseHelper(bool leftHand); + private: class InputDevice : public controller::InputDevice { public: - InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {} + InputDevice(ViveControllerManager& parent, vr::IVRSystem*& system) : controller::InputDevice("Vive"), _parent(parent), _system(system) {} private: // Device functions controller::Input::NamedVector getAvailableInputs() const override; @@ -56,6 +60,7 @@ private: void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void focusOutEvent() override; + void hapticPulseHelper(bool leftHand); bool triggerHapticPulse(float strength, float duration, bool leftHand) override; void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); @@ -94,6 +99,11 @@ private: int _trackedControllers { 0 }; vr::IVRSystem*& _system; + ViveControllerManager& _parent; + float prevLeftHapticStrength; + float prevLeftHapticDuration; + float prevRightHapticStrength; + float prevRightHapticDuration; friend class ViveControllerManager; }; @@ -109,7 +119,10 @@ private: bool _renderControllers { false }; vr::IVRSystem* _system { nullptr }; - std::shared_ptr _inputDevice { std::make_shared(_system) }; + std::shared_ptr _inputDevice { std::make_shared(*this, _system) }; + + QTimer _leftHapticTimer; + QTimer _rightHapticTimer; static const QString NAME; };