Files
OpenVR-AdvancedSettings-frame/src/tabcontrollers/SteamVRTabController.cpp
T
ykeara a97a04efbc 5.5.0 Pairing, Universe Restriction Removal, space drag multiplier (#595)
* add Select Dongle Pairing, fix clipping on long SN names (quest)

* remove test log, add ws log, add pair protection non steamvr

* add missing install commands for new qt modules

* remove bad package

* add auto apply chaperone option, remove old seated/uncal/openxr fixes in favor of always on

* adjust battery overlay for tundras

* fix tundra tracker bat indicator positioning, remove offset page restrictions from non-standing universe, make pairing more responsive and display brief instructions

* add Drag Multiplier

* update documentation

* change version to release

* update readme

* fix format issues readme

* update readme with setting description

* change uid to prevent collision

* changed rounding for grav fling to 2 decimals to be consistand with other values on drag page
2022-04-12 18:07:25 -05:00

632 lines
18 KiB
C++

#include "SteamVRTabController.h"
#include <QQuickWindow>
#include "../overlaycontroller.h"
#include "../utils/update_rate.h"
QT_USE_NAMESPACE
// application namespace
namespace advsettings
{
void SteamVRTabController::initStage1()
{
dashboardLoopTick();
}
void SteamVRTabController::initStage2( OverlayController* var_parent )
{
this->parent = var_parent;
synchSteamVR();
}
void SteamVRTabController::dashboardLoopTick()
{
if ( updateRate.shouldSubjectNotRun( UpdateSubject::SteamVrTabController ) )
{
return;
}
synchSteamVR();
}
void SteamVRTabController::synchSteamVR()
{
// Un-comment these if other Apps make heavy use OR ADDED to STEAMVR
// officially
setPerformanceGraph( performanceGraph() );
// setSystemButton(systemButton());
setMultipleDriver( multipleDriver() );
setDND( dnd() );
setNoFadeToGrid( noFadeToGrid() );
setCameraActive( cameraActive() );
setCameraRoom( cameraRoom() );
setCameraDashboard( cameraDashboard() );
setCameraBounds( cameraBounds() );
}
bool SteamVRTabController::performanceGraph() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Perf_Section, vr::k_pch_Perf_PerfGraphInHMD_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_performanceGraphToggle;
}
void SteamVRTabController::setPerformanceGraph( const bool value,
const bool notify )
{
if ( m_performanceGraphToggle != value )
{
m_performanceGraphToggle = value;
ovr_settings_wrapper::setBool( vr::k_pch_Perf_Section,
vr::k_pch_Perf_PerfGraphInHMD_Bool,
m_performanceGraphToggle );
if ( notify )
{
emit performanceGraphChanged( m_performanceGraphToggle );
}
}
}
bool SteamVRTabController::multipleDriver() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_multipleDriverToggle;
}
void SteamVRTabController::setMultipleDriver( const bool value,
const bool notify )
{
if ( m_multipleDriverToggle != value )
{
m_multipleDriverToggle = value;
ovr_settings_wrapper::setBool(
vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_ActivateMultipleDrivers_Bool,
m_multipleDriverToggle );
if ( notify )
{
emit multipleDriverChanged( m_multipleDriverToggle );
}
}
}
bool SteamVRTabController::noFadeToGrid() const
{
auto p = ovr_settings_wrapper::getBool( vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_DoNotFadeToGrid );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_noFadeToGridToggle;
}
void SteamVRTabController::setNoFadeToGrid( const bool value,
const bool notify )
{
if ( m_noFadeToGridToggle != value )
{
m_noFadeToGridToggle = value;
ovr_settings_wrapper::setBool( vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_DoNotFadeToGrid,
m_noFadeToGridToggle );
if ( notify )
{
emit noFadeToGridChanged( m_noFadeToGridToggle );
}
}
}
bool SteamVRTabController::systemButton() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_SendSystemButtonToAllApps_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_systemButtonToggle;
}
void SteamVRTabController::setSystemButton( const bool value,
const bool notify )
{
if ( m_systemButtonToggle != value )
{
m_systemButtonToggle = value;
ovr_settings_wrapper::setBool(
vr::k_pch_SteamVR_Section,
vr::k_pch_SteamVR_SendSystemButtonToAllApps_Bool,
m_systemButtonToggle );
if ( notify )
{
emit systemButtonChanged( m_systemButtonToggle );
}
}
}
bool SteamVRTabController::dnd() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Notifications_Section,
vr::k_pch_Notifications_DoNotDisturb_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_dnd;
}
void SteamVRTabController::setDND( const bool value, const bool notify )
{
if ( m_dnd != value )
{
m_dnd = value;
ovr_settings_wrapper::setBool(
vr::k_pch_Notifications_Section,
vr::k_pch_Notifications_DoNotDisturb_Bool,
m_dnd );
if ( notify )
{
emit dNDChanged( m_dnd );
}
}
}
/*------------------------------------------*/
/* -----------Camera Setting----------------*/
bool SteamVRTabController::cameraActive() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Camera_Section, vr::k_pch_Camera_EnableCamera_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_cameraActive;
}
void SteamVRTabController::setCameraActive( const bool value,
const bool notify )
{
if ( m_cameraActive != value )
{
m_cameraActive = value;
ovr_settings_wrapper::setBool( vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCamera_Bool,
m_cameraActive );
if ( notify )
{
emit cameraActiveChanged( m_cameraActive );
}
}
}
bool SteamVRTabController::cameraBounds() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraForCollisionBounds_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_cameraBounds;
}
void SteamVRTabController::setCameraBounds( const bool value,
const bool notify )
{
if ( m_cameraBounds != value )
{
m_cameraBounds = value;
ovr_settings_wrapper::setBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraForCollisionBounds_Bool,
m_cameraBounds );
if ( notify )
{
emit cameraBoundsChanged( m_cameraBounds );
}
}
}
bool SteamVRTabController::cameraRoom() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraForRoomView_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_cameraRoom;
}
void SteamVRTabController::setCameraRoom( const bool value, const bool notify )
{
if ( m_cameraRoom != value )
{
m_cameraRoom = value;
ovr_settings_wrapper::setBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraForRoomView_Bool,
m_cameraRoom );
if ( notify )
{
emit cameraRoomChanged( m_cameraRoom );
}
}
}
bool SteamVRTabController::cameraDashboard() const
{
auto p = ovr_settings_wrapper::getBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraInDashboard_Bool );
if ( p.first == ovr_settings_wrapper::SettingsError::NoError )
{
return p.second;
}
return m_cameraDashboard;
}
void SteamVRTabController::updateRXTXList()
{
emit updateRXTX( true );
}
void SteamVRTabController::searchRXTX()
{
m_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;
}
m_deviceList.push_back( DeviceInfo{ device } );
GatherDeviceInfo( m_deviceList.back() );
}
if ( hmdIndex != -1 )
{
auto dongleList
= ovr_system_wrapper::getStringTrackedProperty(
hmdIndex, vr::Prop_AllWirelessDongleDescriptions_String )
.second;
m_unparsedDongleString = QString::fromStdString( dongleList );
int count = 0;
if ( !dongleList.empty() )
{
count++;
}
for ( auto c : dongleList )
{
if ( c == ';' )
{
count++;
}
}
m_dongleCountMax = count;
if ( static_cast<int>( m_deviceList.size() ) < m_dongleCountMax )
{
auto DSNFullList = getDongleSerialList( dongleList );
for ( auto dSN : DSNFullList )
{
bool isPaired = false;
for ( auto pairedDev : m_deviceList )
{
if ( QString::fromStdString( pairedDev.conDongle ) == dSN )
{
isPaired = true;
break;
}
}
if ( isPaired )
{
continue;
}
m_deviceList.push_back( DeviceInfo{} );
AddUnPairedDevice( m_deviceList.back(), dSN.toStdString() );
// TODO create
}
}
}
return;
}
void SteamVRTabController::AddUnPairedDevice( DeviceInfo& device,
std::string donSN )
{
device.conDongle = donSN;
if ( donSN.find( "-RYB" ) != std::string::npos
|| donSN.find( "-LYM" ) != std::string::npos )
{
device.dongleType = "Headset";
}
// TODO 1yx SN
else if ( std::regex_match( donSN, std::regex( "(.*)(-[0-9]YX)" ) ) )
{
device.dongleType = "Tundra Dongle";
}
else
{
device.dongleType = "Standard Dongle";
}
device.index = -1;
device.txName = "No Connection";
device.serialNumber = "n/a";
device.deviceName = "No Connection";
}
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;
vr::VRInputValueHandle_t inputHandle = 0;
auto error2 = vr::VRInput()->GetInputSourceHandle( "/user/hand/right",
&inputHandle );
if ( error2 != vr::VRInputError_None )
{
LOG( ERROR )
<< "failed to get input handle? is your right controller on?";
}
auto error = vr::VRInput()->OpenBindingUI(
application_strings::applicationKey, actionHandle, inputHandle, false );
if ( error != vr::VRInputError_None )
{
LOG( ERROR ) << "Input Error: " << error;
}
}
void SteamVRTabController::setCameraDashboard( const bool value,
const bool notify )
{
if ( m_cameraDashboard != value )
{
m_cameraDashboard = value;
ovr_settings_wrapper::setBool(
vr::k_pch_Camera_Section,
vr::k_pch_Camera_EnableCameraInDashboard_Bool,
m_cameraDashboard );
if ( notify )
{
emit cameraDashboardChanged( m_cameraDashboard );
}
}
}
void SteamVRTabController::restartSteamVR()
{
QString cmd = QString( "cmd.exe /C restartvrserver.bat \"" )
+ parent->getVRRuntimePathUrl().toLocalFile()
+ QString( "\"" );
LOG( INFO ) << "SteamVR Restart Command: " << cmd;
QProcess::startDetached( cmd );
}
Q_INVOKABLE unsigned SteamVRTabController::getRXTXCount()
{
return static_cast<unsigned>( m_deviceList.size() );
}
Q_INVOKABLE QString SteamVRTabController::getTXList( int i )
{
return QString::fromStdString( m_deviceList[i].txName );
}
Q_INVOKABLE QString SteamVRTabController::getDeviceName( int i )
{
return QString::fromStdString( m_deviceList[i].deviceName );
}
Q_INVOKABLE QString SteamVRTabController::getRXList( int i )
{
return QString::fromStdString( m_deviceList[i].conDongle );
}
Q_INVOKABLE QString SteamVRTabController::getDongleType( int i )
{
return QString::fromStdString( m_deviceList[i].dongleType );
}
Q_INVOKABLE QString SteamVRTabController::getDongleUsage()
{
return QString::fromStdString( std::to_string( m_dongleCountCur ) + "/"
+ std::to_string( m_dongleCountMax ) );
}
Q_INVOKABLE void SteamVRTabController::pairDevice( QString sn )
{
if ( !isSteamVRTracked( sn ) )
{
LOG( WARNING ) << sn.toStdString()
<< " Is Not a SteamVR Dongle, skipping Pair";
return;
}
m_last_pair_sn = sn;
auto req = QNetworkRequest();
req.setUrl( QUrl( "ws://127.0.0.1:27062" ) );
req.setRawHeader(
QByteArray( "Referer" ),
QByteArray(
"http://localhost:27062/lighthouse/webinterface/pairing.html" ) );
m_webSocket.open( req );
connect( &m_webSocket,
&QWebSocket::connected,
this,
&SteamVRTabController::onConnected );
connect( &m_webSocket,
&QWebSocket::disconnected,
this,
&SteamVRTabController::onDisconnect );
connect( &m_webSocket,
&QWebSocket::textMessageReceived,
this,
&SteamVRTabController::onMsgRec );
return;
}
bool SteamVRTabController::isSteamVRTracked( QString sn )
{
return m_unparsedDongleString.contains( sn );
}
void SteamVRTabController::onConnected()
{
m_webSocket.sendTextMessage( QStringLiteral( "mailbox_open OVRAS_pair" ) );
QString messageout = "mailbox_send lighthouse_pairing "
"{\"type\":\"start_pairing\", "
"\"returnAddress\":\"OVRAS_pair\", "
"\"serial\":\"";
messageout.append( m_last_pair_sn );
messageout.append( QString::fromStdString( "\", \"timeoutSeconds\":15}" ) );
emit pairStatusChanged( QString( "Pairing..." ) );
if ( m_last_pair_sn == "" )
{
LOG( ERROR ) << "No Last SN to pair, this shouldn't happen";
}
m_webSocket.sendTextMessage( messageout );
// m_webSocket.close();
}
void SteamVRTabController::onDisconnect()
{
LOG( INFO ) << "Pair WS disconnect";
m_webSocket.close();
}
void SteamVRTabController::onMsgRec( QString Msg )
{
if ( Msg.contains( "success" ) )
{
LOG( INFO ) << "Pair Success";
emit pairStatusChanged( QString( "Success" ) );
}
if ( Msg.contains( "timeout" ) )
{
LOG( INFO ) << "Pair Timeout";
emit pairStatusChanged( QString( "Timeout" ) );
}
m_webSocket.close();
}
std::vector<QString>
SteamVRTabController::getDongleSerialList( std::string deviceString )
{
std::vector<QString> dongleList;
size_t pos = 0;
while ( ( pos = deviceString.find( ',' ) ) != std::string::npos )
{
dongleList.push_back(
QString::fromStdString( deviceString.substr( 0, pos ) ) );
pos = deviceString.find( ';' );
if ( pos != std::string::npos )
{
deviceString.erase( 0, pos + 1 );
continue;
}
else
{
pos = deviceString.find( ',' );
if ( pos == std::string::npos )
{
break;
}
dongleList.push_back(
QString::fromStdString( deviceString.substr( 0, pos ) ) );
break;
}
break;
}
return dongleList;
}
} // namespace advsettings