5.4.0 Raw Restriction Setting, Apply Offsets (#577)

* Crash Recovery Defaults to Off, add option to use space drag w/ uncalibrated playspace

* increment version 5.3.3

* Feat/apply offsets binding (#576)

* add apply offsets steamvr input

* add new binding to Readme

Co-authored-by: TheMrGong <gongora656@gmail.com>

* increment version 5.4.0

* added LH Console Interface class, WIP TX/RX list via lh console

* switch over to property based dongle information

* add ovr system wrapper

* add use of parameter to avoid warning as error

* openXR fix, and Change Display State of Chaperone Disabled

* update text

* format files

* clang 9.0.0 format

* add documentation update

* remove windows header include

* remove filesystem header

* fix uncal motion switching issue

Co-authored-by: TheMrGong <gongora656@gmail.com>
This commit is contained in:
ykeara
2022-02-23 16:06:03 -06:00
committed by GitHub
co-authored by TheMrGong
parent 522ba46ac6
commit eea713429d
24 changed files with 992 additions and 14 deletions
+1
View File
@@ -187,6 +187,7 @@ Override actions will take priority over non-override actions during simultaneou
| Gravity Toggle | Binary/Button | Toggles Gravity state when pressed. |
| Gravity Reverse | Binary/Button | Temporarily Reverses Gravity while held. |
| Reset Offsets | Binary/Button | Resets your offset and rotation to 0. |
| Apply Offsets | Binary/Button | Recalibrates center/rotation from offsets |
| Height Toggle | Binary/Button | Shifts the gravity floor level by offset configured in motion tab. If gravity is inactive: also shifts the user's current y-axis position by offset configured in motion tab. |
| Snap-Turn Left | Binary/Button | Rotates a set value to the left based on settings in motion tab. |
| Snap-Turn Right | Binary/Button | Rotates a set value to the right based on settings in motion tab. |
+1 -1
View File
@@ -1 +1 @@
5.3.2-release
5.4.0-release
+1
View File
@@ -37,6 +37,7 @@ DISTFILES += \
src/res/qml/SettingsPage.qml \
src/res/qml/StatisticsPage.qml \
src/res/qml/steamvr_page/SteamVRPage.qml \
src/res/qml/steamvr_page/steamvr_additional/* \
src/res/qml/steamvr_page/camera/* \
src/res/qml/steamvr_page/steamvrmisc/* \
src/res/qml/utilities_page/* \
+4
View File
@@ -15,6 +15,8 @@ SOURCES += src/main.cpp\
src/openvr/ivrinput.cpp \
src/openvr/ovr_settings_wrapper.cpp \
src/openvr/ovr_overlay_wrapper.cpp \
src/openvr/ovr_system_wrapper.cpp \
src/openvr/lh_console_util.cpp \
src/utils/setup.cpp \
src/utils/paths.cpp \
src/utils/FrameRateUtils.cpp \
@@ -52,6 +54,8 @@ HEADERS += src/overlaycontroller.h \
src/openvr/ivrinput.h \
src/openvr/ovr_settings_wrapper.h \
src/openvr/ovr_overlay_wrapper.h \
src/openvr/ovr_system_wrapper.h \
src/openvr/lh_console_util.h \
src/utils/setup.h \
src/utils/paths.h \
src/utils/FrameRateUtils.h \
+1
View File
@@ -21,6 +21,7 @@ For pushing changes to the repo:
2. Clang format. Part of the [LLVM collection](https://releases.llvm.org/download.html).
- **note** use version 9.0.1/9.0.0 of LLVM
Additionally, for fully building portable and installer release versions:
+6
View File
@@ -127,6 +127,7 @@ SteamIVRInput::SteamIVRInput()
m_gravityReverse( action_keys::gravityReverse ),
m_heightToggle( action_keys::heightToggle ),
m_resetOffsets( action_keys::resetOffsets ),
m_applyOffsets( action_keys::applyOffsets ),
m_snapTurnLeft( action_keys::snapTurnLeft ),
m_snapTurnRight( action_keys::snapTurnRight ),
m_smoothTurnLeft( action_keys::smoothTurnLeft ),
@@ -277,6 +278,11 @@ bool SteamIVRInput::resetOffsets()
return isDigitalActionActivatedOnce( m_resetOffsets );
}
bool SteamIVRInput::applyOffsets()
{
return isDigitalActionActivatedOnce( m_applyOffsets );
}
bool SteamIVRInput::snapTurnLeft()
{
return isDigitalActionActivatedOnce( m_snapTurnLeft );
+3
View File
@@ -41,6 +41,7 @@ namespace action_keys
constexpr auto gravityToggle = "/actions/motion/in/GravityToggle";
constexpr auto gravityReverse = "/actions/motion/in/GravityReverse";
constexpr auto resetOffsets = "/actions/motion/in/ResetOffsets";
constexpr auto applyOffsets = "/actions/motion/in/ApplyOffsets";
constexpr auto heightToggle = "/actions/motion/in/HeightToggle";
constexpr auto snapTurnLeft = "/actions/motion/in/SnapTurnLeft";
constexpr auto snapTurnRight = "/actions/motion/in/SnapTurnRight";
@@ -146,6 +147,7 @@ public:
bool gravityReverse();
bool heightToggle();
bool resetOffsets();
bool applyOffsets();
bool snapTurnLeft();
bool snapTurnRight();
bool smoothTurnLeft();
@@ -228,6 +230,7 @@ private:
DigitalAction m_gravityReverse;
DigitalAction m_heightToggle;
DigitalAction m_resetOffsets;
DigitalAction m_applyOffsets;
DigitalAction m_snapTurnLeft;
DigitalAction m_snapTurnRight;
DigitalAction m_smoothTurnLeft;
+151
View File
@@ -0,0 +1,151 @@
#include "lh_console_util.h"
namespace lh_con_util
{
bool LHCUtil::FindAll()
{
if ( !FindAllRX() )
{
LOG( ERROR ) << "Find All Recievers Failed";
return false;
}
if ( !FindAllTX() )
{
LOG( ERROR ) << "Find All Transmitters Failed";
return false;
}
return true;
}
bool LHCUtil::FindAllRX()
{
QProcess* lhProcess = new QProcess();
QString program = "lighthouse_console.exe";
lhProcess->start( path_, QStringList() << "" );
lhProcess->waitForFinished();
QString output = QString( lhProcess->readAllStandardOutput() );
QStringList outputLines
= output.split( QRegExp( "[\r\n]" ), QString::SkipEmptyParts );
bool RecieverStart = false;
for ( auto OutputLine : outputLines )
{
if ( OutputLine.contains( "Attached lighthouse receiver devices:" ) )
{
RecieverStart = true;
continue;
}
if ( RecieverStart )
{
if ( OutputLine.contains( "lighthouse_console" ) )
{
break;
}
OutputLine.simplified().remove( " " );
OutputLine.remove( 0, 1 );
// LOG( WARNING ) << OutputLine << std::endl;
RXTX_Pairs_.push_back( RXTX_Pair{ OutputLine, " ", true, false } );
}
}
return !RXTX_Pairs_.empty();
}
bool LHCUtil::FindConnectedTX( QString RXSerial )
{
LOG( WARNING ) << RXSerial;
QProcess* lhProcess = new QProcess();
lhProcess->start( path_, QStringList() << "/serial" << RXSerial << "exit" );
lhProcess->waitForFinished();
QString output = QString( lhProcess->readAllStandardOutput() );
QStringList outputLines
= output.split( QRegExp( "[\r\n]" ), QString::SkipEmptyParts );
// std::vector<std::string> OutputLines
// = exec( ( "\"" + path_ + "\" /serial " + RXSerial + " exit" ).c_str()
// );
bool lhConFound = false;
for ( auto outputLine : outputLines )
{
// LOG( WARNING ) << outputLine;
if ( outputLine.contains( "Connected to receiver" ) )
{
auto splitList = outputLine.split( ":" );
QString TXSerial = splitList[0];
if ( TXSerial == "lighthouse_console" )
{
lhConFound = true;
continue;
}
for ( auto& rxtx : RXTX_Pairs_ )
{
if ( rxtx.RX_Serial == RXSerial )
{
rxtx.TX_Serial = TXSerial;
rxtx.Is_Paired = true;
rxtx.Is_Init = true;
LOG( WARNING )
<< "tx serial stored: " << TXSerial.toStdString();
return true;
}
}
// TODO error handling
return false;
}
}
if ( lhConFound )
{
for ( auto rxtx : RXTX_Pairs_ )
{
if ( rxtx.RX_Serial == RXSerial )
{
rxtx.TX_Serial = "";
rxtx.Is_Paired = false;
rxtx.Is_Init = true;
LOG( WARNING ) << "tx oops";
return true;
}
}
}
// TODO error handling
return false;
}
bool LHCUtil::FindAllTX()
{
bool NoError = true;
for ( auto rxtx : RXTX_Pairs_ )
{
if ( !FindConnectedTX( rxtx.RX_Serial ) )
{
NoError = false;
}
}
return NoError;
}
QString LHCUtil::GetLinkedTX( QString RXSerial )
{
for ( auto rxtx : RXTX_Pairs_ )
{
if ( rxtx.RX_Serial == RXSerial )
{
return rxtx.TX_Serial;
}
}
return "";
}
QString LHCUtil::GetLinkedRX( QString TXSerial )
{
for ( auto rxtx : RXTX_Pairs_ )
{
if ( rxtx.TX_Serial == TXSerial )
{
return rxtx.RX_Serial;
}
}
return "";
}
} // namespace lh_con_util
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include "openvr.h"
#include <vector>
#include <utility>
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
#include <QProcess>
#include <QString>
#include <QStringList>
#include <QRegularExpression>
#include <easylogging++.h>
namespace lh_con_util
{
struct RXTX_Pair
{
QString RX_Serial = "";
QString TX_Serial = "";
bool Is_Init = false;
bool Is_Paired = false;
};
class LHCUtil
{
private:
QString path_;
bool InPairs( std::string RXSerial );
bool FindAllRX();
bool FindAllTX();
bool path_Init = false;
public:
explicit LHCUtil( QString path )
{
path_ = path;
}
std::vector<RXTX_Pair> RXTX_Pairs_;
bool FindAll();
bool FindConnectedTX( QString RXSerial );
QString GetLinkedTX( QString RXSerial );
QString GetLinkedRX( QString TXSerial );
RXTX_Pair GetConnectedTXRXPair();
bool pairDevice( QString RXSerial );
};
} // namespace lh_con_util
+234
View File
@@ -0,0 +1,234 @@
#include "ovr_system_wrapper.h"
namespace ovr_system_wrapper
{
SystemError handleTrackedPropertyErrors( vr::TrackedDeviceProperty tdp,
vr::ETrackedPropertyError error,
std::string customErrorMsg )
{
if ( error != vr::TrackedProp_Success )
{
LOG( ERROR ) << "Could not get Property with error \""
<< vr::VRSystem()->GetPropErrorNameFromEnum( error )
<< "\" property: "
<< "todo"
<< " " << customErrorMsg;
if ( tdp == vr::Prop_TrackedDeviceProperty_Max )
{
// Just for Error OPPS todo
}
return SystemError::UndefinedError;
}
return SystemError::NoError;
}
std::string getPropertyFromTrackedEnum( vr::TrackedDeviceProperty )
{
return "TODO";
}
std::pair<SystemError, bool>
getBoolTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg )
{
uint32_t unIndex = static_cast<uint32_t>( deviceIndex );
vr::ETrackedPropertyError error;
bool value;
value = vr::VRSystem()->GetBoolTrackedDeviceProperty(
unIndex, property, &error );
SystemError e
= handleTrackedPropertyErrors( property, error, customErrorMsg );
std::pair<SystemError, bool> p( e, value );
return p;
}
std::pair<SystemError, int>
getInt32TrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg )
{
uint32_t unIndex = static_cast<uint32_t>( deviceIndex );
int value;
vr::ETrackedPropertyError error;
value = static_cast<int>( vr::VRSystem()->GetInt32TrackedDeviceProperty(
unIndex, property, &error ) );
SystemError e
= handleTrackedPropertyErrors( property, error, customErrorMsg );
std::pair<SystemError, int> p( e, value );
return p;
}
std::pair<SystemError, float>
getFloatTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg )
{
uint32_t unIndex = static_cast<uint32_t>( deviceIndex );
vr::ETrackedPropertyError error;
float value;
value = vr::VRSystem()->GetFloatTrackedDeviceProperty(
unIndex, property, &error );
SystemError e
= handleTrackedPropertyErrors( property, error, customErrorMsg );
std::pair<SystemError, float> p( e, value );
return p;
}
std::pair<SystemError, std::string>
getStringTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg )
{
// This appears to be correct value as set in CVRSettingHelper as of
// ovr 1.11.11
const uint32_t bufferMax = 4096;
char cStringOut[bufferMax];
uint32_t unIndex = static_cast<uint32_t>( deviceIndex );
vr::VRSystem()->GetStringTrackedDeviceProperty(
unIndex, property, cStringOut, bufferMax );
std::string value = cStringOut;
SystemError e = handleTrackedPropertyErrors(
property, vr::TrackedProp_Success, customErrorMsg );
std::pair<SystemError, std::string> p( e, value );
return p;
}
bool deviceConnected( int index )
{
uint32_t unIndex = static_cast<uint32_t>( index );
return vr::VRSystem()->IsTrackedDeviceConnected( unIndex );
}
vr::ETrackedDeviceClass getDeviceClass( int index )
{
uint32_t unIndex = static_cast<uint32_t>( index );
return vr::VRSystem()->GetTrackedDeviceClass( unIndex );
}
std::string getDeviceName( int index )
{
uint32_t unIndex = static_cast<uint32_t>( index );
// checks if connected returns unknown if not
if ( !vr::VRSystem()->IsTrackedDeviceConnected( unIndex ) )
{
return "No Device Connected";
}
// arbitary max size OVR specifies 32*1024 but that's unrealistic
auto controllerNamePair
= getStringTrackedProperty( index, vr::Prop_ControllerType_String );
if ( controllerNamePair.first != SystemError::NoError )
{
return "Error";
}
std::string cn = controllerNamePair.second;
if ( strcmp( cn.c_str(), "oculus_touch" ) == 0 )
{
return "Touch";
}
if ( strcmp( cn.c_str(), "knuckles" ) == 0 )
{
return "Knuckles";
}
if ( strcmp( cn.c_str(), "vive_controller" ) == 0 )
{
return "Wand";
}
if ( strcmp( cn.c_str(), "hpmotioncontroller" ) == 0 )
{
return "Reverb G2 WMR";
}
if ( strcmp( cn.c_str(), "holographic_controller" ) == 0 )
{
return "WMR";
}
if ( strcmp( cn.c_str(), "vive_cosmos_controller" ) == 0 )
{
return "Cosmos";
}
if ( strcmp( cn.c_str(), "vive_tracker" ) == 0 )
{
return "Tracker";
}
if ( strcmp( cn.c_str(), "indexhmd" ) == 0 )
{
return "Index Headset";
}
if ( cn.find( "vive_tracker_" ) != std::string::npos )
{
std::string side = "";
if ( cn.find( "_left" ) != std::string::npos )
{
side = "left ";
}
else if ( cn.find( "_right" ) != std::string::npos )
{
side = "right ";
}
std::string part = "";
if ( cn.find( "handed" ) != std::string::npos )
{
part = " hand";
}
else if ( cn.find( "shoulder" ) != std::string::npos )
{
part = "shoulder";
}
else if ( cn.find( "knee" ) != std::string::npos )
{
part = "knee";
}
else if ( cn.find( "elbow" ) != std::string::npos )
{
part = "elbow";
}
else if ( cn.find( "foot" ) != std::string::npos )
{
part = "foot";
}
else if ( cn.find( "camera" ) != std::string::npos )
{
part = "camera";
}
else if ( cn.find( "waist" ) != std::string::npos )
{
part = "waist";
}
return "Tracker " + side + part;
}
// TODO add HMD's
return std::string( controllerNamePair.second );
}
std::vector<int> getAllConnectedDevices( bool onlyWearable )
{
std::vector<int> output;
for ( int i = 0; i < static_cast<int>( vr::k_unMaxTrackedDeviceCount );
i++ )
{
if ( deviceConnected( i ) )
{
auto deviceClass = getDeviceClass( i );
if ( onlyWearable )
{
if ( deviceClass == vr::TrackedDeviceClass_Controller
|| deviceClass == vr::TrackedDeviceClass_GenericTracker
|| deviceClass == vr::TrackedDeviceClass_HMD )
{
output.push_back( i );
}
}
else
{
output.push_back( i );
}
}
}
return output;
}
} // namespace ovr_system_wrapper
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <openvr.h>
#include <iostream>
#include <string>
#include <easylogging++.h>
#include <utility>
#include <map>
/* Wrapper For OpenVR's IVR settings class, allows us to do our error logging
* while also minimizing code
*
*/
namespace ovr_system_wrapper
{
// might make sense to mirror ovr's errors exactly, but for now this is more
// than sufficient
enum class SystemError
{
NoError,
UndefinedError,
};
std::pair<SystemError, bool>
getBoolTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg = "" );
std::pair<SystemError, int>
getInt32TrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg = "" );
std::pair<SystemError, float>
getFloatTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg = "" );
std::pair<SystemError, std::string>
getStringTrackedProperty( int deviceIndex,
vr::TrackedDeviceProperty property,
std::string customErrorMsg = "" );
SystemError handleTrackedPropertyErrors( vr::TrackedDeviceProperty tdp,
vr::ETrackedPropertyError error,
std::string customErrorMsg );
std::string getPropertyFromEnum( vr::TrackedDeviceProperty );
bool deviceConnected( int Index );
vr::ETrackedDeviceClass getDeviceClass( int index );
std::vector<int> getAllConnectedDevices( bool onlyWearable = false );
std::string getDeviceName( int index );
} // namespace ovr_system_wrapper
+31 -2
View File
@@ -602,6 +602,7 @@ void OverlayController::processMotionBindings()
m_actions.gravityReverse() );
m_moveCenterTabController.heightToggleAction( m_actions.heightToggle() );
m_moveCenterTabController.resetOffsets( m_actions.resetOffsets() );
m_moveCenterTabController.applyOffsets( m_actions.applyOffsets() );
m_moveCenterTabController.snapTurnLeft( m_actions.snapTurnLeft() );
m_moveCenterTabController.snapTurnRight( m_actions.snapTurnRight() );
m_moveCenterTabController.smoothTurnLeft( m_actions.smoothTurnLeft() );
@@ -818,16 +819,32 @@ void OverlayController::setExclusiveInputEnabled( bool value, bool notify )
}
}
void OverlayController::setOpenXRFixEnabled( bool value, bool notify )
{
settings::setSetting( settings::BoolSetting::APPLICATION_openXRWorkAround,
value );
if ( notify )
{
emit openXRFixEnabledChanged( value );
}
}
bool OverlayController::openXRFixEnabled() const
{
return settings::getSetting(
settings::BoolSetting::APPLICATION_openXRWorkAround );
}
bool OverlayController::crashRecoveryDisabled() const
{
return settings::getSetting(
settings::BoolSetting::APPLICATION_crashRecoveryDisabled );
settings::BoolSetting::APPLICATION_crashRecoveryDisabled2 );
}
void OverlayController::setCrashRecoveryDisabled( bool value, bool notify )
{
settings::setSetting(
settings::BoolSetting::APPLICATION_crashRecoveryDisabled, value );
settings::BoolSetting::APPLICATION_crashRecoveryDisabled2, value );
if ( notify )
{
emit crashRecoveryDisabledChanged( value );
@@ -1240,6 +1257,18 @@ void OverlayController::mainEventLoop()
= std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
}
auto universe = vr::VRCompositor()->GetTrackingSpace();
// This Fix is hopefully temporary as OpenVR doesn't appear to have a way to
// tell if an application is OpenXR outside of VR_init which we don't have
// control over
if ( vr::VRApplications()->GetApplicationProcessId(
"openvr.tool.steamvr_room_setup" )
== 0
&& openXRFixEnabled() )
{
// OpenXR applications will appear as RawAndUncalibrated.
// Unless Room Setup is running, treat this case as Standing.
universe = vr::TrackingUniverseStanding;
}
m_moveCenterTabController.eventLoopTick( universe, devicePoses );
m_utilitiesTabController.eventLoopTick();
+5
View File
@@ -93,6 +93,8 @@ class OverlayController : public QObject
Q_PROPERTY(
bool exclusiveInputEnabled READ exclusiveInputEnabled WRITE
setExclusiveInputEnabled NOTIFY exclusiveInputEnabledChanged )
Q_PROPERTY( bool openXRFixEnabled READ openXRFixEnabled WRITE
setOpenXRFixEnabled NOTIFY openXRFixEnabledChanged )
private:
vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid;
@@ -238,6 +240,7 @@ public:
bool crashRecoveryDisabled() const;
bool exclusiveInputEnabled() const;
bool openXRFixEnabled() const;
bool enableDebug() const;
bool disableVersionCheck() const;
bool newVersionDetected() const;
@@ -270,6 +273,7 @@ public slots:
void setVsyncDisabled( bool value, bool notify = true );
void setCustomTickRateMs( int value, bool notify = true );
void setDebugState( int value, bool notify = true );
void setOpenXRFixEnabled( bool value, bool notify = true );
signals:
void keyBoardInputSignal( QString input, unsigned long userValue = 0 );
@@ -282,6 +286,7 @@ signals:
void vsyncDisabledChanged( bool value );
void customTickRateMsChanged( int value );
void debugStateChanged( int value );
void openXRFixEnabledChanged( bool value );
};
} // namespace advsettings
+7 -1
View File
@@ -131,7 +131,12 @@
"requirement": "optional",
"type": "boolean"
},
{
"name": "/actions/motion/in/ApplyOffsets",
"requirement": "optional",
"type": "boolean"
},
{
"name": "/actions/motion/in/HeightToggle",
@@ -282,6 +287,7 @@
"/actions/motion/in/GravityToggle" : "Gravity Toggle",
"/actions/motion/in/GravityReverse" : "Gravity Reverse",
"/actions/motion/in/ResetOffsets" : "Reset Offsets",
"/actions/motion/in/ApplyOffsets" : "Apply Offsets",
"/actions/motion/in/HeightToggle" : "Height Toggle",
"/actions/motion/in/SnapTurnLeft" : "Snap-Turn Left",
"/actions/motion/in/SnapTurnRight" : "Snap-Turn Right",
+30 -5
View File
@@ -62,10 +62,26 @@ MyStackViewPage {
}
MyToggleButton {
id: disableCrashRecoveryToggle
text: "Disable Automatic Crash Recovery of Chaperone Config"
id: enableUnccalMotionToggle
text: "Enable Motion Features When in Uncalibrated Mode (Experimental)"
onCheckedChanged: {
OverlayController.setCrashRecoveryDisabled(checked, true)
MoveCenterTabController.setEnableUncalMotion(checked, true);
}
}
MyToggleButton {
id: openXRFixToggle
text: "OpenXR Fix (force standing universe [Experimental])"
onCheckedChanged: {
OverlayController.setOpenXRFixEnabled(checked, true);
}
}
MyToggleButton {
id: disableCrashRecoveryToggle
text: "Enable Automatic Crash Recovery of Chaperone Config"
onCheckedChanged: {
OverlayController.setCrashRecoveryDisabled(!checked, true)
}
}
@@ -251,8 +267,9 @@ MyStackViewPage {
oldStyleMotionToggle.checked = MoveCenterTabController.oldStyleMotion
universeCenteredRotationToggle.checked = MoveCenterTabController.universeCenteredRotation
enableSeatedMotionToggle.checked = MoveCenterTabController.enableSeatedMotion
enableUnccalMotionToggle.checked = MoveCenterTabController.enableUncalMotion
disableCrashRecoveryToggle.checked = OverlayController.crashRecoveryDisabled
disableCrashRecoveryToggle.checked = !OverlayController.crashRecoveryDisabled
customTickRateText.text = OverlayController.customTickRateMs
vsyncDisabledToggle.checked = OverlayController.vsyncDisabled
customTickRateText.visible = vsyncDisabledToggle.checked
@@ -264,6 +281,8 @@ MyStackViewPage {
nativeChaperoneToggleButton.checked = SettingsTabController.nativeChaperoneToggle
oculusSdkToggleButton.checked = SettingsTabController.oculusSdkToggle
exclusiveInputToggleButton.checked = OverlayController.exclusiveInputEnabled
openXRFixToggle.checked = OverlayController.openXRFixEnabled
seatedOldExternalWarning.visible = MoveCenterTabController.allowExternalEdits && MoveCenterTabController.oldStyleMotion && MoveCenterTabController.enableSeatedMotion
spaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone
@@ -299,6 +318,9 @@ MyStackViewPage {
enableSeatedMotionToggle.checked = MoveCenterTabController.enableSeatedMotion
seatedOldExternalWarning.visible = MoveCenterTabController.allowExternalEdits && MoveCenterTabController.oldStyleMotion && MoveCenterTabController.enableSeatedMotion
}
onEnableUncalMotionChanged: {
enableUnccalMotionToggle.checked = MoveCenterTabController.enableUncalMotion
}
onAdjustChaperoneChanged: {
spaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone
}
@@ -313,7 +335,7 @@ MyStackViewPage {
customTickRateMsLabel.visible = vsyncDisabledToggle.checked
}
onCrashRecoveryDisabledChanged: {
disableCrashRecoveryToggle.checked = OverlayController.crashRecoveryDisabled
disableCrashRecoveryToggle.checked = !OverlayController.crashRecoveryDisabled
}
onCustomTickRateMsChanged: {
@@ -333,6 +355,9 @@ MyStackViewPage {
onExclusiveInputEnabledChanged:{
exclusiveInputToggleButton.checked = OverlayController.exclusiveInputEnabled
}
onOpenXRFixEnabledChanged:{
openXRFixToggle.checked = OverlayController.openXRFixEnabled
}
}
} // end scroll
}
+6
View File
@@ -10,6 +10,7 @@ import "../chaperone_page"
import "../steamvr_page"
import "../rotation_page"
import "../chaperone_page/chaperone_additional"
import "../steamvr_page/steamvr_additional"
Rectangle {
id: root
@@ -41,6 +42,11 @@ Rectangle {
visible: false
}
property SteamVRTXRXPage steamVRTXRXPage: SteamVRTXRXPage{
stackView: mainView
visible: false
}
property PlayspacePage playspacePage: PlayspacePage {
stackView: mainView
visible: false
+10
View File
@@ -23,6 +23,16 @@ MyStackViewPage {
RowLayout {
Layout.fillWidth: true
MyPushButton {
text: "Device Pairing Information"
Layout.preferredWidth: 350
onClicked: {
MyResources.playFocusChangedSound()
mainView.push(steamVRTXRXPage)
}
}
Item { Layout.fillWidth: true}
MyPushButton {
@@ -0,0 +1,164 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import ovras.advsettings 1.0
import "." // QTBUG-34418, singletons require explicit import to load qmldir file
import "../../common"
MyStackViewPage {
ListModel{
id: listModelRXTX
ListElement{
TX:"Controller"
RX:"Reciever"
Dev:"device"
DT: "Dongle Type"
}
}
headerText: "Device Pairing Information"
content:
ColumnLayout {
spacing: 10
Layout.fillWidth: true
Layout.fillHeight: true
RowLayout{
MyText{
text: "dongles used: "
Layout.preferredWidth: 200
}
MyText{
id: donglesUse
text: ""
Layout.preferredWidth: 100
}
Item{
Layout.fillWidth: true
}
MyPushButton{
Layout.preferredWidth: 250
text: "Refresh Device List"
id: searchButton
onClicked: {
getRXTX()
}
}
}
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
ListView{
id: lvDevInfo
model: listModelRXTX
spacing: 20
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
delegate:
GroupBox {
id: chaperoneTypeGroupBox
Layout.fillWidth: true
label: RowLayout{
MyText {
leftPadding: 10
text: "Device: "
bottomPadding: -10
}
MyText {
leftPadding: 10
text: Dev
bottomPadding: -10
}
}
background: Rectangle {
color: "transparent"
border.color: "#ffffff"
radius: 8
}
ColumnLayout{
anchors.fill: parent
Rectangle {
color: "#ffffff"
height: 1
Layout.fillWidth: true
Layout.bottomMargin: 5
}
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
MyText{
Layout.preferredWidth: 150
text: "Device ID: "
}
MyText{
Layout.preferredWidth: 250
text: TX
}
Item{
Layout.preferredWidth: 50
}
MyText{
Layout.preferredWidth: 300
text: "Connected Dongle Type: "
}
MyText{
Layout.preferredWidth: 250
text: DT
}
}
RowLayout{
Layout.fillHeight: true
Layout.fillWidth: true
clip: true
Item{
Layout.preferredWidth: 600
}
MyText{
Layout.preferredWidth: 150
text: "Dongle ID: "
}
MyText{
Layout.preferredWidth: 250
text: RX
}
}
}
}
ScrollBar{
clip: true
visible: true}
}
}
}
Component.onCompleted: {
getRXTX()
}
function getRXTX() {
listModelRXTX.clear();
SteamVRTabController.searchRXTX();
donglesUse.text = SteamVRTabController.getDongleUsage();
var pairCount = SteamVRTabController.getRXTXCount()
for (var i = 0; i < pairCount; i++) {
var RXget = SteamVRTabController.getRXList(i);
var TXget = SteamVRTabController.getTXList(i);
var nameGet = SteamVRTabController.getDeviceName(i)
var dongletyp = SteamVRTabController.getDongleType(i)
listModelRXTX.append({RX:RXget, TX:TXget, Dev:nameGet, DT:dongletyp})
}
}
}
//TODO content
@@ -281,6 +281,10 @@ private:
SettingCategory::Playspace,
QtInfo{ "adjustChaperone2" },
false },
BoolSettingValue{ BoolSetting::PLAYSPACE_enableUncalMotion,
SettingCategory::Playspace,
QtInfo{ "enableUncalMotion" },
false },
BoolSettingValue{ BoolSetting::APPLICATION_disableVersionCheck,
SettingCategory::Application,
@@ -306,6 +310,14 @@ private:
SettingCategory::Application,
QtInfo{ "enableExclusiveInput" },
false },
BoolSettingValue{ BoolSetting::APPLICATION_crashRecoveryDisabled2,
SettingCategory::Application,
QtInfo{ "crashRecoveryDisabled2" },
true },
BoolSettingValue{ BoolSetting::APPLICATION_openXRWorkAround,
SettingCategory::Application,
QtInfo{ "openXRWorkAround" },
false },
BoolSettingValue{ BoolSetting::AUDIO_pttEnabled,
SettingCategory::Audio,
QtInfo{ "pttEnabled" },
+3
View File
@@ -23,6 +23,7 @@ enum class BoolSetting
PLAYSPACE_showLogMatricesButton,
PLAYSPACE_simpleRecenter,
PLAYSPACE_adjustChaperone2,
PLAYSPACE_enableUncalMotion,
APPLICATION_disableVersionCheck,
APPLICATION_previousShutdownSafe,
@@ -30,6 +31,8 @@ enum class BoolSetting
APPLICATION_crashRecoveryDisabled,
APPLICATION_enableDebug,
APPLICATION_enableExclusiveInput,
APPLICATION_crashRecoveryDisabled2,
APPLICATION_openXRWorkAround,
AUDIO_pttEnabled,
AUDIO_pttShowNotification,
+42 -5
View File
@@ -892,7 +892,32 @@ void MoveCenterTabController::setEnableSeatedMotion( bool value, bool notify )
if ( notify )
{
emit enableSeatedMotionChanged( value );
emit enableUncalMotionChanged( value );
}
}
bool MoveCenterTabController::enableUncalMotion() const
{
return settings::getSetting(
settings::BoolSetting::PLAYSPACE_enableUncalMotion );
}
void MoveCenterTabController::setEnableUncalMotion( bool value, bool notify )
{
if ( !value && m_initComplete )
{
reset();
}
settings::setSetting( settings::BoolSetting::PLAYSPACE_enableUncalMotion,
value );
if ( !value && m_initComplete )
{
m_pendingZeroOffsets = true;
}
if ( notify )
{
emit enableUncalMotionChanged( value );
}
}
@@ -976,7 +1001,7 @@ void MoveCenterTabController::incomingSeatedReset()
void MoveCenterTabController::reset()
{
if ( !m_chaperoneBasisAcquired )
if ( !m_chaperoneBasisAcquired && !enableUncalMotion() )
{
LOG( WARNING ) << "WARNING: Attempted reset offsets before chaperone "
"basis is acquired!";
@@ -1115,7 +1140,8 @@ void MoveCenterTabController::zeroOffsets()
// finished checking if out of bounds, proceed with normal zeroing offsets
if ( vr::VRChaperone()->GetCalibrationState()
== vr::ChaperoneCalibrationState_OK )
== vr::ChaperoneCalibrationState_OK
|| enableUncalMotion() )
{
m_oldOffsetX = 0.0f;
m_oldOffsetY = 0.0f;
@@ -1131,7 +1157,7 @@ void MoveCenterTabController::zeroOffsets()
emit rotationChanged( m_rotation );
updateChaperoneResetData();
m_pendingZeroOffsets = false;
if ( !m_chaperoneBasisAcquired )
if ( !m_chaperoneBasisAcquired && !enableUncalMotion() )
{
m_chaperoneBasisAcquired = true;
if ( !m_initComplete )
@@ -1962,6 +1988,14 @@ void MoveCenterTabController::resetOffsets( bool resetOffsetsJustPressed )
}
}
void MoveCenterTabController::applyOffsets( bool applyOffsetsJustPressed )
{
if ( applyOffsetsJustPressed )
{
zeroOffsets();
}
}
void MoveCenterTabController::snapTurnLeft( bool snapTurnLeftJustPressed )
{
if ( !snapTurnLeftJustPressed )
@@ -2933,6 +2967,7 @@ void MoveCenterTabController::eventLoopTick(
vr::VRChaperoneSetup()->RevertWorkingCopy();
}
setTrackingUniverse( int( universe ) );
// TODO set to allow.
return;
}
@@ -2958,7 +2993,9 @@ void MoveCenterTabController::eventLoopTick(
// if we were in room setup, but got this far in the loop, universe is no
// longer raw mode and we detect room setup exit and zeroOffsets() to apply
// new setup.
if ( m_pendingZeroOffsets || m_roomSetupModeDetected )
if ( m_pendingZeroOffsets
|| ( m_roomSetupModeDetected && !enableUncalMotion() ) )
{
zeroOffsets();
// m_roomSetupModeDetected is set to false in zeroOffsets() if it's
@@ -139,6 +139,8 @@ class MoveCenterTabController : public QObject
setEnableSeatedMotion NOTIFY enableSeatedMotionChanged )
Q_PROPERTY( bool simpleRecenter READ simpleRecenter WRITE setSimpleRecenter
NOTIFY simpleRecenterChanged )
Q_PROPERTY( bool enableUncalMotion READ enableUncalMotion WRITE
setEnableUncalMotion NOTIFY enableUncalMotionChanged )
private:
OverlayController* parent;
@@ -276,6 +278,7 @@ public:
bool oldStyleMotion() const;
bool universeCenteredRotation() const;
bool enableSeatedMotion() const;
bool enableUncalMotion() const;
bool simpleRecenter() const;
bool isInitComplete() const;
double getHmdYawTotal();
@@ -306,6 +309,7 @@ public:
void gravityReverseAction( bool gravityReverseHeld );
void heightToggleAction( bool heightToggleJustPressed );
void resetOffsets( bool resetOffsetsJustPressed );
void applyOffsets( bool applyOffsetsJustPressed );
void snapTurnLeft( bool snapTurnLeftJustPressed );
void snapTurnRight( bool snapTurnRightJustPressed );
void smoothTurnLeft( bool smoothTurnLeftActive );
@@ -356,6 +360,7 @@ public slots:
void setOldStyleMotion( bool value, bool notify = true );
void setUniverseCenteredRotation( bool value, bool notify = true );
void setEnableSeatedMotion( bool value, bool notify = true );
void setEnableUncalMotion( bool value, bool notify = true );
void setSimpleRecenter( bool value, bool notify = true );
void shutdown();
@@ -403,6 +408,7 @@ signals:
void universeCenteredRotationChanged( bool value );
void enableSeatedMotionChanged( bool value );
void simpleRecenterChanged( bool value );
void enableUncalMotionChanged( bool value );
void offsetProfilesUpdated();
};
+135
View File
@@ -289,6 +289,113 @@ bool SteamVRTabController::cameraDashboard() const
return m_cameraDashboard;
}
void SteamVRTabController::searchRXTX()
{
deviceList.clear();
int hmdIndex = -1;
auto indexList = ovr_system_wrapper::getAllConnectedDevices( true );
m_dongleCountCur = 0;
for ( auto device : indexList )
{
if ( vr::TrackedDeviceClass_HMD
== ovr_system_wrapper::getDeviceClass( device ) )
{
hmdIndex = device;
continue;
}
deviceList.push_back( DeviceInfo{ device } );
GatherDeviceInfo( deviceList.back() );
}
if ( hmdIndex != -1 )
{
auto dongleList
= ovr_system_wrapper::getStringTrackedProperty(
hmdIndex, vr::Prop_AllWirelessDongleDescriptions_String )
.second;
int count = 0;
if ( !dongleList.empty() )
{
count++;
}
for ( auto c : dongleList )
{
if ( c == ';' )
{
count++;
}
}
m_dongleCountMax = count;
}
return;
}
void SteamVRTabController::GatherDeviceInfo( DeviceInfo& device )
{
std::string cd = ovr_system_wrapper::getStringTrackedProperty(
device.index, vr::Prop_ConnectedWirelessDongle_String )
.second;
if ( cd.empty() || cd == " " )
{
cd = "n/a";
device.dongleType = "n/a";
}
else
{
m_dongleCountCur++;
if ( cd.find( "-RYB" ) != std::string::npos
|| cd.find( "-LYM" ) != std::string::npos )
{
device.dongleType = "Headset";
}
// TODO 1yx SN
else if ( std::regex_match( cd, std::regex( "(.*)(-[0-9]YX)" ) ) )
{
device.dongleType = "Tundra Dongle";
}
else
{
device.dongleType = "Standard Dongle";
}
}
device.conDongle = cd;
std::string dd = ovr_system_wrapper::getStringTrackedProperty(
device.index, vr::Prop_SerialNumber_String )
.second;
if ( dd.empty() || dd == " " )
{
dd = "n/a";
}
device.txName = dd;
auto devClass = ovr_system_wrapper::getDeviceClass( device.index );
if ( devClass == vr::TrackedDeviceClass_HMD
|| devClass == vr::TrackedDeviceClass_Controller
|| devClass == vr::TrackedDeviceClass_GenericTracker )
{
device.hasName = true;
device.deviceName = ovr_system_wrapper::getDeviceName( device.index );
}
else
{
if ( device.txName.find( "LHB-" ) != std::string::npos )
{
device.deviceName = "Lighthouse";
}
}
int role = ovr_system_wrapper::getInt32TrackedProperty(
device.index, vr::Prop_ControllerRoleHint_Int32 )
.second;
if ( role == 1 )
{
device.deviceName += " (L)";
}
else if ( role == 2 )
{
device.deviceName += " (R)";
}
}
void SteamVRTabController::launchBindingUI()
{
vr::VRActionSetHandle_t actionHandle = 0;
@@ -335,4 +442,32 @@ void SteamVRTabController::restartSteamVR()
QProcess::startDetached( cmd );
}
Q_INVOKABLE unsigned SteamVRTabController::getRXTXCount()
{
return static_cast<unsigned>( deviceList.size() );
}
Q_INVOKABLE QString SteamVRTabController::getTXList( int i )
{
return QString::fromStdString( deviceList[i].txName );
}
Q_INVOKABLE QString SteamVRTabController::getDeviceName( int i )
{
return QString::fromStdString( deviceList[i].deviceName );
}
Q_INVOKABLE QString SteamVRTabController::getRXList( int i )
{
return QString::fromStdString( deviceList[i].conDongle );
}
Q_INVOKABLE QString SteamVRTabController::getDongleType( int i )
{
return QString::fromStdString( deviceList[i].dongleType );
}
Q_INVOKABLE QString SteamVRTabController::getDongleUsage()
{
return QString::fromStdString( std::to_string( m_dongleCountCur ) + "/"
+ std::to_string( m_dongleCountMax ) );
}
} // namespace advsettings
+34
View File
@@ -4,6 +4,13 @@
#include <QObject>
#include "../utils/FrameRateUtils.h"
#include "../openvr/ovr_settings_wrapper.h"
#include "../openvr/lh_console_util.h"
#include <QStringListModel>
#include <QTableWidget>
#include "../openvr/lh_console_util.h"
#include <QDir>
#include "../openvr/ovr_system_wrapper.h"
#include <regex>
class QQuickWindow;
// application namespace
@@ -12,6 +19,18 @@ namespace advsettings
// forward declaration
class OverlayController;
struct DeviceInfo
{
int index = -1;
std::string conDongle = "";
std::string txName = "";
std::string deviceName = "";
std::string hand = "";
std::string dongleType = "n/a";
std::string serialNumber = "";
bool hasName = false;
};
class SteamVRTabController : public QObject
{
Q_OBJECT
@@ -49,7 +68,13 @@ private:
bool m_cameraBounds = false;
bool m_cameraRoom = false;
bool m_cameraDashboard = false;
bool m_pathRXTXInit = false;
int m_dongleCountCur = 0;
int m_dongleCountMax = 0;
std::vector<DeviceInfo> deviceList;
void GatherDeviceInfo( DeviceInfo& device );
void synchSteamVR();
public:
@@ -70,8 +95,17 @@ public:
bool cameraRoom() const;
bool cameraDashboard() const;
Q_INVOKABLE void searchRXTX();
Q_INVOKABLE void launchBindingUI();
Q_INVOKABLE unsigned getRXTXCount();
Q_INVOKABLE QString getTXList( int i );
Q_INVOKABLE QString getRXList( int i );
Q_INVOKABLE QString getDeviceName( int i );
Q_INVOKABLE QString getDongleType( int i );
Q_INVOKABLE QString getDongleUsage();
public slots:
void setPerformanceGraph( bool value, bool notify = true );