mirror of
https://github.com/lubosz/overte.git
synced 2025-08-08 03:48:38 +02:00
Enable Steam VR text input
This commit is contained in:
parent
ca6e86e767
commit
eab611acc0
4 changed files with 84 additions and 2 deletions
|
@ -396,6 +396,8 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) {
|
||||||
|
|
||||||
_renderer->_renderControl->_renderWindow = _proxyWindow;
|
_renderer->_renderControl->_renderWindow = _proxyWindow;
|
||||||
|
|
||||||
|
connect(_renderer->_quickWindow, &QQuickWindow::focusObjectChanged, this, &OffscreenQmlSurface::onFocusObjectChanged);
|
||||||
|
|
||||||
// Create a QML engine.
|
// Create a QML engine.
|
||||||
_qmlEngine = new QQmlEngine;
|
_qmlEngine = new QQmlEngine;
|
||||||
if (!_qmlEngine->incubationController()) {
|
if (!_qmlEngine->incubationController()) {
|
||||||
|
@ -742,3 +744,42 @@ QVariant OffscreenQmlSurface::returnFromUiThread(std::function<QVariant()> funct
|
||||||
|
|
||||||
return function();
|
return function();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
|
||||||
|
if (!object) {
|
||||||
|
setFocusText(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant result;
|
||||||
|
#if 1
|
||||||
|
auto invokeResult = QMetaObject::invokeMethod(object, "inputMethodQuery", Q_RETURN_ARG(QVariant, result),
|
||||||
|
Q_ARG(Qt::InputMethodQuery, Qt::ImEnabled),
|
||||||
|
Q_ARG(QVariant, QVariant()));
|
||||||
|
#else
|
||||||
|
|
||||||
|
//static const char* INPUT_METHOD_QUERY_METHOD_NAME = "inputMethodQuery(Qt::InputMethodQuery, QVariant)";
|
||||||
|
static const char* INPUT_METHOD_QUERY_METHOD_NAME = "inputMethodQuery";
|
||||||
|
auto meta = object->metaObject();
|
||||||
|
qDebug() << "new focus " << object;
|
||||||
|
auto index = meta->indexOfMethod(INPUT_METHOD_QUERY_METHOD_NAME);
|
||||||
|
if (index < 0 || index >= meta->methodCount()) {
|
||||||
|
setFocusText(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto method = meta->method(index);
|
||||||
|
auto invokeResult = method.invoke(object,
|
||||||
|
Q_RETURN_ARG(QVariant, result),
|
||||||
|
Q_ARG(Qt::InputMethodQuery, Qt::ImEnabled),
|
||||||
|
Q_ARG(QVariant, QVariant()));
|
||||||
|
#endif
|
||||||
|
setFocusText(invokeResult && result.toBool());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OffscreenQmlSurface::setFocusText(bool newFocusText) {
|
||||||
|
if (newFocusText != _focusText) {
|
||||||
|
_focusText = newFocusText;
|
||||||
|
emit focusTextChanged(_focusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ class OffscreenQmlRenderThread;
|
||||||
|
|
||||||
class OffscreenQmlSurface : public QObject {
|
class OffscreenQmlSurface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
|
||||||
public:
|
public:
|
||||||
OffscreenQmlSurface();
|
OffscreenQmlSurface();
|
||||||
virtual ~OffscreenQmlSurface();
|
virtual ~OffscreenQmlSurface();
|
||||||
|
@ -55,6 +55,7 @@ public:
|
||||||
_mouseTranslator = mouseTranslator;
|
_mouseTranslator = mouseTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isFocusText() const { return _focusText; }
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
bool isPaused() const;
|
bool isPaused() const;
|
||||||
|
@ -70,6 +71,8 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textureUpdated(unsigned int texture);
|
void textureUpdated(unsigned int texture);
|
||||||
|
void focusObjectChanged(QObject* newFocus);
|
||||||
|
void focusTextChanged(bool focusText);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void requestUpdate();
|
void requestUpdate();
|
||||||
|
@ -78,6 +81,7 @@ public slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterEnabled(QObject* originalDestination, QEvent* event) const;
|
bool filterEnabled(QObject* originalDestination, QEvent* event) const;
|
||||||
|
void setFocusText(bool newFocusText);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
|
QObject* finishQmlLoad(std::function<void(QQmlContext*, QObject*)> f);
|
||||||
|
@ -85,6 +89,7 @@ private:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateQuick();
|
void updateQuick();
|
||||||
|
void onFocusObjectChanged(QObject* newFocus);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class OffscreenQmlRenderThread;
|
friend class OffscreenQmlRenderThread;
|
||||||
|
@ -97,6 +102,7 @@ private:
|
||||||
bool _render{ false };
|
bool _render{ false };
|
||||||
bool _polish{ true };
|
bool _polish{ true };
|
||||||
bool _paused{ true };
|
bool _paused{ true };
|
||||||
|
bool _focusText { false };
|
||||||
uint8_t _maxFps{ 60 };
|
uint8_t _maxFps{ 60 };
|
||||||
MouseTranslator _mouseTranslator{ [](const QPointF& p) { return p.toPoint(); } };
|
MouseTranslator _mouseTranslator{ [](const QPointF& p) { return p.toPoint(); } };
|
||||||
QWindow* _proxyWindow { nullptr };
|
QWindow* _proxyWindow { nullptr };
|
||||||
|
|
|
@ -36,12 +36,14 @@ vec3 _trackedDeviceLinearVelocities[vr::k_unMaxTrackedDeviceCount];
|
||||||
vec3 _trackedDeviceAngularVelocities[vr::k_unMaxTrackedDeviceCount];
|
vec3 _trackedDeviceAngularVelocities[vr::k_unMaxTrackedDeviceCount];
|
||||||
static mat4 _sensorResetMat;
|
static mat4 _sensorResetMat;
|
||||||
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
||||||
|
bool _openVrDisplayActive { false };
|
||||||
|
|
||||||
bool OpenVrDisplayPlugin::isSupported() const {
|
bool OpenVrDisplayPlugin::isSupported() const {
|
||||||
return openVrSupported();
|
return openVrSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenVrDisplayPlugin::internalActivate() {
|
bool OpenVrDisplayPlugin::internalActivate() {
|
||||||
|
_openVrDisplayActive = true;
|
||||||
_container->setIsOptionChecked(StandingHMDSensorMode, true);
|
_container->setIsOptionChecked(StandingHMDSensorMode, true);
|
||||||
|
|
||||||
if (!_system) {
|
if (!_system) {
|
||||||
|
@ -94,6 +96,7 @@ bool OpenVrDisplayPlugin::internalActivate() {
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::internalDeactivate() {
|
void OpenVrDisplayPlugin::internalDeactivate() {
|
||||||
Parent::internalDeactivate();
|
Parent::internalDeactivate();
|
||||||
|
_openVrDisplayActive = false;
|
||||||
_container->setIsOptionChecked(StandingHMDSensorMode, false);
|
_container->setIsOptionChecked(StandingHMDSensorMode, false);
|
||||||
if (_system) {
|
if (_system) {
|
||||||
// Invalidate poses. It's fine if someone else sets these shared values, but we're about to stop updating them, and
|
// Invalidate poses. It's fine if someone else sets these shared values, but we're about to stop updating them, and
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "ViveControllerManager.h"
|
#include "ViveControllerManager.h"
|
||||||
|
|
||||||
#include <QtCore/QProcessEnvironment>
|
#include <QtCore/QProcessEnvironment>
|
||||||
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
|
#include <OffscreenUi.h>
|
||||||
|
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
|
|
||||||
|
@ -55,6 +57,9 @@ bool ViveControllerManager::isSupported() const {
|
||||||
return openVrSupported();
|
return openVrSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMetaObject::Connection _focusConnection;
|
||||||
|
extern bool _openVrDisplayActive;
|
||||||
|
|
||||||
bool ViveControllerManager::activate() {
|
bool ViveControllerManager::activate() {
|
||||||
InputPlugin::activate();
|
InputPlugin::activate();
|
||||||
|
|
||||||
|
@ -67,7 +72,20 @@ bool ViveControllerManager::activate() {
|
||||||
_system = acquireOpenVrSystem();
|
_system = acquireOpenVrSystem();
|
||||||
}
|
}
|
||||||
Q_ASSERT(_system);
|
Q_ASSERT(_system);
|
||||||
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
_focusConnection = connect(offscreenUi.data(), &OffscreenUi::focusTextChanged, [this](bool focusText) {
|
||||||
|
if (_openVrDisplayActive) {
|
||||||
|
auto overlay = vr::VROverlay();
|
||||||
|
if (overlay) {
|
||||||
|
if (focusText) {
|
||||||
|
//virtual EVROverlayError ShowKeyboard( eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0;
|
||||||
|
overlay->ShowKeyboard(vr::EGamepadTextInputMode::k_EGamepadTextInputModeNormal, vr::k_EGamepadTextInputLineModeSingleLine, "Test", 1024, "", false, 0);
|
||||||
|
} else {
|
||||||
|
overlay->HideKeyboard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
// OpenVR provides 3d mesh representations of the controllers
|
// OpenVR provides 3d mesh representations of the controllers
|
||||||
// Disabled controller rendering code
|
// Disabled controller rendering code
|
||||||
/*
|
/*
|
||||||
|
@ -132,6 +150,8 @@ bool ViveControllerManager::activate() {
|
||||||
void ViveControllerManager::deactivate() {
|
void ViveControllerManager::deactivate() {
|
||||||
InputPlugin::deactivate();
|
InputPlugin::deactivate();
|
||||||
|
|
||||||
|
disconnect(_focusConnection);
|
||||||
|
|
||||||
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
||||||
_container->removeMenu(MENU_PATH);
|
_container->removeMenu(MENU_PATH);
|
||||||
|
|
||||||
|
@ -220,6 +240,18 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vr::VREvent_t vrEvent;
|
||||||
|
static char textArray[8192];
|
||||||
|
while (vr::VRSystem()->PollNextEvent(&vrEvent, sizeof(vrEvent))) {
|
||||||
|
if (vrEvent.eventType == vr::VREvent_KeyboardDone) {
|
||||||
|
auto chars = vr::VROverlay()->GetKeyboardText(textArray, 8192);
|
||||||
|
QInputMethodEvent* event = new QInputMethodEvent();
|
||||||
|
event->setCommitString(QString(QByteArray(textArray, chars)), 0, 0);
|
||||||
|
auto focusObject = DependencyManager::get<OffscreenUi>()->getWindow()->focusObject();
|
||||||
|
qApp->postEvent(focusObject, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// because update mutates the internal state we need to lock
|
// because update mutates the internal state we need to lock
|
||||||
userInputMapper->withLock([&, this]() {
|
userInputMapper->withLock([&, this]() {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData);
|
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||||
|
|
Loading…
Reference in a new issue