From 8befade007bd18c47db4ee3487e6828fe6f0bd88 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sun, 4 Oct 2015 15:08:35 +0200 Subject: [PATCH 01/17] expose position and orientation of HMD to Javascript. - HMD.orientation - HMD.position --- interface/src/scripting/HMDScriptingInterface.cpp | 14 ++++++++++++++ interface/src/scripting/HMDScriptingInterface.h | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 68ac511eaf..4629ff5917 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -57,3 +57,17 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* conte float HMDScriptingInterface::getIPD() const { return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); } + +glm::vec3 HMDScriptingInterface::getPosition() const { + if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + return glm::vec3(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()[3]); + } + return glm::vec3(); +} + +glm::quat HMDScriptingInterface::getOrientation() const { + if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + return glm::quat_cast(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()); + } + return glm::quat(); +} diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 82b444abaa..1ac524d7f1 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -20,6 +20,8 @@ class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) + Q_PROPERTY(glm::vec3 position READ getPosition) + Q_PROPERTY(glm::quat orientation READ getOrientation) Q_PROPERTY(float ipd READ getIPD) public: static HMDScriptingInterface& getInstance(); @@ -36,6 +38,12 @@ private: bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } float getIPD() const; + // Get the position of the HMD + glm::vec3 getPosition() const; + + // Get the orientation of the HMD + glm::quat getOrientation() const; + bool getHUDLookAtPosition3D(glm::vec3& result) const; }; From 3c6e9378c39ab0dc5cefa3528c96eef9eaac169a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 6 Oct 2015 20:20:37 +0200 Subject: [PATCH 02/17] fixes merge issues --- interface/src/Application.cpp | 4 ++-- libraries/octree/src/OctreeHeadlessViewer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 565debfbaf..b25f3aa6a5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4981,7 +4981,7 @@ mat4 Application::getEyeProjection(int eye) const { mat4 Application::getEyePose(int eye) const { if (isHMDMode()) { return getActiveDisplayPlugin()->getEyePose((Eye)eye); - } + } return mat4(); } @@ -4990,7 +4990,7 @@ mat4 Application::getEyeOffset(int eye) const { if (isHMDMode()) { mat4 identity; return getActiveDisplayPlugin()->getView((Eye)eye, identity); -} + } return mat4(); } diff --git a/libraries/octree/src/OctreeHeadlessViewer.h b/libraries/octree/src/OctreeHeadlessViewer.h index 009fcb5cb2..605db15cd2 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.h +++ b/libraries/octree/src/OctreeHeadlessViewer.h @@ -53,8 +53,8 @@ public slots: void setMaxPacketsPerSecond(int maxPacketsPerSecond) { _maxPacketsPerSecond = maxPacketsPerSecond; } // getters for camera attributes - const glm::vec3 getPosition() const { return _viewFrustum.getPosition(); } - const glm::quat getOrientation() const { return _viewFrustum.getOrientation(); } + const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); } + const glm::quat& getOrientation() const { return _viewFrustum.getOrientation(); } // getters for LOD and PPS float getVoxelSizeScale() const { return _voxelSizeScale; } From 4e8fc08458b32c396a2eb49b4ca8f6124f5a1025 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 6 Oct 2015 20:48:51 +0200 Subject: [PATCH 03/17] made the changes as suggested by @hyperlogic --- interface/src/scripting/HMDScriptingInterface.cpp | 9 +++++++-- interface/src/scripting/HMDScriptingInterface.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 4629ff5917..ca25f5f72a 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -58,16 +58,21 @@ float HMDScriptingInterface::getIPD() const { return Application::getInstance()->getActiveDisplayPlugin()->getIPD(); } +glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + return myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); +} + glm::vec3 HMDScriptingInterface::getPosition() const { if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { - return glm::vec3(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()[3]); + return extractTranslation(getWorldHMDMatrix()); } return glm::vec3(); } glm::quat HMDScriptingInterface::getOrientation() const { if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { - return glm::quat_cast(Application::getInstance()->getActiveDisplayPlugin()->getHeadPose()); + return glm::normalize(glm::quat_cast(getWorldHMDMatrix())); } return glm::quat(); } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 50944ab695..ac2ab0149e 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -46,6 +46,7 @@ private: bool getHUDLookAtPosition3D(glm::vec3& result) const; + glm::mat4 getWorldHMDMatrix() const; }; #endif // hifi_HMDScriptingInterface_h From 6e5847bb1c773c7f790a90b3bd65b9b6cbab04e5 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 6 Oct 2015 19:58:25 -0700 Subject: [PATCH 04/17] make Hand Input Mouse off by default --- interface/src/Application.cpp | 2 +- interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 2 +- interface/src/ui/ApplicationCompositor.cpp | 7 ++++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b44ac6804d..3ac667f7b4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2745,7 +2745,7 @@ void Application::update(float deltaTime) { Hand* hand = DependencyManager::get()->getMyAvatar()->getHand(); setPalmData(hand, leftHand, deltaTime, LEFT_HAND_INDEX, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK)); setPalmData(hand, rightHand, deltaTime, RIGHT_HAND_INDEX, userInputMapper->getActionState(UserInputMapper::RIGHT_HAND_CLICK)); - if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK), userInputMapper->getActionState(UserInputMapper::SHIFT), LEFT_HAND_INDEX); emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::RIGHT_HAND_CLICK), diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9abfd1e34c..ae41ca2493 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -464,7 +464,7 @@ Menu::Menu() { MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandMouseInput, 0, true); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true, qApp, SLOT(setLowVelocityFilter(bool))); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 33ce659a51..4c9c3ef7b5 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -204,7 +204,7 @@ namespace MenuOption { const QString FrameTimer = "Show Timer"; const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowWhenSpeaking = "Glow When Speaking"; - const QString HandMouseInput = "Enable Hand Mouse Input"; + const QString EnableHandMouseInput = "Enable Hand Controller Mouse Input"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString InputMenu = "Avatar>Input Devices"; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index cb4ae9990c..7a90e30e53 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -313,8 +313,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int glm::mat4 overlayXfm; _modelTransform.getMatrix(overlayXfm); - // Only render the hand pointers if the HandMouseInput is enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + // Only render the hand pointers if the EnableHandMouseInput is enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) { PalmData& palm = myAvatar->getHand()->getPalms()[i]; @@ -435,7 +435,8 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) { _magActive[MOUSE] = _magnifier; _reticleActive[LEFT_CONTROLLER] = false; _reticleActive[RIGHT_CONTROLLER] = false; - } else if (qApp->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) { + } else if (qApp->getLastMouseMoveWasSimulated() + && Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { //only render controller pointer if we aren't already rendering a mouse pointer _reticleActive[MOUSE] = false; _magActive[MOUSE] = false; From ad5a6fac626b1c6d5a119842c7c8c622687ce340 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Oct 2015 15:10:40 +0200 Subject: [PATCH 05/17] - applying of new qApp accessing method. - Some magic constant replacements with Helper "glm::vec3(matrix[3])" -> "extractTranslation(matrix)" --- interface/src/avatar/MyAvatar.cpp | 6 +++--- interface/src/scripting/HMDScriptingInterface.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7592aad061..7baa6cf66f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1345,11 +1345,11 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl glm::mat4 headPose = qApp->getActiveDisplayPlugin()->getHeadPose(); glm::mat4 leftEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Left); leftEyePose = leftEyePose * headPose; - glm::vec3 leftEyePosition = glm::vec3(leftEyePose[3]); + glm::vec3 leftEyePosition = extractTranslation(leftEyePose); glm::mat4 rightEyePose = qApp->getActiveDisplayPlugin()->getEyeToHeadTransform(Eye::Right); rightEyePose = rightEyePose * headPose; - glm::vec3 rightEyePosition = glm::vec3(rightEyePose[3]); - glm::vec3 headPosition = glm::vec3(headPose[3]); + glm::vec3 rightEyePosition = extractTranslation(rightEyePose); + glm::vec3 headPosition = extractTranslation(headPose); getHead()->renderLookAts(renderArgs, cameraPosition + getOrientation() * (leftEyePosition - headPosition), diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index f8a0ba7ed6..28d358fa39 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -70,14 +70,14 @@ glm::mat4 HMDScriptingInterface::getWorldHMDMatrix() const { } glm::vec3 HMDScriptingInterface::getPosition() const { - if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + if (qApp->getActiveDisplayPlugin()->isHmd()) { return extractTranslation(getWorldHMDMatrix()); } return glm::vec3(); } glm::quat HMDScriptingInterface::getOrientation() const { - if (Application::getInstance()->getActiveDisplayPlugin()->isHmd()) { + if (qApp->getActiveDisplayPlugin()->isHmd()) { return glm::normalize(glm::quat_cast(getWorldHMDMatrix())); } return glm::quat(); From 6c2a94fddb1be1cde5885c3c0c8dcfa1b540ab85 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:23:53 -0700 Subject: [PATCH 06/17] remove unused method declarations --- libraries/animation/src/Rig.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index ef802e925d..6d9f7b4688 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -132,7 +132,6 @@ public: bool getJointStateTranslation(int index, glm::vec3& translation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, float priority); JointState getJointState(int jointIndex) const; // XXX - bool getVisibleJointState(int index, glm::quat& rotation) const; void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); @@ -154,9 +153,6 @@ public: bool getJointRotation(int jointIndex, glm::quat& rotation) const; bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; - bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position, - glm::vec3 translation, glm::quat rotation) const; - bool getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result, glm::quat rotation) const; glm::mat4 getJointTransform(int jointIndex) const; glm::mat4 getJointVisibleTransform(int jointIndex) const; void setJointVisibleTransform(int jointIndex, glm::mat4 newTransform); @@ -179,7 +175,6 @@ public: float priority, float mix = 1.0f); bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const; glm::quat getJointDefaultRotationInParentFrame(int jointIndex); - void updateVisibleJointStates(); void clearJointStatePriorities(); virtual void updateJointState(int index, glm::mat4 rootTransform) = 0; From 76264ae704ab962fbc40875370e83fc252ce02a9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:24:27 -0700 Subject: [PATCH 07/17] fix formatting --- libraries/physics/src/DynamicCharacterController.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/libraries/physics/src/DynamicCharacterController.cpp index 163cba6aae..604326168c 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/libraries/physics/src/DynamicCharacterController.cpp @@ -35,9 +35,8 @@ public: if (rayResult.m_collisionObject == _me) { return 1.0f; } - return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace - ); -} + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); + } protected: btRigidBody* _me; }; From 0680be0422d1d30548448ecb9407a9167967513b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 5 Oct 2015 23:25:05 -0700 Subject: [PATCH 08/17] 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 From 464ef2293da0694216ce622b17b3c8cb354bd97d Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Oct 2015 10:52:47 -0700 Subject: [PATCH 09/17] more descriptive variable names --- libraries/shared/src/SettingHandle.cpp | 34 +++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/libraries/shared/src/SettingHandle.cpp b/libraries/shared/src/SettingHandle.cpp index 19239b3cf7..4a2c0cf04b 100644 --- a/libraries/shared/src/SettingHandle.cpp +++ b/libraries/shared/src/SettingHandle.cpp @@ -14,32 +14,32 @@ #include -void Settings::getFloatValueIfValid(const QString& name, float& f) { +void Settings::getFloatValueIfValid(const QString& name, float& floatValue) { const QVariant badDefaultValue = NAN; bool ok = true; float tempFloat = value(name, badDefaultValue).toFloat(&ok); if (ok && !isnan(tempFloat)) { - f = tempFloat; + floatValue = tempFloat; } } -void Settings::getBoolValue(const QString& name, bool& b) { +void Settings::getBoolValue(const QString& name, bool& boolValue) { const QVariant defaultValue = false; - b = value(name, defaultValue).toBool(); + boolValue = value(name, defaultValue).toBool(); } -void Settings::setVec3Value(const QString& name, const glm::vec3& v) { +void Settings::setVec3Value(const QString& name, const glm::vec3& vecValue) { beginGroup(name); { - setValue(QString("x"), v.x); - setValue(QString("y"), v.y); - setValue(QString("z"), v.z); + setValue(QString("x"), vecValue.x); + setValue(QString("y"), vecValue.y); + setValue(QString("z"), vecValue.z); } endGroup(); } -void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { +void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& vecValue) { beginGroup(name); { bool ok = true; @@ -48,24 +48,24 @@ void Settings::getVec3ValueIfValid(const QString& name, glm::vec3& v) { 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); + vecValue = glm::vec3(x, y, z); } } endGroup(); } -void Settings::setQuatValue(const QString& name, const glm::quat& q) { +void Settings::setQuatValue(const QString& name, const glm::quat& quatValue) { beginGroup(name); { - setValue(QString("x"), q.x); - setValue(QString("y"), q.y); - setValue(QString("z"), q.z); - setValue(QString("w"), q.w); + setValue(QString("x"), quatValue.x); + setValue(QString("y"), quatValue.y); + setValue(QString("z"), quatValue.z); + setValue(QString("w"), quatValue.w); } endGroup(); } -void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { +void Settings::getQuatValueIfValid(const QString& name, glm::quat& quatValue) { beginGroup(name); { bool ok = true; @@ -75,7 +75,7 @@ void Settings::getQuatValueIfValid(const QString& name, glm::quat& q) { 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); + quatValue = glm::quat(w, x, y, z); } } endGroup(); From 946d289a992f042c05ed5c32695cb6d45015df72 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 13:05:43 -0700 Subject: [PATCH 10/17] Display name have a arc size instead of pixel size --- interface/src/avatar/Avatar.cpp | 159 +++++++++++--------------------- interface/src/avatar/Avatar.h | 4 +- 2 files changed, 58 insertions(+), 105 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ddee5dfc1f..538d9fb4eb 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -549,7 +549,12 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto cameraMode = qApp->getCamera()->getMode(); if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { - renderDisplayName(batch, *renderArgs->_viewFrustum, renderArgs->_viewport); + auto& frustum = *renderArgs->_viewFrustum; + auto textPosition = getDisplayNamePosition(); + + if (frustum.pointInFrustum(textPosition)) { + renderDisplayName(batch, frustum, textPosition); + } } endRender(); } @@ -716,85 +721,29 @@ glm::vec3 Avatar::getDisplayNamePosition() const { return namePosition; } -Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const { - Transform result; - // We assume textPosition is whithin the frustum - glm::vec3 textPosition = getDisplayNamePosition(); - - // Compute viewProjection matrix - glm::mat4 projMat, viewMat; - Transform view; - frustum.evalProjectionMatrix(projMat); - frustum.evalViewTransform(view); - glm::mat4 viewProj = projMat * view.getInverseMatrix(viewMat); - - // Used to determine correct scale - glm::vec3 testPoint0 = textPosition; - glm::vec3 testPoint1 = testPoint0 + glm::normalize(frustum.getUp()); - // testPoints projections - glm::vec4 p0 = viewProj * glm::vec4(testPoint0, 1.0); - glm::vec4 p1 = viewProj * glm::vec4(testPoint1, 1.0); - - float windowSizeY = viewport.w; - - const float DESIRED_HIGHT_ON_SCREEN = 20; // In pixels (this is double on retinas) - - // Projected point are between -1.0f and 1.0f, hence 0.5f * windowSizeY - float pixelHeight = 0.5f * windowSizeY * glm::abs((p1.y / p1.w) - (p0.y / p0.w)); // - // Handles pixel density (especially for macs retina displays) - float devicePixelRatio = (float)qApp->getDevicePixelRatio() * qApp->getRenderResolutionScale(); // pixels / unit - - // Compute correct scale to apply - float scale = DESIRED_HIGHT_ON_SCREEN / (fontSize * pixelHeight) * devicePixelRatio; -#ifdef DEBUG - // TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed. - // Problem is probably due to an invalid getDisplayNamePosition(). See extra logging above. - if (scale == 0.0f || glm::isnan(scale) || glm::isinf(scale)) { - if (scale == 0.0f) { - qDebug() << "ASSERT because scale == 0.0f"; - } - if (glm::isnan(scale)) { - qDebug() << "ASSERT because isnan(scale)"; - } - if (glm::isinf(scale)) { - qDebug() << "ASSERT because isinf(scale)"; - } - qDebug() << "textPosition =" << textPosition; - qDebug() << "projMat =" << projMat; - qDebug() << "viewMat =" << viewMat; - qDebug() << "viewProj =" << viewProj; - qDebug() << "windowSizeY =" << windowSizeY; - qDebug() << "p1 =" << p1; - qDebug() << "p0 =" << p0; - qDebug() << "qApp->getDevicePixelRatio() =" << qApp->getDevicePixelRatio(); - qDebug() << "fontSize =" << fontSize; - qDebug() << "pixelHeight =" << pixelHeight; - qDebug() << "devicePixelRatio =" << devicePixelRatio; - } -#endif - - // Compute pixel alignment offset - float clipToPix = 0.5f * windowSizeY / p1.w; // Got from clip to pixel coordinates - glm::vec4 screenPos = clipToPix * p1; // in pixels coords - glm::vec4 screenOffset = (glm::round(screenPos) - screenPos) / clipToPix; // in clip coords - glm::vec3 worldOffset = glm::vec3(screenOffset.x, screenOffset.y, 0.0f) / (float)pixelHeight; +Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { + Q_ASSERT_X(frustum.pointInFrustum(textPosition), "Avatar::calculateDisplayNameTransform", + "Text not in viewfrustum."); + glm::vec3 dPosition = frustum.getPosition() - textPosition; // Compute orientation - glm::vec3 dPosition = frustum.getPosition() - getPosition(); - // If x and z are 0, atan(x, z) is undefined, so default to 0 degrees - float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z); + // If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees + const float yawRotation = (dPosition.x == 0.0f && dPosition.z == 0.0f) ? 0.0f : glm::atan(dPosition.x, dPosition.z); glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); - // Set transform (The order IS important) + // Compute correct scale to apply + static const float DESIRED_HIGHT_RAD = glm::radians(2.0f); + float scale = glm::length(dPosition) * glm::tan(DESIRED_HIGHT_RAD); + + // Set transform + Transform result; result.setTranslation(textPosition); result.setRotation(orientation); // Always face the screen - result.postTranslate(worldOffset); // Pixel alignment result.setScale(scale); return result; - } -void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const { +void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const { bool shouldShowReceiveStats = DependencyManager::get()->shouldShowReceiveStats() && !isMyAvatar(); // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return @@ -818,39 +767,43 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co } // Compute display name extent/position offset - glm::vec2 extent = renderer->computeExtent(renderedDisplayName); - QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y); - const int text_x = -nameDynamicRect.width() / 2; - const int text_y = -nameDynamicRect.height() / 2; - - // Compute background position/size - static const float SLIGHTLY_IN_FRONT = 0.1f; - const int border = 0.1f * nameDynamicRect.height(); - const int left = text_x - border; - const int bottom = text_y - border; - const int width = nameDynamicRect.width() + 2.0f * border; - const int height = nameDynamicRect.height() + 2.0f * border; - const int bevelDistance = 0.1f * height; - - // Display name and background colors - glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); - glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f, - (_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA); - - // Compute display name transform - auto textTransform = calculateDisplayNameTransform(frustum, renderer->getFontSize(), viewport); - batch.setModelTransform(textTransform); - - DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); - DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, - bevelDistance, backgroundColor); - // Render actual name - QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); - - // Render text slightly in front to avoid z-fighting - textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); - batch.setModelTransform(textTransform); - renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); + const glm::vec2 extent = renderer->computeExtent(renderedDisplayName); + if (!glm::any(glm::isCompNull(extent, EPSILON))) { + const QRect nameDynamicRect = QRect(0, 0, (int)extent.x, (int)extent.y); + const int text_x = -nameDynamicRect.width() / 2; + const int text_y = -nameDynamicRect.height() / 2; + + // Compute background position/size + static const float SLIGHTLY_IN_FRONT = 0.1f; + const int border = 0.1f * nameDynamicRect.height(); + const int left = text_x - border; + const int bottom = text_y - border; + const int width = nameDynamicRect.width() + 2.0f * border; + const int height = nameDynamicRect.height() + 2.0f * border; + const int bevelDistance = 0.1f * height; + + // Display name and background colors + glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); + glm::vec4 backgroundColor(0.2f, 0.2f, 0.2f, + (_displayNameAlpha / DISPLAYNAME_ALPHA) * DISPLAYNAME_BACKGROUND_ALPHA); + + // Compute display name transform + auto textTransform = calculateDisplayNameTransform(frustum, textPosition); + // Test on extent above insures abs(height) > 0.0f + textTransform.postScale(1.0f / height); + batch.setModelTransform(textTransform); + + DependencyManager::get()->bindSimpleProgram(batch, false, true, true, true); + DependencyManager::get()->renderBevelCornersRect(batch, left, bottom, width, height, + bevelDistance, backgroundColor); + // Render actual name + QByteArray nameUTF8 = renderedDisplayName.toLocal8Bit(); + + // Render text slightly in front to avoid z-fighting + textTransform.postTranslate(glm::vec3(0.0f, 0.0f, SLIGHTLY_IN_FRONT * renderer->getFontSize())); + batch.setModelTransform(textTransform); + renderer->draw(batch, text_x, -text_y, nameUTF8.data(), textColor); + } } void Avatar::setSkeletonOffset(const glm::vec3& offset) { diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 1800f4fdd1..534aefd3cb 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -217,8 +217,8 @@ protected: float getPelvisFloatingHeight() const; glm::vec3 getDisplayNamePosition() const; - Transform calculateDisplayNameTransform(const ViewFrustum& frustum, float fontSize, const glm::ivec4& viewport) const; - void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::ivec4& viewport) const; + Transform calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const; + void renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, const glm::vec3& textPosition) const; virtual void renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, float glowLevel = 0.0f); virtual bool shouldRenderHead(const RenderArgs* renderArgs) const; virtual void fixupModelsInScene(); From 91b46203f3b039c9d8f59d0ecfb42303e9f66581 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 13:56:58 -0700 Subject: [PATCH 11/17] Don't take keyhole into account --- interface/src/avatar/Avatar.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 538d9fb4eb..5b13d6991f 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -552,7 +552,13 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto& frustum = *renderArgs->_viewFrustum; auto textPosition = getDisplayNamePosition(); - if (frustum.pointInFrustum(textPosition)) { + // In the view frustum + auto keyhole = frustum.getKeyholeRadius(); + frustum.setKeyholeRadius(-1.0f); + auto inFrustum = frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE; + frustum.setKeyholeRadius(keyhole); + + if (inFrustum) { renderDisplayName(batch, frustum, textPosition); } } @@ -722,8 +728,8 @@ glm::vec3 Avatar::getDisplayNamePosition() const { } Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { - Q_ASSERT_X(frustum.pointInFrustum(textPosition), "Avatar::calculateDisplayNameTransform", - "Text not in viewfrustum."); + Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, + "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); glm::vec3 dPosition = frustum.getPosition() - textPosition; // Compute orientation From 79b280f73337389c5321aeaaf68917a90f4c6289 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 5 Oct 2015 14:27:04 -0700 Subject: [PATCH 12/17] Update getDisplayNamePosition debug --- interface/src/avatar/Avatar.cpp | 55 +++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5b13d6991f..4ee9a1bbb8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -696,34 +696,51 @@ void Avatar::renderBillboard(RenderArgs* renderArgs) { } float Avatar::getBillboardSize() const { - return _scale * BILLBOARD_DISTANCE * tanf(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); + return _scale * BILLBOARD_DISTANCE * glm::tan(glm::radians(BILLBOARD_FIELD_OF_VIEW / 2.0f)); } +#ifdef DEBUG +void debugValue(const QString& str, const glm::vec3& value) { + if (glm::any(glm::isnan(value)) || glm::any(glm::isinf(value))) { + qCWarning(interfaceapp) << "debugValue() " << str << value; + } +}; +void debugValue(const QString& str, const float& value) { + if (glm::isnan(value) || glm::isinf(value)) { + qCWarning(interfaceapp) << "debugValue() " << str << value; + } +}; +#define DEBUG_VALUE(str, value) debugValue(str, value) +#else +#define DEBUG_VALUE(str, value) +#endif + glm::vec3 Avatar::getDisplayNamePosition() const { glm::vec3 namePosition(0.0f); + glm::vec3 bodyUpDirection = getBodyUpDirection(); + DEBUG_VALUE("bodyUpDirection =", bodyUpDirection); + if (getSkeletonModel().getNeckPosition(namePosition)) { - namePosition += getBodyUpDirection() * getHeadHeight() * 1.1f; + float headHeight = getHeadHeight(); + DEBUG_VALUE("namePosition =", namePosition); + DEBUG_VALUE("headHeight =", headHeight); + + namePosition += bodyUpDirection * headHeight * 1.1f; } else { const float HEAD_PROPORTION = 0.75f; - namePosition = _position + getBodyUpDirection() * (getBillboardSize() * HEAD_PROPORTION); + float billboardSize = getBillboardSize(); + + DEBUG_VALUE("_position =", _position); + DEBUG_VALUE("billboardSize =", billboardSize); + namePosition = _position + bodyUpDirection * (billboardSize * HEAD_PROPORTION); } -#ifdef DEBUG - // TODO: Temporary logging to track cause of invalid scale value; remove once cause has been fixed. - // See other TODO below. - if (glm::isnan(namePosition.x) || glm::isnan(namePosition.y) || glm::isnan(namePosition.z) - || glm::isinf(namePosition.x) || glm::isinf(namePosition.y) || glm::isinf(namePosition.z)) { - qDebug() << "namePosition =" << namePosition; - glm::vec3 tempPosition(0.0f); - if (getSkeletonModel().getNeckPosition(tempPosition)) { - qDebug() << "getBodyUpDirection() =" << getBodyUpDirection(); - qDebug() << "getHeadHeight() =" << getHeadHeight(); - } else { - qDebug() << "_position =" << _position; - qDebug() << "getBodyUpDirection() =" << getBodyUpDirection(); - qDebug() << "getBillboardSize() =" << getBillboardSize(); - } + + if (glm::any(glm::isnan(namePosition)) || glm::any(glm::isinf(namePosition))) { + qCWarning(interfaceapp) << "Invalid display name position" << namePosition + << ", setting is to (0.0f, 0.5f, 0.0f)"; + namePosition = glm::vec3(0.0f, 0.5f, 0.0f); } -#endif + return namePosition; } From fd6f0213ef1a6801b6727c6318adbd2544251c02 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 17:23:54 -0700 Subject: [PATCH 13/17] CR --- interface/src/avatar/Avatar.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4ee9a1bbb8..ad714fefc8 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -725,7 +725,8 @@ glm::vec3 Avatar::getDisplayNamePosition() const { DEBUG_VALUE("namePosition =", namePosition); DEBUG_VALUE("headHeight =", headHeight); - namePosition += bodyUpDirection * headHeight * 1.1f; + static const float SLIGHTLY_ABOVE = 1.1f; + namePosition += bodyUpDirection * headHeight * SLIGHTLY_ABOVE; } else { const float HEAD_PROPORTION = 0.75f; float billboardSize = getBillboardSize(); @@ -747,16 +748,16 @@ glm::vec3 Avatar::getDisplayNamePosition() const { Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); - glm::vec3 dPosition = frustum.getPosition() - textPosition; + glm::vec3 toFrustum = frustum.getPosition() - textPosition; // Compute orientation // If x and z are 0, atan(x, z) adais undefined, so default to 0 degrees - const float yawRotation = (dPosition.x == 0.0f && dPosition.z == 0.0f) ? 0.0f : glm::atan(dPosition.x, dPosition.z); + const float yawRotation = (toFrustum.x == 0.0f && toFrustum.z == 0.0f) ? 0.0f : glm::atan(toFrustum.x, toFrustum.z); glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); // Compute correct scale to apply - static const float DESIRED_HIGHT_RAD = glm::radians(2.0f); - float scale = glm::length(dPosition) * glm::tan(DESIRED_HIGHT_RAD); + static const float DESIRED_HEIGHT_RAD = glm::radians(2.0f); + float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD); // Set transform Transform result; @@ -770,7 +771,7 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co bool shouldShowReceiveStats = DependencyManager::get()->shouldShowReceiveStats() && !isMyAvatar(); // If we have nothing to draw, or it's totally transparent, or it's too close or behind the camera, return - const float CLIP_DISTANCE = 0.2f; + static const float CLIP_DISTANCE = 0.2f; if ((_displayName.isEmpty() && !shouldShowReceiveStats) || _displayNameAlpha == 0.0f || (glm::dot(frustum.getDirection(), getDisplayNamePosition() - frustum.getPosition()) <= CLIP_DISTANCE)) { return; @@ -798,12 +799,14 @@ void Avatar::renderDisplayName(gpu::Batch& batch, const ViewFrustum& frustum, co // Compute background position/size static const float SLIGHTLY_IN_FRONT = 0.1f; - const int border = 0.1f * nameDynamicRect.height(); + static const float BORDER_RELATIVE_SIZE = 0.1f; + static const float BEVEL_FACTOR = 0.1f; + const int border = BORDER_RELATIVE_SIZE * nameDynamicRect.height(); const int left = text_x - border; const int bottom = text_y - border; const int width = nameDynamicRect.width() + 2.0f * border; const int height = nameDynamicRect.height() + 2.0f * border; - const int bevelDistance = 0.1f * height; + const int bevelDistance = BEVEL_FACTOR * height; // Display name and background colors glm::vec4 textColor(0.93f, 0.93f, 0.93f, _displayNameAlpha); From 14a18606709edd4e74116fbc68deab74f7236ca4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 6 Oct 2015 18:08:30 -0700 Subject: [PATCH 14/17] Do not change keyhole radius --- interface/src/avatar/Avatar.cpp | 10 ++-------- libraries/octree/src/ViewFrustum.cpp | 13 +++++++------ libraries/octree/src/ViewFrustum.h | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ad714fefc8..ac55f6de83 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -552,13 +552,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { auto& frustum = *renderArgs->_viewFrustum; auto textPosition = getDisplayNamePosition(); - // In the view frustum - auto keyhole = frustum.getKeyholeRadius(); - frustum.setKeyholeRadius(-1.0f); - auto inFrustum = frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE; - frustum.setKeyholeRadius(keyhole); - - if (inFrustum) { + if (frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE) { renderDisplayName(batch, frustum, textPosition); } } @@ -746,7 +740,7 @@ glm::vec3 Avatar::getDisplayNamePosition() const { } Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, const glm::vec3& textPosition) const { - Q_ASSERT_X(frustum.pointInFrustum(textPosition) == ViewFrustum::INSIDE, + Q_ASSERT_X(frustum.pointInFrustum(textPosition, true) == ViewFrustum::INSIDE, "Avatar::calculateDisplayNameTransform", "Text not in viewfrustum."); glm::vec3 toFrustum = frustum.getPosition() - textPosition; diff --git a/libraries/octree/src/ViewFrustum.cpp b/libraries/octree/src/ViewFrustum.cpp index 820ab32b67..fd175a8e5b 100644 --- a/libraries/octree/src/ViewFrustum.cpp +++ b/libraries/octree/src/ViewFrustum.cpp @@ -241,20 +241,21 @@ ViewFrustum::location ViewFrustum::boxInKeyhole(const AABox& box) const { return result; } -ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point) const { +ViewFrustum::location ViewFrustum::pointInFrustum(const glm::vec3& point, bool ignoreKeyhole) const { ViewFrustum::location regularResult = INSIDE; ViewFrustum::location keyholeResult = OUTSIDE; // If we have a keyholeRadius, check that first, since it's cheaper - if (_keyholeRadius >= 0.0f) { + if (!ignoreKeyhole && _keyholeRadius >= 0.0f) { keyholeResult = pointInKeyhole(point); - } - if (keyholeResult == INSIDE) { - return keyholeResult; + + if (keyholeResult == INSIDE) { + return keyholeResult; + } } // If we're not known to be INSIDE the keyhole, then check the regular frustum - for(int i=0; i < 6; i++) { + for(int i = 0; i < 6; ++i) { float distance = _planes[i].distance(point); if (distance < 0) { return keyholeResult; // escape early will be the value from checking the keyhole diff --git a/libraries/octree/src/ViewFrustum.h b/libraries/octree/src/ViewFrustum.h index fe40cfd53c..596d042506 100644 --- a/libraries/octree/src/ViewFrustum.h +++ b/libraries/octree/src/ViewFrustum.h @@ -79,7 +79,7 @@ public: typedef enum {OUTSIDE, INTERSECT, INSIDE} location; - ViewFrustum::location pointInFrustum(const glm::vec3& point) const; + ViewFrustum::location pointInFrustum(const glm::vec3& point, bool ignoreKeyhole = false) const; ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const; ViewFrustum::location cubeInFrustum(const AACube& cube) const; ViewFrustum::location boxInFrustum(const AABox& box) const; From efeeaa7ea7a2dc147d0cba11d92cafc733e2d972 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 7 Oct 2015 15:14:06 -0700 Subject: [PATCH 15/17] Make display names 25% smaller --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ac55f6de83..0511e5d871 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -750,7 +750,7 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons glm::quat orientation = glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); // Compute correct scale to apply - static const float DESIRED_HEIGHT_RAD = glm::radians(2.0f); + static const float DESIRED_HEIGHT_RAD = glm::radians(1.5f); float scale = glm::length(toFrustum) * glm::tan(DESIRED_HEIGHT_RAD); // Set transform From fb284448b5f07edc05e03cb2ecda7c2820f4b2d1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 7 Oct 2015 15:21:35 -0700 Subject: [PATCH 16/17] Raise display name not to collide with heads --- interface/src/avatar/Avatar.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0511e5d871..c0636314b5 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -758,6 +758,9 @@ Transform Avatar::calculateDisplayNameTransform(const ViewFrustum& frustum, cons result.setTranslation(textPosition); result.setRotation(orientation); // Always face the screen result.setScale(scale); + // raise by half the scale up so that textPosition be the bottom + result.postTranslate(Vectors::UP / 2.0f); + return result; } From 7a918eb2883c8ee3b96c28d7dbab99d8f1b2cf4b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 7 Oct 2015 15:25:07 -0700 Subject: [PATCH 17/17] fix variable names in header --- libraries/shared/src/SettingHandle.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/shared/src/SettingHandle.h b/libraries/shared/src/SettingHandle.h index b86422bcfb..c0b6de7bd4 100644 --- a/libraries/shared/src/SettingHandle.h +++ b/libraries/shared/src/SettingHandle.h @@ -26,14 +26,14 @@ // TODO: remove class Settings : public QSettings { public: - void getFloatValueIfValid(const QString& name, float& f); - void getBoolValue(const QString& name, bool& b); + void getFloatValueIfValid(const QString& name, float& floatValue); + void getBoolValue(const QString& name, bool& boolValue); - void setVec3Value(const QString& name, const glm::vec3& v); - void getVec3ValueIfValid(const QString& name, glm::vec3& v); + void setVec3Value(const QString& name, const glm::vec3& vecValue); + void getVec3ValueIfValid(const QString& name, glm::vec3& vecValue); - void setQuatValue(const QString& name, const glm::quat& q); - void getQuatValueIfValid(const QString& name, glm::quat& q); + void setQuatValue(const QString& name, const glm::quat& quatValue); + void getQuatValueIfValid(const QString& name, glm::quat& quatValue); }; namespace Setting {