New Feature: Control rotation during virtual move
It's now possible to rotate the playspace by turning the controller during a virtual move playspace drag. The feature is activated via a checkbox on the playspace tab. If X Y Z axis lock checkboxes are also checked only rotation will be applied. Offsets will still accumulate as the user swings the playspace around because rotation is now centered at head. This feature is intended for use with manual redirected walking (allowing the user to virtually walk in a straight line while walking circles in physical space). This distance walked is reflected in the X,Z offsets.
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
#include "MoveCenterTabController.h"
|
||||
#include <QQuickWindow>
|
||||
#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<int>( 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<float>( 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<float>( finalHmdRotDiff[0] ),
|
||||
static_cast<float>( finalHmdRotDiff[1] ),
|
||||
static_cast<float>( 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<float>( offset[0] ),
|
||||
static_cast<float>( offset[1] ),
|
||||
static_cast<float>( 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<float>( offset[0] ),
|
||||
static_cast<float>( offset[1] ),
|
||||
static_cast<float>( 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<float>( offset[0] ),
|
||||
static_cast<float>( offset[1] ),
|
||||
static_cast<float>( 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<float>( relativeControllerPosition[0] ) + m_offsetX,
|
||||
static_cast<float>( relativeControllerPosition[1] ) + m_offsetY,
|
||||
static_cast<float>( 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<float>( 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<float>( diff[0] ),
|
||||
static_cast<float>( diff[1] ),
|
||||
static_cast<float>( 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<int>(
|
||||
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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user