Files
OpenVR-AdvancedSettings-frame/src/tabcontrollers/MoveCenterTabController.cpp
T
Vasily 9a2c388a1c Solve initialization bug in MOveCenterTabController
GCC gave error

../src/tabcontrollers/MoveCenterTabController.cpp:57:67: error:
operation on
‘((advsettings::MoveCenterTabController*)this)->advsettings::MoveCenterTabController::lastMoveButtonClick[0]’
may be undefined [-Werror=sequence-point]

Because assigning a value to itself twice is undefined behavior. It is
highly likely that intended behavior was to initialize both array
members to the same value at once.
2018-12-27 12:14:07 +01:00

467 lines
14 KiB
C++

#include "MoveCenterTabController.h"
#include <QQuickWindow>
#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 {
using std::chrono::duration_cast;
using std::chrono::milliseconds;
typedef std::chrono::system_clock clock;
void MoveCenterTabController::initStage1() {
setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace());
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
auto value = settings->value("adjustChaperone", m_adjustChaperone);
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();
}
value = settings->value("requireDoubleClick", m_requireDoubleClick);
if (value.isValid() && !value.isNull()) {
m_requireDoubleClick = value.toBool();
}
value = settings->value("lockXToggle", m_lockXToggle);
if (value.isValid() && !value.isNull()) {
m_lockXToggle = value.toBool();
}
value = settings->value("lockYToggle", m_lockYToggle);
if (value.isValid() && !value.isNull()) {
m_lockYToggle = value.toBool();
}
value = settings->value("lockZToggle", m_lockZToggle);
if (value.isValid() && !value.isNull()) {
m_lockZToggle = value.toBool();
}
settings->endGroup();
lastMoveButtonClick[0] = lastMoveButtonClick[1] = clock::now();
}
void MoveCenterTabController::initStage2(OverlayController * parent, QQuickWindow * widget) {
this->parent = parent;
this->widget = widget;
}
int MoveCenterTabController::trackingUniverse() const {
return (int)m_trackingUniverse;
}
void MoveCenterTabController::setTrackingUniverse(int value, bool notify) {
if (m_trackingUniverse != value) {
reset();
m_trackingUniverse = value;
if (notify) {
emit trackingUniverseChanged(m_trackingUniverse);
}
}
}
float MoveCenterTabController::offsetX() const {
return m_offsetX;
}
void MoveCenterTabController::setOffsetX(float value, bool notify) {
if (m_offsetX != value) {
modOffsetX(value - m_offsetX, notify);
}
}
float MoveCenterTabController::offsetY() const {
return m_offsetY;
}
void MoveCenterTabController::setOffsetY(float value, bool notify) {
if (m_offsetY != value) {
modOffsetY(value - m_offsetY, notify);
}
}
float MoveCenterTabController::offsetZ() const {
return m_offsetZ;
}
void MoveCenterTabController::setOffsetZ(float value, bool notify) {
if (m_offsetZ != value) {
modOffsetZ(value - m_offsetZ, notify);
}
}
int MoveCenterTabController::rotation() const {
return m_rotation;
}
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);
m_rotation = value;
if (notify) {
emit rotationChanged(m_rotation);
}
}
}
void MoveCenterTabController::applyRotation() {
if (m_rotation != m_rotationOld) {
float angle = (m_rotationOld - m_rotation) * 2 * M_PI / 360.0;
parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone);
m_rotationOld = m_rotation;
}
}
bool MoveCenterTabController::adjustChaperone() const {
return m_adjustChaperone;
}
void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) {
if (m_adjustChaperone != value) {
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
};
rotateCoordinates(offset, angle);
parent->AddOffsetToCollisionBounds(offset);
}
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
settings->setValue("adjustChaperone", m_adjustChaperone);
settings->endGroup();
settings->sync();
if (notify) {
emit adjustChaperoneChanged(m_adjustChaperone);
}
}
}
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);
}
}
bool MoveCenterTabController::requireDoubleClick() const {
return m_requireDoubleClick;
}
void MoveCenterTabController::setRequireDoubleClick(bool value, bool notify) {
m_requireDoubleClick = value;
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
settings->setValue("requireDoubleClick", m_requireDoubleClick);
settings->endGroup();
settings->sync();
if (notify) {
emit requireDoubleClickChanged(m_requireDoubleClick);
}
}
bool MoveCenterTabController::lockXToggle() const {
return m_lockXToggle;
}
void MoveCenterTabController::setLockX(bool value, bool notify) {
m_lockXToggle = value;
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
settings->setValue("lockXToggle", m_lockXToggle);
settings->endGroup();
settings->sync();
if (notify) {
emit requireLockXChanged(m_lockXToggle);
}
}
bool MoveCenterTabController::lockYToggle() const {
return m_lockYToggle;
}
void MoveCenterTabController::setLockY(bool value, bool notify) {
m_lockYToggle = value;
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
settings->setValue("lockYToggle", m_lockYToggle);
settings->endGroup();
settings->sync();
if (notify) {
emit requireLockYChanged(m_lockYToggle);
}
}
bool MoveCenterTabController::lockZToggle() const {
return m_lockZToggle;
}
void MoveCenterTabController::setLockZ(bool value, bool notify) {
m_lockZToggle = value;
auto settings = OverlayController::appSettings();
settings->beginGroup("playspaceSettings");
settings->setValue("lockZToggle", m_lockZToggle);
settings->endGroup();
settings->sync();
if (notify) {
emit requireLockZChanged(m_lockZToggle);
}
}
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 };
rotateCoordinates(offset, angle);
parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone);
m_offsetX += value;
if (notify) {
emit offsetXChanged(m_offsetX);
}
}
}
void MoveCenterTabController::modOffsetY(float value, bool notify) {
if (!m_lockYToggle) {
parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, value, m_adjustChaperone);
m_offsetY += value;
if (notify) {
emit offsetYChanged(m_offsetY);
}
}
}
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 };
rotateCoordinates(offset, angle);
parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone);
m_offsetZ += value;
if (notify) {
emit offsetZChanged(m_offsetZ);
}
}
}
void MoveCenterTabController::reset() {
vr::VRChaperoneSetup()->RevertWorkingCopy();
parent->RotateUniverseCenter((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, offset, m_adjustChaperone, false);
vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live);
m_offsetX = 0.0f;
m_offsetY = 0.0f;
m_offsetZ = 0.0f;
m_rotation = 0;
emit offsetXChanged(m_offsetX);
emit offsetYChanged(m_offsetY);
emit offsetZChanged(m_offsetZ);
emit rotationChanged(m_rotation);
}
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);
bool checkDoubleClick = m_requireDoubleClick && activeHand == vr::TrackedControllerRole_Invalid;
auto now = clock::now();
// if we start pressing the shortcut on a controller we set the active one to it
if (rightPressed && !m_moveShortcutRightPressed) {
auto elapsed = duration_cast<milliseconds>(now - lastMoveButtonClick[0]).count();
if (!checkDoubleClick || elapsed < 250) {
activeHand = vr::TrackedControllerRole_RightHand;
}
lastMoveButtonClick[0] = now;
}
if (leftPressed && !m_moveShortcutLeftPressed) {
auto elapsed = duration_cast<milliseconds>(now - lastMoveButtonClick[1]).count();
if (!checkDoubleClick || elapsed < 250) {
activeHand = vr::TrackedControllerRole_LeftHand;
}
lastMoveButtonClick[1] = now;
}
// 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;
if (m_activeMoveController != vr::TrackedControllerRole_Invalid) {
// grace period while switching hands
lastMoveButtonClick[0] = lastMoveButtonClick[1] = now;
}
}
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
//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;
}
parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, diff, m_adjustChaperone);
}
m_lastControllerPosition[0] = absoluteControllerPosition[0];
m_lastControllerPosition[1] = absoluteControllerPosition[1];
m_lastControllerPosition[2] = absoluteControllerPosition[2];
}
}
} // namespace advconfig