diff --git a/src/openvr/ivrinput.cpp b/src/openvr/ivrinput.cpp
index 7a42b325..e4d5c4e2 100644
--- a/src/openvr/ivrinput.cpp
+++ b/src/openvr/ivrinput.cpp
@@ -132,6 +132,8 @@ SteamIVRInput::SteamIVRInput()
m_smoothTurnLeft( action_keys::smoothTurnLeft ),
m_smoothTurnRight( action_keys::smoothTurnRight ),
m_autoTurnToggle( action_keys::autoTurnToggle ),
+ m_addAutoAlignPointLeft( action_keys::addAutoAlignPointLeft ),
+ m_addAutoAlignPointRight( action_keys::addAutoAlignPointRight ),
m_xAxisLockToggle( action_keys::xAxisLockToggle ),
m_yAxisLockToggle( action_keys::yAxisLockToggle ),
m_zAxisLockToggle( action_keys::zAxisLockToggle ),
@@ -300,6 +302,15 @@ bool SteamIVRInput::autoTurnToggle()
{
return isDigitalActionActivatedOnce( m_autoTurnToggle );
}
+bool SteamIVRInput::addAutoAlignPointLeft()
+{
+ return isDigitalActionActivatedOnce( m_addAutoAlignPointLeft );
+}
+
+bool SteamIVRInput::addAutoAlignPointRight()
+{
+ return isDigitalActionActivatedOnce( m_addAutoAlignPointRight );
+}
bool SteamIVRInput::xAxisLockToggle()
{
diff --git a/src/openvr/ivrinput.h b/src/openvr/ivrinput.h
index 91289a84..84248a00 100644
--- a/src/openvr/ivrinput.h
+++ b/src/openvr/ivrinput.h
@@ -47,6 +47,10 @@ namespace action_keys
constexpr auto smoothTurnLeft = "/actions/motion/in/SmoothTurnLeft";
constexpr auto smoothTurnRight = "/actions/motion/in/SmoothTurnRight";
constexpr auto autoTurnToggle = "/actions/motion/in/AutoTurnToggle";
+ constexpr auto addAutoAlignPointLeft
+ = "/actions/motion/in/AddAutoAlignPointLeft";
+ constexpr auto addAutoAlignPointRight
+ = "/actions/motion/in/AddAutoAlignPointRight";
constexpr auto xAxisLockToggle = "/actions/misc/in/XAxisLockToggle";
constexpr auto yAxisLockToggle = "/actions/misc/in/YAxisLockToggle";
@@ -151,6 +155,8 @@ class SteamIVRInput
bool smoothTurnLeft();
bool smoothTurnRight();
bool autoTurnToggle();
+ bool addAutoAlignPointLeft();
+ bool addAutoAlignPointRight();
bool xAxisLockToggle();
bool yAxisLockToggle();
bool zAxisLockToggle();
@@ -233,6 +239,8 @@ class SteamIVRInput
DigitalAction m_smoothTurnLeft;
DigitalAction m_smoothTurnRight;
DigitalAction m_autoTurnToggle;
+ DigitalAction m_addAutoAlignPointLeft;
+ DigitalAction m_addAutoAlignPointRight;
DigitalAction m_xAxisLockToggle;
DigitalAction m_yAxisLockToggle;
DigitalAction m_zAxisLockToggle;
diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp
index bec9952b..a8f921e0 100644
--- a/src/overlaycontroller.cpp
+++ b/src/overlaycontroller.cpp
@@ -755,6 +755,14 @@ void OverlayController::processRotationBindings()
m_rotationTabController.setAutoTurnEnabled(
!( m_rotationTabController.autoTurnEnabled() ) );
}
+ if ( m_actions.addAutoAlignPointLeft() )
+ {
+ m_rotationTabController.addAutoAlignPoint( false );
+ }
+ if ( m_actions.addAutoAlignPointRight() )
+ {
+ m_rotationTabController.addAutoAlignPoint( true );
+ }
}
/*!
Checks if an action has been activated and dispatches the related action if
diff --git a/src/package_files/action_manifest.json b/src/package_files/action_manifest.json
index 43ffb181..f43ef04a 100644
--- a/src/package_files/action_manifest.json
+++ b/src/package_files/action_manifest.json
@@ -163,7 +163,16 @@
"requirement": "optional",
"type": "boolean"
},
-
+ {
+ "name": "/actions/motion/in/AddAutoAlignPointLeft",
+ "requirement": "optional",
+ "type": "boolean"
+ },
+ {
+ "name": "/actions/motion/in/AddAutoAlignPointRight",
+ "requirement": "optional",
+ "type": "boolean"
+ },
{
"name": "/actions/misc/in/XAxisLockToggle",
"requirement": "optional",
@@ -288,6 +297,8 @@
"/actions/motion/in/SmoothTurnLeft" : "Smooth-Turn Left",
"/actions/motion/in/SmoothTurnRight" : "Smooth-Turn Right",
"/actions/motion/in/AutoTurnToggle" : "Auto-Turn Toggle",
+ "/actions/motion/in/AddAutoAlignPointLeft" : "Add Auto Align Point (Left Hand)",
+ "/actions/motion/in/AddAutoAlignPointRight" : "Add Auto Align Point (Right Hand)",
"/actions/misc/in/XAxisLockToggle" : "X-Axis Lock Toggle",
"/actions/misc/in/YAxisLockToggle" : "Y-Axis Lock Toggle",
@@ -303,4 +314,4 @@
"/actions/system/in/KeyPressSystem": "Key Press System"
}
]
-}
\ No newline at end of file
+}
diff --git a/src/res/img/rotation/autoalign.svg b/src/res/img/rotation/autoalign.svg
new file mode 100644
index 00000000..8b933753
--- /dev/null
+++ b/src/res/img/rotation/autoalign.svg
@@ -0,0 +1,108 @@
+
+
diff --git a/src/res/img/rotation/autoalign1.png b/src/res/img/rotation/autoalign1.png
new file mode 100644
index 00000000..98a50304
Binary files /dev/null and b/src/res/img/rotation/autoalign1.png differ
diff --git a/src/res/img/rotation/autoalign2.png b/src/res/img/rotation/autoalign2.png
new file mode 100644
index 00000000..1e7d35dc
Binary files /dev/null and b/src/res/img/rotation/autoalign2.png differ
diff --git a/src/res/img/rotation/autoalign3.png b/src/res/img/rotation/autoalign3.png
new file mode 100644
index 00000000..57367aca
Binary files /dev/null and b/src/res/img/rotation/autoalign3.png differ
diff --git a/src/res/img/rotation/autoalign4.png b/src/res/img/rotation/autoalign4.png
new file mode 100644
index 00000000..ec7c5b84
Binary files /dev/null and b/src/res/img/rotation/autoalign4.png differ
diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp
index 1b52497b..073e5422 100644
--- a/src/tabcontrollers/MoveCenterTabController.cpp
+++ b/src/tabcontrollers/MoveCenterTabController.cpp
@@ -330,8 +330,6 @@ void MoveCenterTabController::setRotation( int value, bool notify )
return;
}
- double angle = ( value - m_rotation ) * k_centidegreesToRadians;
-
// Get hmd pose matrix.
vr::TrackedDevicePose_t
devicePosesForRot[vr::k_unMaxTrackedDeviceCount];
@@ -356,26 +354,39 @@ void MoveCenterTabController::setRotation( int value, bool notify )
vr::HmdMatrix34_t oldHmdPos
= devicePosesForRot[0].mDeviceToAbsoluteTracking;
+ vr::HmdVector3_t oldHmdPos3
+ = { oldHmdPos.m[0][3], oldHmdPos.m[1][3], oldHmdPos.m[2][3] };
+ setRotationAroundPivot( value, notify, oldHmdPos3 );
+ }
+}
+void MoveCenterTabController::setRotationAroundPivot(
+ int value,
+ bool notify,
+ const vr::HmdVector3_t& pivot )
+{
+ if ( m_rotation != value )
+ {
+ double angle = ( value - m_rotation ) * k_centidegreesToRadians;
// Set up xyz coordinate values from pose matrix.
- double oldHmdXyz[3] = { static_cast( oldHmdPos.m[0][3] ),
- static_cast( oldHmdPos.m[1][3] ),
- static_cast( oldHmdPos.m[2][3] ) };
- double newHmdXyz[3] = { static_cast( oldHmdPos.m[0][3] ),
- static_cast( oldHmdPos.m[1][3] ),
- static_cast( oldHmdPos.m[2][3] ) };
-
- // Convert oldHmdXyz into un-rotated coordinates.
+ double oldXyz[3] = { static_cast( pivot.v[0] ),
+ static_cast( pivot.v[1] ),
+ static_cast( pivot.v[2] ) };
+ double newXyz[3] = { static_cast( pivot.v[0] ),
+ static_cast( pivot.v[1] ),
+ static_cast( pivot.v[2] ) };
+
+ // Convert oldXyz into un-rotated coordinates.
double oldAngle = -m_rotation * k_centidegreesToRadians;
- rotateCoordinates( oldHmdXyz, oldAngle );
+ rotateCoordinates( oldXyz, oldAngle );
- // Set newHmdXyz to have additional rotation from incoming angle change.
- rotateCoordinates( newHmdXyz, oldAngle - angle );
+ // Set newXyz to have additional rotation from incoming angle change.
+ rotateCoordinates( newXyz, 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] };
+ = { oldXyz[0] - newXyz[0], 0, oldXyz[2] - newXyz[2] };
m_rotation = value;
if ( notify )
@@ -999,12 +1010,10 @@ void MoveCenterTabController::reset()
m_offsetY = 0.0f;
m_offsetZ = 0.0f;
m_rotation = 0;
- m_lastControllerPosition[0] = 0.0f;
- m_lastControllerPosition[1] = 0.0f;
- m_lastControllerPosition[2] = 0.0f;
m_lastMoveHand = vr::TrackedControllerRole_Invalid;
m_lastRotateHand = vr::TrackedControllerRole_Invalid;
applyChaperoneResetData();
+ m_lastControllerPosition = { 0.0f, 0.0f, 0.0f };
// For Center Marker
// Needs to happen after apply chaperone
@@ -2211,9 +2220,91 @@ void MoveCenterTabController::updateHmdRotationCounter(
m_lastHmdQuaternion = m_hmdQuaternion;
}
+vr::HmdVector3_t MoveCenterTabController::relativeToAbsolute(
+ const vr::HmdVector3_t& relative ) const
+{
+ double relativeControllerPosition[]
+ = { static_cast( relative.v[0] ),
+ static_cast( relative.v[1] ),
+ static_cast( relative.v[2] ) };
+ rotateCoordinates( relativeControllerPosition,
+ -m_rotation * k_centidegreesToRadians );
+ vr::HmdVector3_t absoluteControllerPosition = {
+ static_cast( relativeControllerPosition[0] ) + m_offsetX,
+ static_cast( relativeControllerPosition[1] ) + m_offsetY,
+ static_cast( relativeControllerPosition[2] ) + m_offsetZ,
+ };
+ return absoluteControllerPosition;
+}
+
+vr::HmdVector3_t MoveCenterTabController::absoluteToRelative(
+ const vr::HmdVector3_t& absolute ) const
+{
+ double absoluteControllerPosition[]
+ = { static_cast( absolute.v[0] - m_offsetX ),
+ static_cast( absolute.v[1] - m_offsetY ),
+ static_cast( absolute.v[2] - m_offsetZ ) };
+ rotateCoordinates( absoluteControllerPosition,
+ m_rotation * k_centidegreesToRadians );
+ vr::HmdVector3_t relativeControllerPosition
+ = { static_cast( absoluteControllerPosition[0] ),
+ static_cast( absoluteControllerPosition[1] ),
+ static_cast( absoluteControllerPosition[2] ) };
+ return relativeControllerPosition;
+}
+
+// Displace the entire universe by some difference. Both 'from' and 'to' are in
+// absolute coordinates.
+void MoveCenterTabController::displaceUniverse( const vr::HmdVector3_t& from,
+ const vr::HmdVector3_t& to )
+{
+ double diff[3] = {
+ static_cast( to.v[0] - from.v[0] ),
+ static_cast( to.v[1] - from.v[1] ),
+ static_cast( to.v[2] - from.v[2] ),
+ };
+
+ // offset is un-rotated coordinates
+
+ // prevent positional glitches from exceeding max openvr offset clamps.
+ // We do this by detecting a drag larger than 100m in a single frame.
+ if ( abs( diff[0] ) > 100.0 || abs( diff[1] ) > 100.0
+ || abs( diff[2] ) > 100.0 )
+ {
+ reset();
+ }
+
+ // prevents updating if axis movement is locked
+ if ( !lockXToggle() )
+ {
+ m_offsetX += static_cast( diff[0] );
+ }
+ if ( !lockYToggle() )
+ {
+ m_offsetY += static_cast( diff[1] );
+ }
+ if ( !lockZToggle() )
+ {
+ m_offsetZ += static_cast( diff[2] );
+ }
+
+ double secondsSinceLastDragUpdate
+ = std::chrono::duration( std::chrono::steady_clock::now()
+ - m_lastDragUpdateTimePoint )
+ .count();
+
+ // TODO: Add 'effects fling' boolean? or simply return diff[] as a
+ // HmdVect3_t
+ m_velocity[0] = ( diff[0] / secondsSinceLastDragUpdate )
+ * static_cast( flingStrength() );
+ m_velocity[1] = ( diff[1] / secondsSinceLastDragUpdate )
+ * static_cast( flingStrength() );
+ m_velocity[2] = ( diff[2] / secondsSinceLastDragUpdate )
+ * static_cast( flingStrength() );
+}
+
void MoveCenterTabController::updateHandDrag(
- vr::TrackedDevicePose_t* devicePoses,
- double angle )
+ vr::TrackedDevicePose_t* devicePoses )
{
auto moveHandId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
m_activeDragHand );
@@ -2261,69 +2352,20 @@ void MoveCenterTabController::updateHandDrag(
return;
}
- double relativeControllerPosition[] = {
- static_cast( movePose->mDeviceToAbsoluteTracking.m[0][3] ),
- static_cast( movePose->mDeviceToAbsoluteTracking.m[1][3] ),
- static_cast( movePose->mDeviceToAbsoluteTracking.m[2][3] )
- };
-
- rotateCoordinates( relativeControllerPosition, -angle );
- float absoluteControllerPosition[] = {
- static_cast( relativeControllerPosition[0] ) + m_offsetX,
- static_cast( relativeControllerPosition[1] ) + m_offsetY,
- static_cast( relativeControllerPosition[2] ) + m_offsetZ,
- };
+ vr::HmdVector3_t relativeControllerPosition
+ = { movePose->mDeviceToAbsoluteTracking.m[0][3],
+ movePose->mDeviceToAbsoluteTracking.m[1][3],
+ movePose->mDeviceToAbsoluteTracking.m[2][3] };
+ auto absoluteControllerPosition
+ = relativeToAbsolute( relativeControllerPosition );
if ( m_lastMoveHand == m_activeDragHand )
{
- double diff[3] = {
- static_cast( absoluteControllerPosition[0]
- - m_lastControllerPosition[0] ),
- static_cast( absoluteControllerPosition[1]
- - m_lastControllerPosition[1] ),
- static_cast( absoluteControllerPosition[2]
- - m_lastControllerPosition[2] ),
- };
-
- // offset is un-rotated coordinates
-
- // prevent positional glitches from exceeding max openvr offset clamps.
- // We do this by detecting a drag larger than 100m in a single frame.
- if ( abs( diff[0] ) > 100.0 || abs( diff[1] ) > 100.0
- || abs( diff[2] ) > 100.0 )
- {
- reset();
- }
-
- // prevents updating if axis movement is locked
- if ( !lockXToggle() )
- {
- m_offsetX += static_cast( diff[0] );
- }
- if ( !lockYToggle() )
- {
- m_offsetY += static_cast( diff[1] );
- }
- if ( !lockZToggle() )
- {
- m_offsetZ += static_cast( diff[2] );
- }
-
- double secondsSinceLastDragUpdate
- = std::chrono::duration( std::chrono::steady_clock::now()
- - m_lastDragUpdateTimePoint )
- .count();
-
- m_velocity[0] = ( diff[0] / secondsSinceLastDragUpdate )
- * static_cast( flingStrength() );
- m_velocity[1] = ( diff[1] / secondsSinceLastDragUpdate )
- * static_cast( flingStrength() );
- m_velocity[2] = ( diff[2] / secondsSinceLastDragUpdate )
- * static_cast( flingStrength() );
+ // Displace from last controller position to current
+ displaceUniverse( m_lastControllerPosition,
+ absoluteControllerPosition );
}
- m_lastControllerPosition[0] = absoluteControllerPosition[0];
- m_lastControllerPosition[1] = absoluteControllerPosition[1];
- m_lastControllerPosition[2] = absoluteControllerPosition[2];
+ m_lastControllerPosition = absoluteControllerPosition;
m_lastMoveHand = m_activeDragHand;
}
@@ -3041,7 +3083,7 @@ void MoveCenterTabController::eventLoopTick(
if ( m_dragComfortFrameSkipCounter >= static_cast(
( dragComfortFactor() * dragComfortFactor() ) ) )
{
- updateHandDrag( devicePoses, angle );
+ updateHandDrag( devicePoses );
m_lastDragUpdateTimePoint = std::chrono::steady_clock::now();
m_dragComfortFrameSkipCounter = 0;
}
diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h
index 6759c552..104591ba 100644
--- a/src/tabcontrollers/MoveCenterTabController.h
+++ b/src/tabcontrollers/MoveCenterTabController.h
@@ -158,7 +158,7 @@ class MoveCenterTabController : public QObject
bool m_moveShortcutRightPressed = false;
bool m_moveShortcutLeftPressed = false;
vr::TrackedDeviceIndex_t m_activeMoveController;
- float m_lastControllerPosition[3];
+ vr::HmdVector3_t m_lastControllerPosition;
bool m_heightToggle = false;
float m_gravityFloor = 0.0f;
// Set lastHandQuaternion.w to -1000.0 when last hand is invalid.
@@ -227,7 +227,7 @@ class MoveCenterTabController : public QObject
void updateHmdRotationCounter( vr::TrackedDevicePose_t hmdPose,
double angle );
- void updateHandDrag( vr::TrackedDevicePose_t* devicePoses, double angle );
+ void updateHandDrag( vr::TrackedDevicePose_t* devicePoses );
void updateHandTurn( vr::TrackedDevicePose_t* devicePoses, double angle );
void updateGravity();
void updateSpace( bool forceUpdate = false );
@@ -283,6 +283,16 @@ class MoveCenterTabController : public QObject
void incomingSeatedReset();
void setBoundsBasisHeight( float newHeight );
float getBoundsBasisMaxY();
+ void setRotationAroundPivot( int value,
+ bool notify,
+ const vr::HmdVector3_t& pivot );
+ void displaceUniverse( const vr::HmdVector3_t& from,
+ const vr::HmdVector3_t& to );
+
+ vr::HmdVector3_t
+ relativeToAbsolute( const vr::HmdVector3_t& coordinates_in ) const;
+ vr::HmdVector3_t
+ absoluteToRelative( const vr::HmdVector3_t& absolute ) const;
void updateChaperoneResetData();
diff --git a/src/tabcontrollers/RotationTabController.cpp b/src/tabcontrollers/RotationTabController.cpp
index 07301f9f..d0b4c195 100644
--- a/src/tabcontrollers/RotationTabController.cpp
+++ b/src/tabcontrollers/RotationTabController.cpp
@@ -38,11 +38,27 @@ void RotationTabController::initStage2( OverlayController* var_parent )
constexpr auto autoturnIconFilepath = "/res/img/rotation/autoturn.png";
constexpr auto noautoturnIconFilepath = "/res/img/rotation/noautoturn.png";
+ constexpr auto alignPointOneIconFilepath
+ = "/res/img/rotation/autoalign1.png";
+ constexpr auto alignPointTwoIconFilepath
+ = "/res/img/rotation/autoalign2.png";
+ constexpr auto alignPointThreeIconFilepath
+ = "/res/img/rotation/autoalign3.png";
+ constexpr auto alignPointFourIconFilepath
+ = "/res/img/rotation/autoalign4.png";
const auto autoturnIconFilePath
= paths::verifyIconFilePath( autoturnIconFilepath );
const auto noautoturnIconFilePath
= paths::verifyIconFilePath( noautoturnIconFilepath );
+ const auto alignPointOneIconFilePath
+ = paths::verifyIconFilePath( alignPointOneIconFilepath );
+ const auto alignPointTwoIconFilePath
+ = paths::verifyIconFilePath( alignPointTwoIconFilepath );
+ const auto alignPointThreeIconFilePath
+ = paths::verifyIconFilePath( alignPointThreeIconFilepath );
+ const auto alignPointFourIconFilePath
+ = paths::verifyIconFilePath( alignPointFourIconFilepath );
if ( !autoturnIconFilePath.has_value()
|| !noautoturnIconFilePath.has_value() )
@@ -53,6 +69,10 @@ void RotationTabController::initStage2( OverlayController* var_parent )
m_autoturnValues.autoturnPath = *autoturnIconFilePath;
m_autoturnValues.noautoturnPath = *noautoturnIconFilePath;
+ m_autoturnValues.alignPointOnePath = *alignPointOneIconFilePath;
+ m_autoturnValues.alignPointTwoPath = *alignPointTwoIconFilePath;
+ m_autoturnValues.alignPointThreePath = *alignPointThreeIconFilePath;
+ m_autoturnValues.alignPointFourPath = *alignPointFourIconFilePath;
auto pushToPath = m_autoturnValues.autoturnPath.c_str();
@@ -79,6 +99,27 @@ void RotationTabController::eventLoopTick(
{
if ( devicePoses )
{
+ auto leftHandId
+ = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
+ vr::TrackedControllerRole_LeftHand );
+ if ( vr::k_unTrackedDeviceIndexInvalid
+ && devicePoses[leftHandId].bPoseIsValid
+ && devicePoses[leftHandId].eTrackingResult
+ == vr::TrackingResult_Running_OK )
+ {
+ lastLeftHandPose = devicePoses[leftHandId];
+ }
+ auto rightHandId
+ = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
+ vr::TrackedControllerRole_RightHand );
+ if ( vr::k_unTrackedDeviceIndexInvalid
+ && devicePoses[rightHandId].bPoseIsValid
+ && devicePoses[rightHandId].eTrackingResult
+ == vr::TrackingResult_Running_OK )
+ {
+ lastRightHandPose = devicePoses[rightHandId];
+ }
+
m_isHMDActive = false;
std::lock_guard lock(
parent->chaperoneUtils().mutex() );
@@ -578,6 +619,104 @@ void RotationTabController::doAutoTurn(
}
}
+void RotationTabController::addAutoAlignPoint( bool rightHanded )
+{
+ // TODO: State machine: if we have >2 align points, freeze vestibular
+ // motion/ratchetting/etc remain frozen until after we move away from the
+ // aligned area
+ const auto& lastHandPose
+ = rightHanded ? lastRightHandPose : lastLeftHandPose;
+
+ LOG( DEBUG ) << "point added: " << autoAlignPoints.size();
+ // get the location of hand, push_back onto autoAlignPoints
+ vr::HmdVector3_t new_point
+ = { lastHandPose.mDeviceToAbsoluteTracking.m[0][3],
+ lastHandPose.mDeviceToAbsoluteTracking.m[1][3],
+ lastHandPose.mDeviceToAbsoluteTracking.m[2][3] };
+ // TODO: Probably smarter to actually just keep the virtual points as
+ // virtual until we use them. Then if they drift we don't care.
+ vr::HmdVector3_t absolute_point
+ = parent->m_moveCenterTabController.relativeToAbsolute( new_point );
+ autoAlignPoints.push_back( absolute_point );
+
+ switch ( autoAlignPoints.size() )
+ {
+ case 1:
+ vr::VROverlay()->SetOverlayFromFile(
+ m_autoturnValues.overlayHandle,
+ m_autoturnValues.alignPointOnePath.c_str() );
+ break;
+ case 2:
+ vr::VROverlay()->SetOverlayFromFile(
+ m_autoturnValues.overlayHandle,
+ m_autoturnValues.alignPointTwoPath.c_str() );
+ break;
+ case 3:
+ vr::VROverlay()->SetOverlayFromFile(
+ m_autoturnValues.overlayHandle,
+ m_autoturnValues.alignPointThreePath.c_str() );
+ break;
+ case 4:
+ vr::VROverlay()->SetOverlayFromFile(
+ m_autoturnValues.overlayHandle,
+ m_autoturnValues.alignPointFourPath.c_str() );
+ break;
+ }
+
+ // TODO: configure whether auto-align has HUD popup independently
+ if ( autoTurnShowNotification()
+ && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid )
+ {
+ vr::VROverlay()->SetOverlayAlpha( getNotificationOverlayHandle(),
+ 1.0f );
+ vr::VROverlay()->ShowOverlay( getNotificationOverlayHandle() );
+ m_autoTurnNotificationTimestamp.emplace(
+ std::chrono::steady_clock::now() );
+ }
+
+ // if we have exactly 4 points, go into main loop
+ if ( autoAlignPoints.size() == 4 )
+ {
+ vr::HmdVector3_t realFirstPoint = autoAlignPoints[0];
+ vr::HmdVector3_t realSecondPoint = autoAlignPoints[1];
+ vr::HmdVector3_t virtualFirstPoint = autoAlignPoints[2];
+ vr::HmdVector3_t virtualSecondPoint = autoAlignPoints[3];
+
+ // Rotate the universe to align, pivoting around the real point
+ double realEdgeAngle = static_cast(
+ std::atan2( realFirstPoint.v[0] - realSecondPoint.v[0],
+ realFirstPoint.v[2] - realSecondPoint.v[2] ) );
+ double virtualEdgeAngle = static_cast(
+ std::atan2( virtualFirstPoint.v[0] - virtualSecondPoint.v[0],
+ virtualFirstPoint.v[2] - virtualSecondPoint.v[2] ) );
+ double delta_degrees
+ = ( realEdgeAngle - virtualEdgeAngle ) * k_radiansToCentidegrees;
+ int newRotationAngleDeg = static_cast(
+ parent->m_moveCenterTabController.rotation() + delta_degrees );
+
+ // these need to be in the new, offset position. TODO: needs to be
+ // converted into new relative position?
+ vr::HmdVector3_t autoAlignPivot = realFirstPoint;
+ autoAlignPivot.v[0] -= realFirstPoint.v[0] - virtualFirstPoint.v[0];
+ autoAlignPivot.v[1] -= realFirstPoint.v[1] - virtualFirstPoint.v[1];
+ autoAlignPivot.v[2] -= realFirstPoint.v[2] - virtualFirstPoint.v[2];
+
+ // TODO: if centered, use the center of both points as the pivot
+ parent->m_moveCenterTabController.setRotationAroundPivot(
+ newRotationAngleDeg,
+ true,
+ parent->m_moveCenterTabController.absoluteToRelative(
+ virtualFirstPoint ) );
+
+ // Align the first of VR points (points[2]) with the first of the real
+ // points (points[0]) purely in position
+ parent->m_moveCenterTabController.displaceUniverse( virtualFirstPoint,
+ realFirstPoint );
+
+ // end of main loop, clear autoAlignPoints
+ autoAlignPoints.clear();
+ }
+}
// getters
bool RotationTabController::autoTurnEnabled() const
diff --git a/src/tabcontrollers/RotationTabController.h b/src/tabcontrollers/RotationTabController.h
index de8253a5..3113e06b 100644
--- a/src/tabcontrollers/RotationTabController.h
+++ b/src/tabcontrollers/RotationTabController.h
@@ -101,6 +101,10 @@ class RotationTabController : public QObject
vr::VROverlayHandle_t overlayHandle = vr::k_ulOverlayHandleInvalid;
std::string autoturnPath;
std::string noautoturnPath;
+ std::string alignPointOnePath;
+ std::string alignPointTwoPath;
+ std::string alignPointThreePath;
+ std::string alignPointFourPath;
} m_autoturnValues;
virtual vr::VROverlayHandle_t getNotificationOverlayHandle()
@@ -121,6 +125,9 @@ class RotationTabController : public QObject
std::optional
m_autoTurnNotificationTimestamp;
+ std::vector autoAlignPoints;
+ vr::TrackedDevicePose_t lastLeftHandPose, lastRightHandPose;
+
bool m_isHMDActive = false;
void doAutoTurn(
@@ -171,6 +178,9 @@ public slots:
void setViewRatchettingEnabled( bool value, bool notify = true );
void setViewRatchettingPercent( double value, bool notify = true );
+ // Experimental - auto-align
+ void addAutoAlignPoint( bool rightHanded );
+
signals:
void defaultProfileDisplay();