mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 10:47:11 +02:00
Merge pull request #10866 from druiz17/vive-in-desktop
Allowing Vive controllers and trackers to be used in desktop mode
This commit is contained in:
commit
e384f6d1b7
6 changed files with 134 additions and 29 deletions
|
@ -34,36 +34,32 @@
|
||||||
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
||||||
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
||||||
|
|
||||||
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand"},
|
||||||
{ "from": "Vive.RightHand", "to": "Standard.RightHand", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.RightHand", "to": "Standard.RightHand"},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.RightFoot", "to" : "Standard.RightFoot",
|
"from": "Vive.RightFoot", "to" : "Standard.RightFoot",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.Hips", "to" : "Standard.Hips",
|
"from": "Vive.Hips", "to" : "Standard.Hips",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.Spine2", "to" : "Standard.Spine2",
|
"from": "Vive.Spine2", "to" : "Standard.Spine2",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "from": "Vive.Head", "to" : "Standard.Head", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.Head", "to" : "Standard.Head"},
|
||||||
|
|
||||||
{ "from": "Vive.RightArm", "to" : "Standard.RightArm", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.RightArm", "to" : "Standard.RightArm"},
|
||||||
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm", "when": [ "Application.InHMD" ] }
|
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -642,6 +642,57 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Separator {
|
||||||
|
id: advanceSeperator
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: timeToCalibrate.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayBold {
|
||||||
|
id: advanceSettings
|
||||||
|
|
||||||
|
text: "Advance Settings"
|
||||||
|
size: 12
|
||||||
|
|
||||||
|
color: hifi.colors.white
|
||||||
|
|
||||||
|
anchors.top: advanceSeperator.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: leftMargin
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HifiControls.CheckBox {
|
||||||
|
id: viveInDesktop
|
||||||
|
width: 15
|
||||||
|
height: 15
|
||||||
|
boxRadius: 7
|
||||||
|
|
||||||
|
anchors.top: advanceSettings.bottom
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.left: openVrConfiguration.left
|
||||||
|
anchors.leftMargin: leftMargin + 10
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
sendConfigurationSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayBold {
|
||||||
|
id: viveDesktopText
|
||||||
|
size: 10
|
||||||
|
text: "Use vive devices in desktop mode"
|
||||||
|
color: hifi.colors.white
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: viveInDesktop.right
|
||||||
|
leftMargin: 5
|
||||||
|
verticalCenter: viveInDesktop.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
id: numberAnimation
|
id: numberAnimation
|
||||||
target: openVrConfiguration
|
target: openVrConfiguration
|
||||||
|
@ -728,6 +779,7 @@ Rectangle {
|
||||||
|
|
||||||
var HmdHead = settings["HMDHead"];
|
var HmdHead = settings["HMDHead"];
|
||||||
var viveController = settings["handController"];
|
var viveController = settings["handController"];
|
||||||
|
var desktopMode = settings["desktopMode"];
|
||||||
|
|
||||||
if (HmdHead) {
|
if (HmdHead) {
|
||||||
headBox.checked = true;
|
headBox.checked = true;
|
||||||
|
@ -745,6 +797,8 @@ Rectangle {
|
||||||
handBox.checked = false;
|
handBox.checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viveInDesktop.checked = desktopMode;
|
||||||
|
|
||||||
initializeButtonState();
|
initializeButtonState();
|
||||||
updateCalibrationText();
|
updateCalibrationText();
|
||||||
|
|
||||||
|
@ -901,7 +955,8 @@ Rectangle {
|
||||||
var settingsObject = {
|
var settingsObject = {
|
||||||
"bodyConfiguration": trackerConfiguration,
|
"bodyConfiguration": trackerConfiguration,
|
||||||
"headConfiguration": headObject,
|
"headConfiguration": headObject,
|
||||||
"handConfiguration": handObject
|
"handConfiguration": handObject,
|
||||||
|
"desktopMode": viveInDesktop.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
return settingsObject;
|
return settingsObject;
|
||||||
|
|
|
@ -1634,7 +1634,8 @@ void MyAvatar::prepareForPhysicsSimulation() {
|
||||||
_characterController.setParentVelocity(parentVelocity);
|
_characterController.setParentVelocity(parentVelocity);
|
||||||
|
|
||||||
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
||||||
if (qApp->isHMDMode()) {
|
auto headPose = getHeadControllerPoseInAvatarFrame();
|
||||||
|
if (headPose.isValid()) {
|
||||||
_follow.prePhysicsUpdate(*this, deriveBodyFromHMDSensor(), _bodySensorMatrix, hasDriveInput());
|
_follow.prePhysicsUpdate(*this, deriveBodyFromHMDSensor(), _bodySensorMatrix, hasDriveInput());
|
||||||
} else {
|
} else {
|
||||||
_follow.deactivate();
|
_follow.deactivate();
|
||||||
|
|
|
@ -82,6 +82,12 @@ struct PoseData {
|
||||||
angularVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vAngularVelocity));
|
angularVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vAngularVelocity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetToInvalid() {
|
||||||
|
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||||
|
vrPoses[i].bPoseIsValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME remove once OpenVR header is updated
|
// FIXME remove once OpenVR header is updated
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include <ui-plugins/PluginContainer.h>
|
||||||
|
#include <plugins/DisplayPlugin.h>
|
||||||
|
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
#include <Plugins/InputConfiguration.h>
|
#include <Plugins/InputConfiguration.h>
|
||||||
|
@ -60,11 +62,6 @@ static const int SECOND_FOOT = 1;
|
||||||
static const int HIP = 2;
|
static const int HIP = 2;
|
||||||
static const int CHEST = 3;
|
static const int CHEST = 3;
|
||||||
|
|
||||||
static float HEAD_PUCK_Y_OFFSET = -0.0254f;
|
|
||||||
static float HEAD_PUCK_Z_OFFSET = -0.152f;
|
|
||||||
static float HAND_PUCK_Y_OFFSET = -0.0508f;
|
|
||||||
static float HAND_PUCK_Z_OFFSET = 0.0254f;
|
|
||||||
|
|
||||||
const char* ViveControllerManager::NAME { "OpenVR" };
|
const char* ViveControllerManager::NAME { "OpenVR" };
|
||||||
|
|
||||||
const std::map<vr::ETrackingResult, QString> TRACKING_RESULT_TO_STRING = {
|
const std::map<vr::ETrackingResult, QString> TRACKING_RESULT_TO_STRING = {
|
||||||
|
@ -121,6 +118,29 @@ static QString deviceTrackingResultToString(vr::ETrackingResult trackingResult)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static glm::mat4 calculateResetMat() {
|
||||||
|
auto chaperone = vr::VRChaperone();
|
||||||
|
if (chaperone) {
|
||||||
|
float const UI_RADIUS = 1.0f;
|
||||||
|
float const UI_HEIGHT = 1.6f;
|
||||||
|
float const UI_Z_OFFSET = 0.5;
|
||||||
|
|
||||||
|
float xSize, zSize;
|
||||||
|
chaperone->GetPlayAreaSize(&xSize, &zSize);
|
||||||
|
glm::vec3 uiPos(0.0f, UI_HEIGHT, UI_RADIUS - (0.5f * zSize) - UI_Z_OFFSET);
|
||||||
|
|
||||||
|
return glm::inverse(createMatFromQuatAndPos(glm::quat(), uiPos));
|
||||||
|
}
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViveControllerManager::isDesktopMode() {
|
||||||
|
if (_container) {
|
||||||
|
return !_container->getActiveDisplayPlugin()->isHmd();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ViveControllerManager::calibrate() {
|
void ViveControllerManager::calibrate() {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
_inputDevice->calibrateNextFrame();
|
_inputDevice->calibrateNextFrame();
|
||||||
|
@ -141,13 +161,21 @@ bool ViveControllerManager::isSupported() const {
|
||||||
|
|
||||||
void ViveControllerManager::setConfigurationSettings(const QJsonObject configurationSettings) {
|
void ViveControllerManager::setConfigurationSettings(const QJsonObject configurationSettings) {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
|
if (configurationSettings.contains("desktopMode")) {
|
||||||
|
_desktopMode = configurationSettings["desktopMode"].toBool();
|
||||||
|
if (!_desktopMode) {
|
||||||
|
_resetMatCalculated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
_inputDevice->configureCalibrationSettings(configurationSettings);
|
_inputDevice->configureCalibrationSettings(configurationSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ViveControllerManager::configurationSettings() {
|
QJsonObject ViveControllerManager::configurationSettings() {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
return _inputDevice->configurationSettings();
|
QJsonObject configurationSettings = _inputDevice->configurationSettings();
|
||||||
|
configurationSettings["desktopMode"] = _desktopMode;
|
||||||
|
return configurationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
|
@ -218,6 +246,18 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDesktopMode() && _desktopMode) {
|
||||||
|
if (!_resetMatCalculated) {
|
||||||
|
_resetMat = calculateResetMat();
|
||||||
|
_resetMatCalculated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, _nextSimPoseData.vrPoses, vr::k_unMaxTrackedDeviceCount);
|
||||||
|
_nextSimPoseData.update(_resetMat);
|
||||||
|
} else if (isDesktopMode()) {
|
||||||
|
_nextSimPoseData.resetToInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
handleOpenVrEvents();
|
handleOpenVrEvents();
|
||||||
if (openVrQuitRequested()) {
|
if (openVrQuitRequested()) {
|
||||||
|
@ -344,8 +384,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHead = headObject["override"].toBool();
|
bool overrideHead = headObject["override"].toBool();
|
||||||
if (overrideHead) {
|
if (overrideHead) {
|
||||||
_headConfig = HeadConfig::Puck;
|
_headConfig = HeadConfig::Puck;
|
||||||
HEAD_PUCK_Y_OFFSET = headObject["Y"].toDouble();
|
_headPuckYOffset = headObject["Y"].toDouble();
|
||||||
HEAD_PUCK_Z_OFFSET = headObject["Z"].toDouble();
|
_headPuckZOffset = headObject["Z"].toDouble();
|
||||||
} else {
|
} else {
|
||||||
_headConfig = HeadConfig::HMD;
|
_headConfig = HeadConfig::HMD;
|
||||||
}
|
}
|
||||||
|
@ -354,8 +394,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHands = handsObject["override"].toBool();
|
bool overrideHands = handsObject["override"].toBool();
|
||||||
if (overrideHands) {
|
if (overrideHands) {
|
||||||
_handConfig = HandConfig::Pucks;
|
_handConfig = HandConfig::Pucks;
|
||||||
HAND_PUCK_Y_OFFSET = handsObject["Y"].toDouble();
|
_handPuckYOffset = handsObject["Y"].toDouble();
|
||||||
HAND_PUCK_Z_OFFSET = handsObject["Z"].toDouble();
|
_handPuckZOffset = handsObject["Z"].toDouble();
|
||||||
} else {
|
} else {
|
||||||
_handConfig = HandConfig::HandController;
|
_handConfig = HandConfig::HandController;
|
||||||
}
|
}
|
||||||
|
@ -714,7 +754,7 @@ glm::mat4 ViveControllerManager::InputDevice::calculateDefaultToReferenceForHead
|
||||||
glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f));
|
glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f));
|
||||||
|
|
||||||
glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),
|
glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),
|
||||||
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, HEAD_PUCK_Y_OFFSET, HEAD_PUCK_Z_OFFSET, 1.0f));
|
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, _headPuckYOffset, _headPuckZOffset, 1.0f));
|
||||||
|
|
||||||
glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset;
|
glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset;
|
||||||
|
|
||||||
|
@ -914,7 +954,7 @@ void ViveControllerManager::InputDevice::calibrateLeftHand(glm::mat4& defaultToR
|
||||||
glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 translationOffset = glm::vec3(0.0f, HAND_PUCK_Y_OFFSET, HAND_PUCK_Z_OFFSET);
|
glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset);
|
||||||
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
||||||
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
||||||
|
|
||||||
|
@ -945,7 +985,7 @@ void ViveControllerManager::InputDevice::calibrateRightHand(glm::mat4& defaultTo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 translationOffset = glm::vec3(0.0f, HAND_PUCK_Y_OFFSET, HAND_PUCK_Z_OFFSET);
|
glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset);
|
||||||
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
||||||
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,10 @@ private:
|
||||||
float _leftHapticDuration { 0.0f };
|
float _leftHapticDuration { 0.0f };
|
||||||
float _rightHapticStrength { 0.0f };
|
float _rightHapticStrength { 0.0f };
|
||||||
float _rightHapticDuration { 0.0f };
|
float _rightHapticDuration { 0.0f };
|
||||||
|
float _headPuckYOffset { 0.0f };
|
||||||
|
float _headPuckZOffset { 0.0f };
|
||||||
|
float _handPuckYOffset { 0.0f };
|
||||||
|
float _handPuckZOffset { 0.0f };
|
||||||
bool _triggersPressedHandled { false };
|
bool _triggersPressedHandled { false };
|
||||||
bool _calibrated { false };
|
bool _calibrated { false };
|
||||||
bool _timeTilCalibrationSet { false };
|
bool _timeTilCalibrationSet { false };
|
||||||
|
@ -190,9 +194,12 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
||||||
|
bool isDesktopMode();
|
||||||
bool _registeredWithInputMapper { false };
|
bool _registeredWithInputMapper { false };
|
||||||
bool _modelLoaded { false };
|
bool _modelLoaded { false };
|
||||||
|
bool _resetMatCalculated { false };
|
||||||
|
bool _desktopMode { false };
|
||||||
|
glm::mat4 _resetMat { glm::mat4() };
|
||||||
model::Geometry _modelGeometry;
|
model::Geometry _modelGeometry;
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue