diff --git a/src/res/qml/PlayspacePage.qml b/src/res/qml/PlayspacePage.qml index a109652..cf16fe8 100644 --- a/src/res/qml/PlayspacePage.qml +++ b/src/res/qml/PlayspacePage.qml @@ -47,11 +47,16 @@ MyStackViewPage { } GridLayout { - columns: 5 + columns: 6 MyText { text: "X-Axis (Left/Right):" - Layout.preferredWidth: 500 + Layout.preferredWidth: 340 + } + + MyText { + text: " " + Layout.preferredWidth: 40 } MyPushButton2 { @@ -59,7 +64,7 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "-" onClicked: { - MoveCenterTabController.modOffsetX(-0.5) + MoveCenterTabController.modOffsetX(-0.1) } } @@ -87,12 +92,11 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "+" onClicked: { - MoveCenterTabController.modOffsetX(0.5) + MoveCenterTabController.modOffsetX(0.1) } } MyToggleButton { - Layout.preferredWidth: 240 id: lockXToggle text: "Lock X" onCheckedChanged: { @@ -102,14 +106,22 @@ MyStackViewPage { MyText { text: "Y-Axis (Down/Up):" - Layout.preferredWidth: 380 + Layout.preferredWidth: 340 + } + + MyPushButton2 { + Layout.preferredWidth: 40 + text: "0" + onClicked: { + MoveCenterTabController.offsetY = 0 + } } MyPushButton2 { Layout.preferredWidth: 40 text: "-" onClicked: { - MoveCenterTabController.modOffsetY(-0.5) + MoveCenterTabController.modOffsetY(-0.1) } } @@ -136,13 +148,12 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "+" onClicked: { - MoveCenterTabController.modOffsetY(0.5) + MoveCenterTabController.modOffsetY(0.1) } } MyToggleButton { - Layout.preferredWidth: 240 id: lockYToggle text: "Lock Y" onCheckedChanged: { @@ -152,14 +163,19 @@ MyStackViewPage { MyText { text: "Z-Axis (Forth/Back):" - Layout.preferredWidth: 380 + Layout.preferredWidth: 340 + } + + MyText { + text: " " + Layout.preferredWidth: 40 } MyPushButton2 { Layout.preferredWidth: 40 text: "-" onClicked: { - MoveCenterTabController.modOffsetZ(-0.5) + MoveCenterTabController.modOffsetZ(-0.1) } } @@ -186,13 +202,12 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "+" onClicked: { - MoveCenterTabController.modOffsetZ(0.5) + MoveCenterTabController.modOffsetZ(0.1) } } MyToggleButton { - Layout.preferredWidth: 240 id: lockZToggle text: "Lock Z" onCheckedChanged: { @@ -216,6 +231,7 @@ MyStackViewPage { border.color: "#ffffff" radius: 8 } + ColumnLayout { anchors.fill: parent @@ -233,11 +249,11 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "-" onClicked: { - var val = MoveCenterTabController.rotation - 45 + var val = MoveCenterTabController.tempRotation - 45 if (val < -180) { val = val + 360; } - MoveCenterTabController.rotation = val + MoveCenterTabController.tempRotation = val } } @@ -250,11 +266,11 @@ MyStackViewPage { Layout.fillWidth: true onPositionChanged: { var val = this.from + ( this.position * (this.to - this.from)) - playspaceRotationText.text = Math.round(val) + "°" + MoveCenterTabController.tempRotation = Math.round(val) } onValueChanged: { - MoveCenterTabController.rotation = playspaceRotationSlider.value - playspaceRotationText.text = Math.round(playspaceRotationSlider.value) + "°" + MoveCenterTabController.tempRotation = Math.round(playspaceRotationSlider.value) + //playspaceRotationText.text = Math.round(playspaceRotationSlider.value) + "°" } } @@ -263,11 +279,11 @@ MyStackViewPage { Layout.preferredWidth: 40 text: "+" onClicked: { - var val = MoveCenterTabController.rotation + 45 + var val = MoveCenterTabController.tempRotation + 45 if (val > 180) { val = val -360; } - MoveCenterTabController.rotation = val + MoveCenterTabController.tempRotation = val } } @@ -282,10 +298,10 @@ MyStackViewPage { var val = parseInt(input) if (!isNaN(val)) { val = val % 180 - MoveCenterTabController.rotation = val - text = MoveCenterTabController.rotation + "°" + MoveCenterTabController.tempRotation = val + text = MoveCenterTabController.tempRotation + "°" } else { - text = MoveCenterTabController.rotation + "°" + text = MoveCenterTabController.tempRotation + "°" } } } @@ -294,11 +310,23 @@ MyStackViewPage { Layout.preferredWidth: 145 text:"Apply" onClicked: { - MoveCenterTabController.applyRotation() + MoveCenterTabController.rotation = MoveCenterTabController.tempRotation } + } + } + MyToggleButton { + id: playspaceRotateHandToggle + text: "Virtual Move Shortcut Controls Rotation !ALPHA TEST!" + onCheckedChanged: { + MoveCenterTabController.rotateHand = this.checked } } + + MyText { + text: "Note: Stats page / TurnSignal will ignore turning during virtual move rotation." + font.pointSize: 15.0 + } } } } @@ -318,6 +346,7 @@ MyStackViewPage { } ColumnLayout { RowLayout { + anchors.fill: parent MyToggleButton { id: moveShortcutLeft @@ -346,27 +375,37 @@ MyStackViewPage { } } - MyToggleButton { - id: playspaceAdjustChaperoneToggle - text: "Adjust Chaperone" - onCheckedChanged: { - MoveCenterTabController.adjustChaperone = this.checked + ColumnLayout { + RowLayout { + anchors.fill: parent + + MyPushButton { + id: playspaceResetButton + Layout.preferredWidth: 250 + text: "Reset" + onClicked: { + MoveCenterTabController.reset() + } + } + + MyToggleButton { + id: playspaceAdjustChaperoneToggle + text: "Adjust Chaperone" + onCheckedChanged: { + MoveCenterTabController.adjustChaperone = this.checked + } + } + } } + + Item { Layout.fillHeight: true; Layout.fillWidth: true} - MyPushButton { - id: playspaceResetButton - Layout.preferredWidth: 250 - text: "Reset" - onClicked: { - MoveCenterTabController.reset() - } - } - Component.onCompleted: { playspaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone + playspaceRotateHandToggle.checked = MoveCenterTabController.rotateHand playSpaceMoveXText.text = MoveCenterTabController.offsetX.toFixed(2) playSpaceMoveYText.text = MoveCenterTabController.offsetY.toFixed(2) playSpaceMoveZText.text = MoveCenterTabController.offsetZ.toFixed(2) @@ -409,9 +448,16 @@ MyStackViewPage { onRotationChanged: { playspaceRotationSlider.value = MoveCenterTabController.rotation } + onTempRotationChanged: { + playspaceRotationSlider.value = MoveCenterTabController.tempRotation + playspaceRotationText.text = MoveCenterTabController.tempRotation + "°" + } onAdjustChaperoneChanged: { playspaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone } + onRotateHandChanged: { + playspaceRotateHandToggle.checked = MoveCenterTabController.rotateHand + } onMoveShortcutRightChanged: { moveShortcutRight.checked = MoveCenterTabController.moveShortcutRight } diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index e5c932c..5ad6a6c 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -1,17 +1,18 @@ #include "MoveCenterTabController.h" #include #include "../overlaycontroller.h" +#include "../utils/Matrix.h" -void rotateCoordinates( float coordinates[3], float angle ) +void rotateCoordinates( double coordinates[3], double angle ) { if ( angle == 0 ) { return; } - float s = sin( angle ); - float c = cos( angle ); - float newX = coordinates[0] * c - coordinates[2] * s; - float newZ = coordinates[0] * s + coordinates[2] * c; + double s = sin( angle ); + double c = cos( angle ); + double newX = coordinates[0] * c - coordinates[2] * s; + double newZ = coordinates[0] * s + coordinates[2] * c; coordinates[0] = newX; coordinates[2] = newZ; } @@ -33,6 +34,11 @@ void MoveCenterTabController::initStage1() { m_adjustChaperone = value.toBool(); } + value = settings->value( "rotateHand", m_rotateHand ); + if ( value.isValid() && !value.isNull() ) + { + m_rotateHand = value.toBool(); + } value = settings->value( "moveShortcutRight", m_moveShortcutRightEnabled ); if ( value.isValid() && !value.isNull() ) { @@ -76,7 +82,7 @@ void MoveCenterTabController::initStage2( OverlayController* var_parent, int MoveCenterTabController::trackingUniverse() const { - return ( int ) m_trackingUniverse; + return static_cast( m_trackingUniverse ); } void MoveCenterTabController::setTrackingUniverse( int value, bool notify ) @@ -136,31 +142,111 @@ int MoveCenterTabController::rotation() const return m_rotation; } +int MoveCenterTabController::tempRotation() const +{ + return m_tempRotation; +} + void MoveCenterTabController::setRotation( int value, bool notify ) { if ( m_rotation != value ) { - // float angle = (value - m_rotation) * 2 * M_PI / 360.0; - // parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, - // angle, m_adjustChaperone); + double angle = ( value - m_rotation ) * 2 * M_PI / 360.0; + + // Revert now because we don't commit in RotateUniverseCenter and + // AddOffsetToUniverseCenter. We do this so rotation and offset can + // happen in one go, avoiding positional judder. + vr::VRChaperoneSetup()->RevertWorkingCopy(); + + // Get hmd pose matrix. + vr::TrackedDevicePose_t + devicePosesForRot[vr::k_unMaxTrackedDeviceCount]; + vr::VRSystem()->GetDeviceToAbsoluteTrackingPose( + vr::TrackingUniverseStanding, + 0.0f, + devicePosesForRot, + vr::k_unMaxTrackedDeviceCount ); + vr::HmdMatrix34_t oldHmdPos + = devicePosesForRot[0].mDeviceToAbsoluteTracking; + + // Set up xyz coordinate values from pose matrix. + double oldHmdXyz[3] + = { oldHmdPos.m[0][3], oldHmdPos.m[1][3], oldHmdPos.m[2][3] }; + double newHmdXyz[3] + = { oldHmdPos.m[0][3], oldHmdPos.m[1][3], oldHmdPos.m[2][3] }; + + // Convert oldHmdXyz into un-rotated coordinates. + double oldAngle = -m_rotation * 2 * M_PI / 360.0; + rotateCoordinates( oldHmdXyz, oldAngle ); + + // Set newHmdXyz to have additional rotation from incoming angle change. + rotateCoordinates( newHmdXyz, oldAngle - angle ); + + // find difference in x,z offset due to incoming angle change + // (coordinates are in un-rotated axis). + double hmdRotDiff[3] + = { oldHmdXyz[0] - newHmdXyz[0], 0, oldHmdXyz[2] - newHmdXyz[2] }; + + // Rotate the tracking univese center without committing. + parent->RotateUniverseCenter( + vr::TrackingUniverseOrigin( m_trackingUniverse ), + static_cast( angle ), + m_adjustChaperone, + false ); + m_rotation = value; if ( notify ) { emit rotationChanged( m_rotation ); } + + // Get rotated offset to apply to universe center. + // We use rotated coordinates here because we have already applied + // RotateUniverseCenter. This will be the final offset ready to apply, + // so it must match the current universe axis rotation. + double finalAngle = m_rotation * 2 * M_PI / 360.0; + double finalHmdRotDiff[3] = { hmdRotDiff[0], 0, hmdRotDiff[2] }; + rotateCoordinates( finalHmdRotDiff, finalAngle ); + + // We're done with calculations now so we can down-cast the double + // values to float for compatilibilty with openvr format + float finalHmdRotDiffFloat[3] + = { static_cast( finalHmdRotDiff[0] ), + static_cast( finalHmdRotDiff[1] ), + static_cast( finalHmdRotDiff[2] ) }; + + // Apply the offset (in rotated coordinates) without commit. + // We still can't commit yet because it would call + // vr::VRChaperoneSetup()->RevertWorkingCopy() and we'd lose our + // uncommitted RotateUniverseCenter. + parent->AddOffsetToUniverseCenter( + vr::TrackingUniverseOrigin( m_trackingUniverse ), + finalHmdRotDiffFloat, + m_adjustChaperone, + false ); + + // Commit here because we didn't in RotateUniverseCenter and + // AddOffsetToUniverseCenter to combine into one go. + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + + // Update UI offsets. + m_offsetX += hmdRotDiff[0]; + m_offsetZ += hmdRotDiff[2]; + if ( notify ) + { + emit offsetXChanged( m_offsetX ); + emit offsetZChanged( m_offsetZ ); + } } } -void MoveCenterTabController::applyRotation() +void MoveCenterTabController::setTempRotation( int value, bool notify ) { - if ( m_rotation != m_rotationOld ) + m_tempRotation = value; + if ( notify ) { - float angle = ( m_rotationOld - m_rotation ) * 2 * M_PI / 360.0; - parent->RotateUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, - angle, - m_adjustChaperone ); - m_rotationOld = m_rotation; + emit tempRotationChanged( m_tempRotation ); } } @@ -176,14 +262,21 @@ void MoveCenterTabController::setAdjustChaperone( bool value, bool notify ) m_adjustChaperone = value; if ( m_trackingUniverse == vr::TrackingUniverseStanding ) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offsetdir = m_adjustChaperone ? -1.0 : 1.0; - float offset[3] = { offsetdir * m_offsetX, - offsetdir * m_offsetY, - offsetdir * m_offsetZ }; + double angle = m_rotation * 2 * M_PI / 360.0; + double offsetdir = m_adjustChaperone ? -1.0 : 1.0; + double offset[3] = { offsetdir * m_offsetX, + offsetdir * m_offsetY, + offsetdir * m_offsetZ }; rotateCoordinates( offset, angle ); - parent->AddOffsetToCollisionBounds( offset ); + // We're done with calculations so down-cast to float for + // compatibility with openvr format + + float offsetFloat[3] = { static_cast( offset[0] ), + static_cast( offset[1] ), + static_cast( offset[2] ) }; + + parent->AddOffsetToCollisionBounds( offsetFloat ); } auto settings = OverlayController::appSettings(); settings->beginGroup( "playspaceSettings" ); @@ -197,6 +290,25 @@ void MoveCenterTabController::setAdjustChaperone( bool value, bool notify ) } } +bool MoveCenterTabController::rotateHand() const +{ + return m_rotateHand; +} + +void MoveCenterTabController::setRotateHand( bool value, bool notify ) +{ + m_rotateHand = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "rotateHand", m_rotateHand ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit rotateHandChanged( m_rotateHand ); + } +} + bool MoveCenterTabController::moveShortcutRight() const { return m_moveShortcutRightEnabled; @@ -316,12 +428,15 @@ void MoveCenterTabController::modOffsetX( float value, bool notify ) // TODO ? possible issue with locking position this way if ( !m_lockXToggle ) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offset[3] = { value, 0, 0 }; + double angle = m_rotation * 2 * M_PI / 360.0; + double offset[3] = { value, 0, 0 }; rotateCoordinates( offset, angle ); + float offsetFloat[3] = { static_cast( offset[0] ), + static_cast( offset[1] ), + static_cast( offset[2] ) }; parent->AddOffsetToUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, - offset, + vr::TrackingUniverseOrigin( m_trackingUniverse ), + offsetFloat, m_adjustChaperone ); m_offsetX += value; if ( notify ) @@ -336,7 +451,7 @@ void MoveCenterTabController::modOffsetY( float value, bool notify ) if ( !m_lockYToggle ) { parent->AddOffsetToUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + vr::TrackingUniverseOrigin( m_trackingUniverse ), 1, value, m_adjustChaperone ); @@ -352,12 +467,15 @@ void MoveCenterTabController::modOffsetZ( float value, bool notify ) { if ( !m_lockZToggle ) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offset[3] = { 0, 0, value }; + double angle = m_rotation * 2 * M_PI / 360.0; + double offset[3] = { 0, 0, value }; rotateCoordinates( offset, angle ); + float offsetFloat[3] = { static_cast( offset[0] ), + static_cast( offset[1] ), + static_cast( offset[2] ) }; parent->AddOffsetToUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, - offset, + vr::TrackingUniverseOrigin( m_trackingUniverse ), + offsetFloat, m_adjustChaperone ); m_offsetZ += value; if ( notify ) @@ -371,13 +489,13 @@ void MoveCenterTabController::reset() { vr::VRChaperoneSetup()->RevertWorkingCopy(); parent->RotateUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + vr::TrackingUniverseOrigin( m_trackingUniverse ), -m_rotation * 2 * M_PI / 360.0, m_adjustChaperone, false ); float offset[3] = { -m_offsetX, -m_offsetY, -m_offsetZ }; parent->AddOffsetToUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + vr::TrackingUniverseOrigin( m_trackingUniverse ), offset, m_adjustChaperone, false ); @@ -486,104 +604,179 @@ void MoveCenterTabController::eventLoopTick( vr::ETrackingUniverseOrigin universe, vr::TrackedDevicePose_t* devicePoses ) { - if ( settingsUpdateCounter >= 50 ) + if ( settingsUpdateCounter >= 100 ) { - setTrackingUniverse( ( int ) universe ); + setTrackingUniverse( int( universe ) ); settingsUpdateCounter = 0; } else { settingsUpdateCounter++; - auto oldMoveHand = m_activeMoveController; - auto newMoveHand = getMoveShortcutHand(); - if ( newMoveHand == vr::TrackedControllerRole_Invalid ) + } + auto oldMoveHand = m_activeMoveController; + auto newMoveHand = getMoveShortcutHand(); + if ( newMoveHand == vr::TrackedControllerRole_Invalid ) + { + emit offsetXChanged( m_offsetX ); + emit offsetYChanged( m_offsetY ); + emit offsetZChanged( m_offsetZ ); + + // Set lastHandYaw to placeholder value for invalid (-10.0) when we + // release move shortcut. + if ( m_rotateHand ) + { + lastHandYaw = -10.0; + } + + return; + } + auto handId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( newMoveHand ); + if ( newMoveHand == vr::TrackedControllerRole_Invalid + || handId == vr::k_unTrackedDeviceIndexInvalid + || handId >= vr::k_unMaxTrackedDeviceCount ) + { + if ( oldMoveHand != vr::TrackedControllerRole_Invalid ) { emit offsetXChanged( m_offsetX ); emit offsetYChanged( m_offsetY ); emit offsetZChanged( m_offsetZ ); - return; - } - auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( - newMoveHand ); - if ( newMoveHand == vr::TrackedControllerRole_Invalid - || handId == vr::k_unTrackedDeviceIndexInvalid - || handId >= vr::k_unMaxTrackedDeviceCount ) - { - if ( oldMoveHand != vr::TrackedControllerRole_Invalid ) - { - emit offsetXChanged( m_offsetX ); - emit offsetYChanged( m_offsetY ); - emit offsetZChanged( m_offsetZ ); - } - return; - } - vr::TrackedDevicePose_t* pose = devicePoses + handId; - if ( !pose->bPoseIsValid || !pose->bDeviceIsConnected - || pose->eTrackingResult != vr::TrackingResult_Running_OK ) - { - return; - } - float relativeControllerPosition[] - = { pose->mDeviceToAbsoluteTracking.m[0][3], - pose->mDeviceToAbsoluteTracking.m[1][3], - pose->mDeviceToAbsoluteTracking.m[2][3] }; - auto angle = m_rotation * 2 * M_PI / 360.0; - rotateCoordinates( relativeControllerPosition, -angle ); - float absoluteControllerPosition[] = { - relativeControllerPosition[0] + m_offsetX, - relativeControllerPosition[1] + m_offsetY, - relativeControllerPosition[2] + m_offsetZ, + if ( m_rotateHand ) + { + lastHandYaw = -10.0; + } + } + return; + } + vr::TrackedDevicePose_t* pose = devicePoses + handId; + if ( !pose->bPoseIsValid || !pose->bDeviceIsConnected + || pose->eTrackingResult != vr::TrackingResult_Running_OK ) + { + return; + } + double relativeControllerPosition[] + = { pose->mDeviceToAbsoluteTracking.m[0][3], + pose->mDeviceToAbsoluteTracking.m[1][3], + pose->mDeviceToAbsoluteTracking.m[2][3] }; + + double angle = m_rotation * 2 * M_PI / 360.0; + rotateCoordinates( relativeControllerPosition, -angle ); + float absoluteControllerPosition[] = { + static_cast( relativeControllerPosition[0] ) + m_offsetX, + static_cast( relativeControllerPosition[1] ) + m_offsetY, + static_cast( relativeControllerPosition[2] ) + m_offsetZ, + }; + + // Get hand's rotation. + if ( m_rotateHand ) + { + // handMatrix is in rotated coordinates. + vr::HmdMatrix34_t handMatrix = pose->mDeviceToAbsoluteTracking; + + // We need un-rotated coordinates for valid comparison between + // handYaw and lastHandYaw. Set up (un)rotation matrix. + vr::HmdMatrix34_t handMatrixRotMat; + vr::HmdMatrix34_t handMatrixAbsolute; + utils::initRotationMatrix( + handMatrixRotMat, 1, static_cast( angle ) ); + + // Get handMatrixAbsolute in un-rotated coordinates. + utils::matMul33( handMatrixAbsolute, handMatrixRotMat, handMatrix ); + + // Convert pose matrix to yaw. + handYaw = std::atan2( handMatrixAbsolute.m[0][2], + handMatrixAbsolute.m[2][2] ); + } + + if ( oldMoveHand == newMoveHand ) + { + double diff[3] = { + absoluteControllerPosition[0] - m_lastControllerPosition[0], + absoluteControllerPosition[1] - m_lastControllerPosition[1], + absoluteControllerPosition[2] - m_lastControllerPosition[2], }; - if ( oldMoveHand == newMoveHand ) + // offset is un-rotated coordinates + + // prevents UI from updating if axis movement is locked + if ( !m_lockXToggle ) { - float diff[3] = { - absoluteControllerPosition[0] - m_lastControllerPosition[0], - absoluteControllerPosition[1] - m_lastControllerPosition[1], - absoluteControllerPosition[2] - m_lastControllerPosition[2], - }; + m_offsetX += diff[0]; + } + if ( !m_lockYToggle ) + { + m_offsetY += diff[1]; + } + if ( !m_lockZToggle ) + { + m_offsetZ += diff[2]; + } - // offset is un-rotated coordinates + rotateCoordinates( diff, angle ); - // prevents UI from updating if axis movement is locked - if ( !m_lockXToggle ) - { - m_offsetX += diff[0]; - } - if ( !m_lockYToggle ) - { - m_offsetY += diff[1]; - } - if ( !m_lockZToggle ) - { - m_offsetZ += diff[2]; - } - - rotateCoordinates( diff, angle ); - // If locked removes movement - if ( m_lockXToggle ) - { - diff[0] = 0; - } - if ( m_lockYToggle ) - { - diff[1] = 0; - } - if ( m_lockZToggle ) - { - diff[2] = 0; - } + // Done calculating rotation so we down-cast double to float for openvr + // format + float diffFloat[3] = { static_cast( diff[0] ), + static_cast( diff[1] ), + static_cast( diff[2] ) }; + // If locked removes movement + if ( m_lockXToggle ) + { + diffFloat[0] = 0; + } + if ( m_lockYToggle ) + { + diffFloat[1] = 0; + } + if ( m_lockZToggle ) + { + diffFloat[2] = 0; + } + // Check if diffFloat is anything before comitting. + if ( diffFloat[0] != 0 || diffFloat[1] != 0 || diffFloat[2] != 0 ) + { parent->AddOffsetToUniverseCenter( - ( vr::TrackingUniverseOrigin ) m_trackingUniverse, - diff, + vr::TrackingUniverseOrigin( m_trackingUniverse ), + diffFloat, m_adjustChaperone ); } - m_lastControllerPosition[0] = absoluteControllerPosition[0]; - m_lastControllerPosition[1] = absoluteControllerPosition[1]; - m_lastControllerPosition[2] = absoluteControllerPosition[2]; - } -} + // Get rotation change of hand. + if ( m_rotateHand ) + { + // Checking if set to -10.0 placeholder for invalid hand. + if ( lastHandYaw < -9.0 ) + { + lastHandYaw = handYaw; + } + + else + { + double handYawDiff = handYaw - lastHandYaw; + + // TODO: Increase angular granularity beyond 1 degree. + int newRotationAngleDeg = static_cast( + round( handYawDiff * 180.0 / M_PI ) + m_rotation ); + + // Keep angle within -180 ~ 180 + if ( newRotationAngleDeg > 180 ) + { + newRotationAngleDeg -= 360; + } + else if ( newRotationAngleDeg < -180 ) + { + newRotationAngleDeg += 360; + } + + setRotation( newRotationAngleDeg ); + } + } + } + m_lastControllerPosition[0] = absoluteControllerPosition[0]; + m_lastControllerPosition[1] = absoluteControllerPosition[1]; + m_lastControllerPosition[2] = absoluteControllerPosition[2]; + lastHandYaw = handYaw; +} } // namespace advsettings diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 75af55d..7f33987 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -25,6 +25,8 @@ class MoveCenterTabController : public QObject float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged ) Q_PROPERTY( int rotation READ rotation WRITE setRotation NOTIFY rotationChanged ) + Q_PROPERTY( int tempRotation READ tempRotation WRITE setTempRotation NOTIFY + tempRotationChanged ) Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged ) Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE @@ -39,6 +41,8 @@ class MoveCenterTabController : public QObject requireLockYChanged ) Q_PROPERTY( bool lockZToggle READ lockZToggle WRITE setLockZ NOTIFY requireLockZChanged ) + Q_PROPERTY( bool rotateHand READ rotateHand WRITE setRotateHand NOTIFY + rotateHandChanged ) private: OverlayController* parent; @@ -49,8 +53,9 @@ private: float m_offsetY = 0.0f; float m_offsetZ = 0.0f; int m_rotation = 0; - int m_rotationOld = 0; + int m_tempRotation = 0; bool m_adjustChaperone = true; + bool m_rotateHand = false; bool m_moveShortcutRightPressed = false; bool m_moveShortcutLeftPressed = false; vr::ETrackedControllerRole m_activeMoveController; @@ -62,6 +67,9 @@ private: bool m_lockYToggle = false; bool m_lockZToggle = false; std::chrono::system_clock::time_point lastMoveButtonClick[2]; + // Set to -10.0 when last hand is invalid. + double lastHandYaw = -10.0; + double handYaw; unsigned settingsUpdateCounter = 0; @@ -78,7 +86,9 @@ public: float offsetY() const; float offsetZ() const; int rotation() const; + int tempRotation() const; bool adjustChaperone() const; + bool rotateHand() const; bool moveShortcutRight() const; bool moveShortcutLeft() const; bool requireDoubleClick() const; @@ -96,8 +106,12 @@ public slots: void setRotation( int value, bool notify = true ); + void setTempRotation( int value, bool notify = true ); + void setAdjustChaperone( bool value, bool notify = true ); + void setRotateHand( bool value, bool notify = true ); + void setMoveShortcutRight( bool value, bool notify = true ); void setMoveShortcutLeft( bool value, bool notify = true ); void setRequireDoubleClick( bool value, bool notify = true ); @@ -110,7 +124,6 @@ public slots: void setLockY( bool value, bool notify = true ); void setLockZ( bool value, bool notify = true ); - void applyRotation(); void reset(); signals: @@ -119,7 +132,9 @@ signals: void offsetYChanged( float value ); void offsetZChanged( float value ); void rotationChanged( int value ); + void tempRotationChanged( int value ); void adjustChaperoneChanged( bool value ); + void rotateHandChanged( bool value ); void moveShortcutRightChanged( bool value ); void moveShortcutLeftChanged( bool value ); void requireDoubleClickChanged( bool value );