diff --git a/Readme.md b/Readme.md index 2f89888..3f61fa9 100644 --- a/Readme.md +++ b/Readme.md @@ -125,7 +125,7 @@ Detailed instructions are available [here](docs/building_for_linux.md). ### Overall Feature Overview Guides -- [Kung's 3.0 New Feature Guide (video/youtube)[https://youtu.be/2ZHdjOfnqOU)] +- [Kung's 3.0 New Feature Guide (video/youtube)[https://youtu.be/2ZHdjOfnqOU] ### SteamVR Input System (keybinds for app) @@ -472,7 +472,7 @@ Allows users to temporarily move and rotate the center of the playspace. This al - **Brightness**: Same as regular. - **Opacity**: Adjusts opacity of color overlay. - **Toggle On/Off**: Turns on/off Color Adjustment Overlay. -- ****: Adjusts the overlay to adjust the color. +- **Color (Red/Green/Blue)**: Adjusts the overlay to adjust the color. ## - Utilities Page @@ -546,6 +546,14 @@ Full build instructions can be found [here](docs/building_for_linux.md). - **Cause:** WMR boundary off, or set up for standing only. - **Solution:** Please set-up WMR for all experiences, and then if you don't want WMR boundary you can toggle off the boundary **after** SteamVR/OpenVR has been started. +- **Issue:** While using Trackers (additional devices besides controllers) Keybinds don't work. + - **Cause:** Trackers can Assume controller roles, and prevent your controllers from working properly. + - **Solution:** Assign Tracker Roles Via SteamVR Widget to anything besides `held-in-hand` + +- **Issue:** Custom Key Presses Not Saving In file. + - **Cause:** Key Presses Modified while Advanced Settings is running. + - **Solution:** Only modify the settings file while VR/Advanced Settings is **not** running. + # License This software is released under GPL 3.0, and other third-party Licenses diff --git a/docs/keyboard_input_guide.md b/docs/keyboard_input_guide.md index 1706e37..105f09b 100644 --- a/docs/keyboard_input_guide.md +++ b/docs/keyboard_input_guide.md @@ -118,6 +118,10 @@ ### Case Sensative - basic characters are all LOWER case, while keys such as ENTER are all UPPER case. +### Custom Keys Not Saving. +- We only load keybinds from file on start-up, and save based on what is in memory (not in file) + - **ONLY** edit the settings file while Advanced Settings is **not** running. + ### Focus Issues - we deliver the keypress to the OS, depending on your set-up and program you may have to have the window "in-focus" @@ -126,4 +130,4 @@ - alt + tab, alt + F4 = `*TAB *F4` ## Parser Spec -(Parser Spec)[https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/blob/master/docs/specs/Keyboard_Manager-Parser_Spec.md] +[Parser Spec](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/blob/master/docs/specs/Keyboard_Manager-Parser_Spec.md) diff --git a/src/res/img/rotation/autoturn.png b/src/res/img/rotation/autoturn.png new file mode 100644 index 0000000..37bd883 Binary files /dev/null and b/src/res/img/rotation/autoturn.png differ diff --git a/src/res/img/rotation/noautoturn.png b/src/res/img/rotation/noautoturn.png new file mode 100644 index 0000000..b3a14ef Binary files /dev/null and b/src/res/img/rotation/noautoturn.png differ diff --git a/src/res/img/rotation/noautoturn.svg b/src/res/img/rotation/noautoturn.svg new file mode 100644 index 0000000..755074c --- /dev/null +++ b/src/res/img/rotation/noautoturn.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + A + + + diff --git a/src/res/qml/rotation_page/redirected/AutoTurnGroupBox.qml b/src/res/qml/rotation_page/redirected/AutoTurnGroupBox.qml index 3c0a3e4..81ef06e 100644 --- a/src/res/qml/rotation_page/redirected/AutoTurnGroupBox.qml +++ b/src/res/qml/rotation_page/redirected/AutoTurnGroupBox.qml @@ -35,10 +35,18 @@ GroupBox { MyToggleButton { id: autoTurn text: "Toggle On/Off" - Layout.preferredWidth: 300 + Layout.preferredWidth: 250 onCheckedChanged: { RotationTabController.setAutoTurnEnabled(this.checked, true); } } + MyToggleButton { + id: autoTurnNotificationToggle + text: "HMD Icon" + Layout.preferredWidth: 175 + onCheckedChanged: { + RotationTabController.setAutoTurnShowNotification(this.checked, true) + } + } MyText { text: "Activation Dist:" @@ -160,7 +168,7 @@ GroupBox { } MyText { - text: "Turn Speed (deg/sec):" + text: "Turn Speed(deg/sec):" horizontalAlignment: Text.AlignRight Layout.rightMargin: 10 } @@ -174,7 +182,7 @@ GroupBox { Layout.fillWidth: true onPositionChanged: { var val = this.value - speedValueText.text = val.toFixed() + speedValueText.text = val.toFixed()+ "°" } onValueChanged: { @@ -184,7 +192,7 @@ GroupBox { MyTextField { id: speedValueText - text: "90" + text: "90°" keyBoardUID: 1003 Layout.preferredWidth: 100 Layout.leftMargin: 10 @@ -203,29 +211,30 @@ GroupBox { speedSlider.value = val; } //converts the centidegrees to degrees - text = (((RotationTabController.autoTurnSpeed)/100).toFixed()); + text = (((RotationTabController.autoTurnSpeed)/100).toFixed()) + "°"; } } } RowLayout{ + MyText{ text: "Detangle Angle: " horizontalAlignment: Text.AlignLeft - Layout.preferredWidth: 250 + Layout.preferredWidth: 200 Layout.rightMargin: 5 } MyText{ - text:"Min Rotations(deg):" + text:"Min Rotations:" Layout.rightMargin: 5 } MyTextField { id: detangleAngleStartText - text: "360" + text: "360°" keyBoardUID: 1005 Layout.preferredWidth: 100 Layout.leftMargin: 5 @@ -239,6 +248,7 @@ GroupBox { val = 3600 } RotationTabController.setMinCordTangle((val*(Math.PI/180)), true); + text = (Math.round(val).toFixed())+ "°"; } } } @@ -247,7 +257,7 @@ GroupBox { } MyText{ - text: "Max Wall Angle(deg): " + text: "Max Wall Angle: " horizontalAlignment: Text.AlignRight Layout.rightMargin: 10 Layout.fillWidth: true @@ -255,7 +265,7 @@ GroupBox { } MyTextField { id: detangleAngleAssistText - text: "10" + text: "10°" keyBoardUID: 1006 Layout.preferredWidth: 100 Layout.leftMargin: 10 @@ -269,6 +279,7 @@ GroupBox { val = 3600 } RotationTabController.setCordDetangleAngle((val*(Math.PI/180)), true); + text = (Math.round(val).toFixed())+ "°"; } } } @@ -285,6 +296,7 @@ GroupBox { deactivationSlider.value = RotationTabController.autoTurnDeactivationDistance.toFixed(2) cornerAngle.checked = RotationTabController.autoTurnUseCornerAngle speedSlider.value = (RotationTabController.autoTurnSpeed/100).toFixed() + autoTurnNotificationToggle.checked = RotationTabController.autoTurnShowNotification if(RotationTabController.autoTurnMode === 1){ autoTurnModeToggle.checked = true; @@ -293,8 +305,8 @@ GroupBox { autoTurnModeToggle.checked = false; } - detangleAngleStartText.text = parseInt(RotationTabController.minCordTangle*(180/Math.PI)) - detangleAngleAssistText.text = parseInt(RotationTabController.cordDetangleAngle*(180/Math.PI)) + detangleAngleStartText.text = parseInt(RotationTabController.minCordTangle*(180/Math.PI))+ "°" + detangleAngleAssistText.text = parseInt(RotationTabController.cordDetangleAngle*(180/Math.PI))+ "°" } Connections { @@ -327,10 +339,13 @@ GroupBox { } } onMinCordTangleChanged:{ - detangleAngleStartText.text = parseInt(RotationTabController.minCordTangle*(180/Math.PI)) + detangleAngleStartText.text = parseInt(RotationTabController.minCordTangle*(180/Math.PI))+ "°" } onCordDetangleAngleChanged:{ - detangleAngleAssistText.text = parseInt(RotationTabController.cordDetangleAngle*(180/Math.PI)) + detangleAngleAssistText.text = parseInt(RotationTabController.cordDetangleAngle*(180/Math.PI))+ "°" + } + onAutoTurnShowNotificationChanged:{ + autoTurnNotificationToggle.checked = RotationTabController.autoTurnShowNotification } } } diff --git a/src/settings/internal/settings_controller.h b/src/settings/internal/settings_controller.h index 73ce32a..5d2a0c7 100644 --- a/src/settings/internal/settings_controller.h +++ b/src/settings/internal/settings_controller.h @@ -393,6 +393,10 @@ private: SettingCategory::Rotation, QtInfo{ "autoturnVestibularMotionEnabled" }, false }, + BoolSettingValue{ BoolSetting::ROTATION_autoturnShowNotification, + SettingCategory::Rotation, + QtInfo{ "autoturnShowNotification" }, + true } }; constexpr static auto doubleSettingSize diff --git a/src/settings/settings.h b/src/settings/settings.h index 38df851..b61f6c2 100644 --- a/src/settings/settings.h +++ b/src/settings/settings.h @@ -55,8 +55,9 @@ enum class BoolSetting ROTATION_autoturnEnabled, ROTATION_autoturnUseCornerAngle, ROTATION_autoturnVestibularMotionEnabled, + ROTATION_autoturnShowNotification, // LAST_ENUMERATOR must always be set to the last value - LAST_ENUMERATOR = ROTATION_autoturnVestibularMotionEnabled, + LAST_ENUMERATOR = ROTATION_autoturnShowNotification, }; enum class DoubleSetting diff --git a/src/tabcontrollers/AudioTabController.cpp b/src/tabcontrollers/AudioTabController.cpp index f979379..2344b86 100644 --- a/src/tabcontrollers/AudioTabController.cpp +++ b/src/tabcontrollers/AudioTabController.cpp @@ -63,18 +63,6 @@ void AudioTabController::initStage1() eventLoopTick(); } -std::optional verifyIconFilePath( std::string filename ) -{ - const auto notifIconPath = paths::binaryDirectoryFindFile( filename ); - if ( !notifIconPath.has_value() ) - { - LOG( ERROR ) << "Could not find push to talk icon \"" << filename - << "\""; - } - - return notifIconPath; -} - void AudioTabController::initStage2() { const auto pushToTalkOverlayKey @@ -102,9 +90,9 @@ void AudioTabController::initStage2() = "/res/img/audio/microphone/ptm_notification.png"; const auto pushToTalkIconFilePath - = verifyIconFilePath( pushToTalkIconFilepath ); + = paths::verifyIconFilePath( pushToTalkIconFilepath ); const auto pushToMuteIconFilePath - = verifyIconFilePath( pushToMuteIconFilepath ); + = paths::verifyIconFilePath( pushToMuteIconFilepath ); if ( !pushToTalkIconFilePath.has_value() || !pushToMuteIconFilePath.has_value() ) diff --git a/src/tabcontrollers/RotationTabController.cpp b/src/tabcontrollers/RotationTabController.cpp index 097a1a4..a810f50 100644 --- a/src/tabcontrollers/RotationTabController.cpp +++ b/src/tabcontrollers/RotationTabController.cpp @@ -17,6 +17,60 @@ void RotationTabController::initStage1() void RotationTabController::initStage2( OverlayController* var_parent ) { + const auto autoturnOverlayKey + = std::string( application_strings::applicationKey ) + + ".autoturnnotification"; + + const auto overlayError + = vr::VROverlay()->CreateOverlay( autoturnOverlayKey.c_str(), + autoturnOverlayKey.c_str(), + &m_autoturnValues.overlayHandle ); + if ( overlayError != vr::VROverlayError_None ) + { + LOG( ERROR ) << "Could not create autoturn notification overlay: " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( + overlayError ); + + emit defaultProfileDisplay(); + + return; + } + + constexpr auto autoturnIconFilepath = "/res/img/rotation/autoturn.png"; + constexpr auto noautoturnIconFilepath = "/res/img/rotation/noautoturn.png"; + + const auto autoturnIconFilePath + = paths::verifyIconFilePath( autoturnIconFilepath ); + const auto noautoturnIconFilePath + = paths::verifyIconFilePath( noautoturnIconFilepath ); + + if ( !autoturnIconFilePath.has_value() + || !noautoturnIconFilePath.has_value() ) + { + emit defaultProfileDisplay(); + return; + } + + m_autoturnValues.autoturnPath = *autoturnIconFilePath; + m_autoturnValues.noautoturnPath = *noautoturnIconFilePath; + + auto pushToPath = m_autoturnValues.autoturnPath.c_str(); + + vr::VROverlay()->SetOverlayFromFile( m_autoturnValues.overlayHandle, + pushToPath ); + vr::VROverlay()->SetOverlayWidthInMeters( m_autoturnValues.overlayHandle, + 0.02f ); + vr::HmdMatrix34_t notificationTransform + = { { { 1.0f, 0.0f, 0.0f, 0.12f }, + { 0.0f, 1.0f, 0.0f, 0.08f }, + { 0.0f, 0.0f, 1.0f, -0.3f } } }; + vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative( + m_autoturnValues.overlayHandle, + vr::k_unTrackedDeviceIndex_Hmd, + ¬ificationTransform ); + + emit defaultProfileDisplay(); + this->parent = var_parent; } @@ -65,6 +119,29 @@ void RotationTabController::eventLoopTick( m_autoTurnChaperoneDistancesLast = std::move( chaperoneDistances ); } } + if ( m_autoTurnNotificationTimestamp ) + { + auto count = std::chrono::duration_cast( + std::chrono::steady_clock::now() + - *m_autoTurnNotificationTimestamp ) + .count(); + if ( count > 1500 ) + { + m_autoTurnNotificationTimestamp.reset(); + if ( getNotificationOverlayHandle() + != vr::k_ulOverlayHandleInvalid ) + { + vr::VROverlay()->HideOverlay( getNotificationOverlayHandle() ); + } + } + else + { + float pct + = std::min( 1.0f, 3.0f - static_cast( count ) / 500.0f ); + vr::VROverlay()->SetOverlayAlpha( getNotificationOverlayHandle(), + pct ); + } + } } void RotationTabController::doVestibularMotion( @@ -453,6 +530,12 @@ bool RotationTabController::autoTurnUseCornerAngle() const settings::BoolSetting::ROTATION_autoturnUseCornerAngle ); } +bool RotationTabController::autoTurnShowNotification() const +{ + return settings::getSetting( + settings::BoolSetting::ROTATION_autoturnShowNotification ); +} + double RotationTabController::cordDetangleAngle() const { return settings::getSetting( @@ -505,6 +588,39 @@ void RotationTabController::setAutoTurnEnabled( bool value, bool notify ) { emit autoTurnEnabledChanged( value ); } + + if ( !value ) + { + vr::VROverlay()->SetOverlayFromFile( + m_autoturnValues.overlayHandle, + m_autoturnValues.noautoturnPath.c_str() ); + } + else + { + vr::VROverlay()->SetOverlayFromFile( + m_autoturnValues.overlayHandle, + m_autoturnValues.autoturnPath.c_str() ); + } + + if ( autoTurnShowNotification() + && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid ) + { + vr::VROverlay()->SetOverlayAlpha( getNotificationOverlayHandle(), + 1.0f ); + vr::VROverlay()->ShowOverlay( getNotificationOverlayHandle() ); + m_autoTurnNotificationTimestamp.emplace( + std::chrono::steady_clock::now() ); + } +} +void RotationTabController::setAutoTurnShowNotification( bool value, + bool notify ) +{ + settings::setSetting( + settings::BoolSetting::ROTATION_autoturnShowNotification, value ); + if ( notify ) + { + emit autoTurnShowNotificationChanged( value ); + } } void RotationTabController::setAutoTurnActivationDistance( float value, bool notify ) diff --git a/src/tabcontrollers/RotationTabController.h b/src/tabcontrollers/RotationTabController.h index df6199a..ad6fa80 100644 --- a/src/tabcontrollers/RotationTabController.h +++ b/src/tabcontrollers/RotationTabController.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "../utils/FrameRateUtils.h" #include "../utils/ChaperoneUtils.h" #include "../settings/settings_object.h" @@ -82,10 +83,25 @@ class RotationTabController : public QObject Q_PROPERTY( double vestibularMotionRadius READ vestibularMotionRadius WRITE setVestibularMotionRadius NOTIFY vestibularMotionRadiusChanged ) + Q_PROPERTY( + bool autoTurnShowNotification READ autoTurnShowNotification WRITE + setAutoTurnShowNotification NOTIFY autoTurnShowNotificationChanged ) private: OverlayController* parent; + struct + { + vr::VROverlayHandle_t overlayHandle = vr::k_ulOverlayHandleInvalid; + std::string autoturnPath; + std::string noautoturnPath; + } m_autoturnValues; + + virtual vr::VROverlayHandle_t getNotificationOverlayHandle() + { + return m_autoturnValues.overlayHandle; + } + // Variables int m_autoTurnLinearSmoothTurnRemaining = 0; std::chrono::steady_clock::time_point m_autoTurnLastUpdate; @@ -95,6 +111,9 @@ private: double m_autoTurnRoundingError = 0.0; std::chrono::steady_clock::time_point::duration m_estimatedFrameRate; + std::optional + m_autoTurnNotificationTimestamp; + bool m_isHMDActive = false; void doAutoTurn( @@ -116,6 +135,7 @@ public: float autoTurnActivationDistance() const; float autoTurnDeactivationDistance() const; bool autoTurnUseCornerAngle() const; + bool autoTurnShowNotification() const; double cordDetangleAngle() const; double minCordTangle() const; int autoTurnSpeed() const; @@ -126,6 +146,7 @@ public: public slots: void setAutoTurnEnabled( bool value, bool notify = true ); + void setAutoTurnShowNotification( bool value, bool notify = true ); void setAutoTurnActivationDistance( float value, bool notify = true ); void setAutoTurnDeactivationDistance( float value, bool notify = true ); void setAutoTurnUseCornerAngle( bool value, bool notify = true ); @@ -138,7 +159,9 @@ public slots: signals: + void defaultProfileDisplay(); void autoTurnEnabledChanged( bool value ); + void autoTurnShowNotificationChanged( bool value ); void autoTurnActivationDistanceChanged( float value ); void autoTurnDeactivationDistanceChanged( float value ); void autoTurnUseCornerAngleChanged( bool value ); diff --git a/src/utils/paths.cpp b/src/utils/paths.cpp index d6761d0..9b07c26 100644 --- a/src/utils/paths.cpp +++ b/src/utils/paths.cpp @@ -57,4 +57,15 @@ optional settingsDirectory() return path.toStdString(); } +std::optional verifyIconFilePath( std::string filename ) +{ + const auto notifIconPath = paths::binaryDirectoryFindFile( filename ); + if ( !notifIconPath.has_value() ) + { + LOG( ERROR ) << "Could not find icon \"" << filename << "\""; + } + + return notifIconPath; +} + } // namespace paths diff --git a/src/utils/paths.h b/src/utils/paths.h index 819a67f..63e71c9 100644 --- a/src/utils/paths.h +++ b/src/utils/paths.h @@ -12,4 +12,6 @@ optional binaryDirectoryFindFile( string fileName ); optional settingsDirectory(); +std::optional verifyIconFilePath( std::string filename ); + } // namespace paths