From 0680be0422d1d30548448ecb9407a9167967513b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:25:05 -0700 Subject: [PATCH] save sixense settings and some UI cleanup --- interface/src/Application.cpp | 1 + interface/src/ui/PreferencesDialog.cpp | 5 -- interface/ui/preferencesDialog.ui | 34 -------- .../src/input-plugins/InputPlugin.cpp | 6 ++ .../src/input-plugins/SixenseManager.cpp | 47 ++++++++--- .../src/input-plugins/SixenseManager.h | 19 ++--- libraries/plugins/src/plugins/Plugin.cpp | 2 + libraries/plugins/src/plugins/Plugin.h | 12 +++ .../plugins/src/plugins/PluginManager.cpp | 6 ++ libraries/plugins/src/plugins/PluginManager.h | 1 + libraries/shared/src/SettingHandle.cpp | 83 +++++++++++++++++++ libraries/shared/src/SettingHandle.h | 15 +++- 12 files changed, 168 insertions(+), 63 deletions(-) create mode 100644 libraries/shared/src/SettingHandle.cpp diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 70cc189ad6..5f61c6d978 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2351,6 +2351,7 @@ void Application::saveSettings() { Menu::getInstance()->saveSettings(); getMyAvatar()->saveData(); + PluginManager::getInstance()->saveSettings(); } bool Application::importEntities(const QString& urlOrFilename) { diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index f90bac234d..4ba248c76c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -200,9 +200,6 @@ void PreferencesDialog::loadPreferences() { ui.sixenseReticleMoveSpeedSpin->setValue(InputDevice::getReticleMoveSpeed()); - SixenseManager& sixense = SixenseManager::getInstance(); - ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons()); - // LOD items auto lodManager = DependencyManager::get(); ui.desktopMinimumFPSSpin->setValue(lodManager->getDesktopLODDecreaseFPS()); @@ -276,9 +273,7 @@ void PreferencesDialog::savePreferences() { qApp->getApplicationCompositor().setHmdUIAngularSize(ui.oculusUIAngularSizeSpin->value()); - SixenseManager& sixense = SixenseManager::getInstance(); InputDevice::setReticleMoveSpeed(ui.sixenseReticleMoveSpeedSpin->value()); - sixense.setInvertButtons(ui.invertSixenseButtonsCheckBox->isChecked()); auto audio = DependencyManager::get(); MixedProcessedAudioStream& stream = audio->getReceivedAudioStream(); diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 53b71fb507..a1137a2bf2 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -2768,40 +2768,6 @@ - - - - 7 - - - 7 - - - - - - 0 - 40 - - - - - Arial - - - - Invert Mouse Buttons - - - - 0 - 0 - - - - - - diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp index ea1639ec66..227bd12e1b 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.cpp +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.cpp @@ -37,3 +37,9 @@ InputPluginList getInputPlugins() { } return result; } + +void saveInputPluginSettings(const InputPluginList& plugins) { + foreach (auto inputPlugin, plugins) { + inputPlugin->saveSettings(); + } +} diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index e900e8779e..bc64ec4ccc 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "NumericalConstants.h" @@ -38,7 +39,7 @@ const unsigned int RIGHT_MASK = 1U << 1; #ifdef HAVE_SIXENSE const int CALIBRATION_STATE_IDLE = 0; -const int CALIBRATION_STATE_X = 1; +const int CALIBRATION_STATE_IN_PROGRESS = 1; const int CALIBRATION_STATE_COMPLETE = 2; const glm::vec3 DEFAULT_AVATAR_POSITION(-0.25f, -0.35f, -0.3f); // in hydra frame @@ -56,25 +57,23 @@ typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData #endif const QString SixenseManager::NAME = "Sixense"; +const QString SixenseManager::HYDRA_ID_STRING = "Razer Hydra"; const QString MENU_PARENT = "Avatar"; const QString MENU_NAME = "Sixense"; const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; const QString TOGGLE_SMOOTH = "Smooth Sixense Movement"; +const float DEFAULT_REACH_LENGTH = 1.5f; -SixenseManager& SixenseManager::getInstance() { - static SixenseManager sharedInstance; - return sharedInstance; -} SixenseManager::SixenseManager() : InputDevice("Hydra"), #ifdef __APPLE__ _sixenseLibrary(NULL), #endif + _reachLength(DEFAULT_REACH_LENGTH), _hydrasConnected(false) { - } bool SixenseManager::isSupported() const { @@ -92,7 +91,7 @@ void SixenseManager::activate() { CONTAINER->addMenu(MENU_PATH); CONTAINER->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, - [this] (bool clicked) { this->setFilter(clicked); }, + [this] (bool clicked) { this->setSixenseFilter(clicked); }, true, true); #ifdef __APPLE__ @@ -120,6 +119,7 @@ void SixenseManager::activate() { SixenseBaseFunction sixenseInit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseInit"); #endif + loadSettings(); sixenseInit(); #endif } @@ -144,7 +144,7 @@ void SixenseManager::deactivate() { #endif } -void SixenseManager::setFilter(bool filter) { +void SixenseManager::setSixenseFilter(bool filter) { #ifdef HAVE_SIXENSE #ifdef __APPLE__ SixenseTakeIntFunction sixenseSetFilterEnabled = (SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseSetFilterEnabled"); @@ -282,6 +282,7 @@ void SixenseManager::updateCalibration(void* controllersX) { glm::vec3 xAxis = glm::normalize(_reachRight - _reachLeft); glm::vec3 zAxis = glm::normalize(glm::cross(xAxis, Vectors::UNIT_Y)); xAxis = glm::normalize(glm::cross(Vectors::UNIT_Y, zAxis)); + _reachLength = glm::dot(xAxis, _reachRight - _reachLeft); _avatarRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, Vectors::UNIT_Y, zAxis))); const float Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR = -0.3f; _avatarPosition.y += Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR; @@ -317,7 +318,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _lastDistance = reach; _lockExpiry = usecTimestampNow() + LOCK_DURATION; // move to next state - _calibrationState = CALIBRATION_STATE_X; + _calibrationState = CALIBRATION_STATE_IN_PROGRESS; } return; } @@ -327,7 +328,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _averageLeft = 0.9f * _averageLeft + 0.1f * positionLeft; _averageRight = 0.9f * _averageRight + 0.1f * positionRight; - if (_calibrationState == CALIBRATION_STATE_X) { + if (_calibrationState == CALIBRATION_STATE_IN_PROGRESS) { // compute new sliding average float distance = glm::distance(_averageLeft, _averageRight); if (fabsf(distance - _lastDistance) > MAXIMUM_NOISE_LEVEL) { @@ -340,7 +341,6 @@ void SixenseManager::updateCalibration(void* controllersX) { // lock has expired so clamp the data and move on _lockExpiry = now + LOCK_DURATION; _lastDistance = 0.0f; - _reachUp = 0.5f * (_reachLeft + _reachRight); _calibrationState = CALIBRATION_STATE_COMPLETE; qCDebug(inputplugins, "success: sixense calibration: left"); } @@ -543,6 +543,31 @@ void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { } +// virtual +void SixenseManager::saveSettings() const { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + settings.setVec3Value(QString("avatarPosition"), _avatarPosition); + settings.setQuatValue(QString("avatarRotation"), _avatarRotation); + settings.setValue(QString("reachLength"), QVariant(_reachLength)); + } + settings.endGroup(); +} + +void SixenseManager::loadSettings() { + Settings settings; + QString idString = getID(); + settings.beginGroup(idString); + { + settings.getVec3ValueIfValid(QString("avatarPosition"), _avatarPosition); + settings.getQuatValueIfValid(QString("avatarRotation"), _avatarRotation); + settings.getFloatValueIfValid(QString("reachLength"), _reachLength); + } + settings.endGroup(); +} + UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) { return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON); } diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.h b/libraries/input-plugins/src/input-plugins/SixenseManager.h index 5e3815cd20..9fa7f84a86 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.h +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.h @@ -58,12 +58,11 @@ public: SixenseManager(); - static SixenseManager& getInstance(); - // Plugin functions virtual bool isSupported() const override; virtual bool isJointController() const override { return true; } const QString& getName() const override { return NAME; } + const QString& getID() const override { return HYDRA_ID_STRING; } virtual void activate() override; virtual void deactivate() override; @@ -77,15 +76,15 @@ public: virtual void update(float deltaTime, bool jointsCaptured) override; virtual void focusOutEvent() override; - bool getInvertButtons() const { return _invertButtons; } - void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; } - UserInputMapper::Input makeInput(unsigned int button, int index); UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index); UserInputMapper::Input makeInput(JointChannel joint); + virtual void saveSettings() const override; + virtual void loadSettings() override; + public slots: - void setFilter(bool filter); + void setSixenseFilter(bool filter); private: void handleButtonEvent(unsigned int buttons, int index); @@ -99,7 +98,7 @@ private: // these are calibration results glm::vec3 _avatarPosition; // in hydra-frame glm::quat _avatarRotation; // in hydra-frame - float _armLength; + float _reachLength; // these are measured values used to compute the calibration results quint64 _lockExpiry; @@ -107,9 +106,8 @@ private: glm::vec3 _averageRight; glm::vec3 _reachLeft; glm::vec3 _reachRight; - glm::vec3 _reachUp; - glm::vec3 _reachForward; float _lastDistance; + bool _useSixenseFilter = true; #ifdef __APPLE__ QLibrary* _sixenseLibrary; @@ -117,9 +115,8 @@ private: bool _hydrasConnected; - bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS; - static const QString NAME; + static const QString HYDRA_ID_STRING; }; #endif // hifi_SixenseManager_h diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index ffcc682ebd..2c0b9fa5cf 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -9,6 +9,8 @@ PluginContainer* Plugin::CONTAINER{ nullptr }; +QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); + void Plugin::setContainer(PluginContainer* container) { CONTAINER = container; } diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index eac355b47d..68e012b8e1 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -7,6 +7,8 @@ // #pragma once +#include + #include #include @@ -14,7 +16,12 @@ class Plugin : public QObject { public: + /// \return human-readable name virtual const QString& getName() const = 0; + + /// \return string ID (not necessarily human-readable) + virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } + virtual bool isSupported() const; static void setContainer(PluginContainer* container); @@ -37,6 +44,11 @@ public: */ virtual void idle(); + virtual void saveSettings() const {} + virtual void loadSettings() {} + protected: static PluginContainer* CONTAINER; + static QString UNKNOWN_PLUGIN_ID; + }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 3a71700c9e..2deb41fb13 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -8,6 +8,8 @@ #include "PluginManager.h" #include +#include "Forward.h" + PluginManager* PluginManager::getInstance() { static PluginManager _manager; return &_manager; @@ -16,6 +18,7 @@ PluginManager* PluginManager::getInstance() { // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); +extern void saveInputPluginSettings(const InputPluginList& plugins); const DisplayPluginList& PluginManager::getDisplayPlugins() { static DisplayPluginList displayPlugins; @@ -35,3 +38,6 @@ const InputPluginList& PluginManager::getInputPlugins() { return inputPlugins; } +void PluginManager::saveSettings() { + saveInputPluginSettings(getInputPlugins()); +} diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index b7ec453814..09dcc9d107 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -15,4 +15,5 @@ public: const DisplayPluginList& getDisplayPlugins(); const InputPluginList& getInputPlugins(); + void saveSettings(); }; diff --git a/libraries/shared/src/SettingHandle.cpp b/libraries/shared/src/SettingHandle.cpp new file mode 100644 index 0000000000..19239b3cf7 --- /dev/null +++ b/libraries/shared/src/SettingHandle.cpp @@ -0,0 +1,83 @@ +// +// SettingHandle.h +// +// +// Created by AndrewMeadows 2015.10.05 +// 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 +// + +#include "SettingHandle.h" + +#include + + +void Settings::getFloatValueIfValid(const QString& name, float& f) { + const QVariant badDefaultValue = NAN; + bool ok = true; + float tempFloat = value(name, badDefaultValue).toFloat(&ok); + if (ok && !isnan(tempFloat)) { + f = tempFloat; + } +} + +void Settings::getBoolValue(const QString& name, bool& b) { + const QVariant defaultValue = false; + b = value(name, defaultValue).toBool(); +} + + +void Settings::setVec3Value(const QString& name, const glm::vec3& v) { + beginGroup(name); + { + setValue(QString("x"), v.x); + setValue(QString("y"), v.y); + setValue(QString("z"), v.z); + } + endGroup(); +} + +void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { + beginGroup(name); + { + bool ok = true; + const QVariant badDefaultValue = NAN; + float x = value(QString("x"), badDefaultValue).toFloat(&ok); + float y = value(QString("y"), badDefaultValue).toFloat(&ok); + float z = value(QString("z"), badDefaultValue).toFloat(&ok); + if (ok && (!isnan(x) && !isnan(y) && !isnan(z))) { + v = glm::vec3(x, y, z); + } + } + endGroup(); +} + +void Settings::setQuatValue(const QString& name, const glm::quat& q) { + beginGroup(name); + { + setValue(QString("x"), q.x); + setValue(QString("y"), q.y); + setValue(QString("z"), q.z); + setValue(QString("w"), q.w); + } + endGroup(); +} + +void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { + beginGroup(name); + { + bool ok = true; + const QVariant badDefaultValue = NAN; + float x = value(QString("x"), badDefaultValue).toFloat(&ok); + float y = value(QString("y"), badDefaultValue).toFloat(&ok); + float z = value(QString("z"), badDefaultValue).toFloat(&ok); + float w = value(QString("w"), badDefaultValue).toFloat(&ok); + if (ok && (!isnan(x) && !isnan(y) && !isnan(z) && !isnan(w))) { + q = glm::quat(w, x, y, z); + } + } + endGroup(); +} + diff --git a/libraries/shared/src/SettingHandle.h b/libraries/shared/src/SettingHandle.h index 761e41d321..b86422bcfb 100644 --- a/libraries/shared/src/SettingHandle.h +++ b/libraries/shared/src/SettingHandle.h @@ -18,11 +18,22 @@ #include #include +#include +#include + #include "SettingInterface.h" // TODO: remove class Settings : public QSettings { - +public: + void getFloatValueIfValid(const QString& name, float& f); + void getBoolValue(const QString& name, bool& b); + + void setVec3Value(const QString& name, const glm::vec3& v); + void getVec3ValueIfValid(const QString& name, glm::vec3& v); + + void setQuatValue(const QString& name, const glm::quat& q); + void getQuatValueIfValid(const QString& name, glm::quat& q); }; namespace Setting { @@ -65,4 +76,4 @@ namespace Setting { } } -#endif // hifi_SettingHandle_h \ No newline at end of file +#endif // hifi_SettingHandle_h