mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:24:07 +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.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.LS", "to": "Standard.LS" },
|
||||
{ "from": "Vive.LSTouch", "to": "Standard.LSTouch" },
|
||||
|
||||
{ "from": "Vive.RY", "when": "Vive.RSY", "filters": ["invert"], "to": "Standard.RY" },
|
||||
{ "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.RS", "to": "Standard.RS" },
|
||||
{ "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 {
|
||||
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
|
||||
// interface/src/scripting
|
||||
//
|
||||
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_HMDScriptingInterface_h
|
||||
#define hifi_HMDScriptingInterface_h
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <QtScript/QScriptValue>
|
||||
class QScriptContext;
|
||||
class QScriptEngine;
|
||||
|
@ -38,6 +40,19 @@ public:
|
|||
Q_INVOKABLE QString preferredAudioOutput() 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;
|
||||
/// 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:
|
||||
HMDScriptingInterface();
|
||||
|
|
|
@ -16,16 +16,18 @@
|
|||
#include <QtCore/QSize>
|
||||
#include <QtCore/QPoint>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
class QImage;
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <shared/Bilateral.h>
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
class QImage;
|
||||
|
||||
enum Eye {
|
||||
Left,
|
||||
Right
|
||||
Left = bilateral::Side::Left,
|
||||
Right = bilateral::Side::Right
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -56,7 +58,73 @@ namespace gpu {
|
|||
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
|
||||
using Parent = Plugin;
|
||||
public:
|
||||
|
@ -117,42 +185,12 @@ public:
|
|||
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
|
||||
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
|
||||
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; }
|
||||
// Rate at which we present to the display device
|
||||
virtual float presentRate() const { return -1.0f; }
|
||||
|
@ -160,6 +198,7 @@ public:
|
|||
virtual float newFramePresentRate() const { return -1.0f; }
|
||||
// Rate at which rendered frames are being skipped
|
||||
virtual float droppedFrameRate() const { return -1.0f; }
|
||||
|
||||
uint32_t presentCount() const { return _presentedFrameIndex; }
|
||||
// Time since last call to incrementPresentCount (only valid if DEBUG_PAINT_DELAY is defined)
|
||||
int64_t getPaintDelayUsecs() const;
|
||||
|
@ -168,25 +207,6 @@ public:
|
|||
|
||||
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:
|
||||
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/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QProcessEnvironment>
|
||||
|
||||
#include <controllers/Input.h>
|
||||
#include <controllers/Pose.h>
|
||||
|
@ -53,6 +54,13 @@ bool oculusAvailable() {
|
|||
static std::once_flag once;
|
||||
static bool result { false };
|
||||
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);
|
||||
if (!detect.IsOculusServiceRunning || !detect.IsOculusHMDConnected) {
|
||||
return;
|
||||
|
|
|
@ -253,3 +253,27 @@ void OpenVrDisplayPlugin::updatePresentPose() {
|
|||
mat3 presentRotation(_currentPresentFrameInfo.rawPresentPose);
|
||||
_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;
|
||||
void cycleDebugOutput() override { _lockCurrentTexture = !_lockCurrentTexture; }
|
||||
|
||||
bool suppressKeyboard() override;
|
||||
void unsuppressKeyboard() override;
|
||||
bool isKeyboardVisible() override;
|
||||
|
||||
protected:
|
||||
bool internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
@ -39,8 +43,10 @@ protected:
|
|||
bool isHmdMounted() const override;
|
||||
void postPreview() override;
|
||||
|
||||
|
||||
private:
|
||||
vr::IVRSystem* _system { nullptr };
|
||||
std::atomic<vr::EDeviceActivityLevel> _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown };
|
||||
std::atomic<uint32_t> _keyboardSupressionCount{ 0 };
|
||||
static const QString NAME;
|
||||
};
|
||||
|
|
|
@ -240,6 +240,12 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
|||
_poseStateMap.clear();
|
||||
_buttonPressedMap.clear();
|
||||
|
||||
// While the keyboard is open, we defer strictly to the keyboard values
|
||||
if (isOpenVrKeyboardShown()) {
|
||||
_axisStateMap.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
PerformanceTimer perfTimer("ViveControllerManager::update");
|
||||
|
||||
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
||||
|
|
Loading…
Reference in a new issue