Reimplemented sound effects.
Added chaperone proximity warnings. Other bugfixes and improvements.
This commit is contained in:
@@ -25,7 +25,8 @@ SOURCES += src/main.cpp\
|
|||||||
src/tabcontrollers/UtilitiesTabController.cpp \
|
src/tabcontrollers/UtilitiesTabController.cpp \
|
||||||
src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
|
src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
|
||||||
src/tabcontrollers/PttController.cpp \
|
src/tabcontrollers/PttController.cpp \
|
||||||
src/tabcontrollers/AccessibilityTabController.cpp
|
src/tabcontrollers/AccessibilityTabController.cpp \
|
||||||
|
src/utils/ChaperoneUtils.cpp
|
||||||
|
|
||||||
HEADERS += src/overlaycontroller.h \
|
HEADERS += src/overlaycontroller.h \
|
||||||
src/logging.h \
|
src/logging.h \
|
||||||
@@ -41,7 +42,9 @@ HEADERS += src/overlaycontroller.h \
|
|||||||
src/tabcontrollers/AudioManager.h \
|
src/tabcontrollers/AudioManager.h \
|
||||||
src/tabcontrollers/audiomanager/AudioManagerWindows.h \
|
src/tabcontrollers/audiomanager/AudioManagerWindows.h \
|
||||||
src/tabcontrollers/PttController.h \
|
src/tabcontrollers/PttController.h \
|
||||||
src/tabcontrollers/AccessibilityTabController.h
|
src/tabcontrollers/AccessibilityTabController.h \
|
||||||
|
src/utils/Matrix.h \
|
||||||
|
src/utils/ChaperoneUtils.h
|
||||||
|
|
||||||
INCLUDEPATH += third-party/openvr/include \
|
INCLUDEPATH += third-party/openvr/include \
|
||||||
third-party/easylogging++
|
third-party/easylogging++
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import QtQuick.Controls 2.0
|
|||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Dialogs 1.2
|
import QtQuick.Dialogs 1.2
|
||||||
import matzman666.advsettings 1.0
|
import matzman666.advsettings 1.0
|
||||||
|
import "." // QTBUG-34418, singletons require explicit import to load qmldir file
|
||||||
|
|
||||||
MyStackViewPage {
|
MyStackViewPage {
|
||||||
headerText: "Chaperone Settings"
|
headerText: "Chaperone Settings"
|
||||||
@@ -102,6 +103,11 @@ MyStackViewPage {
|
|||||||
Layout.leftMargin: 32
|
Layout.leftMargin: 32
|
||||||
text: "Force Bounds Setting"
|
text: "Force Bounds Setting"
|
||||||
}
|
}
|
||||||
|
MyToggleButton {
|
||||||
|
id: chaperoneNewProfileIncludeProximityWarnings
|
||||||
|
Layout.leftMargin: 32
|
||||||
|
text: "Proximity Warning Settings"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onClosed: {
|
onClosed: {
|
||||||
if (okClicked) {
|
if (okClicked) {
|
||||||
@@ -115,7 +121,8 @@ MyStackViewPage {
|
|||||||
&& !chaperoneNewProfileIncludeFloorBoundsMarker.checked
|
&& !chaperoneNewProfileIncludeFloorBoundsMarker.checked
|
||||||
&& !chaperoneNewProfileIncludeBoundsColor.checked
|
&& !chaperoneNewProfileIncludeBoundsColor.checked
|
||||||
&& !chaperoneNewProfileIncludeStyle.checked
|
&& !chaperoneNewProfileIncludeStyle.checked
|
||||||
&& !chaperoneNewProfileIncludeForceBounds.checked) {
|
&& !chaperoneNewProfileIncludeForceBounds.checked
|
||||||
|
&& !chaperoneNewProfileIncludeProximityWarnings.checked) {
|
||||||
chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Nothing included.")
|
chaperoneMessageDialog.showMessage("Create New Profile", "ERROR: Nothing included.")
|
||||||
} else {
|
} else {
|
||||||
ChaperoneTabController.addChaperoneProfile(chaperoneNewProfileName.text,
|
ChaperoneTabController.addChaperoneProfile(chaperoneNewProfileName.text,
|
||||||
@@ -127,7 +134,8 @@ MyStackViewPage {
|
|||||||
chaperoneNewProfileIncludeFloorBoundsMarker.checked,
|
chaperoneNewProfileIncludeFloorBoundsMarker.checked,
|
||||||
chaperoneNewProfileIncludeBoundsColor.checked,
|
chaperoneNewProfileIncludeBoundsColor.checked,
|
||||||
chaperoneNewProfileIncludeStyle.checked,
|
chaperoneNewProfileIncludeStyle.checked,
|
||||||
chaperoneNewProfileIncludeForceBounds.checked)
|
chaperoneNewProfileIncludeForceBounds.checked,
|
||||||
|
chaperoneNewProfileIncludeProximityWarnings.checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -143,6 +151,7 @@ MyStackViewPage {
|
|||||||
chaperoneNewProfileIncludeBoundsColor.checked = false
|
chaperoneNewProfileIncludeBoundsColor.checked = false
|
||||||
chaperoneNewProfileIncludeStyle.checked = false
|
chaperoneNewProfileIncludeStyle.checked = false
|
||||||
chaperoneNewProfileIncludeForceBounds.checked = false
|
chaperoneNewProfileIncludeForceBounds.checked = false
|
||||||
|
chaperoneNewProfileIncludeProximityWarnings.checked = false
|
||||||
open()
|
open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,6 +449,18 @@ MyStackViewPage {
|
|||||||
ChaperoneTabController.setForceBounds(this.checked, false)
|
ChaperoneTabController.setForceBounds(this.checked, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
MyPushButton {
|
||||||
|
id: chaperoneWarningsConfigButton
|
||||||
|
text: "Proximity Warning Settings"
|
||||||
|
Layout.preferredWidth: 350
|
||||||
|
onClicked: {
|
||||||
|
MyResources.playFocusChangedSound()
|
||||||
|
mainView.push(chaperoneWarningsPage)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MyPushButton {
|
MyPushButton {
|
||||||
|
|||||||
@@ -0,0 +1,567 @@
|
|||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.0
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import matzman666.advsettings 1.0
|
||||||
|
import "." // QTBUG-34418, singletons require explicit import to load qmldir file
|
||||||
|
|
||||||
|
MyStackViewPage {
|
||||||
|
headerText: "Chaperone Proximity Warning Settings"
|
||||||
|
|
||||||
|
ColorDialog {
|
||||||
|
id: colorDialog
|
||||||
|
title: "Please choose a color"
|
||||||
|
onAccepted: {
|
||||||
|
console.log("You chose: " + colorDialog.color)
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("Canceled")
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content: ColumnLayout {
|
||||||
|
spacing: 36
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
MyToggleButton {
|
||||||
|
id: switchBeginnerToggle
|
||||||
|
text: "Switch to Beginner Mode"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneSwitchToBeginnerEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
MyText {
|
||||||
|
text: "Activation Distance: "
|
||||||
|
Layout.preferredWidth: 250
|
||||||
|
}
|
||||||
|
MyPushButton2 {
|
||||||
|
id: switchBeginnerDistanceMinusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "-"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneSwitchToBeginnerDistance - 0.1
|
||||||
|
if (val <= 0) {
|
||||||
|
val = 0.1;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneSwitchToBeginnerDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySlider {
|
||||||
|
id: switchBeginnerDistanceSlider
|
||||||
|
from: 0
|
||||||
|
to: 2.0
|
||||||
|
stepSize: 0.01
|
||||||
|
value: 0.5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPositionChanged: {
|
||||||
|
var val = this.from + ( this.position * (this.to - this.from))
|
||||||
|
switchBeginnerDistanceText.text = val.toFixed(2)
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
var val = switchBeginnerDistanceSlider.value.toFixed(2)
|
||||||
|
if (val < 0.01) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneSwitchToBeginnerDistance = val
|
||||||
|
switchBeginnerDistanceText.text = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPushButton2 {
|
||||||
|
id: switchBeginnerDistancePlusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "+"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneSwitchToBeginnerDistance + 0.1
|
||||||
|
if (val > 2.0) {
|
||||||
|
val = 2.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneSwitchToBeginnerDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: switchBeginnerDistanceText
|
||||||
|
text: "0.00"
|
||||||
|
keyBoardUID: 801
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
function onInputEvent(input) {
|
||||||
|
var val = parseFloat(input)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
val = val.toFixed(2)
|
||||||
|
ChaperoneTabController.chaperoneSwitchToBeginnerDistance = val
|
||||||
|
text = val
|
||||||
|
} else {
|
||||||
|
text = ChaperoneTabController.chaperoneSwitchToBeginnerDistance.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
MyToggleButton {
|
||||||
|
id: hapticFeedbackToggle
|
||||||
|
text: "Trigger Haptic Feedback"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneHapticFeedbackEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
MyText {
|
||||||
|
text: "Activation Distance: "
|
||||||
|
Layout.preferredWidth: 250
|
||||||
|
}
|
||||||
|
MyPushButton2 {
|
||||||
|
id: hapticFeedbackDistanceMinusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "-"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneHapticFeedbackDistance - 0.1
|
||||||
|
if (val <= 0) {
|
||||||
|
val = 0.1;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneHapticFeedbackDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySlider {
|
||||||
|
id: hapticFeedbackDistanceSlider
|
||||||
|
from: 0
|
||||||
|
to: 2.0
|
||||||
|
stepSize: 0.01
|
||||||
|
value: 0.5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPositionChanged: {
|
||||||
|
var val = this.from + ( this.position * (this.to - this.from))
|
||||||
|
hapticFeedbackDistanceText.text = val.toFixed(2)
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
var val = hapticFeedbackDistanceSlider.value.toFixed(2)
|
||||||
|
if (val < 0.01) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneHapticFeedbackDistance = val
|
||||||
|
hapticFeedbackDistanceText.text = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPushButton2 {
|
||||||
|
id: hapticFeedbackDistancePlusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "+"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneHapticFeedbackDistance + 0.1
|
||||||
|
if (val > 2.0) {
|
||||||
|
val = 2.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneHapticFeedbackDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: hapticFeedbackDistanceText
|
||||||
|
text: "0.00"
|
||||||
|
keyBoardUID: 805
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
function onInputEvent(input) {
|
||||||
|
var val = parseFloat(input)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
val = val.toFixed(2)
|
||||||
|
ChaperoneTabController.chaperoneHapticFeedbackDistance = val
|
||||||
|
text = val
|
||||||
|
} else {
|
||||||
|
text = ChaperoneTabController.chaperoneHapticFeedbackDistance.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
RowLayout {
|
||||||
|
spacing: 32
|
||||||
|
MyToggleButton {
|
||||||
|
id: audioWarningToggle
|
||||||
|
text: "Audio Warning"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyToggleButton {
|
||||||
|
id: audioWarningLoopingToggle
|
||||||
|
text: "Loop Audio"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundLooping = checked
|
||||||
|
audioWarningAdjustVolumeToggle.enabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyToggleButton {
|
||||||
|
id: audioWarningAdjustVolumeToggle
|
||||||
|
text: "Adjust Volume"
|
||||||
|
enabled: false
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundAdjustVolume = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
MyText {
|
||||||
|
text: "Activation Distance: "
|
||||||
|
Layout.preferredWidth: 250
|
||||||
|
}
|
||||||
|
MyPushButton2 {
|
||||||
|
id: audioWarningDistanceMinusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "-"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneAlarmSoundDistance - 0.1
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySlider {
|
||||||
|
id: audioWarningDistanceSlider
|
||||||
|
from: 0
|
||||||
|
to: 2.0
|
||||||
|
stepSize: 0.01
|
||||||
|
value: 0.5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPositionChanged: {
|
||||||
|
var val = this.from + ( this.position * (this.to - this.from))
|
||||||
|
audioWarningDistanceText.text = val.toFixed(2)
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
var val = audioWarningDistanceSlider.value.toFixed(2)
|
||||||
|
if (val < 0.01) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundDistance = val
|
||||||
|
audioWarningDistanceText.text = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPushButton2 {
|
||||||
|
id: audioWarningDistancePlusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "+"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneAlarmSoundDistance + 0.1
|
||||||
|
if (val > 2.0) {
|
||||||
|
val = 2.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: audioWarningDistanceText
|
||||||
|
text: "0.00"
|
||||||
|
keyBoardUID: 802
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
function onInputEvent(input) {
|
||||||
|
var val = parseFloat(input)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
val = val.toFixed(2)
|
||||||
|
ChaperoneTabController.chaperoneAlarmSoundDistance = val
|
||||||
|
text = val
|
||||||
|
} else {
|
||||||
|
text = ChaperoneTabController.chaperoneAlarmSoundDistance.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
MyToggleButton {
|
||||||
|
id: openDashboardToggle
|
||||||
|
text: "Open Dashboard"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneShowDashboardEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
MyText {
|
||||||
|
text: "Activation Distance: "
|
||||||
|
Layout.preferredWidth: 250
|
||||||
|
}
|
||||||
|
MyPushButton2 {
|
||||||
|
id: openDashboardDistanceMinusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "-"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneShowDashboardDistance - 0.1
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneShowDashboardDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySlider {
|
||||||
|
id: openDashboardDistanceSlider
|
||||||
|
from: 0
|
||||||
|
to: 2.0
|
||||||
|
stepSize: 0.01
|
||||||
|
value: 0.5
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPositionChanged: {
|
||||||
|
var val = this.from + ( this.position * (this.to - this.from))
|
||||||
|
openDashboardDistanceText.text = val.toFixed(2)
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
var val = openDashboardDistanceSlider.value.toFixed(2)
|
||||||
|
if (val < 0.01) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneShowDashboardDistance = val
|
||||||
|
openDashboardDistanceText.text = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPushButton2 {
|
||||||
|
id: openDashboardDistancePlusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "+"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneShowDashboardDistance + 0.1
|
||||||
|
if (val > 2.0) {
|
||||||
|
val = 2.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneShowDashboardDistance = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: openDashboardDistanceText
|
||||||
|
text: "0.00"
|
||||||
|
keyBoardUID: 803
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
function onInputEvent(input) {
|
||||||
|
var val = parseFloat(input)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
if (val <= 0.0) {
|
||||||
|
val = 0.01
|
||||||
|
}
|
||||||
|
val = val.toFixed(2)
|
||||||
|
ChaperoneTabController.chaperoneShowDashboardDistance = val
|
||||||
|
text = val
|
||||||
|
} else {
|
||||||
|
text = ChaperoneTabController.chaperoneShowDashboardDistance.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 0
|
||||||
|
MyToggleButton {
|
||||||
|
id: velModifierToggle
|
||||||
|
text: "Velocity Dependent Fade/Activation Distance"
|
||||||
|
onCheckedChanged: {
|
||||||
|
ChaperoneTabController.chaperoneVelocityModifierEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
MyText {
|
||||||
|
text: "Distance Modifier: "
|
||||||
|
Layout.preferredWidth: 250
|
||||||
|
}
|
||||||
|
MyPushButton2 {
|
||||||
|
id: velModifierMinusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "-"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneVelocityModifier - 0.01
|
||||||
|
if (val < 0.0) {
|
||||||
|
val = 0.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneVelocityModifier = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MySlider {
|
||||||
|
id: velModifierSlider
|
||||||
|
from: 0
|
||||||
|
to: 1.0
|
||||||
|
stepSize: 0.01
|
||||||
|
value: 0.3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onPositionChanged: {
|
||||||
|
var val = this.from + ( this.position * (this.to - this.from))
|
||||||
|
velModifierText.text = val.toFixed(2)
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
var val = velModifierSlider.value.toFixed(2)
|
||||||
|
if (val < 0.0) {
|
||||||
|
val = 0.0
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneVelocityModifier = val
|
||||||
|
velModifierText.text = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyPushButton2 {
|
||||||
|
id: velModifierPlusButton
|
||||||
|
Layout.preferredWidth: 40
|
||||||
|
text: "+"
|
||||||
|
onClicked: {
|
||||||
|
var val = ChaperoneTabController.chaperoneVelocityModifier + 0.01
|
||||||
|
if (val > 1.0) {
|
||||||
|
val = 1.0;
|
||||||
|
}
|
||||||
|
ChaperoneTabController.chaperoneVelocityModifier = val.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: velModifierText
|
||||||
|
text: "0.00"
|
||||||
|
keyBoardUID: 803
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
function onInputEvent(input) {
|
||||||
|
var val = parseFloat(input)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
if (val < 0.0) {
|
||||||
|
val = 0.0
|
||||||
|
}
|
||||||
|
val = val.toFixed(2)
|
||||||
|
ChaperoneTabController.chaperoneVelocityModifier = val
|
||||||
|
text = val
|
||||||
|
} else {
|
||||||
|
text = ChaperoneTabController.chaperoneVelocityModifier.toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
switchBeginnerToggle.checked = ChaperoneTabController.chaperoneSwitchToBeginnerEnabled
|
||||||
|
var d = ChaperoneTabController.chaperoneSwitchToBeginnerDistance.toFixed(2)
|
||||||
|
if (d <= switchBeginnerDistanceSlider.to) {
|
||||||
|
switchBeginnerDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
switchBeginnerDistanceText.text = d
|
||||||
|
hapticFeedbackToggle.checked = ChaperoneTabController.chaperoneHapticFeedbackEnabled
|
||||||
|
var d = ChaperoneTabController.chaperoneHapticFeedbackDistance.toFixed(2)
|
||||||
|
if (d <= hapticFeedbackDistanceSlider.to) {
|
||||||
|
hapticFeedbackDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
hapticFeedbackDistanceText.text = d
|
||||||
|
audioWarningToggle.checked = ChaperoneTabController.chaperoneAlarmSoundEnabled
|
||||||
|
audioWarningLoopingToggle.checked = ChaperoneTabController.chaperoneAlarmSoundLooping
|
||||||
|
audioWarningAdjustVolumeToggle.checked = ChaperoneTabController.chaperoneAlarmSoundAdjustVolume
|
||||||
|
d = ChaperoneTabController.chaperoneAlarmSoundDistance.toFixed(2)
|
||||||
|
if (d <= audioWarningDistanceSlider.to) {
|
||||||
|
audioWarningDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
audioWarningDistanceText.text = d
|
||||||
|
openDashboardToggle.checked = ChaperoneTabController.chaperoneShowDashboardEnabled
|
||||||
|
d = ChaperoneTabController.chaperoneShowDashboardDistance.toFixed(2)
|
||||||
|
if (d <= openDashboardDistanceSlider.to) {
|
||||||
|
openDashboardDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
openDashboardDistanceText.text = d
|
||||||
|
velModifierToggle.checked = ChaperoneTabController.chaperoneVelocityModifierEnabled
|
||||||
|
d = ChaperoneTabController.chaperoneVelocityModifier.toFixed(2)
|
||||||
|
if (d <= velModifierSlider.to) {
|
||||||
|
velModifierSlider.value = d
|
||||||
|
}
|
||||||
|
velModifierText.text = d
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ChaperoneTabController
|
||||||
|
onChaperoneSwitchToBeginnerEnabledChanged: {
|
||||||
|
switchBeginnerToggle.checked = ChaperoneTabController.chaperoneSwitchToBeginnerEnabled
|
||||||
|
}
|
||||||
|
onChaperoneSwitchToBeginnerDistanceChanged: {
|
||||||
|
var d = ChaperoneTabController.chaperoneSwitchToBeginnerDistance.toFixed(2)
|
||||||
|
if (d <= switchBeginnerDistanceSlider.to && Math.abs(switchBeginnerDistanceSlider.value - d) > 0.0008) {
|
||||||
|
switchBeginnerDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
switchBeginnerDistanceText.text = d
|
||||||
|
}
|
||||||
|
onChaperoneHapticFeedbackEnabledChanged: {
|
||||||
|
hapticFeedbackToggle.checked = ChaperoneTabController.chaperoneHapticFeedbackEnabled
|
||||||
|
}
|
||||||
|
onChaperoneHapticFeedbackDistanceChanged: {
|
||||||
|
var d = ChaperoneTabController.chaperoneHapticFeedbackDistance.toFixed(2)
|
||||||
|
if (d <= hapticFeedbackDistanceSlider.to && Math.abs(hapticFeedbackDistanceSlider.value - d) > 0.0008) {
|
||||||
|
hapticFeedbackDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
hapticFeedbackDistanceText.text = d
|
||||||
|
}
|
||||||
|
onChaperoneAlarmSoundEnabledChanged: {
|
||||||
|
audioWarningToggle.checked = ChaperoneTabController.chaperoneAlarmSoundEnabled
|
||||||
|
}
|
||||||
|
onChaperoneAlarmSoundLoopingChanged: {
|
||||||
|
audioWarningLoopingToggle.checked = ChaperoneTabController.chaperoneAlarmSoundLooping
|
||||||
|
}
|
||||||
|
onChaperoneAlarmSoundDistanceChanged: {
|
||||||
|
var d = ChaperoneTabController.chaperoneAlarmSoundDistance.toFixed(2)
|
||||||
|
if (d <= audioWarningDistanceSlider.to && Math.abs(audioWarningDistanceSlider.value - d) > 0.0008) {
|
||||||
|
audioWarningDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
audioWarningDistanceText.text = d
|
||||||
|
}
|
||||||
|
onChaperoneShowDashboardEnabledChanged: {
|
||||||
|
openDashboardToggle.checked = ChaperoneTabController.chaperoneShowDashboardEnabled
|
||||||
|
}
|
||||||
|
onChaperoneShowDashboardDistanceChanged: {
|
||||||
|
var d = ChaperoneTabController.chaperoneShowDashboardDistance.toFixed(2)
|
||||||
|
if (d <= openDashboardDistanceSlider.to && Math.abs(openDashboardDistanceSlider.value - d) > 0.0008) {
|
||||||
|
openDashboardDistanceSlider.value = d
|
||||||
|
}
|
||||||
|
openDashboardDistanceText.text = d
|
||||||
|
}
|
||||||
|
onChaperoneVelocityModifierEnabledChanged: {
|
||||||
|
velModifierToggle.checked = ChaperoneTabController.chaperoneVelocityModifierEnabled
|
||||||
|
}
|
||||||
|
onChaperoneVelocityModifierChanged: {
|
||||||
|
var d = ChaperoneTabController.chaperoneVelocityModifier.toFixed(2)
|
||||||
|
if (d <= velModifierSlider.to && Math.abs(velModifierSlider.value - d) > 0.0008) {
|
||||||
|
velModifierSlider.value = d
|
||||||
|
}
|
||||||
|
velModifierText.text = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,19 +5,9 @@ import matzman666.advsettings 1.0
|
|||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
function playActivationSound() {
|
function playActivationSound() {
|
||||||
/*if (!OverlayController.soundDisabled()) {
|
OverlayController.playActivationSound()
|
||||||
activationSound.play()
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
function playFocusChangedSound() {
|
function playFocusChangedSound() {
|
||||||
/*if (!OverlayController.soundDisabled()) {
|
OverlayController.playFocusChangedSound()
|
||||||
focusChangedSound.play()
|
}
|
||||||
}*/
|
|
||||||
}
|
|
||||||
/*property SoundEffect activationSound: SoundEffect {
|
|
||||||
source: vrRuntimePath + "content/panorama/sounds/activation.wav"
|
|
||||||
}
|
|
||||||
property SoundEffect focusChangedSound: SoundEffect {
|
|
||||||
source: vrRuntimePath + "content/panorama/sounds/focus_change.wav"
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ MyStackViewPage {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 80
|
Layout.leftMargin: 80
|
||||||
spacing: 18
|
spacing: 9
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 18
|
spacing: 18
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ Rectangle {
|
|||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property ChaperoneWarningsPage chaperoneWarningsPage: ChaperoneWarningsPage {
|
||||||
|
stackView: mainView
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
property PlayspacePage playspacePage: PlayspacePage {
|
property PlayspacePage playspacePage: PlayspacePage {
|
||||||
stackView: mainView
|
stackView: mainView
|
||||||
visible: false
|
visible: false
|
||||||
|
|||||||
Binary file not shown.
@@ -389,6 +389,7 @@ Delete $INSTDIR\qtdata\Universal\Tumbler.qml
|
|||||||
Delete $INSTDIR\res\qml\AudioPage.qml
|
Delete $INSTDIR\res\qml\AudioPage.qml
|
||||||
Delete $INSTDIR\res\qml\backarrow.svg
|
Delete $INSTDIR\res\qml\backarrow.svg
|
||||||
Delete $INSTDIR\res\qml\ChaperonePage.qml
|
Delete $INSTDIR\res\qml\ChaperonePage.qml
|
||||||
|
Delete $INSTDIR\res\qml\ChaperoneWarningsPage.qml
|
||||||
Delete $INSTDIR\res\qml\FixFloorPage.qml
|
Delete $INSTDIR\res\qml\FixFloorPage.qml
|
||||||
Delete $INSTDIR\res\qml\mainwidget.qml
|
Delete $INSTDIR\res\qml\mainwidget.qml
|
||||||
Delete $INSTDIR\res\qml\mic_off.svg
|
Delete $INSTDIR\res\qml\mic_off.svg
|
||||||
@@ -419,11 +420,13 @@ Delete $INSTDIR\res\qml\SteamVRPage.qml
|
|||||||
Delete $INSTDIR\res\qml\UtilitiesPage.qml
|
Delete $INSTDIR\res\qml\UtilitiesPage.qml
|
||||||
Delete $INSTDIR\res\qml\AccessibilityPage.qml
|
Delete $INSTDIR\res\qml\AccessibilityPage.qml
|
||||||
Delete $INSTDIR\res\thumbicon.png
|
Delete $INSTDIR\res\thumbicon.png
|
||||||
|
Delete $INSTDIR\res\sounds\alarm01.wav
|
||||||
Delete $INSTDIR\restartvrserver.bat
|
Delete $INSTDIR\restartvrserver.bat
|
||||||
Delete $INSTDIR\startdesktopmode.bat
|
Delete $INSTDIR\startdesktopmode.bat
|
||||||
Delete $INSTDIR\Uninstall.exe
|
Delete $INSTDIR\Uninstall.exe
|
||||||
Delete $INSTDIR\vcredist_x64.exe
|
Delete $INSTDIR\vcredist_x64.exe
|
||||||
RMdir $INSTDIR\res\qml
|
RMdir $INSTDIR\res\qml
|
||||||
|
RMdir $INSTDIR\res\sounds
|
||||||
RMdir $INSTDIR\res
|
RMdir $INSTDIR\res
|
||||||
RMdir $INSTDIR\qtdata\Universal
|
RMdir $INSTDIR\qtdata\Universal
|
||||||
RMdir $INSTDIR\qtdata\translations
|
RMdir $INSTDIR\qtdata\translations
|
||||||
|
|||||||
+17
-2
@@ -95,6 +95,21 @@ void removeManifest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MyQApplication : public QApplication {
|
||||||
|
public:
|
||||||
|
using QApplication::QApplication;
|
||||||
|
|
||||||
|
virtual bool notify(QObject * receiver, QEvent * event) override {
|
||||||
|
try {
|
||||||
|
return QApplication::notify(receiver, event);
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
LOG(ERROR) << "Exception thrown from an event handler: " << e.what();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
bool desktopMode = false;
|
bool desktopMode = false;
|
||||||
@@ -149,7 +164,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
QApplication a(argc, argv);
|
MyQApplication a(argc, argv);
|
||||||
a.setOrganizationName("matzman666");
|
a.setOrganizationName("matzman666");
|
||||||
a.setApplicationName("OpenVRAdvancedSettings");
|
a.setApplicationName("OpenVRAdvancedSettings");
|
||||||
a.setApplicationDisplayName(advsettings::OverlayController::applicationName);
|
a.setApplicationDisplayName(advsettings::OverlayController::applicationName);
|
||||||
@@ -174,7 +189,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
conf.setRemainingToDefault();
|
conf.setRemainingToDefault();
|
||||||
el::Loggers::reconfigureAllLoggers(conf);
|
el::Loggers::reconfigureAllLoggers(conf);
|
||||||
LOG(INFO) << "Application started";
|
LOG(INFO) << "Application started (Version " << advsettings::OverlayController::applicationVersionString << ")";
|
||||||
LOG(INFO) << "Log Config: " << QDir::toNativeSeparators(logconfigfile).toStdString();
|
LOG(INFO) << "Log Config: " << QDir::toNativeSeparators(logconfigfile).toStdString();
|
||||||
if (!logFilePath.isEmpty()) {
|
if (!logFilePath.isEmpty()) {
|
||||||
LOG(INFO) << "Log File: " << logFilePath;
|
LOG(INFO) << "Log File: " << logFilePath;
|
||||||
|
|||||||
+110
-4
@@ -15,7 +15,6 @@
|
|||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <exception>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <openvr.h>
|
#include <openvr.h>
|
||||||
@@ -49,6 +48,33 @@ void OverlayController::Init(QQmlEngine* qmlEngine) {
|
|||||||
m_runtimePathUrl = QUrl::fromLocalFile(vr::VR_RuntimePath());
|
m_runtimePathUrl = QUrl::fromLocalFile(vr::VR_RuntimePath());
|
||||||
LOG(INFO) << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile();
|
LOG(INFO) << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile();
|
||||||
|
|
||||||
|
QString activationSoundFile = m_runtimePathUrl.toLocalFile().append("/content/panorama/sounds/activation.wav");
|
||||||
|
QFileInfo activationSoundFileInfo(activationSoundFile);
|
||||||
|
if (activationSoundFileInfo.exists() && activationSoundFileInfo.isFile()) {
|
||||||
|
activationSoundEffect.setSource(QUrl::fromLocalFile(activationSoundFile));
|
||||||
|
activationSoundEffect.setVolume(1.0);
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Could not find activation sound file " << activationSoundFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString focusChangedSoundFile = m_runtimePathUrl.toLocalFile().append("/content/panorama/sounds/focus_change.wav");
|
||||||
|
QFileInfo focusChangedSoundFileInfo(focusChangedSoundFile);
|
||||||
|
if (focusChangedSoundFileInfo.exists() && focusChangedSoundFileInfo.isFile()) {
|
||||||
|
focusChangedSoundEffect.setSource(QUrl::fromLocalFile(focusChangedSoundFile));
|
||||||
|
focusChangedSoundEffect.setVolume(1.0);
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Could not find focus changed sound file " << focusChangedSoundFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString alarm01SoundFile = QApplication::applicationDirPath().append("/res/sounds/alarm01.wav");
|
||||||
|
QFileInfo alarm01SoundFileInfo(alarm01SoundFile);
|
||||||
|
if (alarm01SoundFileInfo.exists() && alarm01SoundFileInfo.isFile()) {
|
||||||
|
alarm01SoundEffect.setSource(QUrl::fromLocalFile(alarm01SoundFile));
|
||||||
|
alarm01SoundEffect.setVolume(1.0);
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Could not find alarm01 sound file " << alarm01SoundFile;
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether OpenVR is too outdated
|
// Check whether OpenVR is too outdated
|
||||||
if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) {
|
if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) {
|
||||||
QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR.");
|
QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR.");
|
||||||
@@ -294,13 +320,21 @@ void OverlayController::renderOverlay() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OverlayController::pollNextEvent(vr::VROverlayHandle_t ulOverlayHandle, vr::VREvent_t* pEvent) {
|
||||||
|
if (isDesktopMode()) {
|
||||||
|
return vr::VRSystem()->PollNextEvent(pEvent, sizeof(vr::VREvent_t));
|
||||||
|
} else {
|
||||||
|
return vr::VROverlay()->PollNextOverlayEvent(ulOverlayHandle, pEvent, sizeof(vr::VREvent_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OverlayController::OnTimeoutPumpEvents() {
|
void OverlayController::OnTimeoutPumpEvents() {
|
||||||
if (!vr::VRSystem())
|
if (!vr::VRSystem())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vr::VREvent_t vrEvent;
|
vr::VREvent_t vrEvent;
|
||||||
while (vr::VROverlay()->PollNextOverlayEvent(m_ulOverlayHandle, &vrEvent, sizeof(vrEvent))) {
|
bool chaperoneDataAlreadyUpdated = false;
|
||||||
|
while (pollNextEvent(m_ulOverlayHandle, &vrEvent)) {
|
||||||
switch (vrEvent.eventType) {
|
switch (vrEvent.eventType) {
|
||||||
case vr::VREvent_MouseMove: {
|
case vr::VREvent_MouseMove: {
|
||||||
QPoint ptNewMouse(vrEvent.data.mouse.x, vrEvent.data.mouse.y);
|
QPoint ptNewMouse(vrEvent.data.mouse.x, vrEvent.data.mouse.y);
|
||||||
@@ -349,6 +383,7 @@ void OverlayController::OnTimeoutPumpEvents() {
|
|||||||
LOG(INFO) << "Received quit request.";
|
LOG(INFO) << "Received quit request.";
|
||||||
vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some time just in case
|
vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some time just in case
|
||||||
moveCenterTabController.reset();
|
moveCenterTabController.reset();
|
||||||
|
chaperoneTabController.shutdown();
|
||||||
Shutdown();
|
Shutdown();
|
||||||
QApplication::exit();
|
QApplication::exit();
|
||||||
return;
|
return;
|
||||||
@@ -373,16 +408,54 @@ void OverlayController::OnTimeoutPumpEvents() {
|
|||||||
emit keyBoardInputSignal(QString(keyboardBuffer), vrEvent.data.keyboard.uUserValue);
|
emit keyBoardInputSignal(QString(keyboardBuffer), vrEvent.data.keyboard.uUserValue);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Multiple ChaperoneUniverseHasChanged are often emitted at the same time (some with a little bit of delay)
|
||||||
|
// There is no sure way to recognize redundant events, we can only exclude redundant events during the same call of OnTimeoutPumpEvents()
|
||||||
|
case vr::VREvent_ChaperoneUniverseHasChanged:
|
||||||
|
case vr::VREvent_ChaperoneDataHasChanged: {
|
||||||
|
if (!chaperoneDataAlreadyUpdated) {
|
||||||
|
LOG(INFO) << "Re-loading chaperone data ...";
|
||||||
|
m_chaperoneUtils.loadChaperoneData();
|
||||||
|
LOG(INFO) << "Found " << m_chaperoneUtils.quadsCount() << " chaperone quads.";
|
||||||
|
if (m_chaperoneUtils.isChaperoneWellFormed()) {
|
||||||
|
LOG(INFO) << "Chaperone data seems to be well-formed.";
|
||||||
|
} else {
|
||||||
|
LOG(INFO) << "Chaperone data is NOT well-formed.";
|
||||||
|
}
|
||||||
|
chaperoneDataAlreadyUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount];
|
||||||
vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0.0f, devicePoses, vr::k_unMaxTrackedDeviceCount);
|
vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0.0f, devicePoses, vr::k_unMaxTrackedDeviceCount);
|
||||||
|
|
||||||
|
// HMD/Controller Velocities
|
||||||
|
auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
||||||
|
float leftSpeed = 0.0f;
|
||||||
|
if (leftId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[leftId].bPoseIsValid && devicePoses[leftId].eTrackingResult == vr::TrackingResult_Running_OK) {
|
||||||
|
auto& vel = devicePoses[leftId].vVelocity.v;
|
||||||
|
leftSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);
|
||||||
|
}
|
||||||
|
auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
|
||||||
|
auto rightSpeed = 0.0f;
|
||||||
|
if (rightId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[rightId].bPoseIsValid && devicePoses[rightId].eTrackingResult == vr::TrackingResult_Running_OK) {
|
||||||
|
auto& vel = devicePoses[rightId].vVelocity.v;
|
||||||
|
rightSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);
|
||||||
|
}
|
||||||
|
auto hmdSpeed = 0.0f;
|
||||||
|
if (devicePoses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid && devicePoses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult == vr::TrackingResult_Running_OK) {
|
||||||
|
auto& vel = devicePoses[vr::k_unTrackedDeviceIndex_Hmd].vVelocity.v;
|
||||||
|
hmdSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]);
|
||||||
|
}
|
||||||
|
|
||||||
fixFloorTabController.eventLoopTick(devicePoses);
|
fixFloorTabController.eventLoopTick(devicePoses);
|
||||||
statisticsTabController.eventLoopTick(devicePoses);
|
statisticsTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed);
|
||||||
moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace());
|
moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace());
|
||||||
steamVRTabController.eventLoopTick();
|
steamVRTabController.eventLoopTick();
|
||||||
chaperoneTabController.eventLoopTick();
|
chaperoneTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed, hmdSpeed);
|
||||||
settingsTabController.eventLoopTick();
|
settingsTabController.eventLoopTick();
|
||||||
reviveTabController.eventLoopTick();
|
reviveTabController.eventLoopTick();
|
||||||
audioTabController.eventLoopTick();
|
audioTabController.eventLoopTick();
|
||||||
@@ -547,4 +620,37 @@ void OverlayController::showKeyboard(QString existingText, unsigned long userVal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OverlayController::playActivationSound() {
|
||||||
|
if (!noSound) {
|
||||||
|
activationSoundEffect.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OverlayController::playFocusChangedSound() {
|
||||||
|
if (!noSound) {
|
||||||
|
focusChangedSoundEffect.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayController::playAlarm01Sound(bool loop) {
|
||||||
|
if (!noSound && !alarm01SoundEffect.isPlaying()) {
|
||||||
|
if (loop) {
|
||||||
|
alarm01SoundEffect.setLoopCount(QSoundEffect::Infinite);
|
||||||
|
} else {
|
||||||
|
alarm01SoundEffect.setLoopCount(1);
|
||||||
|
}
|
||||||
|
alarm01SoundEffect.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayController::setAlarm01SoundVolume(float vol) {
|
||||||
|
alarm01SoundEffect.setVolume(vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayController::cancelAlarm01Sound() {
|
||||||
|
alarm01SoundEffect.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace advconfig
|
} // namespace advconfig
|
||||||
|
|||||||
+19
-1
@@ -19,8 +19,10 @@
|
|||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QQuickRenderControl>
|
#include <QQuickRenderControl>
|
||||||
|
#include <QSoundEffect>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
#include "utils/ChaperoneUtils.h"
|
||||||
|
|
||||||
#include "tabcontrollers/SteamVRTabController.h"
|
#include "tabcontrollers/SteamVRTabController.h"
|
||||||
#include "tabcontrollers/ChaperoneTabController.h"
|
#include "tabcontrollers/ChaperoneTabController.h"
|
||||||
@@ -45,7 +47,7 @@ class OverlayController : public QObject {
|
|||||||
public:
|
public:
|
||||||
static constexpr const char* applicationKey = "matzman666.AdvancedSettings";
|
static constexpr const char* applicationKey = "matzman666.AdvancedSettings";
|
||||||
static constexpr const char* applicationName = "Advanced Settings";
|
static constexpr const char* applicationName = "Advanced Settings";
|
||||||
static constexpr const char* applicationVersionString = "v2.4.1";
|
static constexpr const char* applicationVersionString = "v2.5";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid;
|
vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid;
|
||||||
@@ -69,6 +71,12 @@ private:
|
|||||||
|
|
||||||
QUrl m_runtimePathUrl;
|
QUrl m_runtimePathUrl;
|
||||||
|
|
||||||
|
utils::ChaperoneUtils m_chaperoneUtils;
|
||||||
|
|
||||||
|
QSoundEffect activationSoundEffect;
|
||||||
|
QSoundEffect focusChangedSoundEffect;
|
||||||
|
QSoundEffect alarm01SoundEffect;
|
||||||
|
|
||||||
public: // I know it's an ugly hack to make them public to enable external access, but I am too lazy to implement getters.
|
public: // I know it's an ugly hack to make them public to enable external access, but I am too lazy to implement getters.
|
||||||
SteamVRTabController steamVRTabController;
|
SteamVRTabController steamVRTabController;
|
||||||
ChaperoneTabController chaperoneTabController;
|
ChaperoneTabController chaperoneTabController;
|
||||||
@@ -103,6 +111,8 @@ public:
|
|||||||
|
|
||||||
bool isDesktopMode() { return desktopMode; };
|
bool isDesktopMode() { return desktopMode; };
|
||||||
|
|
||||||
|
utils::ChaperoneUtils& chaperoneUtils() noexcept { return m_chaperoneUtils; }
|
||||||
|
|
||||||
Q_INVOKABLE QString getVersionString();
|
Q_INVOKABLE QString getVersionString();
|
||||||
Q_INVOKABLE QUrl getVRRuntimePathUrl();
|
Q_INVOKABLE QUrl getVRRuntimePathUrl();
|
||||||
|
|
||||||
@@ -111,6 +121,8 @@ public:
|
|||||||
const vr::VROverlayHandle_t& overlayHandle();
|
const vr::VROverlayHandle_t& overlayHandle();
|
||||||
const vr::VROverlayHandle_t& overlayThumbnailHandle();
|
const vr::VROverlayHandle_t& overlayThumbnailHandle();
|
||||||
|
|
||||||
|
bool pollNextEvent(vr::VROverlayHandle_t ulOverlayHandle, vr::VREvent_t* pEvent);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void renderOverlay();
|
void renderOverlay();
|
||||||
void OnRenderRequest();
|
void OnRenderRequest();
|
||||||
@@ -118,6 +130,12 @@ public slots:
|
|||||||
|
|
||||||
void showKeyboard(QString existingText, unsigned long userValue = 0);
|
void showKeyboard(QString existingText, unsigned long userValue = 0);
|
||||||
|
|
||||||
|
void playActivationSound();
|
||||||
|
void playFocusChangedSound();
|
||||||
|
void playAlarm01Sound(bool loop = false);
|
||||||
|
void setAlarm01SoundVolume(float vol);
|
||||||
|
void cancelAlarm01Sound();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void keyBoardInputSignal(QString input, unsigned long userValue = 0);
|
void keyBoardInputSignal(QString input, unsigned long userValue = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,26 @@ namespace advsettings {
|
|||||||
|
|
||||||
void ChaperoneTabController::initStage1() {
|
void ChaperoneTabController::initStage1() {
|
||||||
m_height = getBoundsMaxY();
|
m_height = getBoundsMaxY();
|
||||||
|
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
m_enableChaperoneSwitchToBeginner = settings->value("chaperoneSwitchToBeginnerEnabled", false).toBool();
|
||||||
|
m_chaperoneSwitchToBeginnerDistance = settings->value("chaperoneSwitchToBeginnerDistance", 0.5f).toFloat();
|
||||||
|
m_enableChaperoneHapticFeedback = settings->value("chaperoneHapticFeedbackEnabled", false).toBool();
|
||||||
|
m_chaperoneHapticFeedbackDistance = settings->value("chaperoneHapticFeedbackDistance", 0.5f).toFloat();
|
||||||
|
m_enableChaperoneAlarmSound = settings->value("chaperoneAlarmSoundEnabled", false).toBool();
|
||||||
|
m_chaperoneAlarmSoundLooping = settings->value("chaperoneAlarmSoundLooping", true).toBool();
|
||||||
|
m_chaperoneAlarmSoundAdjustVolume = settings->value("chaperoneAlarmSoundAdjustVolume", false).toBool();
|
||||||
|
m_chaperoneAlarmSoundDistance = settings->value("chaperoneAlarmSoundDistance", 0.5f).toFloat();
|
||||||
|
m_enableChaperoneShowDashboard = settings->value("chaperoneShowDashboardEnabled", false).toBool();
|
||||||
|
m_chaperoneShowDashboardDistance = settings->value("chaperoneShowDashboardDistance", 0.5f).toFloat();
|
||||||
|
m_enableChaperoneVelocityModifier = settings->value("chaperoneVelocityModifierEnabled", false).toBool();
|
||||||
|
m_chaperoneVelocityModifier = settings->value("chaperoneVelocityModifier", 0.3f).toFloat();
|
||||||
|
m_chaperoneVelocityModifierCurrent = 1.0f;
|
||||||
|
settings->endGroup();
|
||||||
|
|
||||||
reloadChaperoneProfiles();
|
reloadChaperoneProfiles();
|
||||||
eventLoopTick();
|
eventLoopTick(nullptr, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -20,6 +38,14 @@ void ChaperoneTabController::initStage2(OverlayController * parent, QQuickWindow
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ChaperoneTabController::~ChaperoneTabController() {
|
||||||
|
m_chaperoneHapticFeedbackActive = false;
|
||||||
|
if (m_chaperoneHapticFeedbackThread.joinable()) {
|
||||||
|
m_chaperoneHapticFeedbackThread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ChaperoneTabController::reloadChaperoneProfiles() {
|
void ChaperoneTabController::reloadChaperoneProfiles() {
|
||||||
chaperoneProfiles.clear();
|
chaperoneProfiles.clear();
|
||||||
auto settings = OverlayController::appSettings();
|
auto settings = OverlayController::appSettings();
|
||||||
@@ -94,6 +120,21 @@ void ChaperoneTabController::reloadChaperoneProfiles() {
|
|||||||
if (entry.includesForceBounds) {
|
if (entry.includesForceBounds) {
|
||||||
entry.forceBounds = settings->value("forceBounds", false).toBool();
|
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();
|
||||||
|
entry.enableChaperoneVelocityModifier = settings->value("chaperoneVelocityModifierEnabled", false).toBool();
|
||||||
|
entry.chaperoneVelocityModifier = settings->value("chaperoneVelocityModifier", 0.3f).toFloat();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
@@ -171,15 +212,191 @@ void ChaperoneTabController::saveChaperoneProfiles() {
|
|||||||
if (p.includesForceBounds) {
|
if (p.includesForceBounds) {
|
||||||
settings->setValue("forceBounds", p.forceBounds);
|
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);
|
||||||
|
settings->setValue("chaperoneVelocityModifierEnabled", p.enableChaperoneVelocityModifier);
|
||||||
|
settings->setValue("chaperoneVelocityModifier", p.chaperoneVelocityModifier);
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
settings->endArray();
|
settings->endArray();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ChaperoneTabController::eventLoopTick() {
|
void ChaperoneTabController::handleChaperoneWarnings(float distance) {
|
||||||
|
vr::VRControllerState_t hmdState;
|
||||||
|
vr::VRSystem()->GetControllerState(vr::k_unTrackedDeviceIndex_Hmd, &hmdState, sizeof(vr::VRControllerState_t));
|
||||||
|
|
||||||
|
// Switch to Beginner Mode
|
||||||
|
if (m_enableChaperoneSwitchToBeginner) {
|
||||||
|
float activationDistance = m_chaperoneSwitchToBeginnerDistance * m_chaperoneVelocityModifierCurrent;
|
||||||
|
if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor)) && !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 || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && 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 (m_enableChaperoneHapticFeedback) {
|
||||||
|
float activationDistance = m_chaperoneHapticFeedbackDistance * m_chaperoneVelocityModifierCurrent;
|
||||||
|
if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) {
|
||||||
|
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) {
|
||||||
|
if (leftIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
||||||
|
vr::VRSystem()->TriggerHapticPulse(leftIndex, 0, 2000);
|
||||||
|
}
|
||||||
|
if (rightIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
||||||
|
vr::VRSystem()->TriggerHapticPulse(rightIndex, 0, 2000);
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
} else if ((distance > activationDistance || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && m_chaperoneHapticFeedbackActive) {
|
||||||
|
m_chaperoneHapticFeedbackActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alarm Sound
|
||||||
|
if (m_enableChaperoneAlarmSound) {
|
||||||
|
float activationDistance = m_chaperoneAlarmSoundDistance * m_chaperoneVelocityModifierCurrent;
|
||||||
|
if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) {
|
||||||
|
if (!m_chaperoneAlarmSoundActive) {
|
||||||
|
parent->playAlarm01Sound(m_chaperoneAlarmSoundLooping);
|
||||||
|
m_chaperoneAlarmSoundActive = true;
|
||||||
|
}
|
||||||
|
if (m_chaperoneAlarmSoundLooping && m_chaperoneAlarmSoundAdjustVolume) {
|
||||||
|
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 || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && m_chaperoneAlarmSoundActive) {
|
||||||
|
parent->cancelAlarm01Sound();
|
||||||
|
m_chaperoneAlarmSoundActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Dashboard
|
||||||
|
if (m_enableChaperoneShowDashboard) {
|
||||||
|
float activationDistance = m_chaperoneShowDashboardDistance * m_chaperoneVelocityModifierCurrent;
|
||||||
|
if (distance <= activationDistance && !m_chaperoneShowDashboardActive) {
|
||||||
|
if (!vr::VROverlay()->IsDashboardVisible()) {
|
||||||
|
vr::VROverlay()->ShowDashboard(OverlayController::applicationKey);
|
||||||
|
}
|
||||||
|
m_chaperoneShowDashboardActive = true;
|
||||||
|
} else if (distance > activationDistance && m_chaperoneShowDashboardActive) {
|
||||||
|
m_chaperoneShowDashboardActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ChaperoneTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed, float hmdSpeed) {
|
||||||
|
m_chaperoneVelocityModifierCurrent = 1.0f;
|
||||||
|
if (m_enableChaperoneVelocityModifier) {
|
||||||
|
float mod = m_chaperoneVelocityModifier * std::max({ leftSpeed, rightSpeed, hmdSpeed });
|
||||||
|
if (mod > 0.02) {
|
||||||
|
m_chaperoneVelocityModifierCurrent += mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//LOG(INFO) << "m_chaperoneVelocityModifierCurrent: " << m_chaperoneVelocityModifierCurrent;
|
||||||
|
float newFadeDistance = m_fadeDistance * m_chaperoneVelocityModifierCurrent;
|
||||||
|
if (m_fadeDistanceModified != newFadeDistance) {
|
||||||
|
m_fadeDistanceModified = newFadeDistance;
|
||||||
|
vr::VRSettings()->SetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, m_fadeDistanceModified);
|
||||||
|
vr::VRSettings()->Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devicePoses) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(parent->chaperoneUtils().mutex());
|
||||||
|
auto minDistance = NAN;
|
||||||
|
auto& poseHmd = devicePoses[vr::k_unTrackedDeviceIndex_Hmd];
|
||||||
|
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 (!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 (!isnan(distanceLeft) && (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 (!isnan(distanceRight) && (isnan(minDistance) || distanceRight < minDistance)) {
|
||||||
|
minDistance = distanceRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isnan(minDistance)) {
|
||||||
|
handleChaperoneWarnings(minDistance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (settingsUpdateCounter >= 50) {
|
if (settingsUpdateCounter >= 50) {
|
||||||
vr::EVRSettingsError vrSettingsError;
|
vr::EVRSettingsError vrSettingsError;
|
||||||
float vis = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaA_Int32, &vrSettingsError);
|
float vis = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaA_Int32, &vrSettingsError);
|
||||||
@@ -187,11 +404,13 @@ void ChaperoneTabController::eventLoopTick() {
|
|||||||
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaA_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaA_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
||||||
}
|
}
|
||||||
setBoundsVisibility(vis/255.0f);
|
setBoundsVisibility(vis/255.0f);
|
||||||
auto fd = vr::VRSettings()->GetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, &vrSettingsError);
|
if (m_chaperoneVelocityModifierCurrent == 1.0f) {
|
||||||
if (vrSettingsError != vr::VRSettingsError_None) {
|
auto fd = vr::VRSettings()->GetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, &vrSettingsError);
|
||||||
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_FadeDistance_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
if (vrSettingsError != vr::VRSettingsError_None) {
|
||||||
|
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_FadeDistance_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
||||||
|
}
|
||||||
|
setFadeDistance(fd);
|
||||||
}
|
}
|
||||||
setFadeDistance(fd);
|
|
||||||
auto cm = vr::VRSettings()->GetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, &vrSettingsError);
|
auto cm = vr::VRSettings()->GetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, &vrSettingsError);
|
||||||
if (vrSettingsError != vr::VRSettingsError_None) {
|
if (vrSettingsError != vr::VRSettingsError_None) {
|
||||||
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
|
||||||
@@ -319,6 +538,62 @@ bool ChaperoneTabController::forceBounds() const {
|
|||||||
return m_forceBounds;
|
return m_forceBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneSwitchToBeginnerEnabled() const {
|
||||||
|
return m_enableChaperoneSwitchToBeginner;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ChaperoneTabController::chaperoneSwitchToBeginnerDistance() const {
|
||||||
|
return m_chaperoneSwitchToBeginnerDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneHapticFeedbackEnabled() const {
|
||||||
|
return m_enableChaperoneHapticFeedback;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ChaperoneTabController::chaperoneHapticFeedbackDistance() const {
|
||||||
|
return m_chaperoneHapticFeedbackDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneAlarmSoundEnabled() const {
|
||||||
|
return m_enableChaperoneAlarmSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneAlarmSoundLooping() const {
|
||||||
|
return m_chaperoneAlarmSoundLooping;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneAlarmSoundAdjustVolume() const {
|
||||||
|
return m_chaperoneAlarmSoundAdjustVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ChaperoneTabController::chaperoneAlarmSoundDistance() const {
|
||||||
|
return m_chaperoneAlarmSoundDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneShowDashboardEnabled() const {
|
||||||
|
return m_enableChaperoneShowDashboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ChaperoneTabController::chaperoneShowDashboardDistance() const {
|
||||||
|
return m_chaperoneShowDashboardDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ChaperoneTabController::isChaperoneVelocityModifierEnabled() const {
|
||||||
|
return m_enableChaperoneVelocityModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ChaperoneTabController::chaperoneVelocityModifier() const {
|
||||||
|
return m_chaperoneVelocityModifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Q_INVOKABLE unsigned ChaperoneTabController::getChaperoneProfileCount() {
|
Q_INVOKABLE unsigned ChaperoneTabController::getChaperoneProfileCount() {
|
||||||
return (unsigned)chaperoneProfiles.size();
|
return (unsigned)chaperoneProfiles.size();
|
||||||
}
|
}
|
||||||
@@ -341,6 +616,207 @@ void ChaperoneTabController::setForceBounds(bool value, bool notify) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneSwitchToBeginnerEnabled(bool value, bool notify) {
|
||||||
|
if (m_enableChaperoneSwitchToBeginner != 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_enableChaperoneSwitchToBeginner = value;
|
||||||
|
m_chaperoneSwitchToBeginnerActive = false;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneSwitchToBeginnerEnabled", m_enableChaperoneSwitchToBeginner);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneSwitchToBeginnerEnabledChanged(m_enableChaperoneSwitchToBeginner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneSwitchToBeginnerDistance(float value, bool notify) {
|
||||||
|
if (m_chaperoneSwitchToBeginnerDistance != value) {
|
||||||
|
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 (m_enableChaperoneHapticFeedback != value) {
|
||||||
|
m_chaperoneHapticFeedbackActive = false;
|
||||||
|
if (m_chaperoneHapticFeedbackThread.joinable()) {
|
||||||
|
m_chaperoneHapticFeedbackThread.join();
|
||||||
|
}
|
||||||
|
m_enableChaperoneHapticFeedback = value;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneHapticFeedbackEnabled", m_enableChaperoneHapticFeedback);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneHapticFeedbackEnabledChanged(m_enableChaperoneHapticFeedback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneHapticFeedbackDistance(float value, bool notify) {
|
||||||
|
if (m_chaperoneHapticFeedbackDistance != value) {
|
||||||
|
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 (m_enableChaperoneAlarmSound != value) {
|
||||||
|
if (!value && m_chaperoneAlarmSoundActive) {
|
||||||
|
parent->cancelAlarm01Sound();
|
||||||
|
}
|
||||||
|
m_enableChaperoneAlarmSound = value;
|
||||||
|
m_chaperoneAlarmSoundActive = false;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneAlarmSoundEnabled", m_enableChaperoneAlarmSound);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneAlarmSoundEnabledChanged(m_enableChaperoneAlarmSound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneAlarmSoundLooping(bool value, bool notify) {
|
||||||
|
if (m_chaperoneAlarmSoundLooping != value) {
|
||||||
|
m_chaperoneAlarmSoundLooping = value;
|
||||||
|
if (m_enableChaperoneAlarmSound && m_chaperoneAlarmSoundActive) {
|
||||||
|
if (m_chaperoneAlarmSoundLooping) {
|
||||||
|
parent->playAlarm01Sound(m_chaperoneAlarmSoundLooping);
|
||||||
|
} else {
|
||||||
|
parent->cancelAlarm01Sound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneAlarmSoundLooping", m_chaperoneAlarmSoundLooping);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneAlarmSoundLoopingChanged(m_chaperoneAlarmSoundLooping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneAlarmSoundAdjustVolume(bool value, bool notify) {
|
||||||
|
if (m_chaperoneAlarmSoundAdjustVolume != value) {
|
||||||
|
m_chaperoneAlarmSoundAdjustVolume = value;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneAlarmSoundAdjustVolume", m_chaperoneAlarmSoundAdjustVolume);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneAlarmSoundAdjustVolumeChanged(m_chaperoneAlarmSoundAdjustVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneAlarmSoundDistance(float value, bool notify) {
|
||||||
|
if (m_chaperoneAlarmSoundDistance != value) {
|
||||||
|
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 (m_enableChaperoneShowDashboard != value) {
|
||||||
|
m_enableChaperoneShowDashboard = value;
|
||||||
|
m_chaperoneShowDashboardActive = false;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneShowDashboardEnabled", m_enableChaperoneShowDashboard);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneShowDashboardEnabledChanged(m_enableChaperoneShowDashboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneShowDashboardDistance(float value, bool notify) {
|
||||||
|
if (m_chaperoneShowDashboardDistance != value) {
|
||||||
|
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::setChaperoneVelocityModifierEnabled(bool value, bool notify) {
|
||||||
|
if (m_enableChaperoneVelocityModifier != value) {
|
||||||
|
m_enableChaperoneVelocityModifier = value;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneVelocityModifierEnabled", m_enableChaperoneVelocityModifier);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneVelocityModifierEnabledChanged(m_enableChaperoneVelocityModifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaperoneTabController::setChaperoneVelocityModifier(float value, bool notify) {
|
||||||
|
if (m_chaperoneVelocityModifier != value) {
|
||||||
|
m_chaperoneVelocityModifier = value;
|
||||||
|
auto settings = OverlayController::appSettings();
|
||||||
|
settings->beginGroup("chaperoneSettings");
|
||||||
|
settings->setValue("chaperoneVelocityModifier", m_chaperoneVelocityModifier);
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
if (notify) {
|
||||||
|
emit chaperoneVelocityModifierChanged(m_chaperoneVelocityModifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ChaperoneTabController::flipOrientation() {
|
void ChaperoneTabController::flipOrientation() {
|
||||||
parent->RotateUniverseCenter(vr::TrackingUniverseStanding, (float)M_PI);
|
parent->RotateUniverseCenter(vr::TrackingUniverseStanding, (float)M_PI);
|
||||||
}
|
}
|
||||||
@@ -351,7 +827,7 @@ void ChaperoneTabController::reloadFromDisk() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ChaperoneTabController::addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker,
|
void ChaperoneTabController::addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker,
|
||||||
bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds) {
|
bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds, bool includesProximityWarningSettings) {
|
||||||
vr::EVRSettingsError vrSettingsError;
|
vr::EVRSettingsError vrSettingsError;
|
||||||
ChaperoneProfile* profile = nullptr;
|
ChaperoneProfile* profile = nullptr;
|
||||||
for (auto& p : chaperoneProfiles) {
|
for (auto& p : chaperoneProfiles) {
|
||||||
@@ -426,6 +902,21 @@ void ChaperoneTabController::addChaperoneProfile(QString name, bool includeGeome
|
|||||||
if (includeForceBounds) {
|
if (includeForceBounds) {
|
||||||
profile->forceBounds = m_forceBounds;
|
profile->forceBounds = m_forceBounds;
|
||||||
}
|
}
|
||||||
|
profile->includesProximityWarningSettings = includesProximityWarningSettings;
|
||||||
|
if (includesProximityWarningSettings) {
|
||||||
|
profile->enableChaperoneSwitchToBeginner = m_enableChaperoneSwitchToBeginner;
|
||||||
|
profile->chaperoneSwitchToBeginnerDistance = m_chaperoneSwitchToBeginnerDistance;
|
||||||
|
profile->enableChaperoneHapticFeedback = m_enableChaperoneHapticFeedback;
|
||||||
|
profile->chaperoneHapticFeedbackDistance = m_chaperoneHapticFeedbackDistance;
|
||||||
|
profile->enableChaperoneAlarmSound = m_enableChaperoneAlarmSound;
|
||||||
|
profile->chaperoneAlarmSoundLooping = m_chaperoneAlarmSoundLooping;
|
||||||
|
profile->chaperoneAlarmSoundAdjustVolume = m_chaperoneAlarmSoundAdjustVolume;
|
||||||
|
profile->chaperoneAlarmSoundDistance = m_chaperoneAlarmSoundDistance;
|
||||||
|
profile->enableChaperoneShowDashboard = m_enableChaperoneShowDashboard;
|
||||||
|
profile->chaperoneShowDashboardDistance = m_chaperoneShowDashboardDistance;
|
||||||
|
profile->enableChaperoneVelocityModifier = m_enableChaperoneVelocityModifier;
|
||||||
|
profile->chaperoneVelocityModifier = m_chaperoneVelocityModifier;
|
||||||
|
}
|
||||||
saveChaperoneProfiles();
|
saveChaperoneProfiles();
|
||||||
OverlayController::appSettings()->sync();
|
OverlayController::appSettings()->sync();
|
||||||
emit chaperoneProfilesUpdated();
|
emit chaperoneProfilesUpdated();
|
||||||
@@ -467,7 +958,21 @@ void ChaperoneTabController::applyChaperoneProfile(unsigned index) {
|
|||||||
if (profile.includesForceBounds) {
|
if (profile.includesForceBounds) {
|
||||||
setForceBounds(profile.forceBounds);
|
setForceBounds(profile.forceBounds);
|
||||||
}
|
}
|
||||||
vr::VRSettings()->Sync();
|
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);
|
||||||
|
setChaperoneVelocityModifier(profile.chaperoneVelocityModifier);
|
||||||
|
setChaperoneVelocityModifierEnabled(profile.enableChaperoneVelocityModifier);
|
||||||
|
}
|
||||||
|
vr::VRSettings()->Sync(true);
|
||||||
updateHeight(getBoundsMaxY());
|
updateHeight(getBoundsMaxY());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,4 +1039,18 @@ void ChaperoneTabController::reset() {
|
|||||||
settingsUpdateCounter = 999; // Easiest way to get default values
|
settingsUpdateCounter = 999; // Easiest way to get default values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ChaperoneTabController::shutdown() {
|
||||||
|
if (m_enableChaperoneSwitchToBeginner && 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 advconfig
|
} // namespace advconfig
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
#include <openvr.h>
|
#include <openvr.h>
|
||||||
|
|
||||||
class QQuickWindow;
|
class QQuickWindow;
|
||||||
@@ -46,6 +48,20 @@ struct ChaperoneProfile {
|
|||||||
|
|
||||||
bool includesForceBounds = false;
|
bool includesForceBounds = false;
|
||||||
bool forceBounds = false;
|
bool forceBounds = false;
|
||||||
|
|
||||||
|
bool includesProximityWarningSettings = false;
|
||||||
|
bool enableChaperoneSwitchToBeginner = false;
|
||||||
|
float chaperoneSwitchToBeginnerDistance = 0.0f;
|
||||||
|
bool enableChaperoneHapticFeedback = false;
|
||||||
|
float chaperoneHapticFeedbackDistance = 0.0f;
|
||||||
|
bool enableChaperoneAlarmSound = false;
|
||||||
|
bool chaperoneAlarmSoundLooping = true;
|
||||||
|
bool chaperoneAlarmSoundAdjustVolume = false;
|
||||||
|
float chaperoneAlarmSoundDistance = 0.0f;
|
||||||
|
bool enableChaperoneShowDashboard = false;
|
||||||
|
float chaperoneShowDashboardDistance = 0.0f;
|
||||||
|
bool enableChaperoneVelocityModifier = false;
|
||||||
|
float chaperoneVelocityModifier = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -58,26 +74,71 @@ class ChaperoneTabController : public QObject {
|
|||||||
Q_PROPERTY(bool playSpaceMarker READ playSpaceMarker WRITE setPlaySpaceMarker NOTIFY playSpaceMarkerChanged)
|
Q_PROPERTY(bool playSpaceMarker READ playSpaceMarker WRITE setPlaySpaceMarker NOTIFY playSpaceMarkerChanged)
|
||||||
Q_PROPERTY(bool forceBounds READ forceBounds WRITE setForceBounds NOTIFY forceBoundsChanged)
|
Q_PROPERTY(bool forceBounds READ forceBounds WRITE setForceBounds NOTIFY forceBoundsChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool chaperoneSwitchToBeginnerEnabled READ isChaperoneSwitchToBeginnerEnabled WRITE setChaperoneSwitchToBeginnerEnabled NOTIFY chaperoneSwitchToBeginnerEnabledChanged)
|
||||||
|
Q_PROPERTY(float chaperoneSwitchToBeginnerDistance READ chaperoneSwitchToBeginnerDistance WRITE setChaperoneSwitchToBeginnerDistance NOTIFY chaperoneSwitchToBeginnerDistanceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool chaperoneHapticFeedbackEnabled READ isChaperoneHapticFeedbackEnabled WRITE setChaperoneHapticFeedbackEnabled NOTIFY chaperoneHapticFeedbackEnabledChanged)
|
||||||
|
Q_PROPERTY(float chaperoneHapticFeedbackDistance READ chaperoneHapticFeedbackDistance WRITE setChaperoneHapticFeedbackDistance NOTIFY chaperoneHapticFeedbackDistanceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool chaperoneAlarmSoundEnabled READ isChaperoneAlarmSoundEnabled WRITE setChaperoneAlarmSoundEnabled NOTIFY chaperoneAlarmSoundEnabledChanged)
|
||||||
|
Q_PROPERTY(bool chaperoneAlarmSoundLooping READ isChaperoneAlarmSoundLooping WRITE setChaperoneAlarmSoundLooping NOTIFY chaperoneAlarmSoundLoopingChanged)
|
||||||
|
Q_PROPERTY(bool chaperoneAlarmSoundAdjustVolume READ isChaperoneAlarmSoundAdjustVolume WRITE setChaperoneAlarmSoundAdjustVolume NOTIFY chaperoneAlarmSoundAdjustVolumeChanged)
|
||||||
|
Q_PROPERTY(float chaperoneAlarmSoundDistance READ chaperoneAlarmSoundDistance WRITE setChaperoneAlarmSoundDistance NOTIFY chaperoneAlarmSoundDistanceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool chaperoneShowDashboardEnabled READ isChaperoneShowDashboardEnabled WRITE setChaperoneShowDashboardEnabled NOTIFY chaperoneShowDashboardEnabledChanged)
|
||||||
|
Q_PROPERTY(float chaperoneShowDashboardDistance READ chaperoneShowDashboardDistance WRITE setChaperoneShowDashboardDistance NOTIFY chaperoneShowDashboardDistanceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool chaperoneVelocityModifierEnabled READ isChaperoneVelocityModifierEnabled WRITE setChaperoneVelocityModifierEnabled NOTIFY chaperoneVelocityModifierEnabledChanged)
|
||||||
|
Q_PROPERTY(float chaperoneVelocityModifier READ chaperoneVelocityModifier WRITE setChaperoneVelocityModifier NOTIFY chaperoneVelocityModifierChanged)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OverlayController* parent;
|
OverlayController* parent;
|
||||||
QQuickWindow* widget;
|
QQuickWindow* widget;
|
||||||
|
|
||||||
float m_visibility = 0.6f;
|
float m_visibility = 0.6f;
|
||||||
float m_fadeDistance = 0.7f;
|
float m_fadeDistance = 0.7f;
|
||||||
|
float m_fadeDistanceModified = 0.7f;
|
||||||
float m_height = 2.0f;
|
float m_height = 2.0f;
|
||||||
bool m_centerMarker = false;
|
bool m_centerMarker = false;
|
||||||
bool m_playSpaceMarker = false;
|
bool m_playSpaceMarker = false;
|
||||||
bool m_forceBounds = false;
|
bool m_forceBounds = false;
|
||||||
|
|
||||||
|
bool m_enableChaperoneSwitchToBeginner = false;
|
||||||
|
float m_chaperoneSwitchToBeginnerDistance = 0.5f;
|
||||||
|
bool m_chaperoneSwitchToBeginnerActive = false;
|
||||||
|
int32_t m_chaperoneSwitchToBeginnerLastStyle = 0;
|
||||||
|
|
||||||
|
bool m_enableChaperoneHapticFeedback = true;
|
||||||
|
float m_chaperoneHapticFeedbackDistance = 0.5f;
|
||||||
|
bool m_chaperoneHapticFeedbackActive = false;
|
||||||
|
std::thread m_chaperoneHapticFeedbackThread;
|
||||||
|
|
||||||
|
bool m_enableChaperoneAlarmSound = false;
|
||||||
|
bool m_chaperoneAlarmSoundLooping = true;
|
||||||
|
bool m_chaperoneAlarmSoundAdjustVolume = false;
|
||||||
|
float m_chaperoneAlarmSoundDistance = 0.5f;
|
||||||
|
bool m_chaperoneAlarmSoundActive = false;
|
||||||
|
|
||||||
|
bool m_enableChaperoneShowDashboard = false;
|
||||||
|
float m_chaperoneShowDashboardDistance = 0.5f;
|
||||||
|
bool m_chaperoneShowDashboardActive = false;
|
||||||
|
|
||||||
|
bool m_enableChaperoneVelocityModifier = false;
|
||||||
|
float m_chaperoneVelocityModifier = 0.0f;
|
||||||
|
float m_chaperoneVelocityModifierCurrent = 1.0f;
|
||||||
|
|
||||||
unsigned settingsUpdateCounter = 0;
|
unsigned settingsUpdateCounter = 0;
|
||||||
|
|
||||||
std::vector<ChaperoneProfile> chaperoneProfiles;
|
std::vector<ChaperoneProfile> chaperoneProfiles;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
~ChaperoneTabController();
|
||||||
|
|
||||||
void initStage1();
|
void initStage1();
|
||||||
void initStage2(OverlayController* parent, QQuickWindow* widget);
|
void initStage2(OverlayController* parent, QQuickWindow* widget);
|
||||||
|
|
||||||
void eventLoopTick();
|
void eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed, float hmdSpeed);
|
||||||
|
void handleChaperoneWarnings(float distance);
|
||||||
|
|
||||||
float boundsVisibility() const;
|
float boundsVisibility() const;
|
||||||
float fadeDistance() const;
|
float fadeDistance() const;
|
||||||
@@ -86,6 +147,23 @@ public:
|
|||||||
bool playSpaceMarker() const;
|
bool playSpaceMarker() const;
|
||||||
bool forceBounds() const;
|
bool forceBounds() const;
|
||||||
|
|
||||||
|
bool isChaperoneSwitchToBeginnerEnabled() const;
|
||||||
|
float chaperoneSwitchToBeginnerDistance() const;
|
||||||
|
|
||||||
|
bool isChaperoneHapticFeedbackEnabled() const;
|
||||||
|
float chaperoneHapticFeedbackDistance() const;
|
||||||
|
|
||||||
|
bool isChaperoneAlarmSoundEnabled() const;
|
||||||
|
bool isChaperoneAlarmSoundLooping() const;
|
||||||
|
bool isChaperoneAlarmSoundAdjustVolume() const;
|
||||||
|
float chaperoneAlarmSoundDistance() const;
|
||||||
|
|
||||||
|
bool isChaperoneShowDashboardEnabled() const;
|
||||||
|
float chaperoneShowDashboardDistance() const;
|
||||||
|
|
||||||
|
bool isChaperoneVelocityModifierEnabled() const;
|
||||||
|
float chaperoneVelocityModifier() const;
|
||||||
|
|
||||||
void reloadChaperoneProfiles();
|
void reloadChaperoneProfiles();
|
||||||
void saveChaperoneProfiles();
|
void saveChaperoneProfiles();
|
||||||
|
|
||||||
@@ -103,16 +181,36 @@ public slots:
|
|||||||
void setPlaySpaceMarker(bool value, bool notify = true);
|
void setPlaySpaceMarker(bool value, bool notify = true);
|
||||||
void setForceBounds(bool value, bool notify = true);
|
void setForceBounds(bool value, bool notify = true);
|
||||||
|
|
||||||
|
void setChaperoneSwitchToBeginnerEnabled(bool value, bool notify = true);
|
||||||
|
void setChaperoneSwitchToBeginnerDistance(float value, bool notify = true);
|
||||||
|
|
||||||
|
void setChaperoneHapticFeedbackEnabled(bool value, bool notify = true);
|
||||||
|
void setChaperoneHapticFeedbackDistance(float value, bool notify = true);
|
||||||
|
|
||||||
|
void setChaperoneAlarmSoundEnabled(bool value, bool notify = true);
|
||||||
|
void setChaperoneAlarmSoundLooping(bool value, bool notify = true);
|
||||||
|
void setChaperoneAlarmSoundAdjustVolume(bool value, bool notify = true);
|
||||||
|
void setChaperoneAlarmSoundDistance(float value, bool notify = true);
|
||||||
|
|
||||||
|
void setChaperoneShowDashboardEnabled(bool value, bool notify = true);
|
||||||
|
void setChaperoneShowDashboardDistance(float value, bool notify = true);
|
||||||
|
|
||||||
|
void setChaperoneVelocityModifierEnabled(bool value, bool notify = true);
|
||||||
|
void setChaperoneVelocityModifier(float value, bool notify = true);
|
||||||
|
|
||||||
void flipOrientation();
|
void flipOrientation();
|
||||||
void reloadFromDisk();
|
void reloadFromDisk();
|
||||||
|
|
||||||
void addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker,
|
void addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker,
|
||||||
bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds);
|
bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds,
|
||||||
|
bool includesProximityWarningSettings);
|
||||||
void applyChaperoneProfile(unsigned index);
|
void applyChaperoneProfile(unsigned index);
|
||||||
void deleteChaperoneProfile(unsigned index);
|
void deleteChaperoneProfile(unsigned index);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void boundsVisibilityChanged(float value);
|
void boundsVisibilityChanged(float value);
|
||||||
void fadeDistanceChanged(float value);
|
void fadeDistanceChanged(float value);
|
||||||
@@ -121,6 +219,23 @@ signals:
|
|||||||
void playSpaceMarkerChanged(bool value);
|
void playSpaceMarkerChanged(bool value);
|
||||||
void forceBoundsChanged(bool value);
|
void forceBoundsChanged(bool value);
|
||||||
|
|
||||||
|
void chaperoneSwitchToBeginnerEnabledChanged(bool value);
|
||||||
|
void chaperoneSwitchToBeginnerDistanceChanged(float value);
|
||||||
|
|
||||||
|
void chaperoneHapticFeedbackEnabledChanged(bool value);
|
||||||
|
void chaperoneHapticFeedbackDistanceChanged(float value);
|
||||||
|
|
||||||
|
void chaperoneAlarmSoundEnabledChanged(bool value);
|
||||||
|
void chaperoneAlarmSoundLoopingChanged(bool value);
|
||||||
|
void chaperoneAlarmSoundAdjustVolumeChanged(bool value);
|
||||||
|
void chaperoneAlarmSoundDistanceChanged(float value);
|
||||||
|
|
||||||
|
void chaperoneShowDashboardEnabledChanged(bool value);
|
||||||
|
void chaperoneShowDashboardDistanceChanged(float value);
|
||||||
|
|
||||||
|
void chaperoneVelocityModifierEnabledChanged(bool value);
|
||||||
|
void chaperoneVelocityModifierChanged(float value);
|
||||||
|
|
||||||
void chaperoneProfilesUpdated();
|
void chaperoneProfilesUpdated();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ void StatisticsTabController::initStage2(OverlayController * parent, QQuickWindo
|
|||||||
this->widget = widget;
|
this->widget = widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatisticsTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses) {
|
void StatisticsTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed) {
|
||||||
vr::Compositor_CumulativeStats pStats;
|
vr::Compositor_CumulativeStats pStats;
|
||||||
vr::VRCompositor()->GetCumulativeStats(&pStats, sizeof(vr::Compositor_CumulativeStats));
|
vr::VRCompositor()->GetCumulativeStats(&pStats, sizeof(vr::Compositor_CumulativeStats));
|
||||||
if (pStats.m_nPid != m_cumStats.m_nPid) {
|
if (pStats.m_nPid != m_cumStats.m_nPid) {
|
||||||
@@ -48,26 +48,14 @@ void StatisticsTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Controller speeds //
|
// Controller speeds //
|
||||||
auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
if (leftSpeed > m_leftControllerMaxSpeed) {
|
||||||
if (leftId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[leftId].bPoseIsValid && devicePoses[leftId].eTrackingResult == vr::TrackingResult_Running_OK) {
|
m_leftControllerMaxSpeed = leftSpeed;
|
||||||
auto& vel = devicePoses[leftId].vVelocity.v;
|
|
||||||
auto lspeed = std::sqrt(std::pow(vel[0], 2) + std::pow(vel[1], 2) + std::pow(vel[2], 2));
|
|
||||||
if (lspeed > m_leftControllerMaxSpeed) {
|
|
||||||
m_leftControllerMaxSpeed = lspeed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (rightSpeed > m_rightControllerMaxSpeed) {
|
||||||
auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
|
m_rightControllerMaxSpeed = rightSpeed;
|
||||||
if (rightId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[rightId].bPoseIsValid && devicePoses[rightId].eTrackingResult == vr::TrackingResult_Running_OK) {
|
|
||||||
auto& vel = devicePoses[rightId].vVelocity.v;
|
|
||||||
auto rspeed = std::sqrt(std::pow(vel[0], 2) + std::pow(vel[1], 2) + std::pow(vel[2], 2));
|
|
||||||
if (rspeed > m_rightControllerMaxSpeed) {
|
|
||||||
m_rightControllerMaxSpeed = rspeed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hmd Rotation //
|
// Hmd Rotation //
|
||||||
|
|
||||||
/*
|
/*
|
||||||
| Intrinsic y-x'-z" rotation matrix:
|
| Intrinsic y-x'-z" rotation matrix:
|
||||||
| cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy |
|
| cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy |
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
void initStage1();
|
void initStage1();
|
||||||
void initStage2(OverlayController* parent, QQuickWindow* widget);
|
void initStage2(OverlayController* parent, QQuickWindow* widget);
|
||||||
|
|
||||||
void eventLoopTick(vr::TrackedDevicePose_t* devicePoses);
|
void eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed);
|
||||||
|
|
||||||
float hmdDistanceMoved() const;
|
float hmdDistanceMoved() const;
|
||||||
float hmdRotations() const;
|
float hmdRotations() const;
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
#include "ChaperoneUtils.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
|
||||||
|
float ChaperoneUtils::_getDistanceToChaperone(const vr::HmdVector3_t & x, vr::HmdVector3_t * projectedPoint) {
|
||||||
|
float distance = NAN;
|
||||||
|
vr::HmdVector3_t* _cornersPtr = _corners.get();
|
||||||
|
for (uint32_t i = 0; i < _quadsCount; i++) {
|
||||||
|
uint32_t i2 = (i + 1) % _quadsCount;
|
||||||
|
vr::HmdVector3_t& r0 = _cornersPtr[i];
|
||||||
|
vr::HmdVector3_t& r1 = _cornersPtr[i2];
|
||||||
|
float u_x = r1.v[0] - r0.v[0];
|
||||||
|
float u_z = r1.v[2] - r0.v[2];
|
||||||
|
float r = ((x.v[0] - r0.v[0]) * u_x + (x.v[2] - r0.v[2]) * u_z) / (u_x*u_x + u_z*u_z);
|
||||||
|
//int mode = 0; // 0 .. projected point on segment, 1 .. projected point outside of segment (r0 closer than r1), 2 .. projected point outside of segment (r1 closer than r0)
|
||||||
|
float d;
|
||||||
|
float x1_x;
|
||||||
|
float x1_z;
|
||||||
|
if (r < 0.0f || r > 1.0f) { // projected point outside of segment
|
||||||
|
float d_x = r0.v[0] - x.v[0];
|
||||||
|
float d_z = r0.v[2] - x.v[2];
|
||||||
|
float d1 = sqrt(d_x*d_x + d_z*d_z);
|
||||||
|
d_x = r1.v[0] - x.v[0];
|
||||||
|
d_z = r1.v[2] - x.v[2];
|
||||||
|
float d2 = sqrt(d_x*d_x + d_z*d_z);
|
||||||
|
if (d1 < d2) {
|
||||||
|
d = d1;
|
||||||
|
x1_x = r0.v[0];
|
||||||
|
x1_z = r0.v[2];
|
||||||
|
} else {
|
||||||
|
d = d2;
|
||||||
|
x1_x = r1.v[0];
|
||||||
|
x1_z = r1.v[2];
|
||||||
|
}
|
||||||
|
} else { // projected point on segment
|
||||||
|
x1_x = r0.v[0] + r * u_x;
|
||||||
|
x1_z = r0.v[2] + r * u_z;
|
||||||
|
float d_x = x1_x - x.v[0];
|
||||||
|
float d_z = x1_z - x.v[2];
|
||||||
|
d = sqrt(d_x*d_x + d_z*d_z);
|
||||||
|
}
|
||||||
|
if (isnan(distance) || d < distance) {
|
||||||
|
distance = d;
|
||||||
|
if (projectedPoint) {
|
||||||
|
projectedPoint->v[0] = x1_x;
|
||||||
|
projectedPoint->v[1] = x.v[1];
|
||||||
|
projectedPoint->v[2] = x1_z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ChaperoneUtils::loadChaperoneData() {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||||
|
vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(nullptr, &_quadsCount);
|
||||||
|
if (_quadsCount > 0) {
|
||||||
|
std::unique_ptr<vr::HmdQuad_t> quadsBuffer(new vr::HmdQuad_t[_quadsCount]);
|
||||||
|
vr::HmdQuad_t* quadsBufferPtr = quadsBuffer.get();
|
||||||
|
_corners.reset((vr::HmdVector3_t*)new vr::HmdQuad_t[_quadsCount]);
|
||||||
|
vr::HmdVector3_t* _cornersPtr = _corners.get();
|
||||||
|
vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(quadsBufferPtr, &_quadsCount);
|
||||||
|
for (uint32_t i = 0; i < _quadsCount; i++) {
|
||||||
|
_cornersPtr[i] = quadsBufferPtr[i].vCorners[0];
|
||||||
|
uint32_t i2 = (i + 1) % _quadsCount;
|
||||||
|
if (quadsBufferPtr[i].vCorners[3].v[0] != quadsBufferPtr[i2].vCorners[0].v[0]
|
||||||
|
|| quadsBufferPtr[i].vCorners[3].v[1] != quadsBufferPtr[i2].vCorners[0].v[1]
|
||||||
|
|| quadsBufferPtr[i].vCorners[3].v[2] != quadsBufferPtr[i2].vCorners[0].v[2]
|
||||||
|
|| quadsBufferPtr[i].vCorners[0].v[1] != 0.0f) {
|
||||||
|
_chaperoneWellFormed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace utils
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <openvr.h>
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
class ChaperoneUtils {
|
||||||
|
private:
|
||||||
|
std::recursive_mutex _mutex;
|
||||||
|
uint32_t _quadsCount = 0;
|
||||||
|
std::unique_ptr<vr::HmdVector3_t> _corners;
|
||||||
|
bool _chaperoneWellFormed = true;
|
||||||
|
|
||||||
|
float _getDistanceToChaperone(const vr::HmdVector3_t& point, vr::HmdVector3_t* projectedPoint);
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t quadsCount() const noexcept { return _quadsCount; }
|
||||||
|
bool isChaperoneWellFormed() const noexcept { return _chaperoneWellFormed; }
|
||||||
|
|
||||||
|
std::recursive_mutex& mutex() noexcept { return _mutex; }
|
||||||
|
|
||||||
|
void loadChaperoneData();
|
||||||
|
|
||||||
|
float getDistanceToChaperone(const vr::HmdVector3_t& point, vr::HmdVector3_t* projectedPoint = nullptr, bool doLock = false) {
|
||||||
|
if (doLock) {
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(_mutex);
|
||||||
|
return _getDistanceToChaperone(point, projectedPoint);
|
||||||
|
} else {
|
||||||
|
return _getDistanceToChaperone(point, projectedPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace utils
|
||||||
|
|
||||||
Reference in New Issue
Block a user