From 6ca02dcad24d4a1a1fa195120c6e24c47509252c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 2 Jun 2016 12:11:13 -0700 Subject: [PATCH 01/15] expose Controller.triggerHapticPulse to javascript (currently does nothing) --- .../controllers/src/controllers/InputDevice.h | 5 +- .../src/controllers/ScriptingInterface.cpp | 104 +++++++++--------- .../src/controllers/ScriptingInterface.h | 6 +- .../src/controllers/UserInputMapper.cpp | 8 ++ .../src/controllers/UserInputMapper.h | 1 + 5 files changed, 71 insertions(+), 53 deletions(-) diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h index afb1f7d1f7..3c8e728f4d 100644 --- a/libraries/controllers/src/controllers/InputDevice.h +++ b/libraries/controllers/src/controllers/InputDevice.h @@ -51,10 +51,13 @@ public: float getValue(const Input& input) const; float getValue(ChannelType channelType, uint16_t channel) const; - Pose getPoseValue(uint16_t channel) const; + Pose getPoseValue(uint16_t channel) const; const QString& getName() const { return _name; } + // By default, Input Devices do not support haptics + virtual bool triggerHapticPulse(float strength, float duration, bool leftHand) { return false; } + // Update call MUST be called once per simulation loop // It takes care of updating the action states and deltas virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData) {}; diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index c2e64ca19e..a7d9270ddf 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -76,69 +76,73 @@ controller::ScriptingInterface::ScriptingInterface() { namespace controller { - QObject* ScriptingInterface::newMapping(const QString& mappingName) { - auto userInputMapper = DependencyManager::get(); - return new MappingBuilderProxy(*userInputMapper, userInputMapper->newMapping(mappingName)); - } + QObject* ScriptingInterface::newMapping(const QString& mappingName) { + auto userInputMapper = DependencyManager::get(); + return new MappingBuilderProxy(*userInputMapper, userInputMapper->newMapping(mappingName)); + } - void ScriptingInterface::enableMapping(const QString& mappingName, bool enable) { - auto userInputMapper = DependencyManager::get(); - userInputMapper->enableMapping(mappingName, enable); - } + void ScriptingInterface::enableMapping(const QString& mappingName, bool enable) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->enableMapping(mappingName, enable); + } - float ScriptingInterface::getValue(const int& source) const { - auto userInputMapper = DependencyManager::get(); - return userInputMapper->getValue(Input((uint32_t)source)); - } + float ScriptingInterface::getValue(const int& source) const { + auto userInputMapper = DependencyManager::get(); + return userInputMapper->getValue(Input((uint32_t)source)); + } - float ScriptingInterface::getButtonValue(StandardButtonChannel source, uint16_t device) const { - return getValue(Input(device, source, ChannelType::BUTTON).getID()); - } + float ScriptingInterface::getButtonValue(StandardButtonChannel source, uint16_t device) const { + return getValue(Input(device, source, ChannelType::BUTTON).getID()); + } - float ScriptingInterface::getAxisValue(StandardAxisChannel source, uint16_t device) const { - return getValue(Input(device, source, ChannelType::AXIS).getID()); - } + float ScriptingInterface::getAxisValue(StandardAxisChannel source, uint16_t device) const { + return getValue(Input(device, source, ChannelType::AXIS).getID()); + } - Pose ScriptingInterface::getPoseValue(const int& source) const { - auto userInputMapper = DependencyManager::get(); - return userInputMapper->getPose(Input((uint32_t)source)); - } - - Pose ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const { - return getPoseValue(Input(device, source, ChannelType::POSE).getID()); - } + Pose ScriptingInterface::getPoseValue(const int& source) const { + auto userInputMapper = DependencyManager::get(); + return userInputMapper->getPose(Input((uint32_t)source)); + } - QVector ScriptingInterface::getAllActions() { - return DependencyManager::get()->getAllActions(); - } + Pose ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const { + return getPoseValue(Input(device, source, ChannelType::POSE).getID()); + } - QString ScriptingInterface::getDeviceName(unsigned int device) { - return DependencyManager::get()->getDeviceName((unsigned short)device); - } + QVector ScriptingInterface::getAllActions() { + return DependencyManager::get()->getAllActions(); + } - QVector ScriptingInterface::getAvailableInputs(unsigned int device) { - return DependencyManager::get()->getAvailableInputs((unsigned short)device); - } + QString ScriptingInterface::getDeviceName(unsigned int device) { + return DependencyManager::get()->getDeviceName((unsigned short)device); + } - int ScriptingInterface::findDevice(QString name) { - return DependencyManager::get()->findDevice(name); - } + QVector ScriptingInterface::getAvailableInputs(unsigned int device) { + return DependencyManager::get()->getAvailableInputs((unsigned short)device); + } - QVector ScriptingInterface::getDeviceNames() { - return DependencyManager::get()->getDeviceNames(); - } + int ScriptingInterface::findDevice(QString name) { + return DependencyManager::get()->findDevice(name); + } - float ScriptingInterface::getActionValue(int action) { - return DependencyManager::get()->getActionState(Action(action)); - } + QVector ScriptingInterface::getDeviceNames() { + return DependencyManager::get()->getDeviceNames(); + } - int ScriptingInterface::findAction(QString actionName) { - return DependencyManager::get()->findAction(actionName); - } + float ScriptingInterface::getActionValue(int action) { + return DependencyManager::get()->getActionState(Action(action)); + } - QVector ScriptingInterface::getActionNames() const { - return DependencyManager::get()->getActionNames(); - } + int ScriptingInterface::findAction(QString actionName) { + return DependencyManager::get()->findAction(actionName); + } + + QVector ScriptingInterface::getActionNames() const { + return DependencyManager::get()->getActionNames(); + } + + bool ScriptingInterface::triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand) const { + return DependencyManager::get()->triggerHapticPulse(device, strength, duration, leftHand); + } void ScriptingInterface::updateMaps() { QVariantMap newHardware; diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index f30212a09e..7f7120a907 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -77,12 +77,14 @@ namespace controller { Q_INVOKABLE QVector getDeviceNames(); Q_INVOKABLE int findAction(QString actionName); Q_INVOKABLE QVector getActionNames() const; - + Q_INVOKABLE float getValue(const int& source) const; Q_INVOKABLE float getButtonValue(StandardButtonChannel source, uint16_t device = 0) const; Q_INVOKABLE float getAxisValue(StandardAxisChannel source, uint16_t device = 0) const; Q_INVOKABLE Pose getPoseValue(const int& source) const; - Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const; + Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const; + + Q_INVOKABLE bool triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand = true) const; Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString()); Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true); diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index c1ee3ce36c..2c9138e120 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -336,6 +336,14 @@ QVector UserInputMapper::getActionNames() const { return result; } +bool UserInputMapper::triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand) { + Locker locker(_lock); + if (_registeredDevices.find(deviceID) != _registeredDevices.end()) { + return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, leftHand); + } + return false; +} + int actionMetaTypeId = qRegisterMetaType(); int inputMetaTypeId = qRegisterMetaType(); int inputPairMetaTypeId = qRegisterMetaType(); diff --git a/libraries/controllers/src/controllers/UserInputMapper.h b/libraries/controllers/src/controllers/UserInputMapper.h index 9c79415b6e..ac60247e8e 100644 --- a/libraries/controllers/src/controllers/UserInputMapper.h +++ b/libraries/controllers/src/controllers/UserInputMapper.h @@ -89,6 +89,7 @@ namespace controller { void setActionState(Action action, float value) { _actionStates[toInt(action)] = value; } void deltaActionState(Action action, float delta) { _actionStates[toInt(action)] += delta; } void setActionState(Action action, const Pose& value) { _poseStates[toInt(action)] = value; } + bool triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand); static Input makeStandardInput(controller::StandardButtonChannel button); static Input makeStandardInput(controller::StandardAxisChannel axis); From 642438a2596c8ea6d4d7f3fb7b55c11deb7d4545 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 2 Jun 2016 12:18:56 -0700 Subject: [PATCH 02/15] fix tabs --- .../controllers/src/controllers/InputDevice.h | 6 +- .../src/controllers/ScriptingInterface.cpp | 106 +++++++++--------- .../src/controllers/ScriptingInterface.h | 6 +- .../src/controllers/UserInputMapper.cpp | 10 +- .../src/controllers/UserInputMapper.h | 2 +- 5 files changed, 65 insertions(+), 65 deletions(-) diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h index 3c8e728f4d..cc158497e0 100644 --- a/libraries/controllers/src/controllers/InputDevice.h +++ b/libraries/controllers/src/controllers/InputDevice.h @@ -51,12 +51,12 @@ public: float getValue(const Input& input) const; float getValue(ChannelType channelType, uint16_t channel) const; - Pose getPoseValue(uint16_t channel) const; + Pose getPoseValue(uint16_t channel) const; const QString& getName() const { return _name; } - // By default, Input Devices do not support haptics - virtual bool triggerHapticPulse(float strength, float duration, bool leftHand) { return false; } + // By default, Input Devices do not support haptics + virtual bool triggerHapticPulse(float strength, float duration, bool leftHand) { return false; } // Update call MUST be called once per simulation loop // It takes care of updating the action states and deltas diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index a7d9270ddf..97b7a9ddd9 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -76,73 +76,73 @@ controller::ScriptingInterface::ScriptingInterface() { namespace controller { - QObject* ScriptingInterface::newMapping(const QString& mappingName) { - auto userInputMapper = DependencyManager::get(); - return new MappingBuilderProxy(*userInputMapper, userInputMapper->newMapping(mappingName)); - } + QObject* ScriptingInterface::newMapping(const QString& mappingName) { + auto userInputMapper = DependencyManager::get(); + return new MappingBuilderProxy(*userInputMapper, userInputMapper->newMapping(mappingName)); + } - void ScriptingInterface::enableMapping(const QString& mappingName, bool enable) { - auto userInputMapper = DependencyManager::get(); - userInputMapper->enableMapping(mappingName, enable); - } + void ScriptingInterface::enableMapping(const QString& mappingName, bool enable) { + auto userInputMapper = DependencyManager::get(); + userInputMapper->enableMapping(mappingName, enable); + } - float ScriptingInterface::getValue(const int& source) const { - auto userInputMapper = DependencyManager::get(); - return userInputMapper->getValue(Input((uint32_t)source)); - } + float ScriptingInterface::getValue(const int& source) const { + auto userInputMapper = DependencyManager::get(); + return userInputMapper->getValue(Input((uint32_t)source)); + } - float ScriptingInterface::getButtonValue(StandardButtonChannel source, uint16_t device) const { - return getValue(Input(device, source, ChannelType::BUTTON).getID()); - } + float ScriptingInterface::getButtonValue(StandardButtonChannel source, uint16_t device) const { + return getValue(Input(device, source, ChannelType::BUTTON).getID()); + } - float ScriptingInterface::getAxisValue(StandardAxisChannel source, uint16_t device) const { - return getValue(Input(device, source, ChannelType::AXIS).getID()); - } + float ScriptingInterface::getAxisValue(StandardAxisChannel source, uint16_t device) const { + return getValue(Input(device, source, ChannelType::AXIS).getID()); + } - Pose ScriptingInterface::getPoseValue(const int& source) const { - auto userInputMapper = DependencyManager::get(); - return userInputMapper->getPose(Input((uint32_t)source)); - } + Pose ScriptingInterface::getPoseValue(const int& source) const { + auto userInputMapper = DependencyManager::get(); + return userInputMapper->getPose(Input((uint32_t)source)); + } + + Pose ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const { + return getPoseValue(Input(device, source, ChannelType::POSE).getID()); + } - Pose ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const { - return getPoseValue(Input(device, source, ChannelType::POSE).getID()); - } + QVector ScriptingInterface::getAllActions() { + return DependencyManager::get()->getAllActions(); + } - QVector ScriptingInterface::getAllActions() { - return DependencyManager::get()->getAllActions(); - } + QString ScriptingInterface::getDeviceName(unsigned int device) { + return DependencyManager::get()->getDeviceName((unsigned short)device); + } - QString ScriptingInterface::getDeviceName(unsigned int device) { - return DependencyManager::get()->getDeviceName((unsigned short)device); - } + QVector ScriptingInterface::getAvailableInputs(unsigned int device) { + return DependencyManager::get()->getAvailableInputs((unsigned short)device); + } - QVector ScriptingInterface::getAvailableInputs(unsigned int device) { - return DependencyManager::get()->getAvailableInputs((unsigned short)device); - } + int ScriptingInterface::findDevice(QString name) { + return DependencyManager::get()->findDevice(name); + } - int ScriptingInterface::findDevice(QString name) { - return DependencyManager::get()->findDevice(name); - } + QVector ScriptingInterface::getDeviceNames() { + return DependencyManager::get()->getDeviceNames(); + } - QVector ScriptingInterface::getDeviceNames() { - return DependencyManager::get()->getDeviceNames(); - } + float ScriptingInterface::getActionValue(int action) { + return DependencyManager::get()->getActionState(Action(action)); + } - float ScriptingInterface::getActionValue(int action) { - return DependencyManager::get()->getActionState(Action(action)); - } + int ScriptingInterface::findAction(QString actionName) { + return DependencyManager::get()->findAction(actionName); + } - int ScriptingInterface::findAction(QString actionName) { - return DependencyManager::get()->findAction(actionName); - } + QVector ScriptingInterface::getActionNames() const { + return DependencyManager::get()->getActionNames(); + } - QVector ScriptingInterface::getActionNames() const { - return DependencyManager::get()->getActionNames(); - } - - bool ScriptingInterface::triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand) const { - return DependencyManager::get()->triggerHapticPulse(device, strength, duration, leftHand); - } + bool ScriptingInterface::triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand) const { + return DependencyManager::get()->triggerHapticPulse(device, strength, duration, leftHand); + } void ScriptingInterface::updateMaps() { QVariantMap newHardware; diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index 7f7120a907..cce159a9a7 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -77,14 +77,14 @@ namespace controller { Q_INVOKABLE QVector getDeviceNames(); Q_INVOKABLE int findAction(QString actionName); Q_INVOKABLE QVector getActionNames() const; - + Q_INVOKABLE float getValue(const int& source) const; Q_INVOKABLE float getButtonValue(StandardButtonChannel source, uint16_t device = 0) const; Q_INVOKABLE float getAxisValue(StandardAxisChannel source, uint16_t device = 0) const; Q_INVOKABLE Pose getPoseValue(const int& source) const; - Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const; + Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const; - Q_INVOKABLE bool triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand = true) const; + Q_INVOKABLE bool triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand = true) const; Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString()); Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true); diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 2c9138e120..c7c62ad7d9 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -337,11 +337,11 @@ QVector UserInputMapper::getActionNames() const { } bool UserInputMapper::triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand) { - Locker locker(_lock); - if (_registeredDevices.find(deviceID) != _registeredDevices.end()) { - return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, leftHand); - } - return false; + Locker locker(_lock); + if (_registeredDevices.find(deviceID) != _registeredDevices.end()) { + return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, leftHand); + } + return false; } int actionMetaTypeId = qRegisterMetaType(); diff --git a/libraries/controllers/src/controllers/UserInputMapper.h b/libraries/controllers/src/controllers/UserInputMapper.h index ac60247e8e..b23657fff7 100644 --- a/libraries/controllers/src/controllers/UserInputMapper.h +++ b/libraries/controllers/src/controllers/UserInputMapper.h @@ -89,7 +89,7 @@ namespace controller { void setActionState(Action action, float value) { _actionStates[toInt(action)] = value; } void deltaActionState(Action action, float delta) { _actionStates[toInt(action)] += delta; } void setActionState(Action action, const Pose& value) { _poseStates[toInt(action)] = value; } - bool triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand); + bool triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand); static Input makeStandardInput(controller::StandardButtonChannel button); static Input makeStandardInput(controller::StandardAxisChannel axis); From 69971a3439163e912a5c677edcf6796ec234687f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 2 Jun 2016 12:20:05 -0700 Subject: [PATCH 03/15] fix one more tab --- libraries/controllers/src/controllers/ScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index cce159a9a7..015ec25454 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -77,7 +77,7 @@ namespace controller { Q_INVOKABLE QVector getDeviceNames(); Q_INVOKABLE int findAction(QString actionName); Q_INVOKABLE QVector getActionNames() const; - + Q_INVOKABLE float getValue(const int& source) const; Q_INVOKABLE float getButtonValue(StandardButtonChannel source, uint16_t device = 0) const; Q_INVOKABLE float getAxisValue(StandardAxisChannel source, uint16_t device = 0) const; From 912b35693b32f5302bbdf32a7b9bac531341dc47 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 2 Jun 2016 18:13:33 -0700 Subject: [PATCH 04/15] added vive single pulse haptics --- plugins/openvr/src/ViveControllerManager.cpp | 18 ++++++++++++++++++ plugins/openvr/src/ViveControllerManager.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 6e75454b5f..6b19646512 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -442,6 +442,24 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const _poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar); } +// Vive Controllers do not support duration +bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, bool leftHand) { + auto handRole = leftHand ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_RightHand; + auto deviceIndex = _system->GetTrackedDeviceIndexForControllerRole(handRole); + + 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 + // https://github.com/ValveSoftware/openvr/wiki/IVRSystem::TriggerHapticPulse + const float MAX_HAPTIC_STRENGTH = 3999.0f; + _system->TriggerHapticPulse(deviceIndex, 0, strength*MAX_HAPTIC_STRENGTH); + return true; + } + return false; +} + controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const { using namespace controller; QVector availableInputs{ diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index bd5d4a39f4..c108d3087f 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -56,6 +56,8 @@ private: void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void focusOutEvent() override; + bool triggerHapticPulse(float strength, float duration, bool leftHand) override; + void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand); void handleAxisEvent(float deltaTime, uint32_t axis, float x, float y, bool isLeftHand); From e2c4b4d3064707ac5310e755566f8c51e23ce252 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 3 Jun 2016 10:17:08 -0700 Subject: [PATCH 05/15] added haptic support to sdl and touch (needs testing) --- plugins/hifiSdl2/src/Joystick.cpp | 11 ++++++- plugins/hifiSdl2/src/Joystick.h | 3 ++ plugins/hifiSdl2/src/SDL2Manager.cpp | 2 +- .../oculus/src/OculusControllerManager.cpp | 31 +++++++++++++++++++ plugins/oculus/src/OculusControllerManager.h | 11 +++++++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index a109656489..136c021913 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -21,9 +21,10 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl InputDevice("GamePad"), _sdlGameController(sdlGameController), _sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)), + _sdlHaptic(SDL_HapticOpenFromJoystick(_sdlJoystick)), _instanceId(instanceId) { - + SDL_HapticRumbleInit(_sdlHaptic); } Joystick::~Joystick() { @@ -31,6 +32,7 @@ Joystick::~Joystick() { } void Joystick::closeJoystick() { + SDL_HapticClose(_sdlHaptic); SDL_GameControllerClose(_sdlGameController); } @@ -62,6 +64,13 @@ void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { } } +bool Joystick::triggerHapticPulse(float strength, float duration, bool leftHand) { + if (SDL_HapticRumblePlay(_sdlHaptic, strength, duration) != 0) { + return false; + } + return true; +} + controller::Input::NamedVector Joystick::getAvailableInputs() const { using namespace controller; static const Input::NamedVector availableInputs{ diff --git a/plugins/hifiSdl2/src/Joystick.h b/plugins/hifiSdl2/src/Joystick.h index e2eaeaef8b..4f785f85ce 100644 --- a/plugins/hifiSdl2/src/Joystick.h +++ b/plugins/hifiSdl2/src/Joystick.h @@ -36,6 +36,8 @@ public: virtual QString getDefaultMappingConfig() const override; virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; virtual void focusOutEvent() override; + + bool triggerHapticPulse(float strength, float duration, bool leftHand) override; Joystick() : InputDevice("GamePad") {} ~Joystick(); @@ -52,6 +54,7 @@ public: private: SDL_GameController* _sdlGameController; SDL_Joystick* _sdlJoystick; + SDL_Haptic* _sdlHaptic; SDL_JoystickID _instanceId; }; diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index 0bdb68f830..09e783864c 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -49,7 +49,7 @@ SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { } void SDL2Manager::init() { - bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0); + bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == 0); if (initSuccess) { int joystickCount = SDL_NumJoysticks(); diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 09ab6ec159..3151db1d90 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -55,6 +55,11 @@ bool OculusControllerManager::activate() { userInputMapper->registerDevice(_touch); } + _leftHapticTimer.setSingleShot(true); + _rightHapticTimer.setSingleShot(true); + connect(&_leftHapticTimer, SIGNAL(timeout()), this, SLOT(stopHapticPulse(true))); + connect(&_rightHapticTimer, SIGNAL(timeout()), this, SLOT(stopHapticPulse(false))); + return true; } @@ -105,6 +110,12 @@ void OculusControllerManager::pluginFocusOutEvent() { } } +void OculusControllerManager::stopHapticPulse(bool leftHand) { + if (_touch) { + _touch->stopHapticPulse(leftHand); + } +} + using namespace controller; static const std::vector> BUTTON_MAP { { @@ -228,6 +239,26 @@ void OculusControllerManager::TouchDevice::handlePose(float deltaTime, pose.velocity = toGlm(handPose.LinearVelocity); } +bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, float duration, bool leftHand) { + auto handType = (leftHand ? ovrControllerType_LTouch : ovrControllerType_RTouch); + if (ovr_SetControllerVibration(_parent._session, handType, 1.0f, strength) != ovrSuccess) { + return false; + } + + if (leftHand) { + _parent._leftHapticTimer.start(duration); + } else { + _parent._rightHapticTimer.start(duration); + } + + return true; +} + +void OculusControllerManager::TouchDevice::stopHapticPulse(bool leftHand) { + auto handType = (leftHand ? ovrControllerType_LTouch : ovrControllerType_RTouch); + ovr_SetControllerVibration(_parent._session, handType, 0.0f, 0.0f); +} + controller::Input::NamedVector OculusControllerManager::TouchDevice::getAvailableInputs() const { using namespace controller; QVector availableInputs{ diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 980e1286f8..20e5726dff 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -10,6 +10,7 @@ #define hifi__OculusControllerManager #include +#include #include #include @@ -32,6 +33,9 @@ public: void pluginFocusOutEvent() override; void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; +private slots: + void stopHapticPulse(bool leftHand); + private: class OculusInputDevice : public controller::InputDevice { public: @@ -64,6 +68,11 @@ private: void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void focusOutEvent() override; + bool triggerHapticPulse(float strength, float duration, bool leftHand) override; + + private: + void stopHapticPulse(bool leftHand); + private: void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); int _trackedControllers { 0 }; @@ -73,6 +82,8 @@ private: ovrSession _session { nullptr }; ovrInputState _inputState {}; RemoteDevice::Pointer _remote; + QTimer _leftHapticTimer; + QTimer _rightHapticTimer; TouchDevice::Pointer _touch; static const QString NAME; }; From c1eab612418a81357e127f9918b4654413007a2f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 3 Jun 2016 11:22:06 -0700 Subject: [PATCH 06/15] sdl haptics aren't working, but might be a bug in sdl: http://stackoverflow.com/questions/23974908/why-is-sdl-hapticopenfromjoystick-not-working-in-sdl-2 --- plugins/hifiSdl2/src/Joystick.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index 136c021913..cf7dde371b 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -24,6 +24,9 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl _sdlHaptic(SDL_HapticOpenFromJoystick(_sdlJoystick)), _instanceId(instanceId) { + if (!_sdlHaptic) { + qDebug(SDL_GetError()); + } SDL_HapticRumbleInit(_sdlHaptic); } From f51cb7ce0c8b847e27e7d017fb1dd5e392fe5abf Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 10:34:32 -0700 Subject: [PATCH 07/15] 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; }; From afca0ec2c9542cc39bfd6f141525fb625e3bfa2e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 13:25:05 -0700 Subject: [PATCH 08/15] moved vive pulses to correct thread, works with duration --- plugins/openvr/src/ViveControllerManager.cpp | 65 ++++++++++---------- plugins/openvr/src/ViveControllerManager.h | 29 +++++---- 2 files changed, 45 insertions(+), 49 deletions(-) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 7d66429ed6..39b5e620ad 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -125,12 +125,6 @@ bool ViveControllerManager::activate() { auto userInputMapper = DependencyManager::get(); 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; } @@ -250,6 +244,17 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); + // handle haptics + { + Locker locker(_lock); + if (_leftHapticDuration > 0.0f) { + hapticsHelper(deltaTime, true); + } + if (_rightHapticDuration > 0.0f) { + hapticsHelper(deltaTime, false); + } + } + int numTrackedControllers = 0; if (leftHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) { numTrackedControllers++; @@ -447,27 +452,28 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const _poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar); } -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) { + Locker locker(_lock); + if (leftHand) { + _leftHapticStrength = strength; + _leftHapticDuration = duration; + } else { + _rightHapticStrength = strength; + _rightHapticDuration = duration; + } + return true; +} + +void ViveControllerManager::InputDevice::hapticsHelper(float deltaTime, bool leftHand) { auto handRole = leftHand ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_RightHand; auto deviceIndex = _system->GetTrackedDeviceIndexForControllerRole(handRole); if (_system->IsTrackedDeviceConnected(deviceIndex) && _system->GetTrackedDeviceClass(deviceIndex) == vr::TrackedDeviceClass_Controller && _trackedDevicePose[deviceIndex].bPoseIsValid) { + float strength = leftHand ? _leftHapticStrength : _rightHapticStrength; + float duration = leftHand ? _leftHapticDuration : _rightHapticDuration; + // 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; @@ -478,22 +484,13 @@ bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, floa // Must wait 5 ms before triggering another pulse on this controller // https://github.com/ValveSoftware/openvr/wiki/IVRSystem::TriggerHapticPulse 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); - } + float remainingHapticTime = duration - (hapticTime / 1000.0f + deltaTime * 1000.0f); // in milliseconds + if (leftHand) { + _leftHapticDuration = remainingHapticTime; + } else { + _rightHapticDuration = remainingHapticTime; } - return true; } - return false; } controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const { diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 67fe43c15a..9bdbd0370e 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -13,7 +13,6 @@ #define hifi__ViveControllerManager #include -#include #include #include @@ -46,13 +45,10 @@ public: void setRenderControllers(bool renderControllers) { _renderControllers = renderControllers; } -private slots: - void hapticPulseHelper(bool leftHand); - private: class InputDevice : public controller::InputDevice { public: - InputDevice(ViveControllerManager& parent, vr::IVRSystem*& system) : controller::InputDevice("Vive"), _parent(parent), _system(system) {} + InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system), _leftHapticDuration(0.0f), _rightHapticDuration(0.0f) {} private: // Device functions controller::Input::NamedVector getAvailableInputs() const override; @@ -60,8 +56,8 @@ 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 hapticsHelper(float deltaTime, bool leftHand); void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand); @@ -97,13 +93,19 @@ private: FilteredStick _filteredLeftStick; FilteredStick _filteredRightStick; + // perform an action when the InputDevice mutex is acquired. + using Locker = std::unique_lock; + template + void withLock(F&& f) { Locker locker(_lock); f(); } + int _trackedControllers { 0 }; vr::IVRSystem*& _system; - ViveControllerManager& _parent; - float prevLeftHapticStrength; - float prevLeftHapticDuration; - float prevRightHapticStrength; - float prevRightHapticDuration; + float _leftHapticStrength; + float _leftHapticDuration; + float _rightHapticStrength; + float _rightHapticDuration; + mutable std::recursive_mutex _lock; + friend class ViveControllerManager; }; @@ -119,10 +121,7 @@ private: bool _renderControllers { false }; vr::IVRSystem* _system { nullptr }; - std::shared_ptr _inputDevice { std::make_shared(*this, _system) }; - - QTimer _leftHapticTimer; - QTimer _rightHapticTimer; + std::shared_ptr _inputDevice { std::make_shared(_system) }; static const QString NAME; }; From e7743cd8e2603927da7099ea6e82e696e237fd1c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 15:03:08 -0700 Subject: [PATCH 09/15] added options for both hands (default), all devices, short pulse, and fixed touch timing mechanism --- .../controllers/src/controllers/InputDevice.h | 8 +++- .../src/controllers/ScriptingInterface.cpp | 18 +++++++- .../src/controllers/ScriptingInterface.h | 5 ++- .../src/controllers/UserInputMapper.cpp | 25 ++++++++++- .../src/controllers/UserInputMapper.h | 4 +- plugins/hifiSdl2/src/Joystick.cpp | 2 +- plugins/hifiSdl2/src/Joystick.h | 2 +- .../oculus/src/OculusControllerManager.cpp | 45 ++++++++++++------- plugins/oculus/src/OculusControllerManager.h | 15 +++++-- plugins/openvr/src/ViveControllerManager.cpp | 10 ++--- plugins/openvr/src/ViveControllerManager.h | 12 ++--- 11 files changed, 105 insertions(+), 41 deletions(-) diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h index cc158497e0..10e1a104f4 100644 --- a/libraries/controllers/src/controllers/InputDevice.h +++ b/libraries/controllers/src/controllers/InputDevice.h @@ -31,6 +31,12 @@ namespace controller { class Endpoint; using EndpointPointer = std::shared_ptr; +enum Hand { + LEFT = 0, + RIGHT, + BOTH +}; + // NOTE: If something inherits from both InputDevice and InputPlugin, InputPlugin must go first. // e.g. class Example : public InputPlugin, public InputDevice // instead of class Example : public InputDevice, public InputPlugin @@ -56,7 +62,7 @@ public: const QString& getName() const { return _name; } // By default, Input Devices do not support haptics - virtual bool triggerHapticPulse(float strength, float duration, bool leftHand) { return false; } + virtual bool triggerHapticPulse(float strength, float duration, controller::Hand hand) { return false; } // Update call MUST be called once per simulation loop // It takes care of updating the action states and deltas diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index 97b7a9ddd9..78e9378c18 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -140,8 +140,22 @@ namespace controller { return DependencyManager::get()->getActionNames(); } - bool ScriptingInterface::triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand) const { - return DependencyManager::get()->triggerHapticPulse(device, strength, duration, leftHand); + bool ScriptingInterface::triggerHapticPulse(float strength, float duration, controller::Hand hand) const { + return DependencyManager::get()->triggerHapticPulse(strength, duration, hand); + } + + bool ScriptingInterface::triggerShortHapticPulse(float strength, controller::Hand hand) const { + const float SHORT_HAPTIC_DURATION_MS = 250.0f; + return DependencyManager::get()->triggerHapticPulse(strength, SHORT_HAPTIC_DURATION_MS, hand); + } + + bool ScriptingInterface::triggerHapticPulseOnDevice(unsigned int device, float strength, float duration, controller::Hand hand) const { + return DependencyManager::get()->triggerHapticPulseOnDevice(device, strength, duration, hand); + } + + bool ScriptingInterface::triggerShortHapticPulseOnDevice(unsigned int device, float strength, controller::Hand hand) const { + const float SHORT_HAPTIC_DURATION_MS = 250.0f; + return DependencyManager::get()->triggerHapticPulseOnDevice(device, strength, SHORT_HAPTIC_DURATION_MS, hand); } void ScriptingInterface::updateMaps() { diff --git a/libraries/controllers/src/controllers/ScriptingInterface.h b/libraries/controllers/src/controllers/ScriptingInterface.h index 015ec25454..713e864561 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.h +++ b/libraries/controllers/src/controllers/ScriptingInterface.h @@ -84,7 +84,10 @@ namespace controller { Q_INVOKABLE Pose getPoseValue(const int& source) const; Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const; - Q_INVOKABLE bool triggerHapticPulse(unsigned int device, float strength, float duration, bool leftHand = true) const; + Q_INVOKABLE bool triggerHapticPulse(float strength, float duration, controller::Hand hand = BOTH) const; + Q_INVOKABLE bool triggerShortHapticPulse(float strength, controller::Hand hand = BOTH) const; + Q_INVOKABLE bool triggerHapticPulseOnDevice(unsigned int device, float strength, float duration, controller::Hand hand = BOTH) const; + Q_INVOKABLE bool triggerShortHapticPulseOnDevice(unsigned int device, float strength, controller::Hand hand = BOTH) const; Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString()); Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true); diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index c7c62ad7d9..921f78c613 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -336,10 +336,19 @@ QVector UserInputMapper::getActionNames() const { return result; } -bool UserInputMapper::triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand) { +bool UserInputMapper::triggerHapticPulse(float strength, float duration, controller::Hand hand) { + Locker locker(_lock); + bool toReturn = false; + for (auto device : _registeredDevices) { + toReturn = toReturn || device.second->triggerHapticPulse(strength, duration, hand); + } + return toReturn; +} + +bool UserInputMapper::triggerHapticPulseOnDevice(uint16 deviceID, float strength, float duration, controller::Hand hand) { Locker locker(_lock); if (_registeredDevices.find(deviceID) != _registeredDevices.end()) { - return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, leftHand); + return _registeredDevices[deviceID]->triggerHapticPulse(strength, duration, hand); } return false; } @@ -348,6 +357,7 @@ int actionMetaTypeId = qRegisterMetaType(); int inputMetaTypeId = qRegisterMetaType(); int inputPairMetaTypeId = qRegisterMetaType(); int poseMetaTypeId = qRegisterMetaType("Pose"); +int handMetaTypeId = qRegisterMetaType(); QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input); void inputFromScriptValue(const QScriptValue& object, Input& input); @@ -355,6 +365,8 @@ QScriptValue actionToScriptValue(QScriptEngine* engine, const Action& action); void actionFromScriptValue(const QScriptValue& object, Action& action); QScriptValue inputPairToScriptValue(QScriptEngine* engine, const Input::NamedPair& inputPair); void inputPairFromScriptValue(const QScriptValue& object, Input::NamedPair& inputPair); +QScriptValue handToScriptValue(QScriptEngine* engine, const controller::Hand& hand); +void handFromScriptValue(const QScriptValue& object, controller::Hand& hand); QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input) { QScriptValue obj = engine->newObject(); @@ -393,12 +405,21 @@ void inputPairFromScriptValue(const QScriptValue& object, Input::NamedPair& inpu inputPair.second = QString(object.property("inputName").toVariant().toString()); } +QScriptValue handToScriptValue(QScriptEngine* engine, const controller::Hand& hand) { + return engine->newVariant((int)hand); +} + +void handFromScriptValue(const QScriptValue& object, controller::Hand& hand) { + hand = Hand(object.toVariant().toInt()); +} + void UserInputMapper::registerControllerTypes(QScriptEngine* engine) { qScriptRegisterSequenceMetaType >(engine); qScriptRegisterSequenceMetaType(engine); qScriptRegisterMetaType(engine, actionToScriptValue, actionFromScriptValue); qScriptRegisterMetaType(engine, inputToScriptValue, inputFromScriptValue); qScriptRegisterMetaType(engine, inputPairToScriptValue, inputPairFromScriptValue); + qScriptRegisterMetaType(engine, handToScriptValue, handFromScriptValue); qScriptRegisterMetaType(engine, Pose::toScriptValue, Pose::fromScriptValue); } diff --git a/libraries/controllers/src/controllers/UserInputMapper.h b/libraries/controllers/src/controllers/UserInputMapper.h index b23657fff7..811b621b09 100644 --- a/libraries/controllers/src/controllers/UserInputMapper.h +++ b/libraries/controllers/src/controllers/UserInputMapper.h @@ -89,7 +89,8 @@ namespace controller { void setActionState(Action action, float value) { _actionStates[toInt(action)] = value; } void deltaActionState(Action action, float delta) { _actionStates[toInt(action)] += delta; } void setActionState(Action action, const Pose& value) { _poseStates[toInt(action)] = value; } - bool triggerHapticPulse(uint16 deviceID, float strength, float duration, bool leftHand); + bool triggerHapticPulse(float strength, float duration, controller::Hand hand); + bool triggerHapticPulseOnDevice(uint16 deviceID, float strength, float duration, controller::Hand hand); static Input makeStandardInput(controller::StandardButtonChannel button); static Input makeStandardInput(controller::StandardAxisChannel axis); @@ -200,6 +201,7 @@ Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(controller::Input) Q_DECLARE_METATYPE(controller::Action) Q_DECLARE_METATYPE(QVector) +Q_DECLARE_METATYPE(controller::Hand) // Cheating. using UserInputMapper = controller::UserInputMapper; diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index cf7dde371b..c20670d4bb 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -67,7 +67,7 @@ void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { } } -bool Joystick::triggerHapticPulse(float strength, float duration, bool leftHand) { +bool Joystick::triggerHapticPulse(float strength, float duration, controller::Hand hand) { if (SDL_HapticRumblePlay(_sdlHaptic, strength, duration) != 0) { return false; } diff --git a/plugins/hifiSdl2/src/Joystick.h b/plugins/hifiSdl2/src/Joystick.h index 4f785f85ce..b37d22de39 100644 --- a/plugins/hifiSdl2/src/Joystick.h +++ b/plugins/hifiSdl2/src/Joystick.h @@ -37,7 +37,7 @@ public: virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; virtual void focusOutEvent() override; - bool triggerHapticPulse(float strength, float duration, bool leftHand) override; + bool triggerHapticPulse(float strength, float duration, controller::Hand hand) override; Joystick() : InputDevice("GamePad") {} ~Joystick(); diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 3151db1d90..2e7044bd69 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -55,11 +55,6 @@ bool OculusControllerManager::activate() { userInputMapper->registerDevice(_touch); } - _leftHapticTimer.setSingleShot(true); - _rightHapticTimer.setSingleShot(true); - connect(&_leftHapticTimer, SIGNAL(timeout()), this, SLOT(stopHapticPulse(true))); - connect(&_rightHapticTimer, SIGNAL(timeout()), this, SLOT(stopHapticPulse(false))); - return true; } @@ -221,6 +216,21 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control _buttonPressedMap.insert(pair.second); } } + + // Haptics + { + Locker locker(_lock); + if (_leftHapticDuration > 0.0f) { + _leftHapticDuration -= deltaTime; + } else { + stopHapticPulse(true); + } + if (_rightHapticDuration > 0.0f) { + _rightHapticDuration -= deltaTime; + } else { + stopHapticPulse(false); + } + } } void OculusControllerManager::TouchDevice::focusOutEvent() { @@ -239,19 +249,22 @@ void OculusControllerManager::TouchDevice::handlePose(float deltaTime, pose.velocity = toGlm(handPose.LinearVelocity); } -bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, float duration, bool leftHand) { - auto handType = (leftHand ? ovrControllerType_LTouch : ovrControllerType_RTouch); - if (ovr_SetControllerVibration(_parent._session, handType, 1.0f, strength) != ovrSuccess) { - return false; +bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) { + Locker locker(_lock); + bool toReturn = true; + if (hand == controller::BOTH || hand == controller::LEFT) { + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_LTouch, 1.0f, strength) != ovrSuccess) { + toReturn = false; + } + _leftHapticDuration = duration; } - - if (leftHand) { - _parent._leftHapticTimer.start(duration); - } else { - _parent._rightHapticTimer.start(duration); + if (hand == controller::BOTH || hand == controller::RIGHT) { + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_RTouch, 1.0f, strength) != ovrSuccess) { + toReturn = false; + } + _rightHapticDuration = duration; } - - return true; + return toReturn; } void OculusControllerManager::TouchDevice::stopHapticPulse(bool leftHand) { diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index e62c5f45ea..244fe41f67 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -10,7 +10,6 @@ #define hifi__OculusControllerManager #include -#include #include #include @@ -68,20 +67,28 @@ private: void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void focusOutEvent() override; - bool triggerHapticPulse(float strength, float duration, bool leftHand) override; + bool triggerHapticPulse(float strength, float duration, controller::Hand hand) override; private: void stopHapticPulse(bool leftHand); void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); int _trackedControllers { 0 }; + + // perform an action when the TouchDevice mutex is acquired. + using Locker = std::unique_lock; + template + void withLock(F&& f) { Locker locker(_lock); f(); } + + float _leftHapticDuration { 0.0f }; + float _rightHapticDuration { 0.0f }; + mutable std::recursive_mutex _lock; + friend class OculusControllerManager; }; ovrSession _session { nullptr }; ovrInputState _inputState {}; RemoteDevice::Pointer _remote; - QTimer _leftHapticTimer; - QTimer _rightHapticTimer; TouchDevice::Pointer _touch; static const QString NAME; }; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 39b5e620ad..27b4887edd 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -452,12 +452,13 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const _poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose.transform(controllerToAvatar); } -bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, bool leftHand) { +bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) { Locker locker(_lock); - if (leftHand) { + if (hand == controller::BOTH || hand == controller::LEFT) { _leftHapticStrength = strength; _leftHapticDuration = duration; - } else { + } + if (hand == controller::BOTH || hand == controller::RIGHT) { _rightHapticStrength = strength; _rightHapticDuration = duration; } @@ -481,9 +482,6 @@ void ViveControllerManager::InputDevice::hapticsHelper(float deltaTime, bool lef _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 HAPTIC_RESET_TIME = 5.0f; float remainingHapticTime = duration - (hapticTime / 1000.0f + deltaTime * 1000.0f); // in milliseconds if (leftHand) { _leftHapticDuration = remainingHapticTime; diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 9bdbd0370e..3a2ef1573f 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -48,7 +48,7 @@ public: private: class InputDevice : public controller::InputDevice { public: - InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system), _leftHapticDuration(0.0f), _rightHapticDuration(0.0f) {} + InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {} private: // Device functions controller::Input::NamedVector getAvailableInputs() const override; @@ -56,7 +56,7 @@ private: void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void focusOutEvent() override; - bool triggerHapticPulse(float strength, float duration, bool leftHand) override; + bool triggerHapticPulse(float strength, float duration, controller::Hand hand) override; void hapticsHelper(float deltaTime, bool leftHand); void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); @@ -100,10 +100,10 @@ private: int _trackedControllers { 0 }; vr::IVRSystem*& _system; - float _leftHapticStrength; - float _leftHapticDuration; - float _rightHapticStrength; - float _rightHapticDuration; + float _leftHapticStrength { 0.0f }; + float _leftHapticDuration { 0.0f }; + float _rightHapticStrength { 0.0f }; + float _rightHapticDuration { 0.0f }; mutable std::recursive_mutex _lock; friend class ViveControllerManager; From cea0d74c358cbe61ecd6ad19d53ddc6f08e34b5e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 15:20:10 -0700 Subject: [PATCH 10/15] fix spaces and touch duration --- plugins/oculus/src/OculusControllerManager.cpp | 4 ++-- plugins/openvr/src/ViveControllerManager.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 2e7044bd69..21d97adbda 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -221,12 +221,12 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control { Locker locker(_lock); if (_leftHapticDuration > 0.0f) { - _leftHapticDuration -= deltaTime; + _leftHapticDuration -= deltaTime * 1000.0f; // milliseconds } else { stopHapticPulse(true); } if (_rightHapticDuration > 0.0f) { - _rightHapticDuration -= deltaTime; + _rightHapticDuration -= deltaTime * 1000.0f; // milliseconds } else { stopHapticPulse(false); } diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 27b4887edd..8e4b277bd7 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -477,8 +477,8 @@ void ViveControllerManager::InputDevice::hapticsHelper(float deltaTime, bool lef // 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) { + float hapticTime = strength * MAX_HAPTIC_TIME; + if (hapticTime < duration * 1000.0f) { _system->TriggerHapticPulse(deviceIndex, 0, hapticTime); } From b59d597780fd4f3ea7789551e0634395a34aa6c1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 15:35:12 -0700 Subject: [PATCH 11/15] if overlapping calls, haptics take on strength and duration of call that will finish last --- plugins/oculus/src/OculusControllerManager.cpp | 10 ++++++---- plugins/oculus/src/OculusControllerManager.h | 2 ++ plugins/openvr/src/ViveControllerManager.cpp | 8 ++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 21d97adbda..02ac44d77c 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -253,16 +253,18 @@ bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, fl Locker locker(_lock); bool toReturn = true; if (hand == controller::BOTH || hand == controller::LEFT) { - if (ovr_SetControllerVibration(_parent._session, ovrControllerType_LTouch, 1.0f, strength) != ovrSuccess) { + _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_LTouch, 1.0f, _leftHapticStrength) != ovrSuccess) { toReturn = false; } - _leftHapticDuration = duration; + _leftHapticDuration = std::max(duration, _leftHapticDuration); } if (hand == controller::BOTH || hand == controller::RIGHT) { - if (ovr_SetControllerVibration(_parent._session, ovrControllerType_RTouch, 1.0f, strength) != ovrSuccess) { + _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_RTouch, 1.0f, _rightHapticStrength) != ovrSuccess) { toReturn = false; } - _rightHapticDuration = duration; + _rightHapticDuration = std::max(duration, _rightHapticDuration); } return toReturn; } diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 244fe41f67..3c5cdeb7c6 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -80,7 +80,9 @@ private: void withLock(F&& f) { Locker locker(_lock); f(); } float _leftHapticDuration { 0.0f }; + float _leftHapticStrength { 0.0f }; float _rightHapticDuration { 0.0f }; + float _rightHapticStrength { 0.0f }; mutable std::recursive_mutex _lock; friend class OculusControllerManager; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 8e4b277bd7..7254117922 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -455,12 +455,12 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) { Locker locker(_lock); if (hand == controller::BOTH || hand == controller::LEFT) { - _leftHapticStrength = strength; - _leftHapticDuration = duration; + _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; + _leftHapticDuration = std::max(duration, _leftHapticDuration); } if (hand == controller::BOTH || hand == controller::RIGHT) { - _rightHapticStrength = strength; - _rightHapticDuration = duration; + _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; + _rightHapticDuration = std::max(duration, _rightHapticDuration); } return true; } From 8fa52fa15987067d67243e7f8d80583e6666aa6b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 16:48:21 -0700 Subject: [PATCH 12/15] trying to fix warning in joystick.cpp --- plugins/hifiSdl2/src/Joystick.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index c20670d4bb..69c83e5d23 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -25,7 +25,7 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl _instanceId(instanceId) { if (!_sdlHaptic) { - qDebug(SDL_GetError()); + qDebug() << SDL_GetError(); } SDL_HapticRumbleInit(_sdlHaptic); } From 7a3cba8580ab1fcfd1bcb04b18007a69b9785a4d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 6 Jun 2016 17:06:59 -0700 Subject: [PATCH 13/15] warning be gone --- plugins/hifiSdl2/src/Joystick.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index 69c83e5d23..aa6b358d38 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -25,7 +25,7 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl _instanceId(instanceId) { if (!_sdlHaptic) { - qDebug() << SDL_GetError(); + qDebug() << QString(SDL_GetError()); } SDL_HapticRumbleInit(_sdlHaptic); } From ff2405437bbbda73d4caaf6df2efca9c94709be1 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 7 Jun 2016 12:19:38 -0700 Subject: [PATCH 14/15] can set strength to 0 --- .../oculus/src/OculusControllerManager.cpp | 26 +++++++++++++------ plugins/openvr/src/ViveControllerManager.cpp | 18 ++++++++++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 02ac44d77c..f00b943d7c 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -253,18 +253,28 @@ bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, fl Locker locker(_lock); bool toReturn = true; if (hand == controller::BOTH || hand == controller::LEFT) { - _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; - if (ovr_SetControllerVibration(_parent._session, ovrControllerType_LTouch, 1.0f, _leftHapticStrength) != ovrSuccess) { - toReturn = false; + if (strength == 0.0f) { + _leftHapticStrength = 0.0f; + _leftHapticDuration = 0.0f; + } else { + _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_LTouch, 1.0f, _leftHapticStrength) != ovrSuccess) { + toReturn = false; + } + _leftHapticDuration = std::max(duration, _leftHapticDuration); } - _leftHapticDuration = std::max(duration, _leftHapticDuration); } if (hand == controller::BOTH || hand == controller::RIGHT) { - _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; - if (ovr_SetControllerVibration(_parent._session, ovrControllerType_RTouch, 1.0f, _rightHapticStrength) != ovrSuccess) { - toReturn = false; + if (strength == 0.0f) { + _rightHapticStrength = 0.0f; + _rightHapticDuration = 0.0f; + } else { + _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; + if (ovr_SetControllerVibration(_parent._session, ovrControllerType_RTouch, 1.0f, _rightHapticStrength) != ovrSuccess) { + toReturn = false; + } + _rightHapticDuration = std::max(duration, _rightHapticDuration); } - _rightHapticDuration = std::max(duration, _rightHapticDuration); } return toReturn; } diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 7254117922..74c232af33 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -455,12 +455,22 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) { Locker locker(_lock); if (hand == controller::BOTH || hand == controller::LEFT) { - _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; - _leftHapticDuration = std::max(duration, _leftHapticDuration); + if (strength == 0.0f) { + _leftHapticStrength = 0.0f; + _leftHapticDuration = 0.0f; + } else { + _leftHapticStrength = (duration > _leftHapticDuration) ? strength : _leftHapticStrength; + _leftHapticDuration = std::max(duration, _leftHapticDuration); + } } if (hand == controller::BOTH || hand == controller::RIGHT) { - _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; - _rightHapticDuration = std::max(duration, _rightHapticDuration); + if (strength == 0.0f) { + _rightHapticStrength = 0.0f; + _rightHapticDuration = 0.0f; + } else { + _rightHapticStrength = (duration > _rightHapticDuration) ? strength : _rightHapticStrength; + _rightHapticDuration = std::max(duration, _rightHapticDuration); + } } return true; } From 2e71a635749350960c2c5d8b171b18a2391b77c0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 7 Jun 2016 13:28:10 -0700 Subject: [PATCH 15/15] cr fixes --- plugins/hifiSdl2/src/Joystick.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index aa6b358d38..e88fe8b958 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -25,9 +25,12 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl _instanceId(instanceId) { if (!_sdlHaptic) { - qDebug() << QString(SDL_GetError()); + qDebug() << "SDL Haptic Open Failure: " << QString(SDL_GetError()); + } else { + if (SDL_HapticRumbleInit(_sdlHaptic) != 0) { + qDebug() << "SDL Haptic Rumble Init Failure: " << QString(SDL_GetError()); + } } - SDL_HapticRumbleInit(_sdlHaptic); } Joystick::~Joystick() { @@ -35,7 +38,9 @@ Joystick::~Joystick() { } void Joystick::closeJoystick() { - SDL_HapticClose(_sdlHaptic); + if (_sdlHaptic) { + SDL_HapticClose(_sdlHaptic); + } SDL_GameControllerClose(_sdlGameController); }