From 53843e8d2b24ab721d523bff39c0642eb6f61c00 Mon Sep 17 00:00:00 2001 From: ksuprynowicz Date: Thu, 3 Aug 2023 09:42:54 +0200 Subject: [PATCH] Fixed control delays that were caused by a filter --- .../qml/hifi/tablet/OpenVrConfiguration.qml | 76 ++++++++++++++++++- plugins/openvr/src/ViveControllerManager.cpp | 14 ++++ plugins/openvr/src/ViveControllerManager.h | 14 +++- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index b2de480842..b2a383f590 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -9,6 +9,7 @@ import QtQuick 2.5 import QtGraphicalEffects 1.0 +import QtQuick.Controls 2.2 import stylesUit 1.0 import "../../controls" @@ -26,6 +27,39 @@ Flickable { property string pluginName: "" property var page: null; + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + parent: flick.parent + anchors.top: flick.top + anchors.right: flick.right + anchors.bottom: flick.bottom + z: 100 // Display over top of separators. + + background: Item { + implicitWidth: verticalScrollWidth + Rectangle { + color: hifi.colors.baseGrayShadow + radius: 4 + anchors { + fill: parent + bottomMargin: 1 + } + } + } + contentItem: Item { + implicitWidth: verticalScrollShaft + Rectangle { + radius: verticalScrollShaft/2 + color: hifi.colors.white30 + anchors { + fill: parent + topMargin: 1 + bottomMargin: 1 + } + } + } + } + onPluginNameChanged: { if (page !== null) { page.pluginName = flick.pluginName; @@ -932,6 +966,43 @@ Flickable { } } + Row { + id: controllerStickHysteresisTimeRow + anchors.top: outOfRangeDataStrategyRow.bottom + anchors.topMargin: 20 + anchors.left: parent.left + anchors.leftMargin: leftMargin + spacing: 15 + + HifiControls.SpinBox { + id: controllerStickHysteresisTime + width: 70 + + minimumValue: 0 + maximumValue: 0.2 + realValue: 0 + realStepSize: 0.05 + colorScheme: hifi.colorSchemes.dark + + onRealValueChanged: { + sendConfigurationSettings(); + } + } + + RalewayBold { + id: controllerStickHysteresisTimeInfo + size: 12 + text: "Stick Hysteresis Time (set to 0.2 for Vive wands)" + color: hifi.colors.white + } + + RalewayRegular { + size: 12 + text: "sec" + color: hifi.colors.lightGray + } + } + RalewayBold { id: viveDesktopText size: 12 @@ -1048,6 +1119,8 @@ Flickable { armCircumference.realValue = settings["armCircumference"]; shoulderWidth.realValue = settings["shoulderWidth"]; + controllerStickHysteresisTime.realValue = settings["controllerStickHysteresisTime"]; + if (HmdHead) { headBox.checked = true; headPuckBox.checked = false; @@ -1236,7 +1309,8 @@ Flickable { "desktopMode": viveInDesktop.checked, "hmdDesktopTracking": hmdInDesktop.checked, "eyeTrackingEnabled": eyeTracking.checked, - "outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex] + "outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex], + "controllerStickHysteresisTime": controllerStickHysteresisTime.realValue } return settingsObject; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 75582c677e..12659b0f9e 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -817,10 +817,12 @@ void ViveControllerManager::loadSettings() { if (_inputDevice) { const double DEFAULT_ARM_CIRCUMFERENCE = 0.33; const double DEFAULT_SHOULDER_WIDTH = 0.48; + const float DEFAULT_ZERO_HYSTERESIS_PERIOD = 0.0f; // in seconds, 0.0f for most controllers and 0.2f for Vive wands const QString DEFAULT_OUT_OF_RANGE_STRATEGY = "DropAfterDelay"; _inputDevice->_armCircumference = settings.value("armCircumference", QVariant(DEFAULT_ARM_CIRCUMFERENCE)).toDouble(); _inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble(); _inputDevice->_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(settings.value("outOfRangeDataStrategy", QVariant(DEFAULT_OUT_OF_RANGE_STRATEGY)).toString()); + _inputDevice->setControllerStickHysteresisTime(settings.value("controllerStickHysteresisTime", QVariant(DEFAULT_ZERO_HYSTERESIS_PERIOD)).toFloat()); } const bool DEFAULT_EYE_TRACKING_ENABLED = false; @@ -838,6 +840,7 @@ void ViveControllerManager::saveSettings() const { settings.setValue(QString("armCircumference"), _inputDevice->_armCircumference); settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth); settings.setValue(QString("outOfRangeDataStrategy"), outOfRangeDataStrategyToString(_inputDevice->_outOfRangeDataStrategy)); + settings.setValue(QString("controllerStickHysteresisTime"), _inputDevice->getControllerStickHysteresisTime()); } settings.setValue(QString("eyeTrackingEnabled"), _eyeTrackingEnabled); @@ -858,6 +861,13 @@ ViveControllerManager::InputDevice::InputDevice(vr::IVRSystem*& system) : _configStringMap[Config::FeetHipsChestAndShoulders] = QString("FeetHipsChestAndShoulders"); } +void ViveControllerManager::InputDevice::setControllerStickHysteresisTime(float value) { + qDebug() << "ViveControllerManager::InputDevice::setControllerStickHysteresisTime: " << value; + _filteredLeftStick.setHysteresisPeriod(value); + _filteredRightStick.setHysteresisPeriod(value); +} + + void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { _poseStateMap.clear(); _buttonPressedMap.clear(); @@ -988,6 +998,9 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso hmdDesktopMode = iter.value().toBool(); } else if (iter.key() == "outOfRangeDataStrategy") { _outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(iter.value().toString()); + } else if (iter.key() == "controllerStickHysteresisTime") { + qDebug() << "controllerStickHysteresisTime: " << iter.value().toDouble(); + setControllerStickHysteresisTime(iter.value().toDouble()); } iter++; } @@ -1011,6 +1024,7 @@ QJsonObject ViveControllerManager::InputDevice::configurationSettings() { configurationSettings["armCircumference"] = (double)(_armCircumference * M_TO_CM); configurationSettings["shoulderWidth"] = (double)(_shoulderWidth * M_TO_CM); configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy); + configurationSettings["controllerStickHysteresisTime"] = getControllerStickHysteresisTime(); return configurationSettings; } diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 1b8c2a2ec5..1615c5c24e 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -105,6 +105,9 @@ private: public: InputDevice(vr::IVRSystem*& system); bool isHeadControllerMounted() const { return _overrideHead; } + float getControllerStickHysteresisTime() { return _filteredLeftStick.getHysteresisPeriod(); }; + // Sets hysteresis period for the filter. This is a workaround needed only for Vive wands which use value 0.2f. + void setControllerStickHysteresisTime(float value); private: // Device functions @@ -156,10 +159,12 @@ private: class FilteredStick { public: + float getHysteresisPeriod() { return _hysteresis_period; }; + // Sets hysteresis period for the filter. This is a workaround needed only for Vive wands which use value 0.2f. + void setHysteresisPeriod(float value) { _hysteresis_period = value; }; glm::vec2 process(float deltaTime, const glm::vec2& stick) { - // Use a timer to prevent the stick going to back to zero. - // This to work around the noisy touch pad that will flash back to zero breifly - const float ZERO_HYSTERESIS_PERIOD = 0.2f; // 200 ms + // Use a timer to prevent the stick going back to zero. + // This to work around the noisy touchpad that will flash back to zero briefly if (glm::length(stick) == 0.0f) { if (_timer <= 0.0f) { return glm::vec2(0.0f, 0.0f); @@ -168,12 +173,13 @@ private: return _stick; } } else { - _timer = ZERO_HYSTERESIS_PERIOD; + _timer = _hysteresis_period; _stick = stick; return stick; } } protected: + float _hysteresis_period{ 0.0f }; float _timer { 0.0f }; glm::vec2 _stick { 0.0f, 0.0f }; };