diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index a9d67fec35..3690dc3f4a 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -71,6 +71,7 @@ Flickable { property int state: buttonState.disabled property var lastConfiguration: null + property bool isConfiguring: false HifiConstants { id: hifi } @@ -840,9 +841,72 @@ Flickable { } } + + HifiControls.CheckBox { + id: eyeTracking + width: 15 + height: 15 + boxRadius: 7 + + anchors.top: viveInDesktop.bottom + anchors.topMargin: 5 + anchors.left: openVrConfiguration.left + anchors.leftMargin: leftMargin + 10 + + onClicked: { + sendConfigurationSettings(); + } + } + + RalewayBold { + id: eyeTrackingLabel + size: 12 + text: "Use eye tracking (if available)." + color: hifi.colors.lightGrayText + anchors { + left: eyeTracking.right + leftMargin: 5 + verticalCenter: eyeTracking.verticalCenter + } + } + + RalewayRegular { + id: privacyStatement + text: "Privacy Statement" + color: hifi.colors.blueHighlight + size: 12 + anchors { + left: eyeTrackingLabel.right + leftMargin: 10 + verticalCenter: eyeTrackingLabel.verticalCenter + } + + Rectangle { + id: privacyStatementUnderline + color: hifi.colors.blueHighlight + width: privacyStatement.width + height: 1 + anchors { + top: privacyStatement.bottom + topMargin: 1 + left: privacyStatement.left + } + visible: false + } + + MouseArea { + anchors.fill: parent; + hoverEnabled: true + onEntered: privacyStatementUnderline.visible = true; + onExited: privacyStatementUnderline.visible = false; + onClicked: HiFiAbout.openUrl("https://vircadia.com/"); // FIXME: URL for privacy statement. + } + } + + Row { id: outOfRangeDataStrategyRow - anchors.top: viveInDesktop.bottom + anchors.top: eyeTracking.bottom anchors.topMargin: 5 anchors.left: openVrConfiguration.left anchors.leftMargin: leftMargin + 10 @@ -966,6 +1030,8 @@ Flickable { } function displayConfiguration() { + isConfiguring = true; + var settings = InputConfiguration.configurationSettings(openVrConfiguration.pluginName); var configurationType = settings["trackerConfiguration"]; displayTrackerConfiguration(configurationType); @@ -982,6 +1048,7 @@ Flickable { var viveController = settings["handController"]; var desktopMode = settings["desktopMode"]; var hmdDesktopPosition = settings["hmdDesktopTracking"]; + var eyeTrackingEnabled = settings["eyeTrackingEnabled"]; armCircumference.realValue = settings.armCircumference; shoulderWidth.realValue = settings.shoulderWidth; @@ -1004,6 +1071,7 @@ Flickable { viveInDesktop.checked = desktopMode; hmdInDesktop.checked = hmdDesktopPosition; + eyeTracking.checked = eyeTrackingEnabled; outOfRangeDataStrategyComboBox.currentIndex = outOfRangeDataStrategyComboBox.model.indexOf(settings.outOfRangeDataStrategy); initializeButtonState(); @@ -1014,6 +1082,8 @@ Flickable { }; UserActivityLogger.logAction("mocap_ui_open_dialog", data); + + isConfiguring = false; } function displayTrackerConfiguration(type) { @@ -1170,6 +1240,7 @@ Flickable { "shoulderWidth": shoulderWidth.realValue, "desktopMode": viveInDesktop.checked, "hmdDesktopTracking": hmdInDesktop.checked, + "eyeTrackingEnabled": eyeTracking.checked, "outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex] } @@ -1177,6 +1248,10 @@ Flickable { } function sendConfigurationSettings() { + if (isConfiguring) { + // Ignore control value changes during dialog initialization. + return; + } var settings = composeConfigurationSettings(); InputConfiguration.setConfigurationSettings(settings, openVrConfiguration.pluginName); updateCalibrationButton(); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index a2312b3247..a47d7218e2 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -279,6 +279,10 @@ void ViveControllerManager::setConfigurationSettings(const QJsonObject configura _hmdDesktopTracking = configurationSettings["hmdDesktopTracking"].toBool(); } + if (configurationSettings.contains("eyeTrackingEnabled")) { + _eyeTrackingEnabled = configurationSettings["eyeTrackingEnabled"].toBool(); + } + _inputDevice->configureCalibrationSettings(configurationSettings); saveSettings(); } @@ -289,6 +293,7 @@ QJsonObject ViveControllerManager::configurationSettings() { QJsonObject configurationSettings = _inputDevice->configurationSettings(); configurationSettings["desktopMode"] = _desktopMode; configurationSettings["hmdDesktopTracking"] = _hmdDesktopTracking; + configurationSettings["eyeTrackingEnabled"] = _eyeTrackingEnabled; return configurationSettings; } @@ -801,7 +806,7 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu _registeredWithInputMapper = true; } - if (_viveProEye) { + if (_viveProEye && _eyeTrackingEnabled) { updateEyeTracker(deltaTime, inputCalibrationData); } @@ -821,6 +826,9 @@ void ViveControllerManager::loadSettings() { _inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble(); _inputDevice->_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(settings.value("outOfRangeDataStrategy", QVariant(DEFAULT_OUT_OF_RANGE_STRATEGY)).toString()); } + + const bool DEFAULT_EYE_TRACKING_ENABLED = false; + _eyeTrackingEnabled = settings.value("eyeTrackingEnabled", QVariant(DEFAULT_EYE_TRACKING_ENABLED)).toBool(); } settings.endGroup(); } @@ -835,6 +843,8 @@ void ViveControllerManager::saveSettings() const { settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth); settings.setValue(QString("outOfRangeDataStrategy"), outOfRangeDataStrategyToString(_inputDevice->_outOfRangeDataStrategy)); } + + settings.setValue(QString("eyeTrackingEnabled"), _eyeTrackingEnabled); } settings.endGroup(); } diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 714be87842..f2eaa3fbff 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -253,6 +253,7 @@ private: std::shared_ptr _inputDevice { std::make_shared(_system) }; bool _viveProEye { false }; + bool _eyeTrackingEnabled { false }; std::shared_ptr _viveProEyeReadThread; EyeDataBuffer _prevEyeData;