Support keyboard suppresion, control suppresion while in keyboard mode

This commit is contained in:
Bradley Austin Davis 2016-06-14 18:25:01 -07:00
parent 71bf9384ce
commit 0b0977f362
9 changed files with 206 additions and 57 deletions

View file

@ -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" },

View file

@ -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();
}

View file

@ -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();

View file

@ -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);

View 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);
}
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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;
};

View file

@ -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);