diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..395028d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +debug +release +assets +*.vcxproj* +*.log +*.vs +*.stash +*.appxmanifest +*.user diff --git a/bin/win64/.gitignore b/bin/win64/.gitignore new file mode 100644 index 00000000..fb345079 --- /dev/null +++ b/bin/win64/.gitignore @@ -0,0 +1,6 @@ +*.log +*.exe +*.dll +*.pdb +qtdata +!openvr_api.dll diff --git a/bin/win64/res/qml/.gitignore b/bin/win64/res/qml/.gitignore new file mode 100644 index 00000000..86950b3e --- /dev/null +++ b/bin/win64/res/qml/.gitignore @@ -0,0 +1 @@ +*.qmlc diff --git a/bin/win64/res/qml/MyToggleButton.qml b/bin/win64/res/qml/MyToggleButton.qml index 85629b6b..0dd69617 100644 --- a/bin/win64/res/qml/MyToggleButton.qml +++ b/bin/win64/res/qml/MyToggleButton.qml @@ -4,22 +4,33 @@ import "." // QTBUG-34418, singletons require explicit import to load qmldir fil CheckBox { - hoverEnabled: true - spacing: 12 + checkState: Qt.Checked + tristate: false + hoverEnabled: true + spacing: 12 indicator: Rectangle { implicitWidth: 28 implicitHeight: 28 x: parent.leftPadding y: parent.height / 2 - height / 2 - color: parent.enabled ? (parent.down ? "#e0e0e0" : "#ffffff") : "#a0a0a0" - border.width: 0 + color: parent.enabled ? (parent.down ? "#e0e0e0" : "#ffffff") : "#a0a0a0" + border.width: 0 + Path { + startX: 0 + startY: 0 + PathLine { + x: 40 + y: 40 + } + } + Image { - width: 38 - height: 38 + width: 28 + height: 28 x: (parent.width - width) / 2 y: (parent.height - height) / 2 - source: "image://default/check/#2c435d" + source: "check.svg" sourceSize.width: width sourceSize.height: height visible: parent.parent.checked @@ -36,7 +47,7 @@ CheckBox { background: Rectangle { color: "#2c435d" - opacity: parent.activeFocus ? 1.0 : 0.0 + opacity: parent.activeFocus ? 1.0 : 0 } onHoveredChanged: { diff --git a/bin/win64/res/qml/PlayspacePage.qml b/bin/win64/res/qml/PlayspacePage.qml index 62ad039b..741121f1 100644 --- a/bin/win64/res/qml/PlayspacePage.qml +++ b/bin/win64/res/qml/PlayspacePage.qml @@ -265,6 +265,40 @@ MyStackViewPage { } } + GroupBox { + Layout.fillWidth: true + + label: MyText { + leftPadding: 10 + text: "Virtual Move Shortcut" + bottomPadding: -10 + } + background: Rectangle { + color: "transparent" + border.color: "#ffffff" + radius: 8 + } + RowLayout { + anchors.fill: parent + + MyToggleButton { + id: moveShortcutLeft + text: "Left Menu Button" + onCheckedChanged: { + MoveCenterTabController.moveShortcutLeft = this.checked + } + } + + MyToggleButton { + id: moveShortcutRight + text: "Right Menu Button" + onCheckedChanged: { + MoveCenterTabController.moveShortcutRight = this.checked + } + } + } + } + MyToggleButton { id: playspaceAdjustChaperoneToggle text: "Adjust Chaperone" @@ -290,6 +324,8 @@ MyStackViewPage { playSpaceMoveYText.text = MoveCenterTabController.offsetY.toFixed(2) playSpaceMoveZText.text = MoveCenterTabController.offsetZ.toFixed(2) playspaceRotationSlider.value = MoveCenterTabController.rotation + moveShortcutRight.checked = MoveCenterTabController.moveShortcutRight; + moveShortcutLeft.checked = MoveCenterTabController.moveShortcutLeft; if (MoveCenterTabController.trackingUniverse === 0) { playspaceModeText.text = "Sitting" playSpaceRotationPlusButton.enabled = false @@ -322,7 +358,13 @@ MyStackViewPage { playspaceRotationSlider.value = MoveCenterTabController.rotation } onAdjustChaperoneChanged: { - playspaceAdjustChaperoneToggle = value + playspaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone + } + onMoveShortcutRightChanged: { + moveShortcutRight.checked = MoveCenterTabController.moveShortcutRight + } + onMoveShortcutLeftChanged: { + moveShortcutLeft.checked = MoveCenterTabController.moveShortcutLeft } onTrackingUniverseChanged: { if (MoveCenterTabController.trackingUniverse === 0) { diff --git a/bin/win64/res/qml/check.svg b/bin/win64/res/qml/check.svg new file mode 100644 index 00000000..6a6f37f7 --- /dev/null +++ b/bin/win64/res/qml/check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index 3b095485..b7a70f3c 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -453,7 +453,7 @@ void OverlayController::OnTimeoutPumpEvents() { fixFloorTabController.eventLoopTick(devicePoses); statisticsTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed); - moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace()); + moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace(), devicePoses); steamVRTabController.eventLoopTick(); chaperoneTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed, hmdSpeed); settingsTabController.eventLoopTick(); @@ -475,7 +475,13 @@ void OverlayController::OnTimeoutPumpEvents() { } void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds, bool commit) { - if (offset != 0.0f) { + float offsetArray[3] = { 0,0,0 }; + offsetArray[axisId] = offset; + AddOffsetToUniverseCenter(universe, offsetArray, adjustBounds, commit); +} + +void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, float offset[3], bool adjustBounds, bool commit) { + if (offset[0] != 0.0f || offset[1] != 0.0f || offset[2] != 0.0f) { if (commit) { vr::VRChaperoneSetup()->RevertWorkingCopy(); } @@ -485,16 +491,23 @@ void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin un } else { vr::VRChaperoneSetup()->GetWorkingSeatedZeroPoseToRawTrackingPose(&curPos); } - curPos.m[0][3] += curPos.m[0][axisId] * offset; - curPos.m[1][3] += curPos.m[1][axisId] * offset; - curPos.m[2][3] += curPos.m[2][axisId] * offset; + for (int i = 0; i < 3; i++) { + curPos.m[0][3] += curPos.m[0][i] * offset[i]; + curPos.m[1][3] += curPos.m[1][i] * offset[i]; + curPos.m[2][3] += curPos.m[2][i] * offset[i]; + } if (universe == vr::TrackingUniverseStanding) { vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose(&curPos); } else { vr::VRChaperoneSetup()->SetWorkingSeatedZeroPoseToRawTrackingPose(&curPos); } if (adjustBounds && universe == vr::TrackingUniverseStanding) { - AddOffsetToCollisionBounds(axisId, -offset, false); + float collisionOffset[] = { + -offset[0], + -offset[1], + -offset[2] + }; + AddOffsetToCollisionBounds(collisionOffset, false); } if (commit) { vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); @@ -537,6 +550,12 @@ void OverlayController::RotateUniverseCenter(vr::ETrackingUniverseOrigin univers void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit) { + float offsetArray[3] = { 0,0,0 }; + offsetArray[axisId] = offset; + AddOffsetToCollisionBounds(offsetArray, commit); +} + +void OverlayController::AddOffsetToCollisionBounds(float offset[3], bool commit) { // Apparently Valve sanity-checks the y-coordinates of the collision bounds (and only the y-coordinates) // I can move the bounds on the xz-plane, I can make the "ceiling" of the chaperone cage lower/higher, but when I // dare to set one single lower corner to something non-zero, every corner gets its y-coordinates reset to the defaults. @@ -551,7 +570,9 @@ void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(collisionBounds, &collisionBoundsCount); for (unsigned b = 0; b < collisionBoundsCount; b++) { for (unsigned c = 0; c < 4; c++) { - collisionBounds[b].vCorners[c].v[axisId] += offset; + collisionBounds[b].vCorners[c].v[0] += offset[0]; + collisionBounds[b].vCorners[c].v[1] += offset[1]; + collisionBounds[b].vCorners[c].v[2] += offset[2]; } } vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(collisionBounds, collisionBoundsCount); diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index 793a7d78..f3aead51 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -105,8 +105,10 @@ class OverlayController : public QObject { void SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key = ""); void AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds = true, bool commit = true); + void AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, float offset[3], bool adjustBounds = true, bool commit = true); void RotateUniverseCenter(vr::ETrackingUniverseOrigin universe, float yAngle, bool adjustBounds = true, bool commit = true); // around y axis void AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit = true); + void AddOffsetToCollisionBounds(float offset[3], bool commit = true); void RotateCollisionBounds(float angle, bool commit = true); // around y axis bool isDesktopMode() { return desktopMode; }; diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index 26977d22..aeea6638 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -2,6 +2,18 @@ #include #include "../overlaycontroller.h" +void rotateCoordinates(float coordinates[3], float 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; + coordinates[0] = newX; + coordinates[2] = newZ; +} + // application namespace namespace advsettings { @@ -10,10 +22,18 @@ void MoveCenterTabController::initStage1() { auto settings = OverlayController::appSettings(); settings->beginGroup("playspaceSettings"); auto value = settings->value("adjustChaperone", m_adjustChaperone); - settings->endGroup(); if (value.isValid() && !value.isNull()) { m_adjustChaperone = value.toBool(); } + value = settings->value("moveShortcutRight", m_moveShortcutRightEnabled); + if (value.isValid() && !value.isNull()) { + m_moveShortcutRightEnabled = value.toBool(); + } + value = settings->value("moveShortcutLeft", m_moveShortcutLeftEnabled); + if (value.isValid() && !value.isNull()) { + m_moveShortcutLeftEnabled = value.toBool(); + } + settings->endGroup(); } void MoveCenterTabController::initStage2(OverlayController * parent, QQuickWindow * widget) { @@ -89,40 +109,16 @@ void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) { if (m_adjustChaperone != value) { m_adjustChaperone = value; if (m_trackingUniverse == vr::TrackingUniverseStanding) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - float offsetdir; - if (m_adjustChaperone) { - offsetdir = -1.0; - } else { - offsetdir = 1.0; - } + 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 + }; + rotateCoordinates(offset, angle); - if (m_offsetX != 0.0f) { - if (m_adjustChaperone || m_rotation == 0) { - parent->AddOffsetToCollisionBounds(0, offsetdir * m_offsetX, false); - } else { - auto angle = m_rotation * 2 * M_PI / 360.0; - parent->AddOffsetToCollisionBounds(0, offsetdir * m_offsetX * std::cos(angle), false); - parent->AddOffsetToCollisionBounds(2, offsetdir * m_offsetX * std::sin(angle), false); - } - } - if (m_offsetY != 0.0f) { - parent->AddOffsetToCollisionBounds(1, offsetdir * m_offsetY, false); - } - if (m_offsetZ != 0.0f) { - if (m_adjustChaperone || m_rotation == 0) { - parent->AddOffsetToCollisionBounds(2, offsetdir * m_offsetZ, false); - } else { - auto angle = m_rotation * 2 * M_PI / 360.0; - parent->AddOffsetToCollisionBounds(2, offsetdir * m_offsetZ * std::cos(angle), false); - parent->AddOffsetToCollisionBounds(0, -offsetdir * m_offsetZ * std::sin(angle), false); - } - } - if (m_rotation != 0) { - float angle = m_rotation * 2 * M_PI / 360.0; - parent->RotateCollisionBounds(offsetdir * angle, false); - } - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); + parent->AddOffsetToCollisionBounds(offset); } auto settings = OverlayController::appSettings(); settings->beginGroup("playspaceSettings"); @@ -135,16 +131,44 @@ void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) { } } -void MoveCenterTabController::modOffsetX(float value, bool notify) { - if (m_rotation == 0) { - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, value, m_adjustChaperone); - } else { - auto angle = m_rotation * 2 * M_PI / 360.0; - vr::VRChaperoneSetup()->RevertWorkingCopy(); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, value * std::cos(angle), m_adjustChaperone, false); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 2, value * std::sin(angle), m_adjustChaperone, false); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); + +bool MoveCenterTabController::moveShortcutRight() const { + return m_moveShortcutRightEnabled; +} + +void MoveCenterTabController::setMoveShortcutRight(bool value, bool notify) { + m_moveShortcutRightEnabled = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup("playspaceSettings"); + settings->setValue("moveShortcutRight", m_moveShortcutRightEnabled); + settings->endGroup(); + settings->sync(); + if (notify) { + emit moveShortcutRightChanged(m_moveShortcutRightEnabled); } +} + +bool MoveCenterTabController::moveShortcutLeft() const { + return m_moveShortcutLeftEnabled; +} + +void MoveCenterTabController::setMoveShortcutLeft(bool value, bool notify) { + m_moveShortcutLeftEnabled = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup("playspaceSettings"); + settings->setValue("moveShortcutLeft", m_moveShortcutLeftEnabled); + settings->endGroup(); + settings->sync(); + if (notify) { + emit moveShortcutLeftChanged(m_moveShortcutLeftEnabled); + } +} + +void MoveCenterTabController::modOffsetX(float value, bool notify) { + auto angle = m_rotation * 2 * M_PI / 360.0; + float offset[3] = { value, 0, 0 }; + rotateCoordinates(offset, angle); + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone); m_offsetX += value; if (notify) { emit offsetXChanged(m_offsetX); @@ -160,15 +184,10 @@ void MoveCenterTabController::modOffsetY(float value, bool notify) { } void MoveCenterTabController::modOffsetZ(float value, bool notify) { - if (m_rotation == 0) { - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 2, value, m_adjustChaperone); - } else { - auto angle = m_rotation * 2 * M_PI / 360.0; - vr::VRChaperoneSetup()->RevertWorkingCopy(); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 2, value * std::cos(angle), m_adjustChaperone, false); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, -value * std::sin(angle), m_adjustChaperone, false); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } + auto angle = m_rotation * 2 * M_PI / 360.0; + float offset[3] = { 0, 0, value }; + rotateCoordinates(offset, angle); + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone); m_offsetZ += value; if (notify) { emit offsetZChanged(m_offsetZ); @@ -178,9 +197,12 @@ void MoveCenterTabController::modOffsetZ(float value, bool notify) { void MoveCenterTabController::reset() { vr::VRChaperoneSetup()->RevertWorkingCopy(); parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, -m_rotation * 2 * M_PI / 360.0, m_adjustChaperone, false); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 0, -m_offsetX, m_adjustChaperone, false); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, -m_offsetY, m_adjustChaperone, false); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 2, -m_offsetZ, m_adjustChaperone, false); + float offset[3] = { + -m_offsetX, + -m_offsetY, + -m_offsetZ + }; + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone, false); vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); m_offsetX = 0.0f; m_offsetY = 0.0f; @@ -192,12 +214,115 @@ void MoveCenterTabController::reset() { emit rotationChanged(m_rotation); } -void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe) { +bool isMoveShortCutPressed(vr::ETrackedControllerRole hand) { + auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(hand); + if (handId == vr::k_unTrackedDeviceIndexInvalid || handId >= vr::k_unMaxTrackedDeviceCount) { + return false; + } + + vr::VRControllerState_t state; + if (vr::VRSystem()->GetControllerState(handId, &state, sizeof(vr::VRControllerState_t))) { + return state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu); + } + + return false; +} + +vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() { + auto activeHand = m_activeMoveController; + + bool rightPressed = m_moveShortcutRightEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_RightHand); + bool leftPressed = m_moveShortcutLeftEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_LeftHand); + + // if we start pressing the shortcut on a controller we set the active one to it + if (rightPressed && !m_moveShortcutRightPressed) { + activeHand = vr::TrackedControllerRole_RightHand; + } + if (leftPressed && !m_moveShortcutLeftPressed) { + activeHand = vr::TrackedControllerRole_LeftHand; + } + + // if we let down of a shortcut we set the active hand to any remaining pressed down hand + if (!rightPressed && m_moveShortcutRightPressed) { + activeHand = leftPressed ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_Invalid; + } + if (!leftPressed && m_moveShortcutLeftPressed) { + activeHand = rightPressed ? vr::TrackedControllerRole_RightHand : vr::TrackedControllerRole_Invalid; + } + + if (!leftPressed && !rightPressed) { + activeHand = vr::TrackedControllerRole_Invalid; + } + + m_activeMoveController = activeHand; + m_moveShortcutRightPressed = rightPressed; + m_moveShortcutLeftPressed = leftPressed; + + return activeHand; +} + + +void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe, vr::TrackedDevicePose_t* devicePoses) { if (settingsUpdateCounter >= 50) { setTrackingUniverse((int)universe); settingsUpdateCounter = 0; } else { settingsUpdateCounter++; + auto oldMoveHand = m_activeMoveController; + auto newMoveHand = getMoveShortcutHand(); + if (newMoveHand == 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 (oldMoveHand == newMoveHand) { + + float diff[3] = { + absoluteControllerPosition[0] - m_lastControllerPosition[0], + absoluteControllerPosition[1] - m_lastControllerPosition[1], + absoluteControllerPosition[2] - m_lastControllerPosition[2], + }; + + // offset is un-rotated coordinates + m_offsetX += diff[0]; + m_offsetY += diff[1]; + m_offsetZ += diff[2]; + + rotateCoordinates(diff, angle); + + parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, diff, m_adjustChaperone); + } + m_lastControllerPosition[0] = absoluteControllerPosition[0]; + m_lastControllerPosition[1] = absoluteControllerPosition[1]; + m_lastControllerPosition[2] = absoluteControllerPosition[2]; } } diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 270582e5..4c356400 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -20,6 +20,8 @@ class MoveCenterTabController : public QObject { Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged) Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) + Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) + Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) private: OverlayController* parent; @@ -31,20 +33,30 @@ class MoveCenterTabController : public QObject { float m_offsetZ = 0.0f; int m_rotation = 0; bool m_adjustChaperone = true; + bool m_moveShortcutRightPressed = false; + bool m_moveShortcutLeftPressed = false; + vr::ETrackedControllerRole m_activeMoveController; + float m_lastControllerPosition[3]; + bool m_moveShortcutRightEnabled = false; + bool m_moveShortcutLeftEnabled = false; unsigned settingsUpdateCounter = 0; + vr::ETrackedControllerRole getMoveShortcutHand(); + public: void initStage1(); void initStage2(OverlayController* parent, QQuickWindow* widget); - void eventLoopTick(vr::ETrackingUniverseOrigin universe); + void eventLoopTick(vr::ETrackingUniverseOrigin universe, vr::TrackedDevicePose_t* devicePoses); float offsetX() const; float offsetY() const; float offsetZ() const; int rotation() const; bool adjustChaperone() const; + bool moveShortcutRight() const; + bool moveShortcutLeft() const; public slots: int trackingUniverse() const; @@ -58,6 +70,9 @@ public slots: void setAdjustChaperone(bool value, bool notify = true); + void setMoveShortcutRight(bool value, bool notify = true); + void setMoveShortcutLeft(bool value, bool notify = true); + void modOffsetX(float value, bool notify = true); void modOffsetY(float value, bool notify = true); void modOffsetZ(float value, bool notify = true); @@ -70,6 +85,8 @@ public slots: void offsetZChanged(float value); void rotationChanged(int value); void adjustChaperoneChanged(bool value); + void moveShortcutRightChanged(bool value); + void moveShortcutLeftChanged(bool value); }; } // namespace advsettings