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:
@@ -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 @@
|
||||
5.3.2-release
|
||||
5.4.0-release
|
||||
@@ -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/* \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user