mirror of
https://github.com/overte-org/overte.git
synced 2025-06-23 09:19:36 +02:00
Support keyboard suppresion, control suppresion while in keyboard mode
This commit is contained in:
parent
71bf9384ce
commit
0b0977f362
9 changed files with 206 additions and 57 deletions
|
@ -4,15 +4,24 @@
|
||||||
{ "from": "Vive.LY", "when": "Vive.LSY", "filters": ["invert"], "to": "Standard.LY" },
|
{ "from": "Vive.LY", "when": "Vive.LSY", "filters": ["invert"], "to": "Standard.LY" },
|
||||||
{ "from": "Vive.LX", "when": "Vive.LSX", "to": "Standard.LX" },
|
{ "from": "Vive.LX", "when": "Vive.LSX", "to": "Standard.LX" },
|
||||||
|
|
||||||
{ "from": "Vive.LT", "to": "Standard.LT" },
|
{
|
||||||
|
"from": "Vive.LT", "to": "Standard.LT",
|
||||||
|
"filters": [
|
||||||
|
{ "type": "deadZone", "min": 0.05 },
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "from": "Vive.LeftGrip", "to": "Standard.LeftGrip" },
|
{ "from": "Vive.LeftGrip", "to": "Standard.LeftGrip" },
|
||||||
{ "from": "Vive.LS", "to": "Standard.LS" },
|
{ "from": "Vive.LS", "to": "Standard.LS" },
|
||||||
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||||
|
|
||||||
{ "from": "Vive.RY", "when": "Vive.RSY", "filters": ["invert"], "to": "Standard.RY" },
|
{ "from": "Vive.RY", "when": "Vive.RSY", "filters": ["invert"], "to": "Standard.RY" },
|
||||||
{ "from": "Vive.RX", "when": "Vive.RSX", "to": "Standard.RX" },
|
{ "from": "Vive.RX", "when": "Vive.RSX", "to": "Standard.RX" },
|
||||||
|
{
|
||||||
{ "from": "Vive.RT", "to": "Standard.RT" },
|
"from": "Vive.RT", "to": "Standard.RT",
|
||||||
|
"filters": [
|
||||||
|
{ "type": "deadZone", "min": 0.05 },
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "from": "Vive.RightGrip", "to": "Standard.RightGrip" },
|
{ "from": "Vive.RightGrip", "to": "Standard.RightGrip" },
|
||||||
{ "from": "Vive.RS", "to": "Standard.RS" },
|
{ "from": "Vive.RS", "to": "Standard.RS" },
|
||||||
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
|
{ "from": "Vive.RSTouch", "to": "Standard.RSTouch" },
|
||||||
|
|
|
@ -115,3 +115,15 @@ bool HMDScriptingInterface::setHandLasers(int hands, bool enabled, const glm::ve
|
||||||
void HMDScriptingInterface::disableHandLasers(int hands) const {
|
void HMDScriptingInterface::disableHandLasers(int hands) const {
|
||||||
qApp->getActiveDisplayPlugin()->setHandLaser(hands, DisplayPlugin::HandLaserMode::None);
|
qApp->getActiveDisplayPlugin()->setHandLaser(hands, DisplayPlugin::HandLaserMode::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HMDScriptingInterface::suppressKeyboard() {
|
||||||
|
return qApp->getActiveDisplayPlugin()->suppressKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HMDScriptingInterface::unsuppressKeyboard() {
|
||||||
|
qApp->getActiveDisplayPlugin()->unsuppressKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HMDScriptingInterface::isKeyboardVisible() {
|
||||||
|
return qApp->getActiveDisplayPlugin()->isKeyboardVisible();
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//
|
|
||||||
// HMDScriptingInterface.h
|
// HMDScriptingInterface.h
|
||||||
// interface/src/scripting
|
// interface/src/scripting
|
||||||
//
|
//
|
||||||
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_HMDScriptingInterface_h
|
#ifndef hifi_HMDScriptingInterface_h
|
||||||
#define hifi_HMDScriptingInterface_h
|
#define hifi_HMDScriptingInterface_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include <QtScript/QScriptValue>
|
#include <QtScript/QScriptValue>
|
||||||
class QScriptContext;
|
class QScriptContext;
|
||||||
class QScriptEngine;
|
class QScriptEngine;
|
||||||
|
@ -38,6 +40,19 @@ public:
|
||||||
Q_INVOKABLE QString preferredAudioOutput() const;
|
Q_INVOKABLE QString preferredAudioOutput() const;
|
||||||
Q_INVOKABLE bool setHandLasers(int hands, bool enabled, const glm::vec4& color, const glm::vec3& direction) const;
|
Q_INVOKABLE bool setHandLasers(int hands, bool enabled, const glm::vec4& color, const glm::vec3& direction) const;
|
||||||
Q_INVOKABLE void disableHandLasers(int hands) const;
|
Q_INVOKABLE void disableHandLasers(int hands) const;
|
||||||
|
/// Suppress the activation of any on-screen keyboard so that a script operation will
|
||||||
|
/// not be interrupted by a keyboard popup
|
||||||
|
/// Returns false if there is already an active keyboard displayed.
|
||||||
|
/// Clients should re-enable the keyboard when the operation is complete and ensure
|
||||||
|
/// that they balance any call to suppressKeyboard() that returns true with a corresponding
|
||||||
|
/// call to unsuppressKeyboard() within a reasonable amount of time
|
||||||
|
Q_INVOKABLE bool suppressKeyboard();
|
||||||
|
|
||||||
|
/// Enable the keyboard following a suppressKeyboard call
|
||||||
|
Q_INVOKABLE void unsuppressKeyboard();
|
||||||
|
|
||||||
|
/// Query the display plugin to determine the current VR keyboard visibility
|
||||||
|
Q_INVOKABLE bool isKeyboardVisible();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HMDScriptingInterface();
|
HMDScriptingInterface();
|
||||||
|
|
|
@ -16,16 +16,18 @@
|
||||||
#include <QtCore/QSize>
|
#include <QtCore/QSize>
|
||||||
#include <QtCore/QPoint>
|
#include <QtCore/QPoint>
|
||||||
#include <QtCore/QElapsedTimer>
|
#include <QtCore/QElapsedTimer>
|
||||||
class QImage;
|
|
||||||
|
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
|
#include <shared/Bilateral.h>
|
||||||
|
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
|
|
||||||
|
class QImage;
|
||||||
|
|
||||||
enum Eye {
|
enum Eye {
|
||||||
Left,
|
Left = bilateral::Side::Left,
|
||||||
Right
|
Right = bilateral::Side::Right
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -56,7 +58,73 @@ namespace gpu {
|
||||||
using TexturePointer = std::shared_ptr<Texture>;
|
using TexturePointer = std::shared_ptr<Texture>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class DisplayPlugin : public Plugin {
|
// Stereo display functionality
|
||||||
|
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||||
|
// displayPlugin->isStereo returns true
|
||||||
|
class StereoDisplay {
|
||||||
|
public:
|
||||||
|
// Stereo specific methods
|
||||||
|
virtual glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const {
|
||||||
|
return baseProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const {
|
||||||
|
return baseProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual float getIPD() const { return AVERAGE_HUMAN_IPD; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// HMD display functionality
|
||||||
|
// TODO move out of this file don't derive DisplayPlugin from this. Instead use dynamic casting when
|
||||||
|
// displayPlugin->isHmd returns true
|
||||||
|
class HmdDisplay : public StereoDisplay {
|
||||||
|
public:
|
||||||
|
// HMD specific methods
|
||||||
|
// TODO move these into another class?
|
||||||
|
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const {
|
||||||
|
static const glm::mat4 transform; return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a copy of the most recent head pose, computed via updateHeadPose
|
||||||
|
virtual glm::mat4 getHeadPose() const {
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed for timewarp style features
|
||||||
|
virtual void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void abandonCalibration() {}
|
||||||
|
|
||||||
|
virtual void resetSensors() {}
|
||||||
|
|
||||||
|
enum Hand {
|
||||||
|
LeftHand = 0x01,
|
||||||
|
RightHand = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HandLaserMode {
|
||||||
|
None, // Render no hand lasers
|
||||||
|
Overlay, // Render hand lasers only if they intersect with the UI layer, and stop at the UI layer
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool setHandLaser(
|
||||||
|
uint32_t hands, // Bits from the Hand enum
|
||||||
|
HandLaserMode mode, // Mode in which to render
|
||||||
|
const vec4& color = vec4(1), // The color of the rendered laser
|
||||||
|
const vec3& direction = vec3(0, 0, -1) // The direction in which to render the hand lasers
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool suppressKeyboard() { return false; }
|
||||||
|
virtual void unsuppressKeyboard() {};
|
||||||
|
virtual bool isKeyboardVisible() { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class DisplayPlugin : public Plugin, public HmdDisplay {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
using Parent = Plugin;
|
using Parent = Plugin;
|
||||||
public:
|
public:
|
||||||
|
@ -117,42 +185,12 @@ public:
|
||||||
return QRect(0, 0, recommendedSize.x, recommendedSize.y);
|
return QRect(0, 0, recommendedSize.x, recommendedSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stereo specific methods
|
|
||||||
virtual glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const {
|
|
||||||
return baseProjection;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const {
|
|
||||||
return baseProjection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fetch the most recently displayed image as a QImage
|
// Fetch the most recently displayed image as a QImage
|
||||||
virtual QImage getScreenshot() const = 0;
|
virtual QImage getScreenshot() const = 0;
|
||||||
|
|
||||||
// HMD specific methods
|
|
||||||
// TODO move these into another class?
|
|
||||||
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const {
|
|
||||||
static const glm::mat4 transform; return transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
// will query the underlying hmd api to compute the most recent head pose
|
// will query the underlying hmd api to compute the most recent head pose
|
||||||
virtual bool beginFrameRender(uint32_t frameIndex) { return true; }
|
virtual bool beginFrameRender(uint32_t frameIndex) { return true; }
|
||||||
|
|
||||||
// returns a copy of the most recent head pose, computed via updateHeadPose
|
|
||||||
virtual glm::mat4 getHeadPose() const {
|
|
||||||
return glm::mat4();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Needed for timewarp style features
|
|
||||||
virtual void setEyeRenderPose(uint32_t frameIndex, Eye eye, const glm::mat4& pose) {
|
|
||||||
// NOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float getIPD() const { return AVERAGE_HUMAN_IPD; }
|
|
||||||
|
|
||||||
virtual void abandonCalibration() {}
|
|
||||||
virtual void resetSensors() {}
|
|
||||||
virtual float devicePixelRatio() { return 1.0f; }
|
virtual float devicePixelRatio() { return 1.0f; }
|
||||||
// Rate at which we present to the display device
|
// Rate at which we present to the display device
|
||||||
virtual float presentRate() const { return -1.0f; }
|
virtual float presentRate() const { return -1.0f; }
|
||||||
|
@ -160,6 +198,7 @@ public:
|
||||||
virtual float newFramePresentRate() const { return -1.0f; }
|
virtual float newFramePresentRate() const { return -1.0f; }
|
||||||
// Rate at which rendered frames are being skipped
|
// Rate at which rendered frames are being skipped
|
||||||
virtual float droppedFrameRate() const { return -1.0f; }
|
virtual float droppedFrameRate() const { return -1.0f; }
|
||||||
|
|
||||||
uint32_t presentCount() const { return _presentedFrameIndex; }
|
uint32_t presentCount() const { return _presentedFrameIndex; }
|
||||||
// Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)
|
// Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)
|
||||||
int64_t getPaintDelayUsecs() const;
|
int64_t getPaintDelayUsecs() const;
|
||||||
|
@ -168,25 +207,6 @@ public:
|
||||||
|
|
||||||
static const QString& MENU_PATH();
|
static const QString& MENU_PATH();
|
||||||
|
|
||||||
enum Hand {
|
|
||||||
LeftHand = 0x01,
|
|
||||||
RightHand = 0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class HandLaserMode {
|
|
||||||
None, // Render no hand lasers
|
|
||||||
Overlay, // Render hand lasers only if they intersect with the UI layer, and stop at the UI layer
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual bool setHandLaser(
|
|
||||||
uint32_t hands, // Bits from the Hand enum
|
|
||||||
HandLaserMode mode, // Mode in which to render
|
|
||||||
const vec4& color = vec4(1), // The color of the rendered laser
|
|
||||||
const vec3& direction = vec3(0, 0, -1) // The direction in which to render the hand lasers
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void recommendedFramebufferSizeChanged(const QSize & size);
|
void recommendedFramebufferSizeChanged(const QSize & size);
|
||||||
|
|
49
libraries/shared/src/shared/Bilateral.h
Normal file
49
libraries/shared/src/shared/Bilateral.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis 2015/10/09
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace bilateral {
|
||||||
|
enum class Side {
|
||||||
|
Left = 0,
|
||||||
|
Right = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
using Indices = Side;
|
||||||
|
|
||||||
|
enum class Bits {
|
||||||
|
Left = 0x01,
|
||||||
|
Right = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint8_t bit(Side side) {
|
||||||
|
switch (side) {
|
||||||
|
case Side::Left:
|
||||||
|
return 0x01;
|
||||||
|
case Side::Right:
|
||||||
|
return 0x02;
|
||||||
|
}
|
||||||
|
return UINT8_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint8_t index(Side side) {
|
||||||
|
switch (side) {
|
||||||
|
case Side::Left:
|
||||||
|
return 0;
|
||||||
|
case Side::Right:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return UINT8_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void for_each_side(F f) {
|
||||||
|
f(Side::Left);
|
||||||
|
f(Side::Right);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QtCore/QLoggingCategory>
|
#include <QtCore/QLoggingCategory>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QProcessEnvironment>
|
||||||
|
|
||||||
#include <controllers/Input.h>
|
#include <controllers/Input.h>
|
||||||
#include <controllers/Pose.h>
|
#include <controllers/Pose.h>
|
||||||
|
@ -53,6 +54,13 @@ bool oculusAvailable() {
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
static bool result { false };
|
static bool result { false };
|
||||||
std::call_once(once, [&] {
|
std::call_once(once, [&] {
|
||||||
|
|
||||||
|
static const QString DEBUG_FLAG("HIFI_DEBUG_OPENVR");
|
||||||
|
static bool enableDebugOpenVR = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
|
||||||
|
if (enableDebugOpenVR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ovrDetectResult detect = ovr_Detect(0);
|
ovrDetectResult detect = ovr_Detect(0);
|
||||||
if (!detect.IsOculusServiceRunning || !detect.IsOculusHMDConnected) {
|
if (!detect.IsOculusServiceRunning || !detect.IsOculusHMDConnected) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -253,3 +253,27 @@ void OpenVrDisplayPlugin::updatePresentPose() {
|
||||||
mat3 presentRotation(_currentPresentFrameInfo.rawPresentPose);
|
mat3 presentRotation(_currentPresentFrameInfo.rawPresentPose);
|
||||||
_currentPresentFrameInfo.presentReprojection = glm::mat3(glm::inverse(renderRotation) * presentRotation);
|
_currentPresentFrameInfo.presentReprojection = glm::mat3(glm::inverse(renderRotation) * presentRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenVrDisplayPlugin::suppressKeyboard() {
|
||||||
|
if (isOpenVrKeyboardShown()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!_keyboardSupressionCount.fetch_add(1)) {
|
||||||
|
disableOpenVrKeyboard();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenVrDisplayPlugin::unsuppressKeyboard() {
|
||||||
|
if (_keyboardSupressionCount == 0) {
|
||||||
|
qWarning() << "Attempted to unsuppress a keyboard that was not suppressed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (1 == _keyboardSupressionCount.fetch_sub(1)) {
|
||||||
|
enableOpenVrKeyboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenVrDisplayPlugin::isKeyboardVisible() {
|
||||||
|
return isOpenVrKeyboardShown();
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ public:
|
||||||
bool beginFrameRender(uint32_t frameIndex) override;
|
bool beginFrameRender(uint32_t frameIndex) override;
|
||||||
void cycleDebugOutput() override { _lockCurrentTexture = !_lockCurrentTexture; }
|
void cycleDebugOutput() override { _lockCurrentTexture = !_lockCurrentTexture; }
|
||||||
|
|
||||||
|
bool suppressKeyboard() override;
|
||||||
|
void unsuppressKeyboard() override;
|
||||||
|
bool isKeyboardVisible() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool internalActivate() override;
|
bool internalActivate() override;
|
||||||
void internalDeactivate() override;
|
void internalDeactivate() override;
|
||||||
|
@ -39,8 +43,10 @@ protected:
|
||||||
bool isHmdMounted() const override;
|
bool isHmdMounted() const override;
|
||||||
void postPreview() override;
|
void postPreview() override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::IVRSystem* _system { nullptr };
|
vr::IVRSystem* _system { nullptr };
|
||||||
std::atomic<vr::EDeviceActivityLevel> _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown };
|
std::atomic<vr::EDeviceActivityLevel> _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown };
|
||||||
|
std::atomic<uint32_t> _keyboardSupressionCount{ 0 };
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
|
@ -240,6 +240,12 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
||||||
|
// While the keyboard is open, we defer strictly to the keyboard values
|
||||||
|
if (isOpenVrKeyboardShown()) {
|
||||||
|
_axisStateMap.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
PerformanceTimer perfTimer("ViveControllerManager::update");
|
PerformanceTimer perfTimer("ViveControllerManager::update");
|
||||||
|
|
||||||
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
||||||
|
|
Loading…
Reference in a new issue