Files
OpenVR-AdvancedSettings-frame/src/tabcontrollers/ChaperoneTabController.cpp
T

1742 lines
61 KiB
C++

#include "ChaperoneTabController.h"
#include <QQuickWindow>
#include "../overlaycontroller.h"
#include "../settings/settings.h"
#include <cmath>
// application namespace
namespace advsettings
{
void ChaperoneTabController::initStage1()
{
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
m_chaperoneSwitchToBeginnerDistance
= settings->value( "chaperoneSwitchToBeginnerDistance", 0.5f )
.toFloat();
m_chaperoneHapticFeedbackDistance
= settings->value( "chaperoneHapticFeedbackDistance", 0.5f ).toFloat();
m_chaperoneAlarmSoundDistance
= settings->value( "chaperoneAlarmSoundDistance", 0.5f ).toFloat();
m_chaperoneShowDashboardDistance
= settings->value( "chaperoneShowDashboardDistance", 0.5f ).toFloat();
m_fadeDistanceRemembered
= settings->value( "fadeDistanceRemembered", 0.5f ).toFloat();
settings->endGroup();
if ( disableChaperone() )
{
setFadeDistance( 0.0f, true );
}
reloadChaperoneProfiles();
m_k_chaperoneSettingsUpdateCounter
= utils::adjustUpdateRate( k_chaperoneSettingsUpdateCounter );
eventLoopTick( nullptr );
}
void ChaperoneTabController::initStage2( OverlayController* var_parent )
{
this->parent = var_parent;
}
ChaperoneTabController::~ChaperoneTabController()
{
m_chaperoneHapticFeedbackActive = false;
if ( m_chaperoneHapticFeedbackThread.joinable() )
{
m_chaperoneHapticFeedbackThread.join();
}
}
void ChaperoneTabController::reloadChaperoneProfiles()
{
chaperoneProfiles.clear();
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
auto profileCount = settings->beginReadArray( "chaperoneProfiles" );
for ( int i = 0; i < profileCount; i++ )
{
settings->setArrayIndex( i );
chaperoneProfiles.emplace_back();
auto& entry = chaperoneProfiles[static_cast<size_t>( i )];
entry.profileName
= settings->value( "profileName" ).toString().toStdString();
entry.includesChaperoneGeometry
= settings->value( "includesChaperoneGeometry", false ).toBool();
if ( entry.includesChaperoneGeometry )
{
entry.chaperoneGeometryQuadCount
= settings->value( "chaperoneGeometryQuadCount", 0 ).toUInt();
entry.chaperoneGeometryQuads.reset(
new vr::HmdQuad_t[entry.chaperoneGeometryQuadCount] );
unsigned qi = 0;
for ( auto q :
settings->value( "chaperoneGeometryQuads" ).toList() )
{
unsigned ci = 0;
for ( auto c : q.toList() )
{
unsigned cci = 0;
for ( auto cc : c.toList() )
{
entry.chaperoneGeometryQuads.get()[qi]
.vCorners[ci]
.v[cci]
= cc.toFloat();
cci++;
}
ci++;
}
qi++;
}
unsigned i1 = 0;
for ( auto l1 : settings->value( "standingCenter" ).toList() )
{
unsigned i2 = 0;
for ( auto l2 : l1.toList() )
{
entry.standingCenter.m[i1][i2] = l2.toFloat();
i2++;
}
i1++;
}
entry.playSpaceAreaX
= settings->value( "playSpaceAreaX", 0.0f ).toFloat();
entry.playSpaceAreaZ
= settings->value( "playSpaceAreaZ", 0.0f ).toFloat();
}
entry.includesVisibility
= settings->value( "includesVisibility", false ).toBool();
if ( entry.includesVisibility )
{
entry.visibility = settings->value( "visibility", 0.6 ).toFloat();
}
entry.includesFadeDistance
= settings->value( "includesFadeDistance", false ).toBool();
if ( entry.includesFadeDistance )
{
entry.fadeDistance
= settings->value( "fadeDistance", 0.7 ).toFloat();
}
entry.includesCenterMarker
= settings->value( "includesCenterMarker", false ).toBool();
if ( entry.includesCenterMarker )
{
entry.centerMarker
= settings->value( "centerMarker", false ).toBool();
}
entry.includesPlaySpaceMarker
= settings->value( "includesPlaySpaceMarker", false ).toBool();
if ( entry.includesPlaySpaceMarker )
{
entry.playSpaceMarker
= settings->value( "playSpaceMarker", false ).toBool();
}
entry.includesFloorBoundsMarker
= settings->value( "includesFloorBoundsMarker", false ).toBool();
if ( entry.includesFloorBoundsMarker )
{
entry.floorBoundsMarker
= settings->value( "floorBoundsMarker", false ).toBool();
}
entry.includesBoundsColor
= settings->value( "includesBoundsColor", false ).toBool();
if ( entry.includesBoundsColor )
{
auto color = settings->value( "boundsColor" ).toList();
entry.boundsColor[0] = color[0].toInt();
entry.boundsColor[1] = color[1].toInt();
entry.boundsColor[2] = color[2].toInt();
}
entry.includesChaperoneStyle
= settings->value( "includesChaperoneStyle", false ).toBool();
if ( entry.includesChaperoneStyle )
{
entry.chaperoneStyle
= settings->value( "chaperoneStyle", 0 ).toInt();
}
entry.includesForceBounds
= settings->value( "includesForceBounds", false ).toBool();
if ( entry.includesForceBounds )
{
entry.forceBounds
= settings->value( "forceBounds", false ).toBool();
}
entry.includesProximityWarningSettings
= settings->value( "includesProximityWarningSettings", false )
.toBool();
if ( entry.includesProximityWarningSettings )
{
entry.enableChaperoneSwitchToBeginner
= settings->value( "chaperoneSwitchToBeginnerEnabled", false )
.toBool();
entry.chaperoneSwitchToBeginnerDistance
= settings->value( "chaperoneSwitchToBeginnerDistance", 0.5f )
.toFloat();
entry.enableChaperoneHapticFeedback
= settings->value( "chaperoneHapticFeedbackEnabled", false )
.toBool();
entry.chaperoneHapticFeedbackDistance
= settings->value( "chaperoneHapticFeedbackDistance", 0.5f )
.toFloat();
entry.enableChaperoneAlarmSound
= settings->value( "chaperoneAlarmSoundEnabled", false )
.toBool();
entry.chaperoneAlarmSoundLooping
= settings->value( "chaperoneAlarmSoundLooping", true )
.toBool();
entry.chaperoneAlarmSoundAdjustVolume
= settings->value( "chaperoneAlarmSoundAdjustVolume", false )
.toBool();
entry.chaperoneAlarmSoundDistance
= settings->value( "chaperoneAlarmSoundDistance", 0.5f )
.toFloat();
entry.enableChaperoneShowDashboard
= settings->value( "chaperoneShowDashboardEnabled", false )
.toBool();
entry.chaperoneShowDashboardDistance
= settings->value( "chaperoneShowDashboardDistance", 0.5f )
.toFloat();
}
}
settings->endArray();
settings->endGroup();
}
void ChaperoneTabController::saveChaperoneProfiles()
{
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->beginWriteArray( "chaperoneProfiles" );
unsigned i = 0;
for ( auto& p : chaperoneProfiles )
{
settings->setArrayIndex( static_cast<int>( i ) );
settings->setValue( "profileName",
QString::fromStdString( p.profileName ) );
settings->setValue( "includesChaperoneGeometry",
p.includesChaperoneGeometry );
if ( p.includesChaperoneGeometry )
{
settings->setValue( "chaperoneGeometryQuadCount",
p.chaperoneGeometryQuadCount );
QVariantList quadList;
for ( unsigned qi = 0; qi < p.chaperoneGeometryQuadCount; qi++ )
{
QVariantList cornerList;
for ( unsigned ci = 0; ci < 4; ci++ )
{
QVariantList coordVector;
for ( unsigned cci = 0; cci < 3; cci++ )
{
coordVector.push_back(
p.chaperoneGeometryQuads.get()[qi]
.vCorners[ci]
.v[cci] );
}
cornerList.push_back( coordVector );
}
quadList.push_back( cornerList );
}
settings->setValue( "chaperoneGeometryQuads", quadList );
QVariantList l1;
for ( unsigned i1 = 0; i1 < 3; i1++ )
{
QVariantList l2;
for ( unsigned i2 = 0; i2 < 4; i2++ )
{
l2.push_back( p.standingCenter.m[i1][i2] );
}
l1.push_back( l2 );
}
settings->setValue( "standingCenter", l1 );
settings->setValue( "playSpaceAreaX", p.playSpaceAreaX );
settings->setValue( "playSpaceAreaZ", p.playSpaceAreaZ );
}
settings->setValue( "includesVisibility", p.includesVisibility );
if ( p.includesVisibility )
{
settings->setValue( "visibility", p.visibility );
}
settings->setValue( "includesFadeDistance", p.includesFadeDistance );
if ( p.includesFadeDistance )
{
settings->setValue( "fadeDistance", p.fadeDistance );
}
settings->setValue( "includesCenterMarker", p.includesCenterMarker );
if ( p.includesCenterMarker )
{
settings->setValue( "centerMarker", p.centerMarker );
}
settings->setValue( "includesPlaySpaceMarker",
p.includesPlaySpaceMarker );
if ( p.includesPlaySpaceMarker )
{
settings->setValue( "playSpaceMarker", p.playSpaceMarker );
}
settings->setValue( "includesFloorBoundsMarker",
p.includesFloorBoundsMarker );
if ( p.includesFloorBoundsMarker )
{
settings->setValue( "floorBoundsMarker", p.floorBoundsMarker );
}
settings->setValue( "includesBoundsColor", p.includesBoundsColor );
if ( p.includesBoundsColor )
{
QVariantList color;
color.push_back( p.boundsColor[0] );
color.push_back( p.boundsColor[1] );
color.push_back( p.boundsColor[2] );
settings->setValue( "boundsColor", color );
}
settings->setValue( "includesChaperoneStyle",
p.includesChaperoneStyle );
if ( p.includesChaperoneStyle )
{
settings->setValue( "chaperoneStyle", p.chaperoneStyle );
}
settings->setValue( "includesForceBounds", p.includesForceBounds );
if ( p.includesForceBounds )
{
settings->setValue( "forceBounds", p.forceBounds );
}
settings->setValue( "includesProximityWarningSettings",
p.includesProximityWarningSettings );
if ( p.includesProximityWarningSettings )
{
settings->setValue( "chaperoneSwitchToBeginnerEnabled",
p.enableChaperoneSwitchToBeginner );
settings->setValue( "chaperoneSwitchToBeginnerDistance",
p.chaperoneSwitchToBeginnerDistance );
settings->setValue( "chaperoneHapticFeedbackEnabled",
p.enableChaperoneHapticFeedback );
settings->setValue( "chaperoneHapticFeedbackDistance",
p.chaperoneHapticFeedbackDistance );
settings->setValue( "chaperoneAlarmSoundEnabled",
p.enableChaperoneAlarmSound );
settings->setValue( "chaperoneAlarmSoundLooping",
p.chaperoneAlarmSoundLooping );
settings->setValue( "chaperoneAlarmSoundAdjustVolume",
p.chaperoneAlarmSoundAdjustVolume );
settings->setValue( "chaperoneAlarmSoundDistance",
p.chaperoneAlarmSoundDistance );
settings->setValue( "chaperoneShowDashboardEnabled",
p.enableChaperoneShowDashboard );
settings->setValue( "chaperoneShowDashboardDistance",
p.chaperoneShowDashboardDistance );
}
i++;
}
settings->endArray();
settings->endGroup();
}
void ChaperoneTabController::handleChaperoneWarnings( float distance )
{
vr::VRControllerState_t hmdState;
vr::VRSystem()->GetControllerState( vr::k_unTrackedDeviceIndex_Hmd,
&hmdState,
sizeof( vr::VRControllerState_t ) );
// If proximity Sensor is True (only can be true if exists)
// Then use prox sensor else use hmd activity level.
// Needed as detection since the "has prox sensor" property is unreliable.
// Note m_isProxActive should only ever be set to true if there is a prox
// sensor AND its currently on.
bool proxSensorOverrideState = false;
m_HMDHasProx ? ( proxSensorOverrideState = m_isProxActive )
: ( proxSensorOverrideState = m_isHMDActive );
// Switch to Beginner Mode
if ( isChaperoneSwitchToBeginnerEnabled() )
{
float activationDistance = m_chaperoneSwitchToBeginnerDistance;
if ( distance <= activationDistance && m_isHMDActive
&& !m_chaperoneSwitchToBeginnerActive )
{
vr::EVRSettingsError vrSettingsError;
m_chaperoneSwitchToBeginnerLastStyle = vr::VRSettings()->GetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING )
<< "Could not read \""
<< vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
else
{
vr::VRSettings()->SetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
vr::COLLISION_BOUNDS_STYLE_BEGINNER,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING )
<< "Could not set \""
<< vr::k_pch_CollisionBounds_Style_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
else
{
vr::VRSettings()->Sync( true );
m_chaperoneSwitchToBeginnerActive = true;
}
}
}
else if ( ( distance > activationDistance || !m_isHMDActive )
&& m_chaperoneSwitchToBeginnerActive )
{
vr::EVRSettingsError vrSettingsError;
vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
m_chaperoneSwitchToBeginnerLastStyle,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING )
<< "Could not set \""
<< vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
else
{
vr::VRSettings()->Sync( true );
m_chaperoneSwitchToBeginnerActive = false;
}
}
}
// Haptic Feedback
if ( isChaperoneHapticFeedbackEnabled() )
{
float activationDistance = m_chaperoneHapticFeedbackDistance;
if ( distance <= activationDistance && proxSensorOverrideState )
{
if ( !m_chaperoneHapticFeedbackActive )
{
if ( m_chaperoneHapticFeedbackThread.joinable() )
{
m_chaperoneHapticFeedbackActive = false;
m_chaperoneHapticFeedbackThread.join();
}
m_chaperoneHapticFeedbackActive = true;
m_chaperoneHapticFeedbackThread = std::thread(
[&]( ChaperoneTabController* _this ) {
auto leftIndex
= vr::VRSystem()
->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_LeftHand );
auto rightIndex
= vr::VRSystem()
->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_RightHand );
while ( _this->m_chaperoneHapticFeedbackActive )
{
// AS it stands both controllers will vibrate
// regardless of which is closer to boundary
// haptic Frequency is 0-320Hz
if ( leftIndex
!= vr::k_unTrackedDeviceIndexInvalid )
{
vr::VRInput()->TriggerHapticVibrationAction(
m_leftActionHandle,
0.0f,
0.2f,
120.0f,
0.5f,
m_leftInputHandle );
}
if ( rightIndex
!= vr::k_unTrackedDeviceIndexInvalid )
{
vr::VRInput()->TriggerHapticVibrationAction(
m_rightActionHandle,
0.0f,
0.2f,
120.0f,
0.5f,
m_rightInputHandle );
}
std::this_thread::sleep_for(
std::chrono::milliseconds( 5 ) );
}
},
this );
}
}
else if ( ( distance > activationDistance || !proxSensorOverrideState )
&& m_chaperoneHapticFeedbackActive )
{
m_chaperoneHapticFeedbackActive = false;
}
}
// Alarm Sound
if ( isChaperoneAlarmSoundEnabled() )
{
// LOG(WARNING) << "In alarm";
float activationDistance = m_chaperoneAlarmSoundDistance;
if ( distance <= activationDistance && proxSensorOverrideState )
{
if ( !m_chaperoneAlarmSoundActive )
{
parent->playAlarm01Sound( isChaperoneAlarmSoundLooping() );
m_chaperoneAlarmSoundActive = true;
}
if ( isChaperoneAlarmSoundLooping()
&& isChaperoneAlarmSoundAdjustVolume() )
{
float vol = 1.1f - distance / activationDistance;
if ( vol > 1.0f )
{
vol = 1.0f;
}
parent->setAlarm01SoundVolume( vol );
}
else
{
parent->setAlarm01SoundVolume( 1.0f );
}
}
else if ( ( distance > activationDistance || !proxSensorOverrideState )
&& m_chaperoneAlarmSoundActive )
{
parent->cancelAlarm01Sound();
m_chaperoneAlarmSoundActive = false;
}
}
// Show Dashboard
if ( isChaperoneShowDashboardEnabled() )
{
float activationDistance = m_chaperoneShowDashboardDistance;
if ( distance <= activationDistance && !m_chaperoneShowDashboardActive )
{
if ( !vr::VROverlay()->IsDashboardVisible() )
{
vr::VROverlay()->ShowDashboard(
application_strings::applicationKey );
}
m_chaperoneShowDashboardActive = true;
}
else if ( distance > activationDistance
&& m_chaperoneShowDashboardActive )
{
m_chaperoneShowDashboardActive = false;
}
}
}
void ChaperoneTabController::eventLoopTick(
vr::TrackedDevicePose_t* devicePoses )
{
if ( devicePoses )
{
m_isHMDActive = false;
std::lock_guard<std::recursive_mutex> lock(
parent->chaperoneUtils().mutex() );
auto minDistance = NAN;
auto& poseHmd = devicePoses[vr::k_unTrackedDeviceIndex_Hmd];
// m_isHMDActive is true when prox sensor OR HMD is moving (~10 seconds
// to update from OVR)
// THIS IS A WORK-AROUND Until proper binding support/calls are made
// availble for prox sensor
if ( vr::VRSystem()->GetTrackedDeviceActivityLevel(
vr::k_unTrackedDeviceIndex_Hmd )
== vr::k_EDeviceActivityLevel_UserInteraction )
{
m_isHMDActive = true;
}
if ( poseHmd.bPoseIsValid && poseHmd.bDeviceIsConnected
&& poseHmd.eTrackingResult == vr::TrackingResult_Running_OK )
{
auto distanceHmd = parent->chaperoneUtils().getDistanceToChaperone(
{ poseHmd.mDeviceToAbsoluteTracking.m[0][3],
poseHmd.mDeviceToAbsoluteTracking.m[1][3],
poseHmd.mDeviceToAbsoluteTracking.m[2][3] } );
if ( !std::isnan( distanceHmd ) )
{
minDistance = distanceHmd;
}
}
auto leftIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_LeftHand );
if ( leftIndex != vr::k_unTrackedDeviceIndexInvalid )
{
auto& poseLeft = devicePoses[leftIndex];
if ( poseLeft.bPoseIsValid && poseLeft.bDeviceIsConnected
&& poseLeft.eTrackingResult == vr::TrackingResult_Running_OK )
{
auto distanceLeft
= parent->chaperoneUtils().getDistanceToChaperone(
{ poseLeft.mDeviceToAbsoluteTracking.m[0][3],
poseLeft.mDeviceToAbsoluteTracking.m[1][3],
poseLeft.mDeviceToAbsoluteTracking.m[2][3] } );
if ( !std::isnan( distanceLeft )
&& ( std::isnan( minDistance )
|| distanceLeft < minDistance ) )
{
minDistance = distanceLeft;
}
}
}
auto rightIndex
= vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_RightHand );
if ( rightIndex != vr::k_unTrackedDeviceIndexInvalid )
{
auto& poseRight = devicePoses[rightIndex];
if ( poseRight.bPoseIsValid && poseRight.bDeviceIsConnected
&& poseRight.eTrackingResult == vr::TrackingResult_Running_OK )
{
auto distanceRight
= parent->chaperoneUtils().getDistanceToChaperone(
{ poseRight.mDeviceToAbsoluteTracking.m[0][3],
poseRight.mDeviceToAbsoluteTracking.m[1][3],
poseRight.mDeviceToAbsoluteTracking.m[2][3] } );
if ( !std::isnan( distanceRight )
&& ( std::isnan( minDistance )
|| distanceRight < minDistance ) )
{
minDistance = distanceRight;
}
}
}
if ( !std::isnan( minDistance ) )
{
handleChaperoneWarnings( minDistance );
}
else
{
// attempts to reload chaperone data once per ~5 seconds.
m_updateTicksChaperoneReload++;
if ( m_updateTicksChaperoneReload >= 500 )
{
m_updateTicksChaperoneReload = 0;
LOG( WARNING ) << "Attempting to reload chaperone data";
parent->chaperoneUtils().loadChaperoneData();
}
}
}
if ( settingsUpdateCounter >= m_k_chaperoneSettingsUpdateCounter )
{
if ( parent->isDashboardVisible() )
{
updateChaperoneSettings();
}
settingsUpdateCounter = 0;
}
else
{
settingsUpdateCounter++;
}
}
void ChaperoneTabController::updateChaperoneSettings()
{
vr::EVRSettingsError vrSettingsError;
float vis = static_cast<float>(
vr::VRSettings()->GetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaA_Int32,
&vrSettingsError ) );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_ColorGammaA_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
setBoundsVisibility( vis / 255.0f );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_FadeDistance_Float
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
auto cm = vr::VRSettings()->GetBool(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_CenterMarkerOn_Bool,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_CenterMarkerOn_Bool
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
setCenterMarker( cm );
auto ps
= vr::VRSettings()->GetBool( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_PlaySpaceOn_Bool,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_PlaySpaceOn_Bool
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
setPlaySpaceMarker( ps );
}
float ChaperoneTabController::boundsVisibility() const
{
return m_visibility;
}
void ChaperoneTabController::setBoundsVisibility( float value, bool notify )
{
if ( fabs( static_cast<double>( m_visibility - m_visibility ) ) > 0.005 )
{
if ( value <= 0.3f )
{
m_visibility = 0.3f;
}
else
{
m_visibility = value;
}
vr::VRSettings()->SetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaA_Int32,
static_cast<int32_t>( 255 * m_visibility ) );
vr::VRSettings()->Sync();
if ( notify )
{
emit boundsVisibilityChanged( m_visibility );
}
}
}
float ChaperoneTabController::fadeDistance() const
{
return m_fadeDistance;
}
void ChaperoneTabController::setFadeDistance( float value, bool notify )
{
if ( fabs( static_cast<double>( m_fadeDistance - value ) ) > 0.005 )
{
m_fadeDistance = value;
vr::VRSettings()->SetFloat(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_FadeDistance_Float,
m_fadeDistance );
vr::VRSettings()->Sync();
if ( notify )
{
emit fadeDistanceChanged( m_fadeDistance );
}
}
}
float ChaperoneTabController::height() const
{
return m_height;
}
void ChaperoneTabController::setHeight( float value, bool notify )
{
if ( fabs( static_cast<double>( m_height - value ) ) > 0.005 )
{
m_height = value;
parent->m_moveCenterTabController.setBoundsBasisHeight( m_height );
if ( notify )
{
emit heightChanged( m_height );
}
}
}
void ChaperoneTabController::updateHeight( float value, bool notify )
{
if ( fabs( static_cast<double>( m_height - value ) ) > 0.005 )
{
m_height = value;
if ( notify )
{
emit heightChanged( m_height );
}
}
}
bool ChaperoneTabController::centerMarker() const
{
return m_centerMarker;
}
void ChaperoneTabController::setCenterMarker( bool value, bool notify )
{
if ( m_centerMarker != value )
{
m_centerMarker = value;
vr::VRSettings()->SetBool(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_CenterMarkerOn_Bool,
m_centerMarker );
vr::VRSettings()->Sync();
if ( notify )
{
emit centerMarkerChanged( m_centerMarker );
}
}
}
bool ChaperoneTabController::playSpaceMarker() const
{
return m_playSpaceMarker;
}
void ChaperoneTabController::setPlaySpaceMarker( bool value, bool notify )
{
if ( m_playSpaceMarker != value )
{
m_playSpaceMarker = value;
vr::VRSettings()->SetBool( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_PlaySpaceOn_Bool,
m_playSpaceMarker );
vr::VRSettings()->Sync();
if ( notify )
{
emit playSpaceMarkerChanged( m_playSpaceMarker );
}
}
}
bool ChaperoneTabController::forceBounds() const
{
return m_forceBounds;
}
bool ChaperoneTabController::isChaperoneSwitchToBeginnerEnabled() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneSwitchToBeginnerEnabled );
}
float ChaperoneTabController::chaperoneSwitchToBeginnerDistance() const
{
return m_chaperoneSwitchToBeginnerDistance;
}
bool ChaperoneTabController::isChaperoneHapticFeedbackEnabled() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneHapticFeedbackEnabled );
}
float ChaperoneTabController::chaperoneHapticFeedbackDistance() const
{
return m_chaperoneHapticFeedbackDistance;
}
bool ChaperoneTabController::isChaperoneAlarmSoundEnabled() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundEnabled );
}
bool ChaperoneTabController::isChaperoneAlarmSoundLooping() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundLooping );
}
bool ChaperoneTabController::isChaperoneAlarmSoundAdjustVolume() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundAdjustVolume );
}
bool ChaperoneTabController::disableChaperone() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_disableChaperone );
}
float ChaperoneTabController::chaperoneAlarmSoundDistance() const
{
return m_chaperoneAlarmSoundDistance;
}
bool ChaperoneTabController::isChaperoneShowDashboardEnabled() const
{
return settings::getSetting(
settings::BoolSetting::CHAPERONE_chaperoneShowDashboardEnabled );
}
float ChaperoneTabController::chaperoneShowDashboardDistance() const
{
return m_chaperoneShowDashboardDistance;
}
Q_INVOKABLE unsigned ChaperoneTabController::getChaperoneProfileCount()
{
return static_cast<unsigned int>( chaperoneProfiles.size() );
}
Q_INVOKABLE QString
ChaperoneTabController::getChaperoneProfileName( unsigned index )
{
if ( index >= chaperoneProfiles.size() )
{
return QString();
}
else
{
return QString::fromStdString( chaperoneProfiles[index].profileName );
}
}
void ChaperoneTabController::setForceBounds( bool value, bool notify )
{
if ( m_forceBounds != value )
{
m_forceBounds = value;
vr::VRChaperone()->ForceBoundsVisible( m_forceBounds );
if ( notify )
{
emit forceBoundsChanged( m_forceBounds );
}
}
}
void ChaperoneTabController::setChaperoneSwitchToBeginnerEnabled( bool value,
bool notify )
{
if ( isChaperoneSwitchToBeginnerEnabled() != value )
{
if ( !value && m_chaperoneSwitchToBeginnerActive )
{
vr::EVRSettingsError vrSettingsError;
vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
m_chaperoneSwitchToBeginnerLastStyle,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING )
<< "Could not set \""
<< vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
else
{
vr::VRSettings()->Sync( true );
}
}
m_chaperoneSwitchToBeginnerActive = false;
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneSwitchToBeginnerEnabled,
value );
if ( notify )
{
emit chaperoneSwitchToBeginnerEnabledChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneSwitchToBeginnerDistance( float value,
bool notify )
{
if ( fabs( static_cast<double>( m_chaperoneSwitchToBeginnerDistance
- value ) )
> 0.005 )
{
m_chaperoneSwitchToBeginnerDistance = value;
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->setValue( "chaperoneSwitchToBeginnerDistance",
m_chaperoneSwitchToBeginnerDistance );
settings->endGroup();
settings->sync();
if ( notify )
{
emit chaperoneSwitchToBeginnerDistanceChanged(
m_chaperoneSwitchToBeginnerDistance );
}
}
}
void ChaperoneTabController::setChaperoneHapticFeedbackEnabled( bool value,
bool notify )
{
if ( isChaperoneHapticFeedbackEnabled() != value )
{
m_chaperoneHapticFeedbackActive = false;
if ( m_chaperoneHapticFeedbackThread.joinable() )
{
m_chaperoneHapticFeedbackThread.join();
}
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneHapticFeedbackEnabled,
value );
if ( notify )
{
emit chaperoneHapticFeedbackEnabledChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneHapticFeedbackDistance( float value,
bool notify )
{
if ( fabs(
static_cast<double>( m_chaperoneHapticFeedbackDistance - value ) )
> 0.005 )
{
m_chaperoneHapticFeedbackDistance = value;
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->setValue( "chaperoneHapticFeedbackDistance",
m_chaperoneHapticFeedbackDistance );
settings->endGroup();
settings->sync();
if ( notify )
{
emit chaperoneHapticFeedbackDistanceChanged(
m_chaperoneHapticFeedbackDistance );
}
}
}
void ChaperoneTabController::setChaperoneAlarmSoundEnabled( bool value,
bool notify )
{
if ( isChaperoneAlarmSoundEnabled() != value )
{
if ( !value && m_chaperoneAlarmSoundActive )
{
parent->cancelAlarm01Sound();
}
m_chaperoneAlarmSoundActive = false;
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundEnabled,
value );
if ( notify )
{
emit chaperoneAlarmSoundEnabledChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneAlarmSoundLooping( bool value,
bool notify )
{
if ( isChaperoneAlarmSoundLooping() != value )
{
if ( isChaperoneAlarmSoundEnabled() && m_chaperoneAlarmSoundActive )
{
if ( isChaperoneAlarmSoundLooping() )
{
parent->playAlarm01Sound( isChaperoneAlarmSoundLooping() );
}
else
{
parent->cancelAlarm01Sound();
}
}
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundLooping,
value );
if ( notify )
{
emit chaperoneAlarmSoundLoopingChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneAlarmSoundAdjustVolume( bool value,
bool notify )
{
if ( isChaperoneAlarmSoundAdjustVolume() != value )
{
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneAlarmSoundAdjustVolume,
value );
if ( notify )
{
emit chaperoneAlarmSoundAdjustVolumeChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneAlarmSoundDistance( float value,
bool notify )
{
if ( fabs( static_cast<double>( m_chaperoneAlarmSoundDistance - value ) )
> 0.005 )
{
m_chaperoneAlarmSoundDistance = value;
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->setValue( "chaperoneAlarmSoundDistance",
m_chaperoneAlarmSoundDistance );
settings->endGroup();
settings->sync();
if ( notify )
{
emit chaperoneAlarmSoundDistanceChanged(
m_chaperoneAlarmSoundDistance );
}
}
}
void ChaperoneTabController::setChaperoneShowDashboardEnabled( bool value,
bool notify )
{
if ( isChaperoneShowDashboardEnabled() != value )
{
m_chaperoneShowDashboardActive = false;
settings::setSetting(
settings::BoolSetting::CHAPERONE_chaperoneShowDashboardEnabled,
value );
if ( notify )
{
emit chaperoneShowDashboardEnabledChanged( value );
}
}
}
void ChaperoneTabController::setChaperoneShowDashboardDistance( float value,
bool notify )
{
if ( fabs( static_cast<double>( m_chaperoneShowDashboardDistance - value ) )
> 0.005 )
{
m_chaperoneShowDashboardDistance = value;
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->setValue( "chaperoneShowDashboardDistance",
m_chaperoneShowDashboardDistance );
settings->endGroup();
settings->sync();
if ( notify )
{
emit chaperoneShowDashboardDistanceChanged(
m_chaperoneShowDashboardDistance );
}
}
}
void ChaperoneTabController::setDisableChaperone( bool value, bool notify )
{
if ( disableChaperone() != value )
{
if ( value )
{
m_fadeDistanceRemembered = m_fadeDistance;
setFadeDistance( 0.0f, true );
}
else
{
setFadeDistance( m_fadeDistanceRemembered, true );
}
auto settings = OverlayController::appSettings();
settings->beginGroup( "chaperoneSettings" );
settings->setValue( "fadeDistanceRemembered",
m_fadeDistanceRemembered );
settings->endGroup();
settings->sync();
settings::setSetting( settings::BoolSetting::CHAPERONE_disableChaperone,
value );
if ( notify )
{
emit disableChaperoneChanged( value );
}
}
}
void ChaperoneTabController::flipOrientation( double degrees )
{
parent->m_moveCenterTabController.reset();
double rad = 0;
rad = degrees * ( M_PI / 180.0 );
parent->RotateUniverseCenter( vr::TrackingUniverseStanding,
static_cast<float>( rad ) );
parent->m_moveCenterTabController.zeroOffsets();
}
void ChaperoneTabController::reloadFromDisk()
{
parent->m_moveCenterTabController.reset();
vr::VRChaperoneSetup()->ReloadFromDisk( vr::EChaperoneConfigFile_Live );
vr::VRChaperoneSetup()->CommitWorkingCopy( vr::EChaperoneConfigFile_Live );
parent->m_moveCenterTabController.zeroOffsets();
}
void ChaperoneTabController::addChaperoneProfile(
QString name,
bool includeGeometry,
bool includeVisbility,
bool includeFadeDistance,
bool includeCenterMarker,
bool includePlaySpaceMarker,
bool includeFloorBounds,
bool includeBoundsColor,
bool includeChaperoneStyle,
bool includeForceBounds,
bool includesProximityWarningSettings )
{
vr::EVRSettingsError vrSettingsError;
ChaperoneProfile* profile = nullptr;
for ( auto& p : chaperoneProfiles )
{
if ( p.profileName.compare( name.toStdString() ) == 0 )
{
profile = &p;
break;
}
}
if ( !profile )
{
auto i = chaperoneProfiles.size();
chaperoneProfiles.emplace_back();
profile = &chaperoneProfiles[i];
}
profile->profileName = name.toStdString();
profile->includesChaperoneGeometry = includeGeometry;
if ( includeGeometry )
{
vr::VRChaperoneSetup()->HideWorkingSetPreview();
vr::VRChaperoneSetup()->RevertWorkingCopy();
uint32_t quadCount = 0;
vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( nullptr,
&quadCount );
profile->chaperoneGeometryQuadCount = quadCount;
profile->chaperoneGeometryQuads.reset( new vr::HmdQuad_t[quadCount] );
vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(
profile->chaperoneGeometryQuads.get(), &quadCount );
vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose(
&profile->standingCenter );
vr::VRChaperoneSetup()->GetWorkingPlayAreaSize(
&profile->playSpaceAreaX, &profile->playSpaceAreaZ );
}
profile->includesVisibility = includeVisbility;
if ( includeVisbility )
{
profile->visibility = m_visibility;
}
profile->includesFadeDistance = includeFadeDistance;
if ( includeFadeDistance )
{
profile->fadeDistance = m_fadeDistance;
}
profile->includesCenterMarker = includeCenterMarker;
if ( includeCenterMarker )
{
profile->centerMarker = m_centerMarker;
}
profile->includesPlaySpaceMarker = includePlaySpaceMarker;
if ( includePlaySpaceMarker )
{
profile->playSpaceMarker = m_playSpaceMarker;
}
profile->includesFloorBoundsMarker = includeFloorBounds;
if ( includeFloorBounds )
{
profile->floorBoundsMarker = vr::VRSettings()->GetBool(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
}
profile->includesBoundsColor = includeBoundsColor;
if ( includeBoundsColor )
{
profile->boundsColor[0] = vr::VRSettings()->GetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaR_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_ColorGammaR_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
profile->boundsColor[1] = vr::VRSettings()->GetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaG_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_ColorGammaG_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
profile->boundsColor[2] = vr::VRSettings()->GetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaB_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_ColorGammaB_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
}
profile->includesChaperoneStyle = includeChaperoneStyle;
if ( includeChaperoneStyle )
{
profile->chaperoneStyle
= vr::VRSettings()->GetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not read \""
<< vr::k_pch_CollisionBounds_Style_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
}
profile->includesForceBounds = includeForceBounds;
if ( includeForceBounds )
{
profile->forceBounds = m_forceBounds;
}
profile->includesProximityWarningSettings
= includesProximityWarningSettings;
if ( includesProximityWarningSettings )
{
profile->enableChaperoneSwitchToBeginner
= isChaperoneSwitchToBeginnerEnabled();
profile->chaperoneSwitchToBeginnerDistance
= m_chaperoneSwitchToBeginnerDistance;
profile->enableChaperoneHapticFeedback
= isChaperoneHapticFeedbackEnabled();
profile->chaperoneHapticFeedbackDistance
= m_chaperoneHapticFeedbackDistance;
profile->enableChaperoneAlarmSound = isChaperoneAlarmSoundEnabled();
profile->chaperoneAlarmSoundLooping = isChaperoneAlarmSoundLooping();
profile->chaperoneAlarmSoundAdjustVolume
= isChaperoneAlarmSoundAdjustVolume();
profile->chaperoneAlarmSoundDistance = m_chaperoneAlarmSoundDistance;
profile->enableChaperoneShowDashboard
= isChaperoneShowDashboardEnabled();
profile->chaperoneShowDashboardDistance
= m_chaperoneShowDashboardDistance;
}
saveChaperoneProfiles();
OverlayController::appSettings()->sync();
emit chaperoneProfilesUpdated();
}
void ChaperoneTabController::applyChaperoneProfile( unsigned index )
{
if ( index < chaperoneProfiles.size() )
{
auto& profile = chaperoneProfiles[index];
if ( profile.includesChaperoneGeometry )
{
parent->m_moveCenterTabController.reset();
vr::VRChaperoneSetup()->HideWorkingSetPreview();
vr::VRChaperoneSetup()->RevertWorkingCopy();
vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(
profile.chaperoneGeometryQuads.get(),
profile.chaperoneGeometryQuadCount );
vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose(
&profile.standingCenter );
vr::VRChaperoneSetup()->SetWorkingPlayAreaSize(
profile.playSpaceAreaX, profile.playSpaceAreaZ );
vr::VRChaperoneSetup()->CommitWorkingCopy(
vr::EChaperoneConfigFile_Live );
parent->m_moveCenterTabController.zeroOffsets();
}
if ( profile.includesVisibility )
{
setBoundsVisibility( profile.visibility );
}
if ( profile.includesFadeDistance )
{
setFadeDistance( profile.fadeDistance );
}
if ( profile.includesCenterMarker )
{
setCenterMarker( profile.centerMarker );
}
if ( profile.includesPlaySpaceMarker )
{
setPlaySpaceMarker( profile.playSpaceMarker );
}
if ( profile.includesFloorBoundsMarker )
{
vr::VRSettings()->SetBool(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool,
profile.floorBoundsMarker );
}
if ( profile.includesBoundsColor )
{
vr::VRSettings()->SetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaR_Int32,
profile.boundsColor[0] );
vr::VRSettings()->SetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaG_Int32,
profile.boundsColor[1] );
vr::VRSettings()->SetInt32(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaB_Int32,
profile.boundsColor[2] );
}
if ( profile.includesChaperoneStyle )
{
vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
profile.chaperoneStyle );
}
if ( profile.includesForceBounds )
{
setForceBounds( profile.forceBounds );
}
if ( profile.includesProximityWarningSettings )
{
setChaperoneSwitchToBeginnerDistance(
profile.chaperoneSwitchToBeginnerDistance );
setChaperoneSwitchToBeginnerEnabled(
profile.enableChaperoneSwitchToBeginner );
setChaperoneHapticFeedbackDistance(
profile.chaperoneHapticFeedbackDistance );
setChaperoneHapticFeedbackEnabled(
profile.enableChaperoneHapticFeedback );
setChaperoneAlarmSoundLooping( profile.chaperoneAlarmSoundLooping );
setChaperoneAlarmSoundAdjustVolume(
profile.chaperoneAlarmSoundAdjustVolume );
setChaperoneAlarmSoundDistance(
profile.chaperoneAlarmSoundDistance );
setChaperoneAlarmSoundEnabled( profile.enableChaperoneAlarmSound );
setChaperoneShowDashboardDistance(
profile.chaperoneShowDashboardDistance );
setChaperoneShowDashboardEnabled(
profile.enableChaperoneShowDashboard );
}
vr::VRSettings()->Sync( true );
}
}
void ChaperoneTabController::deleteChaperoneProfile( unsigned index )
{
if ( index < chaperoneProfiles.size() )
{
auto pos = chaperoneProfiles.begin() + index;
chaperoneProfiles.erase( pos );
saveChaperoneProfiles();
OverlayController::appSettings()->sync();
emit chaperoneProfilesUpdated();
}
}
std::pair<bool, unsigned>
ChaperoneTabController::getChaperoneProfileIndexFromName( std::string name )
{
std::pair<bool, unsigned> result = { false, 0 };
unsigned profileIndex = 0;
for ( auto& p : chaperoneProfiles )
{
if ( name == p.profileName )
{
result.first = true;
result.second = profileIndex;
break;
}
profileIndex++;
}
return result;
}
void ChaperoneTabController::createNewAutosaveProfile()
{
// update settings to live chaperone
updateChaperoneSettings();
// lookup the index for old autosave and delete it
std::pair<bool, unsigned> previousAutosaveIndexLookup
= getChaperoneProfileIndexFromName( "«Autosaved Profile (previous)»" );
if ( previousAutosaveIndexLookup.first )
{
deleteChaperoneProfile( previousAutosaveIndexLookup.second );
}
else
{
LOG( INFO )
<< "[Chaperone Autosave] «Autosaved Profile (previous)» not found";
}
// lookup the index for current autosave and rename to old
std::pair<bool, unsigned> currentAutosaveIndexLookup
= getChaperoneProfileIndexFromName( "«Autosaved Profile»" );
if ( currentAutosaveIndexLookup.first )
{
chaperoneProfiles[currentAutosaveIndexLookup.second].profileName
= "«Autosaved Profile (previous)»";
saveChaperoneProfiles();
OverlayController::appSettings()->sync();
emit chaperoneProfilesUpdated();
}
else
{
LOG( INFO ) << "[Chaperone Autosave] «Autosaved Profile» not found";
}
// create a new autosave from current chaperone (all options set true)
addChaperoneProfile( "«Autosaved Profile»",
true,
true,
true,
true,
true,
true,
true,
true,
true,
true );
}
void ChaperoneTabController::applyAutosavedProfile()
{
// lookup index of autosave
std::pair<bool, unsigned> autosaveIndexLookup
= getChaperoneProfileIndexFromName( "«Autosaved Profile»" );
// check if it exists
if ( autosaveIndexLookup.first )
{
// apply if it exists
applyChaperoneProfile( autosaveIndexLookup.second );
}
else
{
LOG( WARNING ) << "Failed to apply chaperone Autosaved Profile "
"(autosave doesn't exist)";
}
}
void ChaperoneTabController::reset()
{
vr::EVRSettingsError vrSettingsError;
vr::VRSettings()->RemoveKeyInSection(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_ColorGammaA_Int32,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not remove \""
<< vr::k_pch_CollisionBounds_ColorGammaA_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
vr::VRSettings()->RemoveKeyInSection(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_FadeDistance_Float,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not remove \""
<< vr::k_pch_CollisionBounds_FadeDistance_Float
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
vr::VRSettings()->RemoveKeyInSection(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_CenterMarkerOn_Bool,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not remove \""
<< vr::k_pch_CollisionBounds_CenterMarkerOn_Bool
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
vr::VRSettings()->RemoveKeyInSection(
vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_PlaySpaceOn_Bool,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not remove \""
<< vr::k_pch_CollisionBounds_PlaySpaceOn_Bool
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
setForceBounds( false );
vr::VRSettings()->Sync();
settingsUpdateCounter = 999; // Easiest way to get default values
}
void ChaperoneTabController::setRightHapticActionHandle(
vr::VRActionHandle_t handle )
{
m_rightActionHandle = handle;
}
void ChaperoneTabController::setLeftHapticActionHandle(
vr::VRActionHandle_t handle )
{
m_leftActionHandle = handle;
}
void ChaperoneTabController::setRightInputHandle(
vr::VRInputValueHandle_t handle )
{
m_rightInputHandle = handle;
}
void ChaperoneTabController::setLeftInputHandle(
vr::VRInputValueHandle_t handle )
{
m_leftInputHandle = handle;
}
void ChaperoneTabController::addLeftHapticClick( bool leftHapticClickPressed )
{
// detect new press
if ( leftHapticClickPressed && !m_leftHapticClickActivated )
{
// play activation haptic sequence
vr::VRInput()->TriggerHapticVibrationAction(
m_leftActionHandle, 0.0f, 0.08f, 300.0f, 0.7f, m_leftInputHandle );
m_leftHapticClickActivated = true;
return;
}
// detect new release
if ( !leftHapticClickPressed && m_leftHapticClickActivated )
{
// play deactivation haptic sequence
vr::VRInput()->TriggerHapticVibrationAction(
m_leftActionHandle, 0.0f, 0.08f, 120.0f, 0.7f, m_leftInputHandle );
m_leftHapticClickActivated = false;
return;
}
}
void ChaperoneTabController::addRightHapticClick( bool rightHapticClickPressed )
{
// detect new press
if ( rightHapticClickPressed && !m_rightHapticClickActivated )
{
// play activation haptic sequence
vr::VRInput()->TriggerHapticVibrationAction( m_rightActionHandle,
0.0f,
0.08f,
300.0f,
0.7f,
m_rightInputHandle );
m_rightHapticClickActivated = true;
return;
}
// detect new release
if ( !rightHapticClickPressed && m_rightHapticClickActivated )
{
// play deactivation haptic sequence
vr::VRInput()->TriggerHapticVibrationAction( m_rightActionHandle,
0.0f,
0.08f,
120.0f,
0.7f,
m_rightInputHandle );
m_rightHapticClickActivated = false;
return;
}
}
void ChaperoneTabController::setProxState( bool value )
{
if ( value )
{
m_HMDHasProx = true;
}
m_isProxActive = value;
}
void ChaperoneTabController::shutdown()
{
if ( isChaperoneSwitchToBeginnerEnabled()
&& m_chaperoneSwitchToBeginnerActive )
{
vr::EVRSettingsError vrSettingsError;
vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section,
vr::k_pch_CollisionBounds_Style_Int32,
m_chaperoneSwitchToBeginnerLastStyle,
&vrSettingsError );
if ( vrSettingsError != vr::VRSettingsError_None )
{
LOG( WARNING ) << "Could not set \""
<< vr::k_pch_CollisionBounds_Style_Int32
<< "\" setting: "
<< vr::VRSettings()->GetSettingsErrorNameFromEnum(
vrSettingsError );
}
else
{
vr::VRSettings()->Sync( true );
}
}
}
} // namespace advsettings