diff --git a/src/openvr/ivrinput.cpp b/src/openvr/ivrinput.cpp index 9030dc4..4e1994c 100644 --- a/src/openvr/ivrinput.cpp +++ b/src/openvr/ivrinput.cpp @@ -128,6 +128,8 @@ SteamIVRInput::SteamIVRInput() m_resetOffsets( action_keys::resetOffsets ), m_snapTurnLeft( action_keys::snapTurnLeft ), m_snapTurnRight( action_keys::snapTurnRight ), + m_smoothTurnLeft( action_keys::smoothTurnLeft ), + m_smoothTurnRight( action_keys::smoothTurnRight ), m_xAxisLockToggle( action_keys::xAxisLockToggle ), m_yAxisLockToggle( action_keys::yAxisLockToggle ), m_zAxisLockToggle( action_keys::zAxisLockToggle ), @@ -275,6 +277,16 @@ bool SteamIVRInput::snapTurnRight() return isDigitalActionActivatedOnce( m_snapTurnRight ); } +bool SteamIVRInput::smoothTurnLeft() +{ + return isDigitalActionActivatedConstant( m_smoothTurnLeft ); +} + +bool SteamIVRInput::smoothTurnRight() +{ + return isDigitalActionActivatedConstant( m_smoothTurnRight ); +} + bool SteamIVRInput::xAxisLockToggle() { return isDigitalActionActivatedOnce( m_xAxisLockToggle ); diff --git a/src/openvr/ivrinput.h b/src/openvr/ivrinput.h index f0e6022..2838be1 100644 --- a/src/openvr/ivrinput.h +++ b/src/openvr/ivrinput.h @@ -43,6 +43,8 @@ namespace action_keys constexpr auto heightToggle = "/actions/motion/in/HeightToggle"; constexpr auto snapTurnLeft = "/actions/motion/in/SnapTurnLeft"; constexpr auto snapTurnRight = "/actions/motion/in/SnapTurnRight"; + constexpr auto smoothTurnLeft = "/actions/motion/in/SmoothTurnLeft"; + constexpr auto smoothTurnRight = "/actions/motion/in/SmoothTurnRight"; constexpr auto xAxisLockToggle = "/actions/misc/in/XAxisLockToggle"; constexpr auto yAxisLockToggle = "/actions/misc/in/YAxisLockToggle"; @@ -135,6 +137,8 @@ public: bool resetOffsets(); bool snapTurnLeft(); bool snapTurnRight(); + bool smoothTurnLeft(); + bool smoothTurnRight(); bool xAxisLockToggle(); bool yAxisLockToggle(); bool zAxisLockToggle(); @@ -201,6 +205,8 @@ private: DigitalAction m_resetOffsets; DigitalAction m_snapTurnLeft; DigitalAction m_snapTurnRight; + DigitalAction m_smoothTurnLeft; + DigitalAction m_smoothTurnRight; DigitalAction m_xAxisLockToggle; DigitalAction m_yAxisLockToggle; DigitalAction m_zAxisLockToggle; diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index c1baaa8..219d02a 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -579,6 +579,8 @@ void OverlayController::processMotionBindings() m_moveCenterTabController.resetOffsets( m_actions.resetOffsets() ); m_moveCenterTabController.snapTurnLeft( m_actions.snapTurnLeft() ); m_moveCenterTabController.snapTurnRight( m_actions.snapTurnRight() ); + m_moveCenterTabController.smoothTurnLeft( m_actions.smoothTurnLeft() ); + m_moveCenterTabController.smoothTurnRight( m_actions.smoothTurnRight() ); m_moveCenterTabController.xAxisLockToggle( m_actions.xAxisLockToggle() ); m_moveCenterTabController.yAxisLockToggle( m_actions.yAxisLockToggle() ); m_moveCenterTabController.zAxisLockToggle( m_actions.zAxisLockToggle() ); diff --git a/src/package_files/action_manifest.json b/src/package_files/action_manifest.json index 25d7a68..7a4798f 100644 --- a/src/package_files/action_manifest.json +++ b/src/package_files/action_manifest.json @@ -130,6 +130,16 @@ "requirement": "optional", "type": "boolean" }, + { + "name": "/actions/motion/in/SmoothTurnLeft", + "requirement": "optional", + "type": "boolean" + }, + { + "name": "/actions/motion/in/SmoothTurnRight", + "requirement": "optional", + "type": "boolean" + }, { "name": "/actions/misc/in/XAxisLockToggle", @@ -229,6 +239,8 @@ "/actions/motion/in/HeightToggle" : "Height Toggle", "/actions/motion/in/SnapTurnLeft" : "Snap-Turn Left", "/actions/motion/in/SnapTurnRight" : "Snap-Turn Right", + "/actions/motion/in/SmoothTurnLeft" : "Smooth-Turn Left", + "/actions/motion/in/SmoothTurnRight" : "Smooth-Turn Right", "/actions/misc/in/XAxisLockToggle" : "X-Axis Lock Toggle", "/actions/misc/in/YAxisLockToggle" : "Y-Axis Lock Toggle", diff --git a/src/res/qml/SettingsPage.qml b/src/res/qml/SettingsPage.qml index 5575212..37bceed 100644 --- a/src/res/qml/SettingsPage.qml +++ b/src/res/qml/SettingsPage.qml @@ -42,6 +42,14 @@ MyStackViewPage { } } + MyToggleButton { + id: universeCenteredRotationToggle + text: "Universe-Centered Rotation (Disables HMD Centering)" + onCheckedChanged: { + MoveCenterTabController.setUniverseCenteredRotation(checked, true) + } + } + Item { Layout.fillHeight: true } @@ -51,6 +59,7 @@ MyStackViewPage { forceReviveToggle.checked = SettingsTabController.forceRevivePage allowExternalEditsToggle.checked = MoveCenterTabController.allowExternalEdits oldStyleMotionToggle.checked = MoveCenterTabController.oldStyleMotion + universeCenteredRotationToggle.checked = MoveCenterTabController.universeCenteredRotation } Connections { @@ -71,6 +80,9 @@ MyStackViewPage { onOldStyleMotionChanged: { oldStyleMotionToggle.checked = MoveCenterTabController.oldStyleMotion } + onUniverseCenteredRotationChanged: { + universeCenteredRotationToggle.checked = MoveCenterTabController.universeCenteredRotation + } } } } diff --git a/src/res/qml/motion_page/snap_turn/SnapTurnGroupBox.qml b/src/res/qml/motion_page/snap_turn/SnapTurnGroupBox.qml index 5b57ba7..4e25dde 100644 --- a/src/res/qml/motion_page/snap_turn/SnapTurnGroupBox.qml +++ b/src/res/qml/motion_page/snap_turn/SnapTurnGroupBox.qml @@ -24,7 +24,7 @@ GroupBox { id: snapTurnAngleText text: "45°" keyBoardUID: 154 - Layout.preferredWidth: 150 + Layout.preferredWidth: 100 Layout.leftMargin: 10 horizontalAlignment: Text.AlignHCenter function onInputEvent(input) { @@ -39,26 +39,6 @@ GroupBox { } } - Item { - Layout.fillWidth: true - } - - MyPushButton { - id: snapTurnButton15 - Layout.preferredWidth: 90 - text:"15°" - onClicked: { - MoveCenterTabController.snapTurnAngle = 1500 - } - } - MyPushButton { - id: snapTurnButton30 - Layout.preferredWidth: 90 - text:"30°" - onClicked: { - MoveCenterTabController.snapTurnAngle = 3000 - } - } MyPushButton { id: snapTurnButton45 Layout.preferredWidth: 90 @@ -83,11 +63,41 @@ GroupBox { MoveCenterTabController.snapTurnAngle = 18000 } } + + Item { + Layout.fillWidth: true + } + + MyText { + text: "Smooth Turn Rate:" + horizontalAlignment: Text.AlignRight + Layout.rightMargin: 2 + } + + MyTextField { + id: smoothTurnRateText + text: "100%" + keyBoardUID: 155 + Layout.preferredWidth: 130 + Layout.leftMargin: 10 + horizontalAlignment: Text.AlignHCenter + function onInputEvent(input) { + var val = parseInt(input) + if (!isNaN(val)) { + MoveCenterTabController.smoothTurnRate = val + text = MoveCenterTabController.smoothTurnRate + "%" + } else { + text = MoveCenterTabController.smoothTurnRate + "%" + } + } + } + } } Component.onCompleted: { snapTurnAngleText.text = ( Math.round( MoveCenterTabController.snapTurnAngle / 100 ) ) + "°" + smoothTurnRateText.text = MoveCenterTabController.smoothTurnRate + "%" } Connections { @@ -96,5 +106,8 @@ GroupBox { onSnapTurnAngleChanged: { snapTurnAngleText.text = ( Math.round( MoveCenterTabController.snapTurnAngle / 100 ) ) + "°" } + onSmoothTurnRateChanged: { + smoothTurnRateText.text = MoveCenterTabController.smoothTurnRate + "%" + } } } diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index d17687e..b0e4f93 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -83,6 +83,11 @@ void MoveCenterTabController::initStage1() { m_snapTurnAngle = value.toInt(); } + value = settings->value( "smoothTurnRate", m_smoothTurnRate ); + if ( value.isValid() && !value.isNull() ) + { + m_smoothTurnRate = value.toInt(); + } value = settings->value( "heightToggleOffset", m_heightToggleOffset ); if ( value.isValid() && !value.isNull() ) { @@ -133,6 +138,12 @@ void MoveCenterTabController::initStage1() { m_oldStyleMotion = value.toBool(); } + value = settings->value( "universeCenteredRotation", + m_universeCenteredRotation ); + if ( value.isValid() && !value.isNull() ) + { + m_universeCenteredRotation = value.toBool(); + } settings->endGroup(); m_lastDragUpdateTimePoint = std::chrono::steady_clock::now(); m_lastGravityUpdateTimePoint = std::chrono::steady_clock::now(); @@ -199,6 +210,10 @@ void MoveCenterTabController::outputLogSettings() { LOG( INFO ) << "LOADED SETTINGS: Old-Style Motion Enabled"; } + if ( m_universeCenteredRotation ) + { + LOG( INFO ) << "LOADED SETTINGS: Universe-Centered Rotation Enabled"; + } } void MoveCenterTabController::outputLogPoses() @@ -381,6 +396,16 @@ void MoveCenterTabController::setRotation( int value, bool notify ) { if ( m_rotation != value ) { + if ( m_universeCenteredRotation ) + { + m_rotation = value; + if ( notify ) + { + emit rotationChanged( m_rotation ); + } + return; + } + double angle = ( value - m_rotation ) * k_centidegreesToRadians; // Get hmd pose matrix. @@ -476,6 +501,28 @@ void MoveCenterTabController::setSnapTurnAngle( int value, bool notify ) } } +int MoveCenterTabController::smoothTurnRate() const +{ + return m_smoothTurnRate; +} + +void MoveCenterTabController::setSmoothTurnRate( int value, bool notify ) +{ + if ( m_smoothTurnRate != value ) + { + m_smoothTurnRate = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "smoothTurnRate", m_smoothTurnRate ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit smoothTurnRateChanged( m_smoothTurnRate ); + } + } +} + bool MoveCenterTabController::adjustChaperone() const { return m_adjustChaperone; @@ -904,6 +951,29 @@ void MoveCenterTabController::setOldStyleMotion( bool value, bool notify ) << m_oldStyleMotion; } +bool MoveCenterTabController::universeCenteredRotation() const +{ + return m_universeCenteredRotation; +} + +void MoveCenterTabController::setUniverseCenteredRotation( bool value, + bool notify ) +{ + m_universeCenteredRotation = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "universeCenteredRotation", + m_universeCenteredRotation ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit universeCenteredRotationChanged( m_universeCenteredRotation ); + } + LOG( INFO ) << "CHANGED SETTINGS: Universe-Centered Rotation Set: " + << m_universeCenteredRotation; +} + void MoveCenterTabController::modOffsetX( float value, bool notify ) { if ( !m_lockXToggle ) @@ -1780,8 +1850,6 @@ void MoveCenterTabController::snapTurnLeft( bool snapTurnLeftJustPressed ) return; } - // TODO add interface to configure snap angle. - // temporarily hard coded to 45 degrees int newRotationAngleDeg = m_rotation - m_snapTurnAngle; // Keep angle within -18000 ~ 18000 centidegrees if ( newRotationAngleDeg > 18000 ) @@ -1803,8 +1871,6 @@ void MoveCenterTabController::snapTurnRight( bool snapTurnRightJustPressed ) return; } - // TODO add interface to configure snap angle. - // temporarily hard coded to 45 degrees int newRotationAngleDeg = m_rotation + m_snapTurnAngle; // Keep angle within -18000 ~ 18000 centidegrees if ( newRotationAngleDeg > 18000 ) @@ -1819,6 +1885,54 @@ void MoveCenterTabController::snapTurnRight( bool snapTurnRightJustPressed ) setRotation( newRotationAngleDeg ); } +void MoveCenterTabController::smoothTurnLeft( bool smoothTurnLeftActive ) +{ + if ( !smoothTurnLeftActive ) + { + return; + } + + // Activates every tick. m_smoothTurnRate effectively becomes a percentage + // of a degree per tick. A setting of 100 would equal 90 degrees/sec or 15 + // RPM with a framerate of 90fps + int newRotationAngleDeg = m_rotation - m_smoothTurnRate; + // Keep angle within -18000 ~ 18000 centidegrees + if ( newRotationAngleDeg > 18000 ) + { + newRotationAngleDeg -= 36000; + } + else if ( newRotationAngleDeg < -18000 ) + { + newRotationAngleDeg += 36000; + } + + setRotation( newRotationAngleDeg ); +} + +void MoveCenterTabController::smoothTurnRight( bool smoothTurnRightActive ) +{ + if ( !smoothTurnRightActive ) + { + return; + } + + // Activates every tick. m_smoothTurnRate effectively becomes a percentage + // of a degree per tick. A setting of 100 would equal 90 degrees/sec or 15 + // RPM with a framerate of 90fps + int newRotationAngleDeg = m_rotation + m_smoothTurnRate; + // Keep angle within -18000 ~ 18000 centidegrees + if ( newRotationAngleDeg > 18000 ) + { + newRotationAngleDeg -= 36000; + } + else if ( newRotationAngleDeg < -18000 ) + { + newRotationAngleDeg += 36000; + } + + setRotation( newRotationAngleDeg ); +} + void MoveCenterTabController::xAxisLockToggle( bool xAxisLockToggleJustPressed ) { if ( !xAxisLockToggleJustPressed ) diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 68ceb96..71eb4b1 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -36,6 +36,8 @@ class MoveCenterTabController : public QObject tempRotationChanged ) Q_PROPERTY( int snapTurnAngle READ snapTurnAngle WRITE setSnapTurnAngle NOTIFY snapTurnAngleChanged ) + Q_PROPERTY( int smoothTurnRate READ smoothTurnRate WRITE setSmoothTurnRate + NOTIFY smoothTurnRateChanged ) Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged ) Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE @@ -75,6 +77,9 @@ class MoveCenterTabController : public QObject setAllowExternalEdits NOTIFY allowExternalEditsChanged ) Q_PROPERTY( bool oldStyleMotion READ oldStyleMotion WRITE setOldStyleMotion NOTIFY oldStyleMotionChanged ) + Q_PROPERTY( + bool universeCenteredRotation READ universeCenteredRotation WRITE + setUniverseCenteredRotation NOTIFY universeCenteredRotationChanged ) private: OverlayController* parent; @@ -91,6 +96,7 @@ private: int m_oldRotation = 0; int m_tempRotation = 0; int m_snapTurnAngle = 4500; + int m_smoothTurnRate = 100; bool m_adjustChaperone = true; bool m_moveShortcutRightPressed = false; bool m_moveShortcutLeftPressed = false; @@ -151,6 +157,7 @@ private: bool m_showLogMatricesButton = false; bool m_allowExternalEdits = false; bool m_oldStyleMotion = false; + bool m_universeCenteredRotation = false; unsigned settingsUpdateCounter = 0; int m_hmdRotationStatsUpdateCounter = 0; unsigned m_dragComfortFrameSkipCounter = 0; @@ -190,6 +197,7 @@ public: int rotation() const; int tempRotation() const; int snapTurnAngle() const; + int smoothTurnRate() const; bool adjustChaperone() const; bool moveShortcutRight() const; bool moveShortcutLeft() const; @@ -209,6 +217,7 @@ public: bool showLogMatricesButton() const; bool allowExternalEdits() const; bool oldStyleMotion() const; + bool universeCenteredRotation() const; double getHmdYawTotal(); void resetHmdYawTotal(); void incomingSeatedReset(); @@ -230,6 +239,8 @@ public: void resetOffsets( bool resetOffsetsJustPressed ); void snapTurnLeft( bool snapTurnLeftJustPressed ); void snapTurnRight( bool snapTurnRightJustPressed ); + void smoothTurnLeft( bool smoothTurnLeftActive ); + void smoothTurnRight( bool smoothTurnRightActive ); void xAxisLockToggle( bool xAxisLockToggleJustPressed ); void yAxisLockToggle( bool yAxisLockToggleJustPressed ); void zAxisLockToggle( bool zAxisLockToggleJustPressed ); @@ -245,6 +256,7 @@ public slots: void setRotation( int value, bool notify = true ); void setTempRotation( int value, bool notify = true ); void setSnapTurnAngle( int value, bool notify = true ); + void setSmoothTurnRate( int value, bool notify = true ); void setAdjustChaperone( bool value, bool notify = true ); void setMoveShortcutRight( bool value, bool notify = true ); @@ -270,6 +282,7 @@ public slots: void setShowLogMatricesButton( bool value, bool notify = true ); void setAllowExternalEdits( bool value, bool notify = true ); void setOldStyleMotion( bool value, bool notify = true ); + void setUniverseCenteredRotation( bool value, bool notify = true ); void shutdown(); void reset(); @@ -285,6 +298,7 @@ signals: void rotationChanged( int value ); void tempRotationChanged( int value ); void snapTurnAngleChanged( int value ); + void smoothTurnRateChanged( int value ); void adjustChaperoneChanged( bool value ); void moveShortcutRightChanged( bool value ); void moveShortcutLeftChanged( bool value ); @@ -304,6 +318,7 @@ signals: void showLogMatricesButtonChanged( bool value ); void allowExternalEditsChanged( bool value ); void oldStyleMotionChanged( bool value ); + void universeCenteredRotationChanged( bool value ); }; } // namespace advsettings