mirror of
https://github.com/overte-org/overte.git
synced 2025-04-15 12:28:51 +02:00
Merge pull request #7493 from zzmp/fix/plugin-check
Default to desktop when display plugins fail to load
This commit is contained in:
commit
7396fa1cc3
29 changed files with 125 additions and 46 deletions
|
@ -4886,13 +4886,39 @@ void Application::updateDisplayMode() {
|
|||
{
|
||||
std::unique_lock<std::mutex> lock(_displayPluginLock);
|
||||
|
||||
auto oldDisplayPlugin = _displayPlugin;
|
||||
if (_displayPlugin) {
|
||||
_displayPlugin->deactivate();
|
||||
}
|
||||
|
||||
// FIXME probably excessive and useless context switching
|
||||
_offscreenContext->makeCurrent();
|
||||
newDisplayPlugin->activate();
|
||||
|
||||
bool active = newDisplayPlugin->activate();
|
||||
|
||||
if (!active) {
|
||||
// If the new plugin fails to activate, fallback to last display
|
||||
qWarning() << "Failed to activate display: " << newDisplayPlugin->getName();
|
||||
newDisplayPlugin = oldDisplayPlugin;
|
||||
|
||||
if (newDisplayPlugin) {
|
||||
qWarning() << "Falling back to last display: " << newDisplayPlugin->getName();
|
||||
active = newDisplayPlugin->activate();
|
||||
}
|
||||
|
||||
// If there is no last display, or
|
||||
// If the last display fails to activate, fallback to desktop
|
||||
if (!active) {
|
||||
newDisplayPlugin = displayPlugins.at(0);
|
||||
qWarning() << "Falling back to display: " << newDisplayPlugin->getName();
|
||||
active = newDisplayPlugin->activate();
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
qFatal("Failed to activate fallback plugin");
|
||||
}
|
||||
}
|
||||
|
||||
_offscreenContext->makeCurrent();
|
||||
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
||||
_offscreenContext->makeCurrent();
|
||||
|
|
|
@ -19,9 +19,7 @@ const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop");
|
|||
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
||||
Parent::internalActivate();
|
||||
|
||||
bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
||||
_framerateActions.clear();
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), FULLSCREEN,
|
||||
[this](bool clicked) {
|
||||
|
@ -33,6 +31,8 @@ void Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
|||
}, true, false);
|
||||
|
||||
updateFramerate();
|
||||
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) {
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
|
||||
virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
|
||||
virtual void internalActivate() override;
|
||||
virtual bool internalActivate() override;
|
||||
|
||||
virtual void submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) override;
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ void OpenGLDisplayPlugin::cleanupForSceneTexture(const gpu::TexturePointer& scen
|
|||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::activate() {
|
||||
bool OpenGLDisplayPlugin::activate() {
|
||||
if (!_cursorsData.size()) {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
for (const auto iconId : cursorManager.registeredIcons()) {
|
||||
|
@ -238,7 +238,9 @@ void OpenGLDisplayPlugin::activate() {
|
|||
|
||||
// Child classes may override this in order to do things like initialize
|
||||
// libraries, etc
|
||||
internalActivate();
|
||||
if (!internalActivate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if THREADED_PRESENT
|
||||
|
@ -263,7 +265,8 @@ void OpenGLDisplayPlugin::activate() {
|
|||
customizeContext();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
DisplayPlugin::activate();
|
||||
|
||||
return DisplayPlugin::activate();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::deactivate() {
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
|
||||
// These must be final to ensure proper ordering of operations
|
||||
// between the main thread and the presentation thread
|
||||
void activate() override final;
|
||||
bool activate() override final;
|
||||
void deactivate() override final;
|
||||
|
||||
bool eventFilter(QObject* receiver, QEvent* event) override;
|
||||
|
@ -77,7 +77,8 @@ protected:
|
|||
virtual void customizeContext();
|
||||
virtual void uncustomizeContext();
|
||||
|
||||
virtual void internalActivate() {}
|
||||
// Returns true on successful activation
|
||||
virtual bool internalActivate() { return true; }
|
||||
virtual void internalDeactivate() {}
|
||||
virtual void cleanupForSceneTexture(const gpu::TexturePointer& sceneTexture);
|
||||
// Plugin specific functionality to send the composed scene to the output window or device
|
||||
|
|
|
@ -32,7 +32,7 @@ glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const {
|
|||
return CompositorHelper::VIRTUAL_SCREEN_SIZE;
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::internalActivate() {
|
||||
bool HmdDisplayPlugin::internalActivate() {
|
||||
_monoPreview = _container->getBoolSetting("monoPreview", DEFAULT_MONO_VIEW);
|
||||
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), MONO_PREVIEW,
|
||||
|
@ -41,7 +41,8 @@ void HmdDisplayPlugin::internalActivate() {
|
|||
_container->setBoolSetting("monoPreview", _monoPreview);
|
||||
}, true, _monoPreview);
|
||||
_container->removeMenu(FRAMERATE);
|
||||
Parent::internalActivate();
|
||||
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::customizeContext() {
|
||||
|
|
|
@ -33,7 +33,7 @@ protected:
|
|||
virtual bool isHmdMounted() const = 0;
|
||||
virtual void postPreview() {};
|
||||
|
||||
void internalActivate() override;
|
||||
bool internalActivate() override;
|
||||
void compositeOverlay() override;
|
||||
void compositePointer() override;
|
||||
void internalPresent() override;
|
||||
|
|
|
@ -58,7 +58,7 @@ glm::mat4 StereoDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr
|
|||
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
||||
|
||||
std::vector<QAction*> _screenActions;
|
||||
void StereoDisplayPlugin::internalActivate() {
|
||||
bool StereoDisplayPlugin::internalActivate() {
|
||||
auto screens = qApp->screens();
|
||||
_screenActions.resize(screens.size());
|
||||
for (int i = 0; i < screens.size(); ++i) {
|
||||
|
@ -77,7 +77,8 @@ void StereoDisplayPlugin::internalActivate() {
|
|||
|
||||
_screen = qApp->primaryScreen();
|
||||
_container->setFullscreen(_screen);
|
||||
Parent::internalActivate();
|
||||
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::updateScreen() {
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
// virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
|
||||
|
||||
protected:
|
||||
virtual void internalActivate() override;
|
||||
virtual bool internalActivate() override;
|
||||
virtual void internalDeactivate() override;
|
||||
void updateScreen();
|
||||
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
#include "PluginContainer.h"
|
||||
|
||||
void DisplayPlugin::activate() {
|
||||
Parent::activate();
|
||||
bool DisplayPlugin::activate() {
|
||||
if (isHmd() && (getHmdScreen() >= 0)) {
|
||||
_container->showDisplayPluginsTools();
|
||||
}
|
||||
return Parent::activate();
|
||||
}
|
||||
|
||||
void DisplayPlugin::deactivate() {
|
||||
|
|
|
@ -59,7 +59,7 @@ class DisplayPlugin : public Plugin {
|
|||
Q_OBJECT
|
||||
using Parent = Plugin;
|
||||
public:
|
||||
void activate() override;
|
||||
bool activate() override;
|
||||
void deactivate() override;
|
||||
virtual bool isHmd() const { return false; }
|
||||
virtual int getHmdScreen() const { return -1; }
|
||||
|
|
|
@ -38,8 +38,10 @@ public:
|
|||
virtual void deinit();
|
||||
|
||||
/// Called when a plugin is being activated for use. May be called multiple times.
|
||||
virtual void activate() {
|
||||
/// Returns true if plugin was successfully activated.
|
||||
virtual bool activate() {
|
||||
_active = true;
|
||||
return _active;
|
||||
}
|
||||
|
||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||
|
|
|
@ -451,10 +451,10 @@ bool NeuronPlugin::isSupported() const {
|
|||
#endif
|
||||
}
|
||||
|
||||
void NeuronPlugin::activate() {
|
||||
#ifdef HAVE_NEURON
|
||||
bool NeuronPlugin::activate() {
|
||||
InputPlugin::activate();
|
||||
|
||||
#ifdef HAVE_NEURON
|
||||
// register with userInputMapper
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
userInputMapper->registerDevice(_inputDevice);
|
||||
|
@ -473,11 +473,15 @@ void NeuronPlugin::activate() {
|
|||
if (!_socketRef) {
|
||||
// error
|
||||
qCCritical(inputplugins) << "NeuronPlugin: error connecting to " << _serverAddress.c_str() << ":" << _serverPort << ", error = " << BRGetLastErrorMessage();
|
||||
return false;
|
||||
} else {
|
||||
qCDebug(inputplugins) << "NeuronPlugin: success connecting to " << _serverAddress.c_str() << ":" << _serverPort;
|
||||
|
||||
BRRegisterAutoSyncParmeter(_socketRef, Cmd_CombinationMode);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
virtual const QString& getName() const override { return NAME; }
|
||||
const QString& getID() const override { return NEURON_ID_STRING; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual bool activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
|
|
|
@ -99,15 +99,19 @@ void SDL2Manager::deinit() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void SDL2Manager::activate() {
|
||||
bool SDL2Manager::activate() {
|
||||
InputPlugin::activate();
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
for (auto joystick : _openJoysticks) {
|
||||
userInputMapper->registerDevice(joystick);
|
||||
emit joystickAdded(joystick.get());
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
InputPlugin::activate();
|
||||
}
|
||||
|
||||
void SDL2Manager::deactivate() {
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
virtual void deinit() override;
|
||||
|
||||
/// Called when a plugin is being activated for use. May be called multiple times.
|
||||
virtual void activate() override;
|
||||
virtual bool activate() override;
|
||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||
virtual void deactivate() override;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ bool SixenseManager::isSupported() const {
|
|||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::activate() {
|
||||
bool SixenseManager::activate() {
|
||||
InputPlugin::activate();
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
@ -101,6 +101,9 @@ void SixenseManager::activate() {
|
|||
|
||||
loadSettings();
|
||||
_sixenseLoaded = (sixenseInit() == SIXENSE_SUCCESS);
|
||||
return _sixenseLoaded;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual const QString& getID() const override { return HYDRA_ID_STRING; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual bool activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
|
|
|
@ -34,8 +34,11 @@ void OculusBaseDisplayPlugin::customizeContext() {
|
|||
Parent::customizeContext();
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::internalActivate() {
|
||||
bool OculusBaseDisplayPlugin::internalActivate() {
|
||||
_session = acquireOculusSession();
|
||||
if (!_session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_hmdDesc = ovr_GetHmdDesc(_session);
|
||||
|
||||
|
@ -65,7 +68,7 @@ void OculusBaseDisplayPlugin::internalActivate() {
|
|||
|
||||
if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
|
||||
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
||||
qWarning() << "Could not attach to sensor device";
|
||||
logWarning("Failed to attach to sensor device");
|
||||
}
|
||||
|
||||
// Parent class relies on our _session intialization, so it must come after that.
|
||||
|
@ -81,7 +84,7 @@ void OculusBaseDisplayPlugin::internalActivate() {
|
|||
// This must come after the initialization, so that the values calculated
|
||||
// above are available during the customizeContext call (when not running
|
||||
// in threaded present mode)
|
||||
Parent::internalActivate();
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::internalDeactivate() {
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
|
||||
protected:
|
||||
void customizeContext() override;
|
||||
void internalActivate() override;
|
||||
bool internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -67,7 +67,7 @@ void OculusDisplayPlugin::hmdPresent() {
|
|||
ovrLayerHeader* layers = &_sceneLayer.Header;
|
||||
ovrResult result = ovr_SubmitFrame(_session, _currentRenderFrameIndex, &_viewScaleDesc, &layers, 1);
|
||||
if (!OVR_SUCCESS(result)) {
|
||||
qDebug() << result;
|
||||
logWarning("Failed to present");
|
||||
}
|
||||
}
|
||||
_sceneFbo->Increment();
|
||||
|
|
|
@ -10,16 +10,34 @@
|
|||
|
||||
#include <atomic>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
using Mutex = std::mutex;
|
||||
using Lock = std::unique_lock<Mutex>;
|
||||
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(oculus)
|
||||
Q_LOGGING_CATEGORY(oculus, "hifi.plugins.oculus")
|
||||
|
||||
static std::atomic<uint32_t> refCount { 0 };
|
||||
static ovrSession session { nullptr };
|
||||
|
||||
inline ovrErrorInfo getError() {
|
||||
ovrErrorInfo error;
|
||||
ovr_GetLastErrorInfo(&error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void logWarning(const char* what) {
|
||||
qWarning(oculus) << what << ":" << getError().ErrorString;
|
||||
}
|
||||
|
||||
void logFatal(const char* what) {
|
||||
std::string error("[oculus] ");
|
||||
error += what;
|
||||
error += ": ";
|
||||
error += getError().ErrorString;
|
||||
qFatal(error.c_str());
|
||||
}
|
||||
|
||||
bool oculusAvailable() {
|
||||
ovrDetectResult detect = ovr_Detect(0);
|
||||
return (detect.IsOculusServiceRunning && detect.IsOculusHMDConnected);
|
||||
|
@ -37,14 +55,14 @@ ovrSession acquireOculusSession() {
|
|||
init.ConnectionTimeoutMS = 0;
|
||||
init.LogCallback = nullptr;
|
||||
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
||||
qCWarning(oculus) << "Failed to initialize Oculus SDK";
|
||||
logWarning("Failed to initialize Oculus SDK");
|
||||
return session;
|
||||
}
|
||||
|
||||
Q_ASSERT(0 == refCount);
|
||||
ovrGraphicsLuid luid;
|
||||
if (!OVR_SUCCESS(ovr_Create(&session, &luid))) {
|
||||
qCWarning(oculus) << "Failed to acquire Oculus session";
|
||||
logWarning("Failed to acquire Oculus session");
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +123,7 @@ void SwapFramebufferWrapper::initColor() {
|
|||
destroyColor();
|
||||
|
||||
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(_session, GL_SRGB8_ALPHA8, size.x, size.y, &color))) {
|
||||
qFatal("Unable to create swap textures");
|
||||
logFatal("Failed to create swap textures");
|
||||
}
|
||||
|
||||
for (int i = 0; i < color->TextureCount; ++i) {
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include <gl/OglplusHelpers.h>
|
||||
|
||||
void logWarning(const char* what);
|
||||
void logFatal(const char* what);
|
||||
bool oculusAvailable();
|
||||
ovrSession acquireOculusSession();
|
||||
void releaseOculusSession();
|
||||
|
|
|
@ -68,18 +68,20 @@ bool OculusLegacyDisplayPlugin::isSupported() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void OculusLegacyDisplayPlugin::internalActivate() {
|
||||
bool OculusLegacyDisplayPlugin::internalActivate() {
|
||||
Parent::internalActivate();
|
||||
|
||||
if (!(ovr_Initialize(nullptr))) {
|
||||
Q_ASSERT(false);
|
||||
qFatal("Failed to Initialize SDK");
|
||||
return false;
|
||||
}
|
||||
|
||||
_hswDismissed = false;
|
||||
_hmd = ovrHmd_Create(0);
|
||||
if (!_hmd) {
|
||||
qFatal("Failed to acquire HMD");
|
||||
return false;
|
||||
}
|
||||
|
||||
_ipd = ovrHmd_GetFloat(_hmd, OVR_KEY_IPD, _ipd);
|
||||
|
@ -107,6 +109,8 @@ void OculusLegacyDisplayPlugin::internalActivate() {
|
|||
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0)) {
|
||||
qFatal("Could not attach to sensor device");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OculusLegacyDisplayPlugin::internalDeactivate() {
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
virtual float getTargetFrameRate() override;
|
||||
|
||||
protected:
|
||||
virtual void internalActivate() override;
|
||||
virtual bool internalActivate() override;
|
||||
virtual void internalDeactivate() override;
|
||||
|
||||
virtual void customizeContext() override;
|
||||
|
|
|
@ -41,14 +41,18 @@ bool OpenVrDisplayPlugin::isSupported() const {
|
|||
return !isOculusPresent() && vr::VR_IsHmdPresent();
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::internalActivate() {
|
||||
bool OpenVrDisplayPlugin::internalActivate() {
|
||||
Parent::internalActivate();
|
||||
|
||||
_container->setIsOptionChecked(StandingHMDSensorMode, true);
|
||||
|
||||
if (!_system) {
|
||||
_system = acquireOpenVrSystem();
|
||||
}
|
||||
Q_ASSERT(_system);
|
||||
if (!_system) {
|
||||
qWarning() << "Failed to initialize OpenVR";
|
||||
return false;
|
||||
}
|
||||
|
||||
_system->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
|
||||
// Recommended render target size is per-eye, so double the X size for
|
||||
|
@ -86,6 +90,8 @@ void OpenVrDisplayPlugin::internalActivate() {
|
|||
} else {
|
||||
qDebug() << "OpenVR: error could not get chaperone pointer";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::internalDeactivate() {
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
virtual void updateHeadPose(uint32_t frameIndex) override;
|
||||
|
||||
protected:
|
||||
void internalActivate() override;
|
||||
bool internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
||||
void hmdPresent() override;
|
||||
|
|
|
@ -53,8 +53,9 @@ bool ViveControllerManager::isSupported() const {
|
|||
return !isOculusPresent() && vr::VR_IsHmdPresent();
|
||||
}
|
||||
|
||||
void ViveControllerManager::activate() {
|
||||
bool ViveControllerManager::activate() {
|
||||
InputPlugin::activate();
|
||||
|
||||
_container->addMenu(MENU_PATH);
|
||||
_container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS,
|
||||
[this] (bool clicked) { this->setRenderControllers(clicked); },
|
||||
|
@ -122,6 +123,8 @@ void ViveControllerManager::activate() {
|
|||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
userInputMapper->registerDevice(_inputDevice);
|
||||
_registeredWithInputMapper = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViveControllerManager::deactivate() {
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
virtual bool isJointController() const override { return true; }
|
||||
const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual bool activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||
|
@ -111,8 +111,6 @@ private:
|
|||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>(_system) };
|
||||
|
||||
static const QString NAME;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi__ViveControllerManager
|
||||
|
|
Loading…
Reference in a new issue