From 7579102b1ac0526ee8ad136b11caa5e588843841 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 20 Jun 2016 15:50:49 -0700 Subject: [PATCH 01/77] updates --- .../DomainContent/Toybox/bow/bow.js | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index b287966d2c..9a0da44961 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -125,6 +125,18 @@ Entities.deleteEntity(this.arrow); }, + startNearGrab:function(entityID, args){ + _this.startEquip(entityID, args); + }, + + continueNearGrab:function(entityID, args){ + _this.continueEquip(entityID, args); + }, + + releaseGrab:function(){ + _this.releaseEquip(); + }, + startEquip: function(entityID, args) { this.hand = args[0]; avatarID = args[1]; @@ -137,6 +149,9 @@ var data = getEntityCustomData('grabbableKey', this.entityID, {}); data.grabbable = false; setEntityCustomData('grabbableKey', this.entityID, data); + Entities.editEntity(_this.entityID, { + collidesWith: "" + }) }, continueEquip: function(entityID, args) { @@ -181,6 +196,9 @@ Entities.deleteEntity(this.arrow); this.aiming = false; this.hasArrowNotched = false; + Entities.editEntity(_this.entityID, { + collidesWith: "static,dynamic,kinematic,otherAvatar,myAvatar" + }) }, createArrow: function() { @@ -526,4 +544,4 @@ }; return new Bow(); -}); +}); \ No newline at end of file From a52fab00a9852b2e0f4560920820df8ecf09ce2d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 20 Jun 2016 16:04:39 -0700 Subject: [PATCH 02/77] commit possible fix for testing --- interface/src/ui/ApplicationOverlay.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 2395f62468..41d249b635 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -166,13 +166,11 @@ void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { batch.setViewTransform(Transform()); float screenRatio = ((float)qApp->getDevicePixelRatio()); - float renderRatio = ((float)screenRatio * qApp->getRenderResolutionScale()); + float renderRatio = ((float)qApp->getRenderResolutionScale()); auto viewport = qApp->getMirrorViewRect(); - glm::vec2 bottomLeft(viewport.left(), viewport.top() + viewport.height()); - glm::vec2 topRight(viewport.left() + viewport.width(), viewport.top()); - bottomLeft *= screenRatio; - topRight *= screenRatio; + glm::vec2 bottomLeft(viewport.left(), viewport.top() + screenRatio * viewport.height()); + glm::vec2 topRight(viewport.left() + screenRatio * viewport.width(), viewport.top()); glm::vec2 texCoordMinCorner(0.0f, 0.0f); glm::vec2 texCoordMaxCorner(viewport.width() * renderRatio / float(selfieTexture->getWidth()), viewport.height() * renderRatio / float(selfieTexture->getHeight())); From aa742a50ca27549e3641221b9678b18b9ff1eac5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 20 Jun 2016 16:19:34 -0700 Subject: [PATCH 03/77] release --- unpublishedScripts/DomainContent/Toybox/bow/bow.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 9a0da44961..7dccf06628 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -133,8 +133,8 @@ _this.continueEquip(entityID, args); }, - releaseGrab:function(){ - _this.releaseEquip(); + releaseGrab:function(entityID, args){ + _this.releaseEquip(entityID, args); }, startEquip: function(entityID, args) { From f6d19ba32fc53edbe5172c44a07fef21e2b4a0a5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 20 Jun 2016 16:25:48 -0700 Subject: [PATCH 04/77] add short haptic pulse on release --- unpublishedScripts/DomainContent/Toybox/bow/bow.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 7dccf06628..cba45087a9 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -479,10 +479,14 @@ // rotation: arrowProps.rotation }; + //actually shoot the arrow and play its sound Entities.editEntity(this.arrow, arrowProperties); this.playShootArrowSound(); + var whichHand = this.hand==='left' ? 0 :1; + Controller.triggerShortHapticPulse(whichHand, 2); + //clear the strings back to only the single straight one this.deleteStrings(); Entities.editEntity(this.preNotchString, { From d8aeb26a6ceae98c97550ad9d9d54239200f801e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 20 Jun 2016 16:26:48 -0700 Subject: [PATCH 05/77] haptic --- unpublishedScripts/DomainContent/Toybox/bow/bow.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index cba45087a9..2430b68076 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -125,15 +125,15 @@ Entities.deleteEntity(this.arrow); }, - startNearGrab:function(entityID, args){ + startNearGrab: function(entityID, args) { _this.startEquip(entityID, args); }, - continueNearGrab:function(entityID, args){ + continueNearGrab: function(entityID, args) { _this.continueEquip(entityID, args); }, - releaseGrab:function(entityID, args){ + releaseGrab: function(entityID, args) { _this.releaseEquip(entityID, args); }, @@ -484,7 +484,7 @@ Entities.editEntity(this.arrow, arrowProperties); this.playShootArrowSound(); - var whichHand = this.hand==='left' ? 0 :1; + var whichHand = this.hand === 'left' ? 0 : 1; Controller.triggerShortHapticPulse(whichHand, 2); //clear the strings back to only the single straight one From f0b78eae478e69cbcefe78b1efc9ef75595f924f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 16:48:32 -0700 Subject: [PATCH 06/77] fix mini mirror --- interface/src/ui/ApplicationOverlay.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 41d249b635..9330f1f6c4 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -169,8 +169,10 @@ void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { float renderRatio = ((float)qApp->getRenderResolutionScale()); auto viewport = qApp->getMirrorViewRect(); - glm::vec2 bottomLeft(viewport.left(), viewport.top() + screenRatio * viewport.height()); - glm::vec2 topRight(viewport.left() + screenRatio * viewport.width(), viewport.top()); + glm::vec2 bottomLeft(viewport.left(), viewport.top() + viewport.height()); + glm::vec2 topRight(viewport.left() + viewport.width(), viewport.top()); + bottomLeft *= screenRatio; + topRight *= screenRatio; glm::vec2 texCoordMinCorner(0.0f, 0.0f); glm::vec2 texCoordMaxCorner(viewport.width() * renderRatio / float(selfieTexture->getWidth()), viewport.height() * renderRatio / float(selfieTexture->getHeight())); From 78a1845afe63c23c41a6f52b203b490b6955c9f6 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 21 Jun 2016 18:13:11 -0700 Subject: [PATCH 07/77] fixed resizing of qml overlays when device pixel ratio changes --- interface/src/Application.cpp | 11 +++-------- libraries/gl/src/gl/OffscreenQmlSurface.cpp | 4 ++-- libraries/gl/src/gl/OffscreenQmlSurface.h | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9bcd85fd02..cff36dcf99 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1459,13 +1459,7 @@ void Application::initializeUi() { }); offscreenUi->resume(); connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){ - static qreal oldDevicePixelRatio = 0; - qreal devicePixelRatio = getActiveDisplayPlugin()->devicePixelRatio(); - if (devicePixelRatio != oldDevicePixelRatio) { - oldDevicePixelRatio = devicePixelRatio; - qDebug() << "Device pixel ratio changed, triggering GL resize"; - resizeGL(); - } + resizeGL(); }); // This will set up the input plugins UI @@ -1840,7 +1834,8 @@ void Application::resizeGL() { static qreal lastDevicePixelRatio = 0; qreal devicePixelRatio = _window->devicePixelRatio(); if (offscreenUi->size() != fromGlm(uiSize) || devicePixelRatio != lastDevicePixelRatio) { - offscreenUi->resize(fromGlm(uiSize)); + qDebug() << "Device pixel ratio changed, triggering resize"; + offscreenUi->resize(fromGlm(uiSize), true); _offscreenContext->makeCurrent(); lastDevicePixelRatio = devicePixelRatio; } diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 388ca26482..9ba4b5e134 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -414,7 +414,7 @@ void OffscreenQmlSurface::create(QOpenGLContext* shareContext) { _updateTimer.start(); } -void OffscreenQmlSurface::resize(const QSize& newSize_) { +void OffscreenQmlSurface::resize(const QSize& newSize_, bool forceResize) { if (!_renderer || !_renderer->_quickWindow) { return; @@ -433,7 +433,7 @@ void OffscreenQmlSurface::resize(const QSize& newSize_) { } QSize currentSize = _renderer->_quickWindow->geometry().size(); - if (newSize == currentSize) { + if (newSize == currentSize && !forceResize) { return; } diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h index 22a1b99fe6..4014f2ff25 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.h +++ b/libraries/gl/src/gl/OffscreenQmlSurface.h @@ -38,7 +38,7 @@ public: using MouseTranslator = std::function; virtual void create(QOpenGLContext* context); - void resize(const QSize& size); + void resize(const QSize& size, bool forceResize = false); QSize size() const; Q_INVOKABLE QObject* load(const QUrl& qmlSource, std::function f = [](QQmlContext*, QObject*) {}); Q_INVOKABLE QObject* load(const QString& qmlSourceFile, std::function f = [](QQmlContext*, QObject*) {}) { From d4cfe6256a93884bf13f6869f1c2192bd6e4c442 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 22 Jun 2016 14:46:08 -0700 Subject: [PATCH 08/77] don't render mini mirror if rendering fullscreen mirror --- interface/src/ui/ApplicationOverlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 9330f1f6c4..6d5df31766 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -150,7 +150,8 @@ void ApplicationOverlay::renderRearViewToFbo(RenderArgs* renderArgs) { } void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) { - if (!qApp->isHMDMode() && Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror)) { + if (!qApp->isHMDMode() && Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) && + !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { gpu::Batch& batch = *renderArgs->_batch; auto geometryCache = DependencyManager::get(); From cf44783550a906679324fa5f13847b617ec4dd3c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 22 Jun 2016 17:53:38 -0700 Subject: [PATCH 09/77] can't enter independent mode through edit.js in HMD mode --- scripts/system/libraries/entityCameraTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entityCameraTool.js b/scripts/system/libraries/entityCameraTool.js index a8e9335956..63f7c43fdc 100644 --- a/scripts/system/libraries/entityCameraTool.js +++ b/scripts/system/libraries/entityCameraTool.js @@ -141,7 +141,7 @@ CameraManager = function() { }; that.enable = function() { - if (Camera.mode == "independent" || that.enabled) return; + if (Camera.mode == "independent" || that.enabled || HMD.active) return; for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.captureKeyEvents({ From 7307bc6a1b6a80dfed4ec0245bca365d6009a3b0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Jun 2016 09:51:25 -0700 Subject: [PATCH 10/77] revert to domain connection refusal check with string --- libraries/networking/src/DomainHandler.cpp | 22 +++------------------- libraries/networking/src/DomainHandler.h | 2 +- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 170669dede..3213e7319a 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -407,25 +407,9 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer(); diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 3ab583d597..be8ccbe50f 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -144,7 +144,7 @@ private: QString _pendingPath; QTimer _settingsTimer; - QList _domainConnectionRefusals; + QStringList _domainConnectionRefusals; bool _hasSignalledProtocolMismatch { false }; bool _hasCheckedForAccessToken { false }; int _connectionDenialsSinceKeypairRegen { 0 }; From f9b3165350bfee7243268e38ab91777538a5e4bf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 23 Jun 2016 09:37:17 -0700 Subject: [PATCH 11/77] use a QSet instead of a QStringList --- libraries/networking/src/DomainHandler.cpp | 2 +- libraries/networking/src/DomainHandler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 3213e7319a..c4b979e0b8 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -408,7 +408,7 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer _domainConnectionRefusals; bool _hasSignalledProtocolMismatch { false }; bool _hasCheckedForAccessToken { false }; int _connectionDenialsSinceKeypairRegen { 0 }; From a0bb55e4c8579679b7832542bb6b67459fb3c109 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 23 Jun 2016 10:48:29 -0700 Subject: [PATCH 12/77] coding standard fun --- scripts/system/libraries/entityCameraTool.js | 37 +++++++++++--------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/scripts/system/libraries/entityCameraTool.js b/scripts/system/libraries/entityCameraTool.js index 63f7c43fdc..301b60f550 100644 --- a/scripts/system/libraries/entityCameraTool.js +++ b/scripts/system/libraries/entityCameraTool.js @@ -141,7 +141,9 @@ CameraManager = function() { }; that.enable = function() { - if (Camera.mode == "independent" || that.enabled || HMD.active) return; + if (Camera.mode == "independent" || that.enabled || HMD.active) { + return; + } for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.captureKeyEvents({ @@ -179,7 +181,9 @@ CameraManager = function() { } that.disable = function(ignoreCamera) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.releaseKeyEvents({ @@ -352,27 +356,21 @@ CameraManager = function() { that.mousePressEvent = function(event) { if (cameraTool.mousePressEvent(event)) { - return true; } - - if (!that.enabled) return; + if (!that.enabled) { + return; + } if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { - that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { - - that.mode = MODE_PAN; } if (that.mode !== MODE_INACTIVE) { - - hasDragged = false; - return true; } @@ -381,7 +379,9 @@ CameraManager = function() { that.mouseReleaseEvent = function(event) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } that.mode = MODE_INACTIVE; Reticle.setVisible(true); @@ -403,7 +403,9 @@ CameraManager = function() { }; that.wheelEvent = function(event) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } var dZoom = -event.delta * SCROLL_SENSITIVITY; @@ -459,8 +461,12 @@ CameraManager = function() { } function normalizeDegrees(degrees) { - while (degrees > 180) degrees -= 360; - while (degrees < -180) degrees += 360; + while (degrees > 180) { + degrees -= 360; + } + while (degrees < -180) { + degrees += 360; + } return degrees; } @@ -483,7 +489,6 @@ CameraManager = function() { that.targetZoomDistance = clamp(that.targetZoomDistance, MIN_ZOOM_DISTANCE, MAX_ZOOM_DISTANCE); } - if (easing) { easingTime = Math.min(EASE_TIME, easingTime + dt); } From 15fbff4ffb1ebc2225d7234ee820c2334978a755 Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Fri, 24 Jun 2016 10:09:52 -0700 Subject: [PATCH 13/77] Add eslintrc file --- scripts/.eslintrc.js | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 scripts/.eslintrc.js diff --git a/scripts/.eslintrc.js b/scripts/.eslintrc.js new file mode 100644 index 0000000000..e866713b11 --- /dev/null +++ b/scripts/.eslintrc.js @@ -0,0 +1,72 @@ +module.exports = { + "root": true, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 5 + }, + "globals": { + "Account": false, + "AnimationCache": false, + "Assets": false, + "Audio": false, + "AudioDevice": false, + "AudioEffectOptions": false, + "AvatarList": false, + "AvatarManager": false, + "Camera": false, + "Clipboard": false, + "Controller": false, + "DialogsManager": false, + "Entities": false, + "FaceTracker": false, + "GlobalServices": false, + "HMD": false, + "LODManager": false, + "Mat4": false, + "Menu": false, + "Messages": false, + "ModelCache": false, + "MyAvatar": false, + "Overlays": false, + "Paths": false, + "Quat": false, + "Rates": false, + "Recording": false, + "Reticle": false, + "Scene": false, + "Script": false, + "ScriptDiscoveryService": false, + "Settings": false, + "SoundCache": false, + "Stats": false, + "TextureCache": false, + "Uuid": false, + "UndoStack": false, + "Vec3": false, + "WebSocket": false, + "WebWindow": false, + "Window": false, + "XMLHttpRequest": false, + "location": false, + "print": false + }, + "rules": { + "brace-style": ["error", "1tbs", { "allowSingleLine": false }], + "comma-dangle": ["error", "only-multiline"], + "camelcase": ["error"], + "curly": ["error", "all"], + "indent": ["error", 4, { "SwitchCase": 1 }], + "keyword-spacing": ["error", { "before": true, "after": true }], + "max-len": ["error", 128, 4], + "new-cap": ["error"], + //"no-magic-numbers": ["error", { "ignore": [0, 1], "ignoreArrayIndexes": true }], + "no-multiple-empty-lines": ["error"], + "no-multi-spaces": ["error"], + "no-unused-vars": ["error", { "args": "none", "vars": "local" }], + "semi": ["error", "always"], + "spaced-comment": ["error", "always", { + "line": { "markers": ["/"] } + }], + "space-before-function-paren": ["error", "never"] + } +}; From 5e69af83c69c94e78ec813cd7aea4bfbe270e031 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 22 Jun 2016 17:53:38 -0700 Subject: [PATCH 14/77] can't enter independent mode through edit.js in HMD mode --- scripts/system/libraries/entityCameraTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entityCameraTool.js b/scripts/system/libraries/entityCameraTool.js index a8e9335956..63f7c43fdc 100644 --- a/scripts/system/libraries/entityCameraTool.js +++ b/scripts/system/libraries/entityCameraTool.js @@ -141,7 +141,7 @@ CameraManager = function() { }; that.enable = function() { - if (Camera.mode == "independent" || that.enabled) return; + if (Camera.mode == "independent" || that.enabled || HMD.active) return; for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.captureKeyEvents({ From d5feac94f4cb3581f755cda07fbda4261f0a89bf Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 23 Jun 2016 10:48:29 -0700 Subject: [PATCH 15/77] coding standard fun --- scripts/system/libraries/entityCameraTool.js | 37 +++++++++++--------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/scripts/system/libraries/entityCameraTool.js b/scripts/system/libraries/entityCameraTool.js index 63f7c43fdc..301b60f550 100644 --- a/scripts/system/libraries/entityCameraTool.js +++ b/scripts/system/libraries/entityCameraTool.js @@ -141,7 +141,9 @@ CameraManager = function() { }; that.enable = function() { - if (Camera.mode == "independent" || that.enabled || HMD.active) return; + if (Camera.mode == "independent" || that.enabled || HMD.active) { + return; + } for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.captureKeyEvents({ @@ -179,7 +181,9 @@ CameraManager = function() { } that.disable = function(ignoreCamera) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } for (var i = 0; i < CAPTURED_KEYS.length; i++) { Controller.releaseKeyEvents({ @@ -352,27 +356,21 @@ CameraManager = function() { that.mousePressEvent = function(event) { if (cameraTool.mousePressEvent(event)) { - return true; } - - if (!that.enabled) return; + if (!that.enabled) { + return; + } if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { - that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { - - that.mode = MODE_PAN; } if (that.mode !== MODE_INACTIVE) { - - hasDragged = false; - return true; } @@ -381,7 +379,9 @@ CameraManager = function() { that.mouseReleaseEvent = function(event) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } that.mode = MODE_INACTIVE; Reticle.setVisible(true); @@ -403,7 +403,9 @@ CameraManager = function() { }; that.wheelEvent = function(event) { - if (!that.enabled) return; + if (!that.enabled) { + return; + } var dZoom = -event.delta * SCROLL_SENSITIVITY; @@ -459,8 +461,12 @@ CameraManager = function() { } function normalizeDegrees(degrees) { - while (degrees > 180) degrees -= 360; - while (degrees < -180) degrees += 360; + while (degrees > 180) { + degrees -= 360; + } + while (degrees < -180) { + degrees += 360; + } return degrees; } @@ -483,7 +489,6 @@ CameraManager = function() { that.targetZoomDistance = clamp(that.targetZoomDistance, MIN_ZOOM_DISTANCE, MAX_ZOOM_DISTANCE); } - if (easing) { easingTime = Math.min(EASE_TIME, easingTime + dt); } From f90a351400c5de2a89a30c25dc72a00fe25ca8ab Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 24 Jun 2016 16:31:24 -0700 Subject: [PATCH 16/77] Don't reposition windows prior to selecting the initial display plugin --- interface/resources/qml/desktop/Desktop.qml | 16 +++++++++++++++- interface/src/Application.cpp | 8 +++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 9f10cfc64a..27fa9692b9 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -24,6 +24,13 @@ FocusScope { readonly property int invalid_position: -9999; property rect recommendedRect: Qt.rect(0,0,0,0); property var expectedChildren; + property bool repositionLocked: true + + onRepositionLockedChanged: { + if (!repositionLocked) { + d.handleSizeChanged(); + } + } onHeightChanged: d.handleSizeChanged(); @@ -52,11 +59,14 @@ FocusScope { readonly property real menu: 8000 } - QtObject { id: d function handleSizeChanged() { + if (desktop.repositionLocked) { + return; + } + var oldRecommendedRect = recommendedRect; var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect(); var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, @@ -235,6 +245,10 @@ FocusScope { } function repositionAll() { + if (desktop.repositionLocked) { + return; + } + var oldRecommendedRect = recommendedRect; var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height }; var newRecommendedRect = Controller.getRecommendedOverlayRect(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 26da43fb58..858b86025f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -963,6 +963,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : updateHeartbeat(); loadSettings(); + + // Now that we've loaded the menu and thus switched to the previous display plugin + // we can unlock the desktop repositioning code, since all the positions will be + // relative to the desktop size for this plugin + auto offscreenUi = DependencyManager::get(); + offscreenUi->getDesktop()->setProperty("repositionLocked", false); + // Make sure we don't time out during slow operations at startup updateHeartbeat(); @@ -5348,7 +5355,6 @@ void Application::updateDisplayMode() { _displayPlugin = newDisplayPlugin; } - emit activeDisplayPluginChanged(); // reset the avatar, to set head and hand palms back to a reasonable default pose. From 2786061d71d96ce6157c2b98b59a59f292347736 Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Fri, 24 Jun 2016 16:34:54 -0700 Subject: [PATCH 17/77] Fix bug with entity adding w/o permission Entities could be added to the local tree, but be rejected by the server because of a lack of permissions. --- libraries/entities/src/EntityTree.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 7ebfecbe8e..21e5865c09 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -320,6 +320,11 @@ EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const Enti return nullptr; } + if (!properties.getClientOnly() && getIsClient() && + !nodeList->getThisNodeCanRez() && !nodeList->getThisNodeCanRezTmp()) { + return nullptr; + } + bool recordCreationTime = false; if (props.getCreated() == UNKNOWN_CREATED_TIME) { // the entity's creation time was not specified in properties, which means this is a NEW entity From a4da63c1ff33ad58f04ca35ed7d31647400b71bd Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Fri, 24 Jun 2016 16:39:57 -0700 Subject: [PATCH 18/77] Fix bug with Entities.addEntity returning bad id If addEntity failed for whatever reason (eg. lack of permission), it would return a non-null UUID. Fixes [FogBugz case #365](https://highfidelity.fogbugz.com/f/cases/356/Entities-addEntity-can-return-a-UUID-even-when-unsuccessful). --- libraries/entities/src/EntityScriptingInterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 55d93d5b5b..856e526b4c 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -191,9 +191,11 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties if (success) { emit debitEnergySource(cost); queueEntityMessage(PacketType::EntityAdd, id, propertiesWithSimID); - } - return id; + return id; + } else { + return QUuid(); + } } QUuid EntityScriptingInterface::addModelEntity(const QString& name, const QString& modelUrl, const glm::vec3& position) { From 8a5369fcb15e98cdf2143d690834d29fa58f1ec7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jun 2016 12:03:36 +1200 Subject: [PATCH 19/77] Undo hide users.js when logged out --- scripts/system/users.js | 109 +++++++++++++++------------------------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 5b0ba42a45..54fa5951ac 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var PopUpMenu = function(properties) { +var PopUpMenu = function (properties) { var value = properties.value, promptOverlay, valueOverlay, @@ -217,7 +217,7 @@ var PopUpMenu = function(properties) { }; }; -var usersWindow = (function() { +var usersWindow = (function () { var baseURL = Script.resolvePath("assets/images/tools/"), WINDOW_WIDTH = 260, @@ -253,11 +253,7 @@ var usersWindow = (function() { WINDOW_BORDER_BOTTOM_MARGIN = WINDOW_BASE_MARGIN, WINDOW_BORDER_LEFT_MARGIN = WINDOW_BASE_MARGIN, WINDOW_BORDER_RADIUS = 4, - WINDOW_BORDER_COLOR = { - red: 255, - green: 255, - blue: 255 - }, + WINDOW_BORDER_COLOR = { red: 255, green: 255, blue: 255 }, WINDOW_BORDER_ALPHA = 0.5, windowBorder, @@ -381,12 +377,9 @@ var usersWindow = (function() { isMirrorDisplay = false, isFullscreenMirror = false, - windowPosition = {}, // Bottom left corner of window pane. + windowPosition = {}, // Bottom left corner of window pane. isMovingWindow = false, - movingClickOffset = { - x: 0, - y: 0 - }, + movingClickOffset = { x: 0, y: 0 }, isUsingScrollbars = false, isMovingScrollbar = false, @@ -408,7 +401,9 @@ var usersWindow = (function() { } // Reserve space for title, friends button, and option controls - nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER + windowLineHeight + VISIBILITY_SPACER + windowLineHeight + WINDOW_BASE_MARGIN; + nonUsersHeight = WINDOW_MARGIN + windowLineHeight + FRIENDS_BUTTON_SPACER + FRIENDS_BUTTON_HEIGHT + DISPLAY_SPACER + + windowLineHeight + VISIBILITY_SPACER + + windowLineHeight + WINDOW_BASE_MARGIN; // Limit window to height of viewport above window position minus VU meter and mirror if displayed windowHeight = linesOfUsers.length * windowLineHeight - windowLineSpacing + nonUsersHeight; @@ -461,14 +456,17 @@ var usersWindow = (function() { x: scrollbarBackgroundPosition.x, y: scrollbarBackgroundPosition.y }); - scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1 + scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2); + scrollbarBarPosition.y = scrollbarBackgroundPosition.y + 1 + + scrollbarValue * (scrollbarBackgroundHeight - scrollbarBarHeight - 2); Overlays.editOverlay(scrollbarBar, { x: scrollbarBackgroundPosition.x + 1, y: scrollbarBarPosition.y }); x = windowLeft + WINDOW_MARGIN; - y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER - windowLineHeight - VISIBILITY_SPACER - windowLineHeight - WINDOW_BASE_MARGIN; + y = windowPosition.y - FRIENDS_BUTTON_HEIGHT - DISPLAY_SPACER + - windowLineHeight - VISIBILITY_SPACER + - windowLineHeight - WINDOW_BASE_MARGIN; Overlays.editOverlay(friendsButton, { x: x, y: y @@ -556,36 +554,9 @@ var usersWindow = (function() { usersRequest.ontimeout = pollUsersTimedOut; usersRequest.onreadystatechange = processUsers; usersRequest.send(); - checkLoggedIn(); } - var loggedIn = false; - - function checkLoggedIn() { - loggedIn = Account.isLoggedIn(); - if (loggedIn === false) { - Overlays.editOverlay(friendsButton, { - visible: false - }); - visibilityControl.setVisible(false); - displayControl.setVisible(false); - } else { - if (isMinimized === true) { - loggedIn = true; - return - } - Overlays.editOverlay(friendsButton, { - visible: true - }); - visibilityControl.setVisible(true); - displayControl.setVisible(true); - loggedIn = true; - - } - } - - - processUsers = function() { + processUsers = function () { var response, myUsername, user, @@ -638,7 +609,7 @@ var usersWindow = (function() { } }; - pollUsersTimedOut = function() { + pollUsersTimedOut = function () { print("Error: Request for users status timed out"); usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay. }; @@ -662,15 +633,11 @@ var usersWindow = (function() { Overlays.editOverlay(scrollbarBar, { visible: isVisible && isUsingScrollbars && !isMinimized }); - - if (loggedIn === true) { - Overlays.editOverlay(friendsButton, { - visible: isVisible && !isMinimized - }); - displayControl.setVisible(isVisible && !isMinimized); - visibilityControl.setVisible(isVisible && !isMinimized); - } - + Overlays.editOverlay(friendsButton, { + visible: isVisible && !isMinimized + }); + displayControl.setVisible(isVisible && !isMinimized); + visibilityControl.setVisible(isVisible && !isMinimized); } function setVisible(visible) { @@ -763,7 +730,9 @@ var usersWindow = (function() { userClicked = firstUserToDisplay + lineClicked; - if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) { + if (0 <= userClicked && userClicked < linesOfUsers.length && 0 <= overlayX + && overlayX <= usersOnline[linesOfUsers[userClicked]].textWidth) { + //print("Go to " + usersOnline[linesOfUsers[userClicked]].username); location.goToUser(usersOnline[linesOfUsers[userClicked]].username); } @@ -831,8 +800,12 @@ var usersWindow = (function() { var isVisible; if (isMovingScrollbar) { - if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x && event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN && scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y && event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) { - scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y) / (scrollbarBackgroundHeight - scrollbarBarHeight - 2); + if (scrollbarBackgroundPosition.x - WINDOW_MARGIN <= event.x + && event.x <= scrollbarBackgroundPosition.x + SCROLLBAR_BACKGROUND_WIDTH + WINDOW_MARGIN + && scrollbarBackgroundPosition.y - WINDOW_MARGIN <= event.y + && event.y <= scrollbarBackgroundPosition.y + scrollbarBackgroundHeight + WINDOW_MARGIN) { + scrollbarValue = (event.y - scrollbarBarClickedAt * scrollbarBarHeight - scrollbarBackgroundPosition.y) + / (scrollbarBackgroundHeight - scrollbarBarHeight - 2); scrollbarValue = Math.min(Math.max(scrollbarValue, 0.0), 1.0); firstUserToDisplay = Math.floor(scrollbarValue * (linesOfUsers.length - numUsersToDisplay)); updateOverlayPositions(); @@ -858,9 +831,13 @@ var usersWindow = (function() { isVisible = isBorderVisible; if (isVisible) { - isVisible = windowPosition.x - WINDOW_BORDER_LEFT_MARGIN <= event.x && event.x <= windowPosition.x - WINDOW_BORDER_LEFT_MARGIN + WINDOW_BORDER_WIDTH && windowPosition.y - windowHeight - WINDOW_BORDER_TOP_MARGIN <= event.y && event.y <= windowPosition.y + WINDOW_BORDER_BOTTOM_MARGIN; + isVisible = windowPosition.x - WINDOW_BORDER_LEFT_MARGIN <= event.x + && event.x <= windowPosition.x - WINDOW_BORDER_LEFT_MARGIN + WINDOW_BORDER_WIDTH + && windowPosition.y - windowHeight - WINDOW_BORDER_TOP_MARGIN <= event.y + && event.y <= windowPosition.y + WINDOW_BORDER_BOTTOM_MARGIN; } else { - isVisible = windowPosition.x <= event.x && event.x <= windowPosition.x + WINDOW_WIDTH && windowPosition.y - windowHeight <= event.y && event.y <= windowPosition.y; + isVisible = windowPosition.x <= event.x && event.x <= windowPosition.x + WINDOW_WIDTH + && windowPosition.y - windowHeight <= event.y && event.y <= windowPosition.y; } if (isVisible !== isBorderVisible) { isBorderVisible = isVisible; @@ -901,7 +878,8 @@ var usersWindow = (function() { isMirrorDisplay = Menu.isOptionChecked(MIRROR_MENU_ITEM); isFullscreenMirror = Menu.isOptionChecked(FULLSCREEN_MIRROR_MENU_ITEM); - if (viewport.y !== oldViewport.y || isMirrorDisplay !== oldIsMirrorDisplay || isFullscreenMirror !== oldIsFullscreenMirror) { + if (viewport.y !== oldViewport.y || isMirrorDisplay !== oldIsMirrorDisplay + || isFullscreenMirror !== oldIsFullscreenMirror) { calculateWindowHeight(); updateUsersDisplay(); } @@ -951,8 +929,8 @@ var usersWindow = (function() { } else { hmdViewport = Controller.getRecommendedOverlayRect(); windowPosition = { - x: (viewport.x - hmdViewport.width) / 2, // HMD viewport is narrower than screen. - y: hmdViewport.height // HMD viewport starts at top of screen but only extends down so far. + x: (viewport.x - hmdViewport.width) / 2, // HMD viewport is narrower than screen. + y: hmdViewport.height // HMD viewport starts at top of screen but only extends down so far. }; } @@ -960,7 +938,7 @@ var usersWindow = (function() { windowBorder = Overlays.addOverlay("rectangle", { x: 0, - y: viewport.y, // Start up off-screen + y: viewport.y, // Start up off-screen width: WINDOW_BORDER_WIDTH, height: windowBorderHeight, radius: WINDOW_BORDER_RADIUS, @@ -1123,11 +1101,6 @@ var usersWindow = (function() { visible: isVisible && !isMinimized }); - - Script.setTimeout(function() { - checkLoggedIn() - }, 0); - Controller.mousePressEvent.connect(onMousePressEvent); Controller.mouseMoveEvent.connect(onMouseMoveEvent); Controller.mouseReleaseEvent.connect(onMouseReleaseEvent); @@ -1170,4 +1143,4 @@ var usersWindow = (function() { setUp(); Script.scriptEnding.connect(tearDown); -}()); \ No newline at end of file +}()); From 1c1d81ae25437e3b06aca39bbb973c0be634c5ee Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jun 2016 12:18:03 +1200 Subject: [PATCH 20/77] Fix missing users.js menu item --- scripts/system/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 54fa5951ac..92a05b30fd 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -361,9 +361,9 @@ var usersWindow = (function () { myVisibility, - MENU_NAME = "Tools", + MENU_NAME = "View", MENU_ITEM = "Users Online", - MENU_ITEM_AFTER = "Chat...", + MENU_ITEM_AFTER = "Overlays", SETTING_USERS_WINDOW_MINIMIZED = "UsersWindow.Minimized", SETINGS_USERS_WINDOW_OFFSET = "UsersWindow.Offset", From 8b0f59c9cfd032de2010d3d0cf1a9b93851f28a1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jun 2016 13:12:16 +1200 Subject: [PATCH 21/77] Fix users window minimized state not being remembered --- scripts/system/users.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 92a05b30fd..afc3ac2de4 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -370,7 +370,7 @@ var usersWindow = (function () { // +ve x, y values are offset from left, top of screen; -ve from right, bottom. isVisible = true, - isMinimized = false, + isMinimized = true, isBorderVisible = false, viewport, @@ -388,6 +388,12 @@ var usersWindow = (function () { scrollbarBarClickedAt, // 0.0 .. 1.0 scrollbarValue = 0.0; // 0.0 .. 1.0 + function isValueTrue(value) { + // Work around Boolean Settings values being read as string when Interface starts up but as Booleans when re-read after + // Being written if refresh script. + return value === true || value === "true"; + } + function calculateWindowHeight() { var AUDIO_METER_HEIGHT = 52, MIRROR_HEIGHT = 220, @@ -664,6 +670,7 @@ var usersWindow = (function () { } }); updateOverlayVisibility(); + Settings.setValue(SETTING_USERS_WINDOW_MINIMIZED, isMinimized); } function onMenuItemEvent(event) { @@ -1121,12 +1128,10 @@ var usersWindow = (function () { pollUsers(); // Set minimized at end - setup code does not handle `minimized == false` correctly - setMinimized(Settings.getValue(SETTING_USERS_WINDOW_MINIMIZED, false)); + setMinimized(isValueTrue(Settings.getValue(SETTING_USERS_WINDOW_MINIMIZED, false))); } function tearDown() { - Settings.setValue(SETTING_USERS_WINDOW_MINIMIZED, isMinimized); - Menu.removeMenuItem(MENU_NAME, MENU_ITEM); Script.clearTimeout(usersTimer); From 0b6797acc354c44b89316fb429b90f83845d53c6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jun 2016 13:48:43 +1200 Subject: [PATCH 22/77] Fix "show me" and "visible to" in users window not being remembered --- scripts/system/users.js | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index afc3ac2de4..b5fe7c4fad 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -359,14 +359,17 @@ var usersWindow = (function () { usersTimer = null, USERS_UPDATE_TIMEOUT = 5000, // ms = 5s + showMe, myVisibility, MENU_NAME = "View", MENU_ITEM = "Users Online", MENU_ITEM_AFTER = "Overlays", + SETTING_USERS_SHOW_ME = "UsersWindow.ShowMe", + SETTING_USERS_VISIBLE_TO = "UsersWindow.VisibleTo", SETTING_USERS_WINDOW_MINIMIZED = "UsersWindow.Minimized", - SETINGS_USERS_WINDOW_OFFSET = "UsersWindow.Offset", + SETTING_USERS_WINDOW_OFFSET = "UsersWindow.Offset", // +ve x, y values are offset from left, top of screen; -ve from right, bottom. isVisible = true, @@ -550,7 +553,7 @@ var usersWindow = (function () { function pollUsers() { var url = API_URL; - if (displayControl.getValue() === DISPLAY_FRIENDS) { + if (showMe === DISPLAY_FRIENDS) { url += API_FRIENDS_FILTER; } @@ -681,9 +684,11 @@ var usersWindow = (function () { function onFindableByChanged(event) { if (VISIBILITY_VALUES.indexOf(event) !== -1) { + myVisibility = event; visibilityControl.setValue(event); + Settings.setValue(SETTING_USERS_VISIBLE_TO, myVisibility); } else { - print("Error: Unrecognized onFindableByChanged value: " + myVisibility); + print("Error: Unrecognized onFindableByChanged value: " + event); } } @@ -713,11 +718,15 @@ var usersWindow = (function () { usersTimer = null; } pollUsers(); + showMe = displayControl.getValue(); + Settings.setValue(SETTING_USERS_SHOW_ME, showMe); return; } if (visibilityControl.handleClick(clickedOverlay)) { - GlobalServices.findableBy = visibilityControl.getValue(); + myVisibility = visibilityControl.getValue(); + GlobalServices.findableBy = myVisibility; + Settings.setValue(SETTING_USERS_VISIBLE_TO, myVisibility); return; } @@ -869,7 +878,7 @@ var usersWindow = (function () { // Save offset of bottom of window to nearest edge of the window. offset.x = (windowPosition.x + WINDOW_WIDTH / 2 < viewport.x / 2) ? windowPosition.x : windowPosition.x - viewport.x; offset.y = (windowPosition.y < viewport.y / 2) ? windowPosition.y : windowPosition.y - viewport.y; - Settings.setValue(SETINGS_USERS_WINDOW_OFFSET, JSON.stringify(offset)); + Settings.setValue(SETTING_USERS_WINDOW_OFFSET, JSON.stringify(offset)); isMovingWindow = false; } } @@ -925,9 +934,9 @@ var usersWindow = (function () { viewport = Controller.getViewportDimensions(); - offsetSetting = Settings.getValue(SETINGS_USERS_WINDOW_OFFSET); + offsetSetting = Settings.getValue(SETTING_USERS_WINDOW_OFFSET); if (offsetSetting !== "") { - offset = JSON.parse(Settings.getValue(SETINGS_USERS_WINDOW_OFFSET)); + offset = JSON.parse(Settings.getValue(SETTING_USERS_WINDOW_OFFSET)); } if (offset.hasOwnProperty("x") && offset.hasOwnProperty("y")) { windowPosition.x = offset.x < 0 ? viewport.x + offset.x : offset.x; @@ -1048,9 +1057,14 @@ var usersWindow = (function () { alpha: FRIENDS_BUTTON_ALPHA }); + showMe = Settings.getValue(SETTING_USERS_SHOW_ME, ""); + if (DISPLAY_VALUES.indexOf(showMe) === -1) { + showMe = DISPLAY_EVERYONE; + } + displayControl = new PopUpMenu({ prompt: DISPLAY_PROMPT, - value: DISPLAY_VALUES[0], + value: showMe, values: DISPLAY_VALUES, displayValues: DISPLAY_DISPLAY_VALUES, x: 0, @@ -1075,10 +1089,9 @@ var usersWindow = (function () { visible: isVisible && !isMinimized }); - myVisibility = GlobalServices.findableBy; + myVisibility = Settings.getValue(SETTING_USERS_VISIBLE_TO, ""); if (VISIBILITY_VALUES.indexOf(myVisibility) === -1) { - print("Error: Unrecognized findableBy value: " + myVisibility); - myVisibility = VISIBILITY_ALL; + myVisibility = VISIBILITY_FRIENDS; } visibilityControl = new PopUpMenu({ From dc07368dc9717c71e212b4c46ef6f20b48201660 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 25 Jun 2016 14:23:35 +1200 Subject: [PATCH 23/77] Hide users list when logged out --- scripts/system/users.js | 94 +++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index b5fe7c4fad..f23a0ea215 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -372,6 +372,7 @@ var usersWindow = (function () { SETTING_USERS_WINDOW_OFFSET = "UsersWindow.Offset", // +ve x, y values are offset from left, top of screen; -ve from right, bottom. + isLoggedIn = false, isVisible = true, isMinimized = true, isBorderVisible = false, @@ -526,13 +527,13 @@ var usersWindow = (function () { scrollbarBackgroundHeight = numUsersToDisplay * windowLineHeight - windowLineSpacing / 2; Overlays.editOverlay(scrollbarBackground, { height: scrollbarBackgroundHeight, - visible: isUsingScrollbars + visible: isLoggedIn && isUsingScrollbars }); scrollbarBarHeight = Math.max(numUsersToDisplay / linesOfUsers.length * scrollbarBackgroundHeight, SCROLLBAR_BAR_MIN_HEIGHT); Overlays.editOverlay(scrollbarBar, { height: scrollbarBarHeight, - visible: isUsingScrollbars + visible: isLoggedIn && isUsingScrollbars }); } @@ -550,6 +551,41 @@ var usersWindow = (function () { }); } + function updateOverlayVisibility() { + Overlays.editOverlay(windowBorder, { + visible: isLoggedIn && isVisible && isBorderVisible + }); + Overlays.editOverlay(windowPane, { + visible: isLoggedIn && isVisible + }); + Overlays.editOverlay(windowHeading, { + visible: isLoggedIn && isVisible + }); + Overlays.editOverlay(minimizeButton, { + visible: isLoggedIn && isVisible + }); + Overlays.editOverlay(scrollbarBackground, { + visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized + }); + Overlays.editOverlay(scrollbarBar, { + visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized + }); + Overlays.editOverlay(friendsButton, { + visible: isLoggedIn && isVisible && !isMinimized + }); + displayControl.setVisible(isLoggedIn && isVisible && !isMinimized); + visibilityControl.setVisible(isLoggedIn && isVisible && !isMinimized); + } + + function checkLoggedIn() { + var wasLoggedIn = isLoggedIn; + + isLoggedIn = Account.isLoggedIn(); + if (isLoggedIn !== wasLoggedIn) { + updateOverlayVisibility(); + } + } + function pollUsers() { var url = API_URL; @@ -563,6 +599,8 @@ var usersWindow = (function () { usersRequest.ontimeout = pollUsersTimedOut; usersRequest.onreadystatechange = processUsers; usersRequest.send(); + + checkLoggedIn(); } processUsers = function () { @@ -623,32 +661,6 @@ var usersWindow = (function () { usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay. }; - function updateOverlayVisibility() { - Overlays.editOverlay(windowBorder, { - visible: isVisible && isBorderVisible - }); - Overlays.editOverlay(windowPane, { - visible: isVisible - }); - Overlays.editOverlay(windowHeading, { - visible: isVisible - }); - Overlays.editOverlay(minimizeButton, { - visible: isVisible - }); - Overlays.editOverlay(scrollbarBackground, { - visible: isVisible && isUsingScrollbars && !isMinimized - }); - Overlays.editOverlay(scrollbarBar, { - visible: isVisible && isUsingScrollbars && !isMinimized - }); - Overlays.editOverlay(friendsButton, { - visible: isVisible && !isMinimized - }); - displayControl.setVisible(isVisible && !isMinimized); - visibilityControl.setVisible(isVisible && !isMinimized); - } - function setVisible(visible) { isVisible = visible; @@ -662,7 +674,6 @@ var usersWindow = (function () { } updateOverlayVisibility(); - } function setMinimized(minimized) { @@ -876,8 +887,10 @@ var usersWindow = (function () { if (isMovingWindow) { // Save offset of bottom of window to nearest edge of the window. - offset.x = (windowPosition.x + WINDOW_WIDTH / 2 < viewport.x / 2) ? windowPosition.x : windowPosition.x - viewport.x; - offset.y = (windowPosition.y < viewport.y / 2) ? windowPosition.y : windowPosition.y - viewport.y; + offset.x = (windowPosition.x + WINDOW_WIDTH / 2 < viewport.x / 2) + ? windowPosition.x : windowPosition.x - viewport.x; + offset.y = (windowPosition.y < viewport.y / 2) + ? windowPosition.y : windowPosition.y - viewport.y; Settings.setValue(SETTING_USERS_WINDOW_OFFSET, JSON.stringify(offset)); isMovingWindow = false; } @@ -960,7 +973,7 @@ var usersWindow = (function () { radius: WINDOW_BORDER_RADIUS, color: WINDOW_BORDER_COLOR, alpha: WINDOW_BORDER_ALPHA, - visible: isVisible && isBorderVisible + visible: false }); windowPane = Overlays.addOverlay("text", { @@ -976,7 +989,7 @@ var usersWindow = (function () { backgroundAlpha: WINDOW_BACKGROUND_ALPHA, text: "", font: WINDOW_FONT, - visible: isVisible + visible: false }); windowHeading = Overlays.addOverlay("text", { @@ -991,7 +1004,7 @@ var usersWindow = (function () { backgroundAlpha: 0.0, text: "No users online", font: WINDOW_FONT, - visible: isVisible && !isMinimized + visible: false }); minimizeButton = Overlays.addOverlay("image", { @@ -1008,7 +1021,7 @@ var usersWindow = (function () { }, color: MIN_MAX_BUTTON_COLOR, alpha: MIN_MAX_BUTTON_ALPHA, - visible: isVisible && !isMinimized + visible: false }); scrollbarBackgroundPosition = { @@ -1023,7 +1036,7 @@ var usersWindow = (function () { backgroundColor: SCROLLBAR_BACKGROUND_COLOR, backgroundAlpha: SCROLLBAR_BACKGROUND_ALPHA, text: "", - visible: isVisible && isUsingScrollbars && !isMinimized + visible: false }); scrollbarBarPosition = { @@ -1038,7 +1051,7 @@ var usersWindow = (function () { backgroundColor: SCROLLBAR_BAR_COLOR, backgroundAlpha: SCROLLBAR_BAR_ALPHA, text: "", - visible: isVisible && isUsingScrollbars && !isMinimized + visible: false }); friendsButton = Overlays.addOverlay("image", { @@ -1054,7 +1067,8 @@ var usersWindow = (function () { height: FRIENDS_BUTTON_SVG_HEIGHT }, color: FRIENDS_BUTTON_COLOR, - alpha: FRIENDS_BUTTON_ALPHA + alpha: FRIENDS_BUTTON_ALPHA, + visible: false }); showMe = Settings.getValue(SETTING_USERS_SHOW_ME, ""); @@ -1086,7 +1100,7 @@ var usersWindow = (function () { popupBackgroundAlpha: DISPLAY_OPTIONS_BACKGROUND_ALPHA, buttonColor: MIN_MAX_BUTTON_COLOR, buttonAlpha: MIN_MAX_BUTTON_ALPHA, - visible: isVisible && !isMinimized + visible: false }); myVisibility = Settings.getValue(SETTING_USERS_VISIBLE_TO, ""); @@ -1118,7 +1132,7 @@ var usersWindow = (function () { popupBackgroundAlpha: DISPLAY_OPTIONS_BACKGROUND_ALPHA, buttonColor: MIN_MAX_BUTTON_COLOR, buttonAlpha: MIN_MAX_BUTTON_ALPHA, - visible: isVisible && !isMinimized + visible: false }); Controller.mousePressEvent.connect(onMousePressEvent); From 17ce80ed69e97cdb075c27584751cccb78098cf5 Mon Sep 17 00:00:00 2001 From: Marko Kudjerski Date: Fri, 24 Jun 2016 19:28:31 -0700 Subject: [PATCH 24/77] sign executables with SHA256 --- cmake/macros/OptionalWinExecutableSigning.cmake | 2 +- cmake/templates/NSIS.template.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/macros/OptionalWinExecutableSigning.cmake b/cmake/macros/OptionalWinExecutableSigning.cmake index 784aae716f..41ca5762dc 100644 --- a/cmake/macros/OptionalWinExecutableSigning.cmake +++ b/cmake/macros/OptionalWinExecutableSigning.cmake @@ -22,7 +22,7 @@ macro(optional_win_executable_signing) # setup a post build command to sign the executable add_custom_command( TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${SIGNTOOL_EXECUTABLE} sign /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 ${EXECUTABLE_PATH} + COMMAND ${SIGNTOOL_EXECUTABLE} sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 ${EXECUTABLE_PATH} ) else () message(FATAL_ERROR "HF_PFX_PASSPHRASE must be set for executables to be signed.") diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 0ea1199c09..4786b12743 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -64,7 +64,7 @@ ; The Inner invocation has written an uninstaller binary for us. ; We need to sign it if it's a production or PR build. !if @PRODUCTION_BUILD@ == 1 - !system '"@SIGNTOOL_EXECUTABLE@" sign /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 + !system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 !endif ; Good. Now we can carry on writing the real installer. From bbe9b931bee9364581feb1ab983de329f7d0c301 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 26 Jun 2016 14:59:42 -0700 Subject: [PATCH 25/77] on Linux, don't mess with the menus from the hydra plugin because it makes Qt stop --- plugins/hifiSixense/src/SixenseManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index ade643ec72..baf13f1fae 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -77,6 +77,7 @@ bool SixenseManager::activate() { InputPlugin::activate(); #ifdef HAVE_SIXENSE + #if !defined(Q_OS_LINUX) _container->addMenu(MENU_PATH); _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, TOGGLE_SMOOTH, [this] (bool clicked) { setSixenseFilter(clicked); }, @@ -89,6 +90,7 @@ bool SixenseManager::activate() { _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, SHOW_DEBUG_CALIBRATED, [this] (bool clicked) { _inputDevice->setDebugDrawCalibrated(clicked); }, true, false); + #endif auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(_inputDevice); @@ -106,8 +108,10 @@ void SixenseManager::deactivate() { InputPlugin::deactivate(); #ifdef HAVE_SIXENSE + #if !defined(Q_OS_LINUX) _container->removeMenuItem(MENU_NAME, TOGGLE_SMOOTH); _container->removeMenu(MENU_PATH); + #endif _inputDevice->_poseStateMap.clear(); From 55c2466249d65875f2a65e04a520de976edb4f34 Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Mon, 27 Jun 2016 10:25:53 -0700 Subject: [PATCH 26/77] Move .eslintrc.js to project root This way, all project scripts are in scope, and the .eslintrc doesn't get pushed to the installer with the default scripts. --- scripts/.eslintrc.js => .eslintrc.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/.eslintrc.js => .eslintrc.js (100%) diff --git a/scripts/.eslintrc.js b/.eslintrc.js similarity index 100% rename from scripts/.eslintrc.js rename to .eslintrc.js From 235ee4bd463e69c3bcd1d808ece0244c1014926d Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Mon, 27 Jun 2016 13:06:12 -0700 Subject: [PATCH 27/77] Refactor Camera scripting interface a little get/setRotation has been removed, as it was a duplicate of get/setOrientation, but undocumented and barely used. get/setTransform and get/setPerspective have been changed to methods from slots, since glm::mat4 is not exposed to the scriping interface so they don't work in scripting. --- interface/src/Application.cpp | 26 +++++++++++++------------- interface/src/Camera.cpp | 16 ++++++++-------- interface/src/Camera.h | 27 ++++++++++++--------------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 26da43fb58..049356e298 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1717,22 +1717,22 @@ void Application::paintGL() { if (isHMDMode()) { mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setRotation(glm::quat_cast(camMat)); + _myCamera.setOrientation(glm::quat_cast(camMat)); } else { _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setRotation(myAvatar->getHead()->getCameraOrientation()); + _myCamera.setOrientation(myAvatar->getHead()->getCameraOrientation()); } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { if (isHMDMode()) { auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setRotation(glm::normalize(glm::quat_cast(hmdWorldMat))); + _myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat))); _myCamera.setPosition(extractTranslation(hmdWorldMat) + myAvatar->getOrientation() * boomOffset); } else { - _myCamera.setRotation(myAvatar->getHead()->getOrientation()); + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getRotation() * boomOffset); + + _myCamera.getOrientation() * boomOffset); } else { _myCamera.setPosition(myAvatar->getDefaultEyePosition() + myAvatar->getOrientation() * boomOffset); @@ -1751,7 +1751,7 @@ void Application::paintGL() { glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - _myCamera.setRotation(worldMirrorRotation); + _myCamera.setOrientation(worldMirrorRotation); glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); // Mirror HMD lateral offsets @@ -1762,7 +1762,7 @@ void Application::paintGL() { + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + mirrorBodyOrientation * hmdOffset); } else { - _myCamera.setRotation(myAvatar->getWorldAlignedOrientation() + _myCamera.setOrientation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); _myCamera.setPosition(myAvatar->getDefaultEyePosition() + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) @@ -1775,11 +1775,11 @@ void Application::paintGL() { if (cameraEntity != nullptr) { if (isHMDMode()) { glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setRotation(cameraEntity->getRotation() * hmdRotation); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); } else { - _myCamera.setRotation(cameraEntity->getRotation()); + _myCamera.setOrientation(cameraEntity->getRotation()); _myCamera.setPosition(cameraEntity->getPosition()); } } @@ -3314,9 +3314,9 @@ void Application::updateMyAvatarLookAtPosition() { if (isLookingAtSomeone) { deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; } - lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( + lookAtSpot = origin + _myCamera.getOrientation() * glm::quat(glm::radians(glm::vec3( eyePitch * deflection, eyeYaw * deflection, 0.0f))) * - glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); + glm::inverse(_myCamera.getOrientation()) * (lookAtSpot - origin); } } @@ -4032,7 +4032,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { // Set the viewFrustum up with the correct position and orientation of the camera viewFrustum.setPosition(camera.getPosition()); - viewFrustum.setOrientation(camera.getRotation()); + viewFrustum.setOrientation(camera.getOrientation()); // Ask the ViewFrustum class to calculate our corners viewFrustum.calculate(); @@ -4305,7 +4305,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * myAvatar->getScale()); } _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); - _mirrorCamera.setRotation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); + _mirrorCamera.setOrientation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); // set the bounds of rear mirror view diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 53a3500bff..227bdadb97 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -62,14 +62,14 @@ void Camera::update(float deltaTime) { } void Camera::recompose() { - mat4 orientation = glm::mat4_cast(_rotation); + mat4 orientation = glm::mat4_cast(_orientation); mat4 translation = glm::translate(mat4(), _position); _transform = translation * orientation; } void Camera::decompose() { _position = vec3(_transform[3]); - _rotation = glm::quat_cast(_transform); + _orientation = glm::quat_cast(_transform); } void Camera::setTransform(const glm::mat4& transform) { @@ -85,8 +85,8 @@ void Camera::setPosition(const glm::vec3& position) { } } -void Camera::setRotation(const glm::quat& rotation) { - _rotation = rotation; +void Camera::setOrientation(const glm::quat& orientation) { + _orientation = orientation; recompose(); if (_isKeepLookingAt) { lookAt(_lookingAt); @@ -154,9 +154,9 @@ QString Camera::getModeString() const { void Camera::lookAt(const glm::vec3& lookAt) { glm::vec3 up = IDENTITY_UP; glm::mat4 lookAtMatrix = glm::lookAt(_position, lookAt, up); - glm::quat rotation = glm::quat_cast(lookAtMatrix); - rotation.w = -rotation.w; // Rosedale approved - _rotation = rotation; + glm::quat orientation = glm::quat_cast(lookAtMatrix); + orientation.w = -orientation.w; // Rosedale approved + _orientation = orientation; } void Camera::keepLookingAt(const glm::vec3& point) { @@ -171,7 +171,7 @@ void Camera::loadViewFrustum(ViewFrustum& frustum) const { // Set the viewFrustum up with the correct position and orientation of the camera frustum.setPosition(getPosition()); - frustum.setOrientation(getRotation()); + frustum.setOrientation(getOrientation()); // Ask the ViewFrustum class to calculate our corners frustum.calculate(); diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 486b98c100..46cad2efc8 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -45,7 +45,7 @@ class Camera : public QObject { public: Camera(); - void initialize(); // instantly put the camera at the ideal position and rotation. + void initialize(); // instantly put the camera at the ideal position and orientation. void update( float deltaTime ); @@ -57,25 +57,22 @@ public: EntityItemPointer getCameraEntityPointer() const { return _cameraEntity; } -public slots: - QString getModeString() const; - void setModeString(const QString& mode); - - glm::quat getRotation() const { return _rotation; } - void setRotation(const glm::quat& rotation); - - glm::vec3 getPosition() const { return _position; } - void setPosition(const glm::vec3& position); - - glm::quat getOrientation() const { return getRotation(); } - void setOrientation(const glm::quat& orientation) { setRotation(orientation); } - const glm::mat4& getTransform() const { return _transform; } void setTransform(const glm::mat4& transform); const glm::mat4& getProjection() const { return _projection; } void setProjection(const glm::mat4& projection); +public slots: + QString getModeString() const; + void setModeString(const QString& mode); + + glm::vec3 getPosition() const { return _position; } + void setPosition(const glm::vec3& position); + + glm::quat getOrientation() const { return _orientation; } + void setOrientation(const glm::quat& orientation); + QUuid getCameraEntity() const; void setCameraEntity(QUuid entityID); @@ -105,7 +102,7 @@ private: // derived glm::vec3 _position; - glm::quat _rotation; + glm::quat _orientation; bool _isKeepLookingAt{ false }; glm::vec3 _lookingAt; EntityItemPointer _cameraEntity; From 68be819ea25eecc159d1034869098a2f8e125b91 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 27 Jun 2016 14:07:13 -0700 Subject: [PATCH 28/77] fix crash when hmd context menu triggers a modal --- .../resources/qml/menus/MenuMouseHandler.qml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/menus/MenuMouseHandler.qml b/interface/resources/qml/menus/MenuMouseHandler.qml index 9ba158cb28..48574d41e5 100644 --- a/interface/resources/qml/menus/MenuMouseHandler.qml +++ b/interface/resources/qml/menus/MenuMouseHandler.qml @@ -39,6 +39,19 @@ Item { onSelected: d.handleSelection(subMenu, currentItem, item) } } + property var delay: Timer { // No setTimeout in QML. + property var menuItem: null; + interval: 0 + repeat: false + running: false + function trigger(item) { // Capture item and schedule asynchronous Timer. + menuItem = item; + start(); + } + onTriggered: { + menuItem.trigger(); // Now trigger the item. + } + } function toModel(items) { var result = modelMaker.createObject(desktop); @@ -128,7 +141,8 @@ Item { case MenuItemType.Item: console.log("Triggering " + item.text) - item.trigger(); + // Don't block waiting for modal dialogs and such that the menu might open. + delay.trigger(item); clearMenus(); break; } From 79cfd2e9dc4f67d0bd1167c86f7e9a501e551f66 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 28 Jun 2016 11:40:49 +1200 Subject: [PATCH 29/77] Reduce users window flicker when restart script --- scripts/system/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index f23a0ea215..d25e1b76b4 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -599,8 +599,6 @@ var usersWindow = (function () { usersRequest.ontimeout = pollUsersTimedOut; usersRequest.onreadystatechange = processUsers; usersRequest.send(); - - checkLoggedIn(); } processUsers = function () { @@ -646,6 +644,8 @@ var usersWindow = (function () { updateUsersDisplay(); updateOverlayPositions(); + checkLoggedIn(); + } else { print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText); usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay. From b36a39b2bcda94de87fdc831da884611f8a85eea Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 28 Jun 2016 09:59:59 -0700 Subject: [PATCH 30/77] Add version to launch user activity --- interface/src/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1a0a11ccc3..1d8b3ae9d9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -773,6 +773,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto gpuIdent = GPUIdent::getInstance(); auto glContextData = getGLContextData(); QJsonObject properties = { + { "version", applicationVersion() }, { "previousSessionCrashed", _previousSessionCrashed }, { "previousSessionRuntime", sessionRunTime.get() }, { "cpu_architecture", QSysInfo::currentCpuArchitecture() }, From 18a1f74c3752bd35a6d93f5135027453c0a9a671 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 28 Jun 2016 10:32:43 -0700 Subject: [PATCH 31/77] remove unused boolean for signalling protocol mismatch --- libraries/networking/src/DomainHandler.cpp | 1 - libraries/networking/src/DomainHandler.h | 1 - 2 files changed, 2 deletions(-) diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index c4b979e0b8..739c0f8f4a 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -117,7 +117,6 @@ void DomainHandler::hardReset() { _hostname = QString(); _sockAddr.clear(); - _hasSignalledProtocolMismatch = false; _domainConnectionRefusals.clear(); _hasCheckedForAccessToken = false; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 0c041da47d..50639a4817 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -145,7 +145,6 @@ private: QTimer _settingsTimer; QSet _domainConnectionRefusals; - bool _hasSignalledProtocolMismatch { false }; bool _hasCheckedForAccessToken { false }; int _connectionDenialsSinceKeypairRegen { 0 }; From 799686f29d46eb53c96742a53cea1bf9b4a7eea4 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 28 Jun 2016 11:36:08 -0700 Subject: [PATCH 32/77] Only update the (invisible) cursor position from hand controllers when the trigger is partially squeezed. --- .../controllers/handControllerPointer.js | 71 ++++++++++++------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index a0f1f47b3c..981600f0bd 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -187,6 +187,32 @@ function overlayFromWorldPoint(point) { return { x: horizontalPixels, y: verticalPixels }; } +function activeHudPoint2d(activeHand) { // if controller is valid, update reticle position and answer 2d point. Otherwise falsey. + var controllerPose = Controller.getPoseValue(activeHand); + // Valid if any plugged-in hand controller is "on". (uncradled Hydra, green-lighted Vive...) + if (!controllerPose.valid) { + return; // Controller is cradled. + } + var controllerPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, controllerPose.translation), + MyAvatar.position); + // This gets point direction right, but if you want general quaternion it would be more complicated: + var controllerDirection = Quat.getUp(Quat.multiply(MyAvatar.orientation, controllerPose.rotation)); + + var hudPoint3d = calculateRayUICollisionPoint(controllerPosition, controllerDirection); + if (!hudPoint3d) { + if (Menu.isOptionChecked("Overlays")) { // With our hud resetting strategy, hudPoint3d should be valid here + print('Controller is parallel to HUD'); // so let us know that our assumptions are wrong. + } + return; + } + var hudPoint2d = overlayFromWorldPoint(hudPoint3d); + + // We don't know yet if we'll want to make the cursor or laser visble, but we need to move it to see if + // it's pointing at a QML tool (aka system overlay). + setReticlePosition(hudPoint2d); + return hudPoint2d; +} + // MOUSE ACTIVITY -------- // var isSeeking = false; @@ -351,8 +377,23 @@ function isPointingAtOverlayStartedNonFullTrigger(trigger) { } clickMapping.from(rightTrigger.full).when(isPointingAtOverlayStartedNonFullTrigger(rightTrigger)).to(Controller.Actions.ReticleClick); clickMapping.from(leftTrigger.full).when(isPointingAtOverlayStartedNonFullTrigger(leftTrigger)).to(Controller.Actions.ReticleClick); -clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(Controller.Actions.ContextMenu); -clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(Controller.Actions.ContextMenu); +// The following is essentially like Left and Right versions of +// clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(Controller.Actions.ContextMenu); +// except that we first update the reticle position from the appropriate hand position, before invoking the ContextMenu. +var wantsMenu = 0; +clickMapping.from(function () { return wantsMenu; }).to(Controller.Actions.ContextMenu); +clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(function (clicked) { + if (clicked) { + activeHudPoint2d(Controller.Standard.RightHand); + } + wantsMenu = clicked; +}); +clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (clicked) { + if (clicked) { + activeHudPoint2d(Controller.Standard.LeftHand); + } + wantsMenu = clicked; +}); clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () { // Allow the reticle depth to be set correctly: // Wait a tick for the context menu to be displayed, and then simulate a (non-hand-controller) mouse move @@ -408,28 +449,13 @@ function update() { } leftTrigger.update(); rightTrigger.update(); - var controllerPose = Controller.getPoseValue(activeHand); - // Valid if any plugged-in hand controller is "on". (uncradled Hydra, green-lighted Vive...) - if (!controllerPose.valid) { - return off(); // Controller is cradled. + if (!activeTrigger.state) { + return off(); // No trigger } - var controllerPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, controllerPose.translation), - MyAvatar.position); - // This gets point direction right, but if you want general quaternion it would be more complicated: - var controllerDirection = Quat.getUp(Quat.multiply(MyAvatar.orientation, controllerPose.rotation)); - - var hudPoint3d = calculateRayUICollisionPoint(controllerPosition, controllerDirection); - if (!hudPoint3d) { - if (Menu.isOptionChecked("Overlays")) { // With our hud resetting strategy, hudPoint3d should be valid here - print('Controller is parallel to HUD'); // so let us know that our assumptions are wrong. - } + var hudPoint2d = activeHudPoint2d(activeHand); + if (!hudPoint2d) { return off(); } - var hudPoint2d = overlayFromWorldPoint(hudPoint3d); - - // We don't know yet if we'll want to make the cursor visble, but we need to move it to see if - // it's pointing at a QML tool (aka system overlay). - setReticlePosition(hudPoint2d); // If there's a HUD element at the (newly moved) reticle, just make it visible and bail. if (isPointingAtOverlay(hudPoint2d)) { if (HMD.active) { @@ -446,9 +472,6 @@ function update() { return; } // We are not pointing at a HUD element (but it could be a 3d overlay). - if (!activeTrigger.state) { - return off(); // No trigger - } clearSystemLaser(); Reticle.visible = false; } From c492d125e080a018d20b56b322a43a523ecb9e2e Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 28 Jun 2016 13:19:03 -0700 Subject: [PATCH 33/77] limit hand controller actions to recommended area --- scripts/system/controllers/handControllerPointer.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index a0f1f47b3c..8e2edbe467 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -125,8 +125,18 @@ function ignoreMouseActivity() { weMovedReticle = false; return true; } +var reticleMinX, reticleMaxX, reticleMinY, reticleMaxY; +function updateRecommendedArea() { + var rectangle = Controller.getRecommendedOverlayRect(); + reticleMinX = rectangle.x; + reticleMaxX = rectangle.x + rectangle.width; + reticleMinY = rectangle.y; + reticleMaxY = rectangle.y + rectangle.height; +} var setReticlePosition = function (point2d) { weMovedReticle = true; + point2d.x = Math.max(reticleMinX, Math.min(point2d.x, reticleMaxX)); + point2d.y = Math.max(reticleMinY, Math.min(point2d.y, reticleMaxY)); Reticle.setPosition(point2d); }; @@ -463,6 +473,7 @@ Script.scriptEnding.connect(function () { var SETTINGS_CHANGE_RECHECK_INTERVAL = 10 * 1000; // milliseconds function checkSettings() { updateFieldOfView(); + updateRecommendedArea(); } checkSettings(); var settingsChecker = Script.setInterval(checkSettings, SETTINGS_CHANGE_RECHECK_INTERVAL); From e538625fe07a062988351c35b77cdf07cbc01b69 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Jun 2016 16:35:32 -0700 Subject: [PATCH 34/77] fix warning about convex hull vertex count cap --- libraries/physics/src/PhysicalEntitySimulation.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index cdf33a6edb..9714059e7c 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -218,10 +218,12 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); int numPoints = shapeInfo.getLargestSubshapePointCount(); - if (numPoints > MAX_HULL_POINTS) { - qWarning() << "convex hull with" << numPoints - << "points for entity" << entity->getName() - << "at" << entity->getPosition() << " will be reduced"; + if (shapeInfo.getType() == SHAPE_TYPE_COMPOUND) { + if (numPoints > MAX_HULL_POINTS) { + qWarning() << "convex hull with" << numPoints + << "points for entity" << entity->getName() + << "at" << entity->getPosition() << " will be reduced"; + } } btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { From 74781c078638fbddd9a0fe5c5cbb6960a91526e9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Jun 2016 16:36:10 -0700 Subject: [PATCH 35/77] boxify static meshes with too many vertices --- .../entities-renderer/src/RenderableModelEntityItem.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 366e365107..43fea75eac 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -696,6 +696,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { QVector localTransforms; const FBXGeometry& geometry = _model->getFBXGeometry(); int numberOfMeshes = geometry.meshes.size(); + int totalNumVertices = 0; for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& mesh = geometry.meshes.at(i); if (mesh.clusters.size() > 0) { @@ -706,6 +707,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { glm::mat4 identity; localTransforms.push_back(identity); } + totalNumVertices += mesh.vertices.size(); + } + const int MAX_VERTICES_PER_STATIC_MESH = 1e6; + if (totalNumVertices > MAX_VERTICES_PER_STATIC_MESH) { + qWarning() << "model" << getModelURL() << "has too many vertices" << totalNumVertices << "and will collide as a box."; + info.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions); + return; } updateModelBounds(); From d650c50a5bc5754cfbdc7f0a7d3cd1df62e90428 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 28 Jun 2016 17:44:30 -0700 Subject: [PATCH 36/77] Use normal Script.update (60hz) instead of a timer (@20hz). --- scripts/system/controllers/handControllerPointer.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index a0f1f47b3c..f7a85b2a43 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -398,7 +398,7 @@ function update() { } updateSeeking(true); if (!handControllerLockOut.expired(now)) { - return off(); // Let them use mouse it in peace. + return off(); // Let them use mouse in peace. } if (!Menu.isOptionChecked("First Person")) { return off(); // What to do? menus can be behind hand! @@ -406,13 +406,13 @@ function update() { if (!Window.hasFocus() || !Reticle.allowMouseCapture) { return off(); // Don't mess with other apps or paused mouse activity } - leftTrigger.update(); - rightTrigger.update(); var controllerPose = Controller.getPoseValue(activeHand); // Valid if any plugged-in hand controller is "on". (uncradled Hydra, green-lighted Vive...) if (!controllerPose.valid) { return off(); // Controller is cradled. } + leftTrigger.update(); + rightTrigger.update(); var controllerPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, controllerPose.translation), MyAvatar.position); // This gets point direction right, but if you want general quaternion it would be more complicated: @@ -452,12 +452,7 @@ function update() { clearSystemLaser(); Reticle.visible = false; } - -var UPDATE_INTERVAL = 50; // milliseconds. Script.update is too frequent. -var updater = Script.setInterval(update, UPDATE_INTERVAL); -Script.scriptEnding.connect(function () { - Script.clearInterval(updater); -}); +setupHandler(Script.update, update); // Check periodically for changes to setup. var SETTINGS_CHANGE_RECHECK_INTERVAL = 10 * 1000; // milliseconds From b551bc3c1ae20be28d312184e50fa2d0dd56461d Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 28 Jun 2016 18:01:09 -0700 Subject: [PATCH 37/77] Use the whole area, less a margin. --- scripts/system/controllers/handControllerPointer.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 8e2edbe467..00aca2af86 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -125,13 +125,12 @@ function ignoreMouseActivity() { weMovedReticle = false; return true; } -var reticleMinX, reticleMaxX, reticleMinY, reticleMaxY; +var MARGIN = 50; +var reticleMinX = MARGIN, reticleMaxX, reticleMinY = MARGIN, reticleMaxY; function updateRecommendedArea() { - var rectangle = Controller.getRecommendedOverlayRect(); - reticleMinX = rectangle.x; - reticleMaxX = rectangle.x + rectangle.width; - reticleMinY = rectangle.y; - reticleMaxY = rectangle.y + rectangle.height; + var dims = Controller.getViewportDimensions(); + reticleMaxX = dims.x - MARGIN; + reticleMaxY = dims.y - MARGIN; } var setReticlePosition = function (point2d) { weMovedReticle = true; From 962f9d5f22b1debaf131c1322742cc4e06edb582 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Jun 2016 18:10:06 -0700 Subject: [PATCH 38/77] Don't update the shown state of the tool window when it's already invisible --- interface/resources/qml/ToolWindow.qml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml index bbfc74493d..c957a37886 100644 --- a/interface/resources/qml/ToolWindow.qml +++ b/interface/resources/qml/ToolWindow.qml @@ -137,12 +137,15 @@ ScrollingWindow { } function updateVisiblity() { - for (var i = 0; i < tabView.count; ++i) { - if (tabView.getTab(i).enabled) { - return; + if (visible) { + for (var i = 0; i < tabView.count; ++i) { + if (tabView.getTab(i).enabled) { + console.log("QQQ tab is visible, returning early"); + return; + } } + shown = false; } - shown = false; } function findIndexForUrl(source) { From 21d2c977a36f656b0a1c3c56afa435c8c1c5098f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Jun 2016 18:30:07 -0700 Subject: [PATCH 39/77] Remove roll from cursor in HMD --- .../src/display-plugins/CompositorHelper.cpp | 2 +- libraries/shared/src/GLMHelpers.cpp | 6 ++++++ libraries/shared/src/GLMHelpers.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 032350a07c..89ff2e0c8d 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -425,7 +425,7 @@ glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const d = glm::normalize(overlaySurfacePoint); } reticlePosition = headPosition + (d * getReticleDepth()); - quat reticleOrientation = glm::quat_cast(_currentDisplayPlugin->getHeadPose()); + quat reticleOrientation = cancelOutRoll(glm::quat_cast(_currentDisplayPlugin->getHeadPose())); vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize * getReticleDepth()); return glm::inverse(eyePose) * createMatFromScaleQuatAndPos(reticleScale, reticleOrientation, reticlePosition); } else { diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 556c313f95..8dbd0a146f 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -466,6 +466,12 @@ glm::mat4 createMatFromScaleQuatAndPos(const glm::vec3& scale, const glm::quat& glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f)); } +// cancel out roll +glm::quat cancelOutRoll(const glm::quat& q) { + glm::vec3 forward = q * glm::vec3(0.0f, 0.0f, -1.0f); + return glm::quat_cast(glm::inverse(glm::lookAt(Vectors::ZERO, forward, Vectors::UP))); +} + // cancel out roll and pitch glm::quat cancelOutRollAndPitch(const glm::quat& q) { glm::vec3 zAxis = q * glm::vec3(0.0f, 0.0f, 1.0f); diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index ae9ec25195..ef3bfeb674 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -221,6 +221,7 @@ glm::detail::tvec4 lerp(const glm::detail::tvec4& x, const glm::deta glm::mat4 createMatFromQuatAndPos(const glm::quat& q, const glm::vec3& p); glm::mat4 createMatFromScaleQuatAndPos(const glm::vec3& scale, const glm::quat& rot, const glm::vec3& trans); +glm::quat cancelOutRoll(const glm::quat& q); glm::quat cancelOutRollAndPitch(const glm::quat& q); glm::mat4 cancelOutRollAndPitch(const glm::mat4& m); glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& p); From b16812aa4d5d4bf497a97f2b55fe435efc98a2b2 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 19 May 2016 00:37:58 -0700 Subject: [PATCH 40/77] Adding GL 4.5 backend --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 11 +- .../gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp | 4 +- libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp | 149 ++++++++++++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 85 ++++++++ .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 48 +++++ .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 83 ++++++++ .../gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp | 145 ++++++++++++++ .../gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp | 38 ++++ .../src/gpu/gl45/GL45BackendTexture.cpp | 181 +++++++++++++++++ .../src/gpu/gl45/GL45BackendTransform.cpp | 71 +++++++ libraries/gpu/src/gpu/null/NullBackend.h | 54 +++++ tests/gpu-test/src/TestFbx.cpp | 187 ++++++++++++++++++ tests/gpu-test/src/TestFbx.h | 35 ++++ tests/gpu-test/src/TestFloorGrid.cpp | 54 +++++ tests/gpu-test/src/TestFloorGrid.h | 26 +++ tests/gpu-test/src/TestFloorTexture.cpp | 88 +++++++++ tests/gpu-test/src/TestFloorTexture.h | 22 +++ tests/gpu-test/src/main.cpp | 7 +- tests/gpu-test/src/unlit.slf | 28 --- tests/gpu-test/src/unlit.slv | 36 ---- 20 files changed, 1276 insertions(+), 76 deletions(-) create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45Backend.h create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp create mode 100644 libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp create mode 100644 libraries/gpu/src/gpu/null/NullBackend.h create mode 100644 tests/gpu-test/src/TestFbx.cpp create mode 100644 tests/gpu-test/src/TestFbx.h create mode 100644 tests/gpu-test/src/TestFloorGrid.cpp create mode 100644 tests/gpu-test/src/TestFloorGrid.h create mode 100644 tests/gpu-test/src/TestFloorTexture.cpp create mode 100644 tests/gpu-test/src/TestFloorTexture.h delete mode 100644 tests/gpu-test/src/unlit.slf delete mode 100644 tests/gpu-test/src/unlit.slv diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index e18b784018..32e063a4c6 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -17,6 +17,7 @@ #include #include "../gl41/GL41Backend.h" +#include "../gl45/GL45Backend.h" #if defined(NSIGHT_FOUND) #include "nvToolsExt.h" @@ -31,25 +32,19 @@ using namespace gpu; using namespace gpu::gl; - static const QString DEBUG_FLAG("HIFI_ENABLE_OPENGL_45"); bool enableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); Backend* GLBackend::createBackend() { - -#if 0 // FIXME provide a mechanism to override the backend for testing // Where the gpuContext is initialized and where the TRUE Backend is created and assigned auto version = QOpenGLContextWrapper::currentContextVersion(); GLBackend* result; if (enableOpenGL45 && version >= 0x0405) { - result = new gpu::gl45::GLBackend; + result = new gpu::gl45::GL45Backend(); } else { - result = new gpu::gl41::GLBackend; + result = new gpu::gl41::GL41Backend(); } -#else - GLBackend* result = new gpu::gl41::GL41Backend; -#endif result->initInput(); result->initTransform(); gl::GLTexture::initTextureTransferHelper(); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp index 3c6109bbdf..478d210535 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendQuery.cpp @@ -16,7 +16,7 @@ using namespace gpu; using namespace gpu::gl41; class GL41Query : public gpu::gl::GLQuery { - using Parent = gpu::gl::GLBuffer; + using Parent = gpu::gl::GLQuery; public: static GLuint allocateQuery() { GLuint result; @@ -25,7 +25,7 @@ public: } GL41Query(const Query& query) - : gl::GLQuery(query, allocateQuery()) { } + : Parent(query, allocateQuery()) { } }; gl::GLQuery* GL41Backend::syncGPUObject(const Query& query) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp new file mode 100644 index 0000000000..bb6ae67233 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.cpp @@ -0,0 +1,149 @@ +// +// Created by Sam Gateau on 10/27/2014. +// Copyright 2014 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 "GL45Backend.h" + +#include +#include +#include +#include +#include + +Q_LOGGING_CATEGORY(gpugl45logging, "hifi.gpu.gl45") + +using namespace gpu; +using namespace gpu::gl45; + +void GL45Backend::do_draw(Batch& batch, size_t paramOffset) { + Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; + uint32 numVertices = batch._params[paramOffset + 1]._uint; + uint32 startVertex = batch._params[paramOffset + 0]._uint; + + if (isStereo()) { + setupStereoSide(0); + glDrawArrays(mode, startVertex, numVertices); + setupStereoSide(1); + glDrawArrays(mode, startVertex, numVertices); + + _stats._DSNumTriangles += 2 * numVertices / 3; + _stats._DSNumDrawcalls += 2; + + } else { + glDrawArrays(mode, startVertex, numVertices); + _stats._DSNumTriangles += numVertices / 3; + _stats._DSNumDrawcalls++; + } + _stats._DSNumAPIDrawcalls++; + + (void) CHECK_GL_ERROR(); +} + +void GL45Backend::do_drawIndexed(Batch& batch, size_t paramOffset) { + Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; + uint32 numIndices = batch._params[paramOffset + 1]._uint; + uint32 startIndex = batch._params[paramOffset + 0]._uint; + + GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; + + auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; + GLvoid* indexBufferByteOffset = reinterpret_cast(startIndex * typeByteSize + _input._indexBufferOffset); + + if (isStereo()) { + setupStereoSide(0); + glDrawElements(mode, numIndices, glType, indexBufferByteOffset); + setupStereoSide(1); + glDrawElements(mode, numIndices, glType, indexBufferByteOffset); + + _stats._DSNumTriangles += 2 * numIndices / 3; + _stats._DSNumDrawcalls += 2; + } else { + glDrawElements(mode, numIndices, glType, indexBufferByteOffset); + _stats._DSNumTriangles += numIndices / 3; + _stats._DSNumDrawcalls++; + } + _stats._DSNumAPIDrawcalls++; + + (void) CHECK_GL_ERROR(); +} + +void GL45Backend::do_drawInstanced(Batch& batch, size_t paramOffset) { + GLint numInstances = batch._params[paramOffset + 4]._uint; + Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[primitiveType]; + uint32 numVertices = batch._params[paramOffset + 2]._uint; + uint32 startVertex = batch._params[paramOffset + 1]._uint; + + + if (isStereo()) { + GLint trueNumInstances = 2 * numInstances; + + setupStereoSide(0); + glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); + setupStereoSide(1); + glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); + + _stats._DSNumTriangles += (trueNumInstances * numVertices) / 3; + _stats._DSNumDrawcalls += trueNumInstances; + } else { + glDrawArraysInstanced(mode, startVertex, numVertices, numInstances); + _stats._DSNumTriangles += (numInstances * numVertices) / 3; + _stats._DSNumDrawcalls += numInstances; + } + _stats._DSNumAPIDrawcalls++; + + (void) CHECK_GL_ERROR(); +} + +void GL45Backend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) { + GLint numInstances = batch._params[paramOffset + 4]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 3]._uint]; + uint32 numIndices = batch._params[paramOffset + 2]._uint; + uint32 startIndex = batch._params[paramOffset + 1]._uint; + uint32 startInstance = batch._params[paramOffset + 0]._uint; + GLenum glType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; + auto typeByteSize = TYPE_SIZE[_input._indexBufferType]; + GLvoid* indexBufferByteOffset = reinterpret_cast(startIndex * typeByteSize + _input._indexBufferOffset); + + if (isStereo()) { + GLint trueNumInstances = 2 * numInstances; + setupStereoSide(0); + glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); + setupStereoSide(1); + glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); + _stats._DSNumTriangles += (trueNumInstances * numIndices) / 3; + _stats._DSNumDrawcalls += trueNumInstances; + } else { + glDrawElementsInstancedBaseVertexBaseInstance(mode, numIndices, glType, indexBufferByteOffset, numInstances, 0, startInstance); + _stats._DSNumTriangles += (numInstances * numIndices) / 3; + _stats._DSNumDrawcalls += numInstances; + } + + _stats._DSNumAPIDrawcalls++; + + (void)CHECK_GL_ERROR(); +} + +void GL45Backend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) { + uint commandCount = batch._params[paramOffset + 0]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint]; + glMultiDrawArraysIndirect(mode, reinterpret_cast(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); + _stats._DSNumDrawcalls += commandCount; + _stats._DSNumAPIDrawcalls++; + (void)CHECK_GL_ERROR(); +} + +void GL45Backend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) { + uint commandCount = batch._params[paramOffset + 0]._uint; + GLenum mode = gl::PRIMITIVE_TO_GL[(Primitive)batch._params[paramOffset + 1]._uint]; + GLenum indexType = gl::ELEMENT_TYPE_TO_GL[_input._indexBufferType]; + glMultiDrawElementsIndirect(mode, indexType, reinterpret_cast(_input._indirectBufferOffset), commandCount, (GLsizei)_input._indirectBufferStride); + _stats._DSNumDrawcalls += commandCount; + _stats._DSNumAPIDrawcalls++; + (void)CHECK_GL_ERROR(); +} diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h new file mode 100644 index 0000000000..d0dfbd0e41 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -0,0 +1,85 @@ +// +// GL45Backend.h +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 10/27/2014. +// Copyright 2014 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 +// +#ifndef hifi_gpu_45_GL45Backend_h +#define hifi_gpu_45_GL45Backend_h + +#include "../gl/GLBackend.h" +#include "../gl/GLTexture.h" + +namespace gpu { namespace gl45 { + +class GL45Backend : public gl::GLBackend { + using Parent = gl::GLBackend; + // Context Backend static interface required + friend class Context; + +public: + explicit GL45Backend(bool syncCache) : Parent(syncCache) {} + GL45Backend() : Parent() {} + + class GL45Texture : public gpu::gl::GLTexture { + using Parent = gpu::gl::GLTexture; + GLuint allocate(const Texture& texture); + public: + GL45Texture(const Texture& texture, bool transferrable); + GL45Texture(const Texture& texture, GLTexture* original); + + protected: + void transferMip(uint16_t mipLevel, uint8_t face = 0) const; + void allocateStorage() const override; + void updateSize() const override; + void transfer() const override; + void syncSampler() const override; + void generateMips() const override; + void withPreservedTexture(std::function f) const override; + }; + + +protected: + GLuint getFramebufferID(const FramebufferPointer& framebuffer) override; + gl::GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; + + GLuint getBufferID(const Buffer& buffer) override; + gl::GLBuffer* syncGPUObject(const Buffer& buffer) override; + + GLuint getTextureID(const TexturePointer& texture, bool needTransfer = true) override; + gl::GLTexture* syncGPUObject(const TexturePointer& texture, bool sync = true) override; + + GLuint getQueryID(const QueryPointer& query) override; + gl::GLQuery* syncGPUObject(const Query& query) override; + + // Draw Stage + void do_draw(Batch& batch, size_t paramOffset) override; + void do_drawIndexed(Batch& batch, size_t paramOffset) override; + void do_drawInstanced(Batch& batch, size_t paramOffset) override; + void do_drawIndexedInstanced(Batch& batch, size_t paramOffset) override; + void do_multiDrawIndirect(Batch& batch, size_t paramOffset) override; + void do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) override; + + // Input Stage + void updateInput() override; + + // Synchronize the state cache of this Backend with the actual real state of the GL Context + void transferTransformState(const Batch& batch) const override; + void initTransform() override; + void updateTransform(const Batch& batch); + void resetTransformStage(); + + // Output stage + void do_blit(Batch& batch, size_t paramOffset) override; +}; + +} } + +Q_DECLARE_LOGGING_CATEGORY(gpugl45logging) + + +#endif diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp new file mode 100644 index 0000000000..b7bb04cbfb --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -0,0 +1,48 @@ +// +// Created by Bradley Austin Davis on 2016/05/15 +// Copyright 2013-2016 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 "GL45Backend.h" +#include "../gl/GLBuffer.h" + +using namespace gpu; +using namespace gpu::gl45; + +class GL45Buffer : public gl::GLBuffer { + using Parent = gpu::gl::GLBuffer; + static GLuint allocate() { + GLuint result; + glCreateBuffers(1, &result); + return result; + } + +public: + GL45Buffer(const Buffer& buffer, GLBuffer* original) : Parent(buffer, allocate()) { + glNamedBufferStorage(_buffer, _size, nullptr, GL_DYNAMIC_STORAGE_BIT); + glCopyNamedBufferSubData(original->_buffer, _buffer, 0, 0, std::min(original->_size, _size)); + Backend::setGPUObject(buffer, this); + } + + void transfer() override { + Size offset; + Size size; + Size currentPage { 0 }; + auto data = _gpuObject.getSysmem().readData(); + while (_gpuObject.getNextTransferBlock(offset, size, currentPage)) { + glNamedBufferSubData(_buffer, (GLintptr)offset, (GLsizeiptr)size, data + offset); + } + (void)CHECK_GL_ERROR(); + _gpuObject._flags &= ~Buffer::DIRTY; + } +}; + +GLuint GL45Backend::getBufferID(const Buffer& buffer) { + return GL45Buffer::getId(buffer); +} + +gl::GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { + return GL45Buffer::sync(buffer); +} diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp new file mode 100644 index 0000000000..5cefe40448 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -0,0 +1,83 @@ +// +// GL45BackendInput.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 3/8/2015. +// Copyright 2014 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 "GL45Backend.h" + +using namespace gpu; +using namespace gpu::gl45; + +void GL45Backend::updateInput() { + if (_input._invalidFormat) { + + InputStageState::ActivationCache newActivation; + + // Assign the vertex format required + if (_input._format) { + for (auto& it : _input._format->getAttributes()) { + const Stream::Attribute& attrib = (it).second; + + GLuint slot = attrib._slot; + GLuint count = attrib._element.getLocationScalarCount(); + uint8_t locationCount = attrib._element.getLocationCount(); + GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; + GLuint offset = (GLuint)attrib._offset;; + GLboolean isNormalized = attrib._element.isNormalized(); + + GLenum perLocationSize = attrib._element.getLocationSize(); + + for (uint8_t locNum = 0; locNum < locationCount; ++locNum) { + newActivation.set(slot + locNum); + glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); + glVertexAttribBinding(slot + locNum, attrib._channel); + } + glVertexBindingDivisor(attrib._channel, attrib._frequency); + } + (void) CHECK_GL_ERROR(); + } + + // Manage Activation what was and what is expected now + for (uint32_t i = 0; i < newActivation.size(); i++) { + bool newState = newActivation[i]; + if (newState != _input._attributeActivation[i]) { + if (newState) { + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + } + _input._attributeActivation.flip(i); + } + } + (void) CHECK_GL_ERROR(); + + _input._invalidFormat = false; + _stats._ISNumFormatChanges++; + } + + if (_input._invalidBuffers.any()) { + auto numBuffers = _input._buffers.size(); + auto buffer = _input._buffers.data(); + auto vbo = _input._bufferVBOs.data(); + auto offset = _input._bufferOffsets.data(); + auto stride = _input._bufferStrides.data(); + + for (uint32_t bufferNum = 0; bufferNum < numBuffers; bufferNum++) { + if (_input._invalidBuffers.test(bufferNum)) { + glBindVertexBuffer(bufferNum, (*vbo), (GLuint)(*offset), (GLuint)(*stride)); + } + buffer++; + vbo++; + offset++; + stride++; + } + _input._invalidBuffers.reset(); + (void) CHECK_GL_ERROR(); + } +} + diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp new file mode 100644 index 0000000000..7f511be3e8 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp @@ -0,0 +1,145 @@ +// +// GL45BackendTexture.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 1/19/2015. +// Copyright 2014 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 "GL45Backend.h" +#include "../gl/GLFramebuffer.h" +#include "../gl/GLTexture.h" + +#include + +namespace gpu { namespace gl45 { + +class GL45Framebuffer : public gl::GLFramebuffer { + using Parent = gl::GLFramebuffer; + static GLuint allocate() { + GLuint result; + glCreateFramebuffers(1, &result); + return result; + } +public: + void update() override { + gl::GLTexture* gltexture = nullptr; + TexturePointer surface; + if (_gpuObject.getColorStamps() != _colorStamps) { + if (_gpuObject.hasColor()) { + _colorBuffers.clear(); + static const GLenum colorAttachments[] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, + GL_COLOR_ATTACHMENT5, + GL_COLOR_ATTACHMENT6, + GL_COLOR_ATTACHMENT7, + GL_COLOR_ATTACHMENT8, + GL_COLOR_ATTACHMENT9, + GL_COLOR_ATTACHMENT10, + GL_COLOR_ATTACHMENT11, + GL_COLOR_ATTACHMENT12, + GL_COLOR_ATTACHMENT13, + GL_COLOR_ATTACHMENT14, + GL_COLOR_ATTACHMENT15 }; + + int unit = 0; + for (auto& b : _gpuObject.getRenderBuffers()) { + surface = b._texture; + if (surface) { + gltexture = gl::GLTexture::sync(surface, false); // Grab the gltexture and don't transfer + } else { + gltexture = nullptr; + } + + if (gltexture) { + glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0); + _colorBuffers.push_back(colorAttachments[unit]); + } else { + glNamedFramebufferTexture(_id, colorAttachments[unit], 0, 0); + } + unit++; + } + } + _colorStamps = _gpuObject.getColorStamps(); + } + + GLenum attachement = GL_DEPTH_STENCIL_ATTACHMENT; + if (!_gpuObject.hasStencil()) { + attachement = GL_DEPTH_ATTACHMENT; + } else if (!_gpuObject.hasDepth()) { + attachement = GL_STENCIL_ATTACHMENT; + } + + if (_gpuObject.getDepthStamp() != _depthStamp) { + auto surface = _gpuObject.getDepthStencilBuffer(); + if (_gpuObject.hasDepthStencil() && surface) { + gltexture = gl::GLTexture::sync(surface, false); // Grab the gltexture and don't transfer + } + + if (gltexture) { + glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0); + } else { + glNamedFramebufferTexture(_id, attachement, 0, 0); + } + _depthStamp = _gpuObject.getDepthStamp(); + } + + + // Last but not least, define where we draw + if (!_colorBuffers.empty()) { + glDrawBuffers((GLsizei)_colorBuffers.size(), _colorBuffers.data()); + } else { + glDrawBuffer(GL_NONE); + } + + // Now check for completness + _status = glCheckNamedFramebufferStatus(_id, GL_DRAW_FRAMEBUFFER); + + // restore the current framebuffer + checkStatus(GL_DRAW_FRAMEBUFFER); + } + + +public: + GL45Framebuffer(const gpu::Framebuffer& framebuffer) + : Parent(framebuffer, allocate()) { } +}; + +gl::GLFramebuffer* GL45Backend::syncGPUObject(const Framebuffer& framebuffer) { + return gl::GLFramebuffer::sync(framebuffer); +} + +GLuint GL45Backend::getFramebufferID(const FramebufferPointer& framebuffer) { + return framebuffer ? gl::GLFramebuffer::getId(*framebuffer) : 0; +} + +void GL45Backend::do_blit(Batch& batch, size_t paramOffset) { + auto srcframebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint); + Vec4i srcvp; + for (auto i = 0; i < 4; ++i) { + srcvp[i] = batch._params[paramOffset + 1 + i]._int; + } + + auto dstframebuffer = batch._framebuffers.get(batch._params[paramOffset + 5]._uint); + Vec4i dstvp; + for (auto i = 0; i < 4; ++i) { + dstvp[i] = batch._params[paramOffset + 6 + i]._int; + } + + // Assign dest framebuffer if not bound already + auto destFbo = getFramebufferID(dstframebuffer); + auto srcFbo = getFramebufferID(srcframebuffer); + glBlitNamedFramebuffer(srcFbo, destFbo, + srcvp.x, srcvp.y, srcvp.z, srcvp.w, + dstvp.x, dstvp.y, dstvp.z, dstvp.w, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + (void) CHECK_GL_ERROR(); +} + +} } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp new file mode 100644 index 0000000000..a7a7c26bed --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendQuery.cpp @@ -0,0 +1,38 @@ +// +// GL45BackendQuery.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 7/7/2015. +// 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 "GL45Backend.h" + +#include "../gl/GLQuery.h" + +namespace gpu { namespace gl45 { + +class GL45Query : public gpu::gl::GLQuery { + using Parent = gpu::gl::GLQuery; +public: + static GLuint allocateQuery() { + GLuint result; + glCreateQueries(GL_TIME_ELAPSED, 1, &result); + return result; + } + + GL45Query(const Query& query) + : Parent(query, allocateQuery()) { } +}; + +gl::GLQuery* GL45Backend::syncGPUObject(const Query& query) { + return GL45Query::sync(query); +} + +GLuint GL45Backend::getQueryID(const QueryPointer& query) { + return GL45Query::getId(query); +} + +} } \ No newline at end of file diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp new file mode 100644 index 0000000000..36fb4bfde3 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -0,0 +1,181 @@ +// +// GL45BackendTexture.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 1/19/2015. +// Copyright 2014 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 "GL45Backend.h" + +#include +#include +#include + +#include "../gl/GLTexelFormat.h" + +using namespace gpu; +using namespace gpu::gl45; + +using GLTexelFormat = gl::GLTexelFormat; +using GL45Texture = GL45Backend::GL45Texture; + +GLuint GL45Texture::allocate(const Texture& texture) { + Backend::incrementTextureGPUCount(); + GLuint result; + glCreateTextures(getGLTextureType(texture), 1, &result); + return result; +} + +GLuint GL45Backend::getTextureID(const TexturePointer& texture, bool transfer) { + return GL45Texture::getId(texture, transfer); +} + +gl::GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texture, bool transfer) { + return GL45Texture::sync(texture, transfer); +} + +GL45Backend::GL45Texture::GL45Texture(const Texture& texture, bool transferrable) + : gl::GLTexture(texture, allocate(texture), transferrable) {} + +GL45Backend::GL45Texture::GL45Texture(const Texture& texture, GLTexture* original) + : gl::GLTexture(texture, allocate(texture), original) {} + +void GL45Backend::GL45Texture::withPreservedTexture(std::function f) const { + f(); +} + +void GL45Backend::GL45Texture::generateMips() const { + glGenerateTextureMipmap(_id); + (void)CHECK_GL_ERROR(); +} + +void GL45Backend::GL45Texture::allocateStorage() const { + gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); + glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip); + if (_gpuObject.getTexelFormat().isCompressed()) { + qFatal("Compressed textures not yet supported"); + } + // Get the dimensions, accounting for the downgrade level + Vec3u dimensions = _gpuObject.evalMipDimensions(_minMip); + glTextureStorage2D(_id, usedMipLevels(), texelFormat.internalFormat, dimensions.x, dimensions.y); + (void)CHECK_GL_ERROR(); +} + +void GL45Backend::GL45Texture::updateSize() const { + setSize(_virtualSize); + if (!_id) { + return; + } + + if (_gpuObject.getTexelFormat().isCompressed()) { + qFatal("Compressed textures not yet supported"); + } +} + +// Move content bits from the CPU to the GPU for a given mip / face +void GL45Backend::GL45Texture::transferMip(uint16_t mipLevel, uint8_t face) const { + auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); + gl::GLTexelFormat texelFormat = gl::GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); + auto size = _gpuObject.evalMipDimensions(mipLevel); + if (GL_TEXTURE_2D == _target) { + glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData()); + } else if (GL_TEXTURE_CUBE_MAP == _target) { + glTextureSubImage3D(_id, mipLevel, 0, 0, face, size.x, size.y, 1, texelFormat.format, texelFormat.type, mip->readData()); + } else { + Q_ASSERT(false); + } + (void)CHECK_GL_ERROR(); +} + +// This should never happen on the main thread +// Move content bits from the CPU to the GPU +void GL45Backend::GL45Texture::transfer() const { + PROFILE_RANGE(__FUNCTION__); + //qDebug() << "Transferring texture: " << _privateTexture; + // Need to update the content of the GPU object from the source sysmem of the texture + if (_contentStamp >= _gpuObject.getDataStamp()) { + return; + } + + if (_downsampleSource._texture) { + GLuint fbo { 0 }; + glCreateFramebuffers(1, &fbo); + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + // Find the distance between the old min mip and the new one + uint16 mipOffset = _minMip - _downsampleSource._minMip; + for (uint16 i = _minMip; i <= _maxMip; ++i) { + uint16 targetMip = i - _minMip; + uint16 sourceMip = targetMip + mipOffset; + Vec3u dimensions = _gpuObject.evalMipDimensions(i); + for (GLenum target : getFaceTargets(_target)) { + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, _downsampleSource._texture, sourceMip); + (void)CHECK_GL_ERROR(); + glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, dimensions.x, dimensions.y); + (void)CHECK_GL_ERROR(); + } + } + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &fbo); + } else { + // GO through the process of allocating the correct storage and/or update the content + switch (_gpuObject.getType()) { + case Texture::TEX_2D: + { + for (uint16_t i = _minMip; i <= _maxMip; ++i) { + if (_gpuObject.isStoredMipFaceAvailable(i)) { + transferMip(i); + } + } + } + break; + + case Texture::TEX_CUBE: + // transfer pixels from each faces + for (uint8_t f = 0; f < CUBE_NUM_FACES; f++) { + for (uint16_t i = 0; i < Sampler::MAX_MIP_LEVEL; ++i) { + if (_gpuObject.isStoredMipFaceAvailable(i, f)) { + transferMip(i, f); + } + } + } + break; + + default: + qCWarning(gpugl45logging) << __FUNCTION__ << " case for Texture Type " << _gpuObject.getType() << " not supported"; + break; + } + } + if (_gpuObject.isAutogenerateMips()) { + glGenerateTextureMipmap(_id); + (void)CHECK_GL_ERROR(); + } +} + +void GL45Backend::GL45Texture::syncSampler() const { + const Sampler& sampler = _gpuObject.getSampler(); + + const auto& fm = FILTER_MODES[sampler.getFilter()]; + glTextureParameteri(_id, GL_TEXTURE_MIN_FILTER, fm.minFilter); + glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter); + + if (sampler.doComparison()) { + glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, gl::COMPARISON_TO_GL[sampler.getComparisonFunction()]); + } else { + glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE); + } + + glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]); + glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]); + glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]); + glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor()); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, (uint16)sampler.getMipOffset()); + glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); + glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); + glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); +} + diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp new file mode 100644 index 0000000000..fd49729164 --- /dev/null +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp @@ -0,0 +1,71 @@ +// +// GL45BackendTransform.cpp +// libraries/gpu/src/gpu +// +// Created by Sam Gateau on 3/8/2015. +// Copyright 2014 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 "GL45Backend.h" + +using namespace gpu; +using namespace gpu::gl45; + +void GL45Backend::initTransform() { + GLuint transformBuffers[3]; + glCreateBuffers(3, transformBuffers); + _transform._objectBuffer = transformBuffers[0]; + _transform._cameraBuffer = transformBuffers[1]; + _transform._drawCallInfoBuffer = transformBuffers[2]; + glCreateTextures(1, GL_TEXTURE_2D, &_transform._objectBufferTexture); + size_t cameraSize = sizeof(TransformStageState::CameraBufferElement); + while (_transform._cameraUboSize < cameraSize) { + _transform._cameraUboSize += _uboAlignment; + } +} + +void GL45Backend::transferTransformState(const Batch& batch) const { + // FIXME not thread safe + static std::vector bufferData; + if (!_transform._cameras.empty()) { + bufferData.resize(_transform._cameraUboSize * _transform._cameras.size()); + for (size_t i = 0; i < _transform._cameras.size(); ++i) { + memcpy(bufferData.data() + (_transform._cameraUboSize * i), &_transform._cameras[i], sizeof(TransformStageState::CameraBufferElement)); + } + glNamedBufferData(_transform._cameraBuffer, bufferData.size(), bufferData.data(), GL_STREAM_DRAW); + } + + if (!batch._objects.empty()) { + auto byteSize = batch._objects.size() * sizeof(Batch::TransformObject); + bufferData.resize(byteSize); + memcpy(bufferData.data(), batch._objects.data(), byteSize); + glNamedBufferData(_transform._objectBuffer, bufferData.size(), bufferData.data(), GL_STREAM_DRAW); + } + + if (!batch._namedData.empty()) { + bufferData.clear(); + for (auto& data : batch._namedData) { + auto currentSize = bufferData.size(); + auto bytesToCopy = data.second.drawCallInfos.size() * sizeof(Batch::DrawCallInfo); + bufferData.resize(currentSize + bytesToCopy); + memcpy(bufferData.data() + currentSize, data.second.drawCallInfos.data(), bytesToCopy); + _transform._drawCallInfoOffsets[data.first] = (GLvoid*)currentSize; + } + glNamedBufferData(_transform._drawCallInfoBuffer, bufferData.size(), bufferData.data(), GL_STREAM_DRAW); + } + +#ifdef GPU_SSBO_DRAW_CALL_INFO + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _transform._objectBuffer); +#else + glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); + glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer); +#endif + + CHECK_GL_ERROR(); + + // Make sure the current Camera offset is unknown before render Draw + _transform._currentCameraOffset = INVALID_OFFSET; +} diff --git a/libraries/gpu/src/gpu/null/NullBackend.h b/libraries/gpu/src/gpu/null/NullBackend.h new file mode 100644 index 0000000000..097cee27e7 --- /dev/null +++ b/libraries/gpu/src/gpu/null/NullBackend.h @@ -0,0 +1,54 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 +// +#ifndef hifi_gpu_Null_Backend_h +#define hifi_gpu_Null_Backend_h + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../Context.h" + +namespace gpu { namespace null { + +class Backend : public gpu::Backend { + using Parent = gpu::Backend; + // Context Backend static interface required + friend class gpu::Context; + static void init() {} + static gpu::Backend* createBackend() { return new Backend(); } + static bool makeProgram(Shader& shader, const Shader::BindingSet& slotBindings) { return true; } + +protected: + explicit Backend(bool syncCache) : Parent() { } + Backend() : Parent() { } +public: + ~Backend() { } + + void render(Batch& batch) final { } + + // This call synchronize the Full Backend cache with the current GLState + // THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync + // the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls + // Let's try to avoid to do that as much as possible! + void syncCache() final { } + + // This is the ugly "download the pixels to sysmem for taking a snapshot" + // Just avoid using it, it's ugly and will break performances + virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) final { } +}; + +} } + +#endif diff --git a/tests/gpu-test/src/TestFbx.cpp b/tests/gpu-test/src/TestFbx.cpp new file mode 100644 index 0000000000..cea356e125 --- /dev/null +++ b/tests/gpu-test/src/TestFbx.cpp @@ -0,0 +1,187 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestFbx.h" + +#include + +#include + +#include + +struct MyVertex { + vec3 position; + vec2 texCoords; + vec3 normal; + uint32_t color; + + static gpu::Stream::FormatPointer getVertexFormat() { + static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; + static const gpu::Element TEXTURE_ELEMENT { gpu::VEC2, gpu::FLOAT, gpu::UV }; + static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; + static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA }; + gpu::Stream::FormatPointer vertexFormat { std::make_shared() }; + vertexFormat->setAttribute(gpu::Stream::POSITION, 0, POSITION_ELEMENT, offsetof(MyVertex, position)); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD, 0, TEXTURE_ELEMENT, offsetof(MyVertex, texCoords)); + vertexFormat->setAttribute(gpu::Stream::COLOR, 0, COLOR_ELEMENT, offsetof(MyVertex, color)); + vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, NORMAL_ELEMENT, offsetof(MyVertex, normal)); + return vertexFormat; + } + +}; + +struct Part { + size_t baseVertex; + size_t baseIndex; + size_t materialId; +}; + +struct DrawElementsIndirectCommand { + uint count { 0 }; + uint instanceCount { 1 }; + uint firstIndex { 0 }; + uint baseVertex { 0 }; + uint baseInstance { 0 }; +}; + + +class FileDownloader : public QObject { + Q_OBJECT +public: + explicit FileDownloader(QUrl imageUrl, QObject *parent = 0) : QObject(parent) { + connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileDownloaded(QNetworkReply*))); + QNetworkRequest request(imageUrl); + m_WebCtrl.get(request); + } + + virtual ~FileDownloader() {} + + const QByteArray& downloadedData() const { + return m_DownloadedData; + } + +signals: + void downloaded(); + +private slots: + void fileDownloaded(QNetworkReply* pReply) { + m_DownloadedData = pReply->readAll(); + pReply->deleteLater(); + emit downloaded(); + } + +private: + QNetworkAccessManager m_WebCtrl; + QByteArray m_DownloadedData; +}; + + +static const QUrl TEST_ASSET = QString("https://s3.amazonaws.com/DreamingContent/assets/models/tardis/console.fbx"); +static const mat4 TEST_ASSET_TRANSFORM = glm::translate(mat4(), vec3(0, -1.5f, 0)) * glm::scale(mat4(), vec3(0.01f)); +//static const QUrl TEST_ASSET = QString("https://s3.amazonaws.com/DreamingContent/assets/simple/SimpleMilitary/Models/Vehicles/tank_02_c.fbx"); +//static const mat4 TEST_ASSET_TRANSFORM = glm::translate(mat4(), vec3(0, -0.5f, 0)) * glm::scale(mat4(), vec3(0.1f)); + +TestFbx::TestFbx(const render::ShapePlumberPointer& shapePlumber) : _shapePlumber(shapePlumber) { + FileDownloader* downloader = new FileDownloader(TEST_ASSET, qApp); + QObject::connect(downloader, &FileDownloader::downloaded, [this, downloader] { + parseFbx(downloader->downloadedData()); + }); +} + +bool TestFbx::isReady() const { + return _partCount != 0; +} + +void TestFbx::parseFbx(const QByteArray& fbxData) { + QVariantHash mapping; + FBXGeometry* fbx = readFBX(fbxData, mapping); + size_t totalVertexCount = 0; + size_t totalIndexCount = 0; + size_t totalPartCount = 0; + size_t highestIndex = 0; + for (const auto& mesh : fbx->meshes) { + size_t vertexCount = mesh.vertices.size(); + totalVertexCount += mesh.vertices.size(); + highestIndex = std::max(highestIndex, vertexCount); + totalPartCount += mesh.parts.size(); + for (const auto& part : mesh.parts) { + totalIndexCount += part.quadTrianglesIndices.size(); + totalIndexCount += part.triangleIndices.size(); + } + } + size_t baseVertex = 0; + std::vector vertices; + vertices.reserve(totalVertexCount); + std::vector indices; + indices.reserve(totalIndexCount); + std::vector parts; + parts.reserve(totalPartCount); + _partCount = totalPartCount; + for (const auto& mesh : fbx->meshes) { + baseVertex = vertices.size(); + + vec3 color; + for (const auto& part : mesh.parts) { + DrawElementsIndirectCommand partIndirect; + partIndirect.baseVertex = (uint)baseVertex; + partIndirect.firstIndex = (uint)indices.size(); + partIndirect.baseInstance = (uint)parts.size(); + _partTransforms.push_back(mesh.modelTransform); + auto material = fbx->materials[part.materialID]; + color = material.diffuseColor; + for (auto index : part.quadTrianglesIndices) { + indices.push_back(index); + } + for (auto index : part.triangleIndices) { + indices.push_back(index); + } + size_t triangles = (indices.size() - partIndirect.firstIndex); + Q_ASSERT(0 == (triangles % 3)); + //triangles /= 3; + partIndirect.count = (uint)triangles; + parts.push_back(partIndirect); + } + + size_t vertexCount = mesh.vertices.size(); + for (size_t i = 0; i < vertexCount; ++i) { + MyVertex vertex; + vertex.position = mesh.vertices[(int)i]; + vec3 n = mesh.normals[(int)i]; + vertex.normal = n; + vertex.texCoords = mesh.texCoords[(int)i]; + vertex.color = toCompactColor(vec4(color, 1)); + vertices.push_back(vertex); + } + } + + _vertexBuffer->append(vertices); + _indexBuffer->append(indices); + _indirectBuffer->append(parts); + delete fbx; +} + +void TestFbx::renderTest(size_t testId, RenderArgs* args) { + gpu::Batch& batch = *(args->_batch); + //pipeline->pipeline + if (_partCount) { + for (size_t i = 0; i < _partCount; ++i) { + batch.setModelTransform(TEST_ASSET_TRANSFORM * _partTransforms[i]); + batch.setupNamedCalls(__FUNCTION__, [this](gpu::Batch& batch, gpu::Batch::NamedBatchData&) { + RenderArgs args; args._batch = &batch; + _shapePlumber->pickPipeline(&args, render::ShapeKey()); + batch.setInputBuffer(0, _vertexBuffer, 0, sizeof(MyVertex)); + batch.setIndexBuffer(gpu::UINT16, _indexBuffer, 0); + batch.setInputFormat(MyVertex::getVertexFormat()); + batch.setIndirectBuffer(_indirectBuffer, 0); + batch.multiDrawIndexedIndirect((uint)_partCount, gpu::TRIANGLES); + }); + } + } +} + +#include "TestFbx.moc" diff --git a/tests/gpu-test/src/TestFbx.h b/tests/gpu-test/src/TestFbx.h new file mode 100644 index 0000000000..1f3c0bb50e --- /dev/null +++ b/tests/gpu-test/src/TestFbx.h @@ -0,0 +1,35 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include "TestHelpers.h" + +#include + +class FBXGeometry; + +class TestFbx : public GpuTestBase { + size_t _partCount { 0 }; + model::Material _material; + render::ShapeKey _shapeKey; + std::vector _partTransforms; + render::ShapePlumberPointer _shapePlumber; + gpu::Stream::FormatPointer _vertexFormat { std::make_shared() }; + gpu::BufferPointer _vertexBuffer { std::make_shared() }; + gpu::BufferPointer _indexBuffer { std::make_shared() }; + gpu::BufferPointer _indirectBuffer { std::make_shared() }; +public: + TestFbx(const render::ShapePlumberPointer& shapePlumber); + bool isReady() const override; + void renderTest(size_t test, RenderArgs* args) override; + +private: + void parseFbx(const QByteArray& fbxData); +}; + + diff --git a/tests/gpu-test/src/TestFloorGrid.cpp b/tests/gpu-test/src/TestFloorGrid.cpp new file mode 100644 index 0000000000..a24b4778d4 --- /dev/null +++ b/tests/gpu-test/src/TestFloorGrid.cpp @@ -0,0 +1,54 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestFloorGrid.h" + + +TestFloorGrid::TestFloorGrid() { + auto geometryCache = DependencyManager::get(); + // Render grid on xz plane (not the optimal way to do things, but w/e) + // Note: GeometryCache::renderGrid will *not* work, as it is apparenly unaffected by batch rotations and renders xy only + static const std::string GRID_INSTANCE = "Grid"; + static auto compactColor1 = toCompactColor(vec4 { 0.35f, 0.25f, 0.15f, 1.0f }); + static auto compactColor2 = toCompactColor(vec4 { 0.15f, 0.25f, 0.35f, 1.0f }); + static std::vector transforms; + static gpu::BufferPointer colorBuffer; + if (!transforms.empty()) { + transforms.reserve(200); + colorBuffer = std::make_shared(); + for (int i = 0; i < 100; ++i) { + { + glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i)); + transform = glm::scale(transform, vec3(100, 1, 1)); + transforms.push_back(transform); + colorBuffer->append(compactColor1); + } + + { + glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0))); + transform = glm::translate(transform, vec3(0, -1, -50 + i)); + transform = glm::scale(transform, vec3(100, 1, 1)); + transforms.push_back(transform); + colorBuffer->append(compactColor2); + } + } + } + +} + +void TestFloorGrid::renderTest(size_t testId, RenderArgs* args) { + //gpu::Batch& batch = *(args->_batch); + //auto pipeline = geometryCache->getSimplePipeline(); + //for (auto& transform : transforms) { + // batch.setModelTransform(transform); + // batch.setupNamedCalls(GRID_INSTANCE, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + // batch.setPipeline(_pipeline); + // geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count(), colorBuffer); + // }); + //} +} diff --git a/tests/gpu-test/src/TestFloorGrid.h b/tests/gpu-test/src/TestFloorGrid.h new file mode 100644 index 0000000000..566c8f0968 --- /dev/null +++ b/tests/gpu-test/src/TestFloorGrid.h @@ -0,0 +1,26 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once + +#include +#include +#include + +#include +#include + +#include "TestHelpers.h" + +class TestFloorGrid : public GpuTestBase { +public: + TestFloorGrid(); + void renderTest(size_t testId, RenderArgs* args) override; +}; + + diff --git a/tests/gpu-test/src/TestFloorTexture.cpp b/tests/gpu-test/src/TestFloorTexture.cpp new file mode 100644 index 0000000000..884be5ec30 --- /dev/null +++ b/tests/gpu-test/src/TestFloorTexture.cpp @@ -0,0 +1,88 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 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 "TestFloorTexture.h" + +struct Vertex { + vec4 position; + vec4 texture; + vec4 normal; + vec4 color; +}; +static const uint TEXTURE_OFFSET = offsetof(Vertex, texture); +static const uint NORMAL_OFFSET = offsetof(Vertex, normal); +static const uint POSITION_OFFSET = offsetof(Vertex, position); +static const uint COLOR_OFFSET = offsetof(Vertex, color); +static const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; +static const gpu::Element TEXTURE_ELEMENT { gpu::VEC2, gpu::FLOAT, gpu::UV }; +static const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; +static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::FLOAT, gpu::RGBA }; + +FloorTextureTest::FloorTextureTest() { + auto geometryCache = DependencyManager::get(); + std::vector vertices; + const int MINX = -1000; + const int MAXX = 1000; + + vertices.push_back({ + vec4(MAXX, 0, MAXX, 1), + vec4(MAXX, MAXX, 0, 0), + vec4(0, 1, 0, 1), + vec4(1), + }); + + vertices.push_back({ + vec4(MAXX, 0, MINX, 1), + vec4(MAXX, 0, 0, 0), + vec4(0, 1, 0, 1), + vec4(1), + }); + + vertices.push_back({ + vec4(MINX, 0, MINX, 1), + vec4(0, 0, 0, 0), + vec4(0, 1, 0, 1), + vec4(1), + }); + + vertices.push_back({ + vec4(MINX, 0, MAXX, 1), + vec4(0, MAXX, 0, 0), + vec4(0, 1, 0, 1), + vec4(1), + }); + + vertexBuffer->append(vertices); + indexBuffer->append(std::vector({ 0, 1, 2, 2, 3, 0 })); + texture = DependencyManager::get()->getImageTexture("C:/Users/bdavis/Git/openvr/samples/bin/cube_texture.png"); + //texture = DependencyManager::get()->getImageTexture("H:/test.png"); + //texture = DependencyManager::get()->getImageTexture("H:/crate_blue.fbm/lambert8SG_Normal_OpenGL.png"); + vertexFormat->setAttribute(gpu::Stream::POSITION, 0, POSITION_ELEMENT, POSITION_OFFSET); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD, 0, TEXTURE_ELEMENT, TEXTURE_OFFSET); + vertexFormat->setAttribute(gpu::Stream::COLOR, 0, COLOR_ELEMENT, COLOR_OFFSET); + vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, NORMAL_ELEMENT, NORMAL_OFFSET); +} + +void FloorTextureTest::renderTest(size_t testId, RenderArgs* args) { + gpu::Batch& batch = *(args->_batch); + auto geometryCache = DependencyManager::get(); + static auto start = usecTimestampNow(); + auto now = usecTimestampNow(); + if ((now - start) > USECS_PER_SECOND * 1) { + start = now; + texture->incremementMinMip(); + } + + geometryCache->bindSimpleProgram(batch, true, true, true); + batch.setInputBuffer(0, vertexBuffer, 0, sizeof(Vertex)); + batch.setInputFormat(vertexFormat); + batch.setIndexBuffer(gpu::UINT16, indexBuffer, 0); + batch.setResourceTexture(0, texture); + batch.setModelTransform(glm::translate(glm::mat4(), vec3(0, -0.1, 0))); + batch.drawIndexed(gpu::TRIANGLES, 6, 0); +} diff --git a/tests/gpu-test/src/TestFloorTexture.h b/tests/gpu-test/src/TestFloorTexture.h new file mode 100644 index 0000000000..99eaf902b8 --- /dev/null +++ b/tests/gpu-test/src/TestFloorTexture.h @@ -0,0 +1,22 @@ +// +// Created by Bradley Austin Davis on 2016/05/16 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once + +#include "TestHelpers.h" + +class FloorTextureTest : public GpuTestBase { + gpu::BufferPointer vertexBuffer { std::make_shared() }; + gpu::BufferPointer indexBuffer { std::make_shared() }; + gpu::Stream::FormatPointer vertexFormat { std::make_shared() }; + gpu::TexturePointer texture; +public: + FloorTextureTest(); + void renderTest(size_t testId, RenderArgs* args) override; +}; + + diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index e672fe3c86..0f06546327 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -62,6 +62,9 @@ #include #include "TestWindow.h" +#include "TestFbx.h" +#include "TestFloorGrid.h" +#include "TestFloorTexture.h" #include "TestInstancedShapes.h" #include "TestShapes.h" @@ -90,8 +93,8 @@ class MyTestWindow : public TestWindow { #endif updateCamera(); _testBuilders = TestBuilders({ - //[this] { return new TestFbx(_shapePlumber); }, - [] { return new TestShapes(); }, + [this] { return new TestFbx(_shapePlumber); }, + [] { return new TestInstancedShapes(); }, }); } diff --git a/tests/gpu-test/src/unlit.slf b/tests/gpu-test/src/unlit.slf deleted file mode 100644 index f88fcb510b..0000000000 --- a/tests/gpu-test/src/unlit.slf +++ /dev/null @@ -1,28 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// simple.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/15/14. -// Copyright 2014 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 DeferredBufferWrite.slh@> -<@include model/Material.slh@> - -// the interpolated normal -in vec3 _normal; -in vec3 _color; - -void main(void) { - packDeferredFragment( - normalize(_normal.xyz), - 1.0, - _color.rgb, - DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, DEFAULT_OCCLUSION); -} diff --git a/tests/gpu-test/src/unlit.slv b/tests/gpu-test/src/unlit.slv deleted file mode 100644 index d51d817429..0000000000 --- a/tests/gpu-test/src/unlit.slv +++ /dev/null @@ -1,36 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// simple.vert -// vertex shader -// -// Created by Andrzej Kapolka on 9/15/14. -// Copyright 2014 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 gpu/Inputs.slh@> - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - -// the interpolated normal -out vec3 _normal; -out vec3 _color; -out vec2 _texCoord0; - -void main(void) { - _color = inColor.rgb; - _texCoord0 = inTexCoord0.st; - - // standard transform - TransformCamera cam = getTransformCamera(); - TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> - <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> - _normal = vec3(0.0, 0.0, 1.0); -} \ No newline at end of file From 8b56444ddeb0a78dba2258a92f7b8db413e62529 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 23 May 2016 14:47:16 -0700 Subject: [PATCH 41/77] Fix crash in GL45 buffer re-allocation --- libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index b7bb04cbfb..1676b0ce1c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -22,7 +22,9 @@ class GL45Buffer : public gl::GLBuffer { public: GL45Buffer(const Buffer& buffer, GLBuffer* original) : Parent(buffer, allocate()) { glNamedBufferStorage(_buffer, _size, nullptr, GL_DYNAMIC_STORAGE_BIT); - glCopyNamedBufferSubData(original->_buffer, _buffer, 0, 0, std::min(original->_size, _size)); + if (original && original->_size) { + glCopyNamedBufferSubData(original->_buffer, _buffer, 0, 0, std::min(original->_size, _size)); + } Backend::setGPUObject(buffer, this); } From a41de3a60dc71932e4f1b9e3d6ab297fda5a0be8 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 23 May 2016 15:46:47 -0700 Subject: [PATCH 42/77] Making GL 4.5 enabled by default, adding logging --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index 32e063a4c6..60641c122d 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -32,17 +32,19 @@ using namespace gpu; using namespace gpu::gl; -static const QString DEBUG_FLAG("HIFI_ENABLE_OPENGL_45"); -bool enableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); +static const QString DEBUG_FLAG("HIFI_DISABLE_OPENGL_45"); +bool disableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); Backend* GLBackend::createBackend() { // FIXME provide a mechanism to override the backend for testing // Where the gpuContext is initialized and where the TRUE Backend is created and assigned auto version = QOpenGLContextWrapper::currentContextVersion(); GLBackend* result; - if (enableOpenGL45 && version >= 0x0405) { + if (!disableOpenGL45 && version >= 0x0405) { + qDebug() << "OpenGL 4.5 detected"; result = new gpu::gl45::GL45Backend(); } else { + qDebug() << "OpenGL 4.5 not detected / enabled, using compatibility backend"; result = new gpu::gl41::GL41Backend(); } result->initInput(); From ab7fed1af89a285e50e97cb7bd888800be522c0e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 31 May 2016 13:28:39 -0700 Subject: [PATCH 43/77] Switch back to disable GL 4.5 by default, add support for logging when enabled --- libraries/gl/src/gl/GLHelpers.cpp | 14 +++++++++++--- libraries/gl/src/gl/OffscreenGLCanvas.cpp | 14 ++++++++++---- libraries/gl/src/gl/OffscreenGLCanvas.h | 3 --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 10 +++++----- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/libraries/gl/src/gl/GLHelpers.cpp b/libraries/gl/src/gl/GLHelpers.cpp index 79b39a2331..2781d5b9b0 100644 --- a/libraries/gl/src/gl/GLHelpers.cpp +++ b/libraries/gl/src/gl/GLHelpers.cpp @@ -6,6 +6,14 @@ #include #include #include +#include +#ifdef DEBUG +static bool enableDebug = true; +#else +static const QString DEBUG_FLAG("HIFI_ENABLE_OPENGL_45"); +static bool enableDebug = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); +#endif + const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { static QSurfaceFormat format; @@ -15,9 +23,9 @@ const QSurfaceFormat& getDefaultOpenGLSurfaceFormat() { format.setDepthBufferSize(DEFAULT_GL_DEPTH_BUFFER_BITS); format.setStencilBufferSize(DEFAULT_GL_STENCIL_BUFFER_BITS); setGLFormatVersion(format); -#ifdef DEBUG - format.setOption(QSurfaceFormat::DebugContext); -#endif + if (enableDebug) { + format.setOption(QSurfaceFormat::DebugContext); + } format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); QSurfaceFormat::setDefaultFormat(format); }); diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.cpp b/libraries/gl/src/gl/OffscreenGLCanvas.cpp index 90ff369cd6..eec3d2bf6b 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.cpp +++ b/libraries/gl/src/gl/OffscreenGLCanvas.cpp @@ -12,23 +12,30 @@ #include "OffscreenGLCanvas.h" +#include #include #include #include #include "GLHelpers.h" +#ifdef DEBUG +static bool enableDebugLogger = true; +#else +static const QString DEBUG_FLAG("HIFI_ENABLE_OPENGL_45"); +static bool enableDebugLogger = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); +#endif + + OffscreenGLCanvas::OffscreenGLCanvas() : _context(new QOpenGLContext), _offscreenSurface(new QOffscreenSurface){ } OffscreenGLCanvas::~OffscreenGLCanvas() { -#ifdef DEBUG if (_logger) { makeCurrent(); delete _logger; _logger = nullptr; } -#endif _context->doneCurrent(); } @@ -60,7 +67,7 @@ bool OffscreenGLCanvas::makeCurrent() { qDebug() << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); }); -#ifdef DEBUG + if (result && !_logger) { _logger = new QOpenGLDebugLogger(this); if (_logger->initialize()) { @@ -71,7 +78,6 @@ bool OffscreenGLCanvas::makeCurrent() { _logger->startLogging(QOpenGLDebugLogger::LoggingMode::SynchronousLogging); } } -#endif return result; } diff --git a/libraries/gl/src/gl/OffscreenGLCanvas.h b/libraries/gl/src/gl/OffscreenGLCanvas.h index 387804bf56..69210f638d 100644 --- a/libraries/gl/src/gl/OffscreenGLCanvas.h +++ b/libraries/gl/src/gl/OffscreenGLCanvas.h @@ -36,10 +36,7 @@ protected: std::once_flag _reportOnce; QOpenGLContext* _context; QOffscreenSurface* _offscreenSurface; -#ifdef DEBUG QOpenGLDebugLogger* _logger{ nullptr }; -#endif - }; #endif // hifi_OffscreenGLCanvas_h diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index 60641c122d..ce2f4c8d66 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -32,19 +32,19 @@ using namespace gpu; using namespace gpu::gl; -static const QString DEBUG_FLAG("HIFI_DISABLE_OPENGL_45"); -bool disableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); +static const QString DEBUG_FLAG("HIFI_ENABLE_OPENGL_45"); +static bool enableOpenGL45 = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); Backend* GLBackend::createBackend() { // FIXME provide a mechanism to override the backend for testing // Where the gpuContext is initialized and where the TRUE Backend is created and assigned auto version = QOpenGLContextWrapper::currentContextVersion(); GLBackend* result; - if (!disableOpenGL45 && version >= 0x0405) { - qDebug() << "OpenGL 4.5 detected"; + if (enableOpenGL45 && version >= 0x0405) { + qDebug() << "Using OpenGL 4.5 backend"; result = new gpu::gl45::GL45Backend(); } else { - qDebug() << "OpenGL 4.5 not detected / enabled, using compatibility backend"; + qDebug() << "Using OpenGL 4.1 backend"; result = new gpu::gl41::GL41Backend(); } result->initInput(); From 542601fd9dafe4f219d9f3939f8a78cb9b7ea931 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jun 2016 13:58:54 -0700 Subject: [PATCH 44/77] Fix invalid GL 4.5 calls --- libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp | 4 ++-- libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp index 7f511be3e8..b846dd4df3 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendOutput.cpp @@ -93,9 +93,9 @@ public: // Last but not least, define where we draw if (!_colorBuffers.empty()) { - glDrawBuffers((GLsizei)_colorBuffers.size(), _colorBuffers.data()); + glNamedFramebufferDrawBuffers(_id, (GLsizei)_colorBuffers.size(), _colorBuffers.data()); } else { - glDrawBuffer(GL_NONE); + glNamedFramebufferDrawBuffer(_id, GL_NONE); } // Now check for completness diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp index fd49729164..96afb4cc71 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTransform.cpp @@ -19,7 +19,7 @@ void GL45Backend::initTransform() { _transform._objectBuffer = transformBuffers[0]; _transform._cameraBuffer = transformBuffers[1]; _transform._drawCallInfoBuffer = transformBuffers[2]; - glCreateTextures(1, GL_TEXTURE_2D, &_transform._objectBufferTexture); + glCreateTextures(GL_TEXTURE_BUFFER, 1, &_transform._objectBufferTexture); size_t cameraSize = sizeof(TransformStageState::CameraBufferElement); while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; @@ -59,9 +59,9 @@ void GL45Backend::transferTransformState(const Batch& batch) const { #ifdef GPU_SSBO_DRAW_CALL_INFO glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _transform._objectBuffer); #else + glTextureBuffer(_transform._objectBufferTexture, GL_RGBA32F, _transform._objectBuffer); glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture); - glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer); #endif CHECK_GL_ERROR(); From f93a91a97ff442781b8d274256d022fcda058ec4 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Jun 2016 19:18:16 -0700 Subject: [PATCH 45/77] Abandon seperate vertex formats for now --- libraries/gpu-gl/src/gpu/gl/GLBackend.h | 2 +- .../gpu-gl/src/gpu/gl/GLBackendInput.cpp | 173 ++++++++++++++++++ .../gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 168 +---------------- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 67 +------ 4 files changed, 176 insertions(+), 234 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index 5255a6cb25..d27ec3808b 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -186,7 +186,7 @@ protected: virtual void killInput() final; virtual void syncInputStateCache() final; virtual void resetInputStage() final; - virtual void updateInput() = 0; + virtual void updateInput(); struct InputStageState { bool _invalidFormat { true }; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp index 448cc508eb..99c1ff0438 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendInput.cpp @@ -150,3 +150,176 @@ void GLBackend::do_setIndirectBuffer(Batch& batch, size_t paramOffset) { (void)CHECK_GL_ERROR(); } + + +// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding +// Core 43 does :) +// FIXME crashing problem with glVertexBindingDivisor / glVertexAttribFormat +// Once resolved, break this up into the GL 4.1 and 4.5 backends +#if 1 || (GPU_INPUT_PROFILE == GPU_CORE_41) +#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT +#else +#define SUPPORT_VERTEX_ATTRIB_FORMAT +#endif + +void GLBackend::updateInput() { +#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) + if (_input._invalidFormat) { + + InputStageState::ActivationCache newActivation; + + // Assign the vertex format required + if (_input._format) { + for (auto& it : _input._format->getAttributes()) { + const Stream::Attribute& attrib = (it).second; + + GLuint slot = attrib._slot; + GLuint count = attrib._element.getLocationScalarCount(); + uint8_t locationCount = attrib._element.getLocationCount(); + GLenum type = _elementTypeToGL41Type[attrib._element.getType()]; + GLuint offset = attrib._offset;; + GLboolean isNormalized = attrib._element.isNormalized(); + + GLenum perLocationSize = attrib._element.getLocationSize(); + + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + newActivation.set(slot + locNum); + glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); + glVertexAttribBinding(slot + locNum, attrib._channel); + } + glVertexBindingDivisor(attrib._channel, attrib._frequency); + } + (void)CHECK_GL_ERROR(); + } + + // Manage Activation what was and what is expected now + for (size_t i = 0; i < newActivation.size(); i++) { + bool newState = newActivation[i]; + if (newState != _input._attributeActivation[i]) { + if (newState) { + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + } + _input._attributeActivation.flip(i); + } + } + (void)CHECK_GL_ERROR(); + + _input._invalidFormat = false; + _stats._ISNumFormatChanges++; + } + + if (_input._invalidBuffers.any()) { + int numBuffers = _input._buffers.size(); + auto buffer = _input._buffers.data(); + auto vbo = _input._bufferVBOs.data(); + auto offset = _input._bufferOffsets.data(); + auto stride = _input._bufferStrides.data(); + + for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) { + if (_input._invalidBuffers.test(bufferNum)) { + glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride)); + } + buffer++; + vbo++; + offset++; + stride++; + } + _input._invalidBuffers.reset(); + (void)CHECK_GL_ERROR(); + } +#else + if (_input._invalidFormat || _input._invalidBuffers.any()) { + + if (_input._invalidFormat) { + InputStageState::ActivationCache newActivation; + + _stats._ISNumFormatChanges++; + + // Check expected activation + if (_input._format) { + for (auto& it : _input._format->getAttributes()) { + const Stream::Attribute& attrib = (it).second; + uint8_t locationCount = attrib._element.getLocationCount(); + for (int i = 0; i < locationCount; ++i) { + newActivation.set(attrib._slot + i); + } + } + } + + // Manage Activation what was and what is expected now + for (unsigned int i = 0; i < newActivation.size(); i++) { + bool newState = newActivation[i]; + if (newState != _input._attributeActivation[i]) { + + if (newState) { + glEnableVertexAttribArray(i); + } else { + glDisableVertexAttribArray(i); + } + (void)CHECK_GL_ERROR(); + + _input._attributeActivation.flip(i); + } + } + } + + // now we need to bind the buffers and assign the attrib pointers + if (_input._format) { + const Buffers& buffers = _input._buffers; + const Offsets& offsets = _input._bufferOffsets; + const Offsets& strides = _input._bufferStrides; + + const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); + auto& inputChannels = _input._format->getChannels(); + _stats._ISNumInputBufferChanges++; + + GLuint boundVBO = 0; + for (auto& channelIt : inputChannels) { + const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; + if ((channelIt).first < buffers.size()) { + int bufferNum = (channelIt).first; + + if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) { + // GLuint vbo = gpu::GL41Backend::getBufferID((*buffers[bufferNum])); + GLuint vbo = _input._bufferVBOs[bufferNum]; + if (boundVBO != vbo) { + glBindBuffer(GL_ARRAY_BUFFER, vbo); + (void)CHECK_GL_ERROR(); + boundVBO = vbo; + } + _input._invalidBuffers[bufferNum] = false; + + for (unsigned int i = 0; i < channel._slots.size(); i++) { + const Stream::Attribute& attrib = attributes.at(channel._slots[i]); + GLuint slot = attrib._slot; + GLuint count = attrib._element.getLocationScalarCount(); + uint8_t locationCount = attrib._element.getLocationCount(); + GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; + // GLenum perLocationStride = strides[bufferNum]; + GLenum perLocationStride = attrib._element.getLocationSize(); + GLuint stride = (GLuint)strides[bufferNum]; + GLuint pointer = (GLuint)(attrib._offset + offsets[bufferNum]); + GLboolean isNormalized = attrib._element.isNormalized(); + + for (size_t locNum = 0; locNum < locationCount; ++locNum) { + glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, + reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); + glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency); + } + + // TODO: Support properly the IAttrib version + + (void)CHECK_GL_ERROR(); + } + } + } + } + } + // everything format related should be in sync now + _input._invalidFormat = false; + } +#endif +} + diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 1b0caa7345..d3e86de606 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -13,173 +13,7 @@ using namespace gpu; using namespace gpu::gl41; -// Core 41 doesn't expose the features to really separate the vertex format from the vertex buffers binding -// Core 43 does :) -// FIXME crashing problem with glVertexBindingDivisor / glVertexAttribFormat -#if 1 || (GPU_INPUT_PROFILE == GPU_CORE_41) -#define NO_SUPPORT_VERTEX_ATTRIB_FORMAT -#else -#define SUPPORT_VERTEX_ATTRIB_FORMAT -#endif - void GL41Backend::updateInput() { -#if defined(SUPPORT_VERTEX_ATTRIB_FORMAT) - if (_input._invalidFormat) { - - InputStageState::ActivationCache newActivation; - - // Assign the vertex format required - if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; - - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = _elementTypeToGL41Type[attrib._element.getType()]; - GLuint offset = attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); - - GLenum perLocationSize = attrib._element.getLocationSize(); - - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - newActivation.set(slot + locNum); - glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); - glVertexAttribBinding(slot + locNum, attrib._channel); - } - glVertexBindingDivisor(attrib._channel, attrib._frequency); - } - (void) CHECK_GL_ERROR(); - } - - // Manage Activation what was and what is expected now - for (size_t i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - _input._attributeActivation.flip(i); - } - } - (void) CHECK_GL_ERROR(); - - _input._invalidFormat = false; - _stats._ISNumFormatChanges++; - } - - if (_input._invalidBuffers.any()) { - int numBuffers = _input._buffers.size(); - auto buffer = _input._buffers.data(); - auto vbo = _input._bufferVBOs.data(); - auto offset = _input._bufferOffsets.data(); - auto stride = _input._bufferStrides.data(); - - for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) { - if (_input._invalidBuffers.test(bufferNum)) { - glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride)); - } - buffer++; - vbo++; - offset++; - stride++; - } - _input._invalidBuffers.reset(); - (void) CHECK_GL_ERROR(); - } -#else - if (_input._invalidFormat || _input._invalidBuffers.any()) { - - if (_input._invalidFormat) { - InputStageState::ActivationCache newActivation; - - _stats._ISNumFormatChanges++; - - // Check expected activation - if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; - uint8_t locationCount = attrib._element.getLocationCount(); - for (int i = 0; i < locationCount; ++i) { - newActivation.set(attrib._slot + i); - } - } - } - - // Manage Activation what was and what is expected now - for (unsigned int i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - (void) CHECK_GL_ERROR(); - - _input._attributeActivation.flip(i); - } - } - } - - // now we need to bind the buffers and assign the attrib pointers - if (_input._format) { - const Buffers& buffers = _input._buffers; - const Offsets& offsets = _input._bufferOffsets; - const Offsets& strides = _input._bufferStrides; - - const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); - auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges++; - - GLuint boundVBO = 0; - for (auto& channelIt : inputChannels) { - const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; - if ((channelIt).first < buffers.size()) { - int bufferNum = (channelIt).first; - - if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) { - // GLuint vbo = gpu::GL41Backend::getBufferID((*buffers[bufferNum])); - GLuint vbo = _input._bufferVBOs[bufferNum]; - if (boundVBO != vbo) { - glBindBuffer(GL_ARRAY_BUFFER, vbo); - (void) CHECK_GL_ERROR(); - boundVBO = vbo; - } - _input._invalidBuffers[bufferNum] = false; - - for (unsigned int i = 0; i < channel._slots.size(); i++) { - const Stream::Attribute& attrib = attributes.at(channel._slots[i]); - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; - // GLenum perLocationStride = strides[bufferNum]; - GLenum perLocationStride = attrib._element.getLocationSize(); - GLuint stride = (GLuint)strides[bufferNum]; - GLuint pointer = (GLuint)(attrib._offset + offsets[bufferNum]); - GLboolean isNormalized = attrib._element.isNormalized(); - - for (size_t locNum = 0; locNum < locationCount; ++locNum) { - glVertexAttribPointer(slot + (GLuint)locNum, count, type, isNormalized, stride, - reinterpret_cast(pointer + perLocationStride * (GLuint)locNum)); - glVertexAttribDivisor(slot + (GLuint)locNum, attrib._frequency); - } - - // TODO: Support properly the IAttrib version - - (void) CHECK_GL_ERROR(); - } - } - } - } - } - // everything format related should be in sync now - _input._invalidFormat = false; - } -#endif + Parent::updateInput(); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 5cefe40448..b578d7d7a8 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -14,70 +14,5 @@ using namespace gpu; using namespace gpu::gl45; void GL45Backend::updateInput() { - if (_input._invalidFormat) { - - InputStageState::ActivationCache newActivation; - - // Assign the vertex format required - if (_input._format) { - for (auto& it : _input._format->getAttributes()) { - const Stream::Attribute& attrib = (it).second; - - GLuint slot = attrib._slot; - GLuint count = attrib._element.getLocationScalarCount(); - uint8_t locationCount = attrib._element.getLocationCount(); - GLenum type = gl::ELEMENT_TYPE_TO_GL[attrib._element.getType()]; - GLuint offset = (GLuint)attrib._offset;; - GLboolean isNormalized = attrib._element.isNormalized(); - - GLenum perLocationSize = attrib._element.getLocationSize(); - - for (uint8_t locNum = 0; locNum < locationCount; ++locNum) { - newActivation.set(slot + locNum); - glVertexAttribFormat(slot + locNum, count, type, isNormalized, offset + locNum * perLocationSize); - glVertexAttribBinding(slot + locNum, attrib._channel); - } - glVertexBindingDivisor(attrib._channel, attrib._frequency); - } - (void) CHECK_GL_ERROR(); - } - - // Manage Activation what was and what is expected now - for (uint32_t i = 0; i < newActivation.size(); i++) { - bool newState = newActivation[i]; - if (newState != _input._attributeActivation[i]) { - if (newState) { - glEnableVertexAttribArray(i); - } else { - glDisableVertexAttribArray(i); - } - _input._attributeActivation.flip(i); - } - } - (void) CHECK_GL_ERROR(); - - _input._invalidFormat = false; - _stats._ISNumFormatChanges++; - } - - if (_input._invalidBuffers.any()) { - auto numBuffers = _input._buffers.size(); - auto buffer = _input._buffers.data(); - auto vbo = _input._bufferVBOs.data(); - auto offset = _input._bufferOffsets.data(); - auto stride = _input._bufferStrides.data(); - - for (uint32_t bufferNum = 0; bufferNum < numBuffers; bufferNum++) { - if (_input._invalidBuffers.test(bufferNum)) { - glBindVertexBuffer(bufferNum, (*vbo), (GLuint)(*offset), (GLuint)(*stride)); - } - buffer++; - vbo++; - offset++; - stride++; - } - _input._invalidBuffers.reset(); - (void) CHECK_GL_ERROR(); - } + Parent::updateInput(); } - From b649b30777a86733c98a596c3899a2c27506c850 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 29 Jun 2016 08:20:47 -0700 Subject: [PATCH 46/77] Reduce margin. --- scripts/system/controllers/handControllerPointer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 00aca2af86..36442e92d1 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -125,7 +125,7 @@ function ignoreMouseActivity() { weMovedReticle = false; return true; } -var MARGIN = 50; +var MARGIN = 25; var reticleMinX = MARGIN, reticleMaxX, reticleMinY = MARGIN, reticleMaxY; function updateRecommendedArea() { var dims = Controller.getViewportDimensions(); From 5a9be817df1fc30898ca988efb5607150d8c93ce Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 29 Jun 2016 10:28:55 -0700 Subject: [PATCH 47/77] PR comments --- interface/resources/qml/ToolWindow.qml | 1 - libraries/shared/src/GLMHelpers.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/resources/qml/ToolWindow.qml b/interface/resources/qml/ToolWindow.qml index c957a37886..f6a4600e06 100644 --- a/interface/resources/qml/ToolWindow.qml +++ b/interface/resources/qml/ToolWindow.qml @@ -140,7 +140,6 @@ ScrollingWindow { if (visible) { for (var i = 0; i < tabView.count; ++i) { if (tabView.getTab(i).enabled) { - console.log("QQQ tab is visible, returning early"); return; } } diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 8dbd0a146f..0c02cd5b03 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -468,7 +468,7 @@ glm::mat4 createMatFromScaleQuatAndPos(const glm::vec3& scale, const glm::quat& // cancel out roll glm::quat cancelOutRoll(const glm::quat& q) { - glm::vec3 forward = q * glm::vec3(0.0f, 0.0f, -1.0f); + glm::vec3 forward = q * Vectors::FRONT; return glm::quat_cast(glm::inverse(glm::lookAt(Vectors::ZERO, forward, Vectors::UP))); } From fcb6e7869dce8583dca423fc94a0acafd44b757e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 29 Jun 2016 10:54:24 -0700 Subject: [PATCH 48/77] logging --- .../DomainContent/Toybox/bow/bow.js | 5 ++- .../DomainContent/Toybox/bow/createBow.js | 41 ++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 2430b68076..02854e4de4 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -484,8 +484,9 @@ Entities.editEntity(this.arrow, arrowProperties); this.playShootArrowSound(); - var whichHand = this.hand === 'left' ? 0 : 1; - Controller.triggerShortHapticPulse(whichHand, 2); + var backHand = this.hand === 'left' ? 1 : 0; + var haptic = Controller.triggerShortHapticPulse(1, backHand); + print('JBP TRIGGERED HAPTIC ' + haptic +" hand: "+ backHand) //clear the strings back to only the single straight one this.deleteStrings(); diff --git a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js index 5deec3f6bc..4daeba320a 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js @@ -62,24 +62,35 @@ function makeBow() { shapeType: 'compound', compoundShapeURL: COLLISION_HULL_URL, script: SCRIPT_URL, + collidesWith: 'dynamic,kinetmatic,static', userData: JSON.stringify({ grabbableKey: { invertSolidWhileHeld: true }, - wearable:{joints:{RightHand:[{x:0.03960523009300232, - y:0.01979270577430725, - z:0.03294898942112923}, - {x:-0.7257906794548035, - y:-0.4611682891845703, - z:0.4436084032058716, - w:-0.25251442193984985}], - LeftHand:[{x:0.0055799782276153564, - y:0.04354757443070412, - z:0.05119767785072327}, - {x:-0.14914104342460632, - y:0.6448180079460144, - z:-0.2888556718826294, - w:-0.6917579770088196}]}} + wearable: { + joints: { + RightHand: [{ + x: 0.03960523009300232, + y: 0.01979270577430725, + z: 0.03294898942112923 + }, { + x: -0.7257906794548035, + y: -0.4611682891845703, + z: 0.4436084032058716, + w: -0.25251442193984985 + }], + LeftHand: [{ + x: 0.0055799782276153564, + y: 0.04354757443070412, + z: 0.05119767785072327 + }, { + x: -0.14914104342460632, + y: 0.6448180079460144, + z: -0.2888556718826294, + w: -0.6917579770088196 + }] + } + } }) }; @@ -148,4 +159,4 @@ function cleanup() { Entities.deleteEntity(preNotchString); } -Script.scriptEnding.connect(cleanup); +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 0e3b54c1303b26b8663b27eb32574b25fb25e2c9 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 29 Jun 2016 11:07:48 -0700 Subject: [PATCH 49/77] remove logging --- unpublishedScripts/DomainContent/Toybox/bow/bow.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 02854e4de4..89a3d166d6 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -143,7 +143,6 @@ //disable the opposite hand in handControllerGrab.js by message var handToDisable = this.hand === 'right' ? 'left' : 'right'; - print("disabling hand: " + handToDisable); Messages.sendMessage('Hifi-Hand-Disabler', handToDisable); var data = getEntityCustomData('grabbableKey', this.entityID, {}); @@ -202,7 +201,7 @@ }, createArrow: function() { - print('create arrow') + // print('create arrow') this.playArrowNotchSound(); var arrow = Entities.addEntity({ @@ -486,7 +485,6 @@ var backHand = this.hand === 'left' ? 1 : 0; var haptic = Controller.triggerShortHapticPulse(1, backHand); - print('JBP TRIGGERED HAPTIC ' + haptic +" hand: "+ backHand) //clear the strings back to only the single straight one this.deleteStrings(); From 6d3129899beadd857582a00ee395be3733ca9142 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 29 Jun 2016 11:47:41 -0700 Subject: [PATCH 50/77] remove prints, fix typo, formatting --- .../DomainContent/Toybox/bow/bow.js | 43 ++++++++----------- .../DomainContent/Toybox/bow/createBow.js | 2 +- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/unpublishedScripts/DomainContent/Toybox/bow/bow.js b/unpublishedScripts/DomainContent/Toybox/bow/bow.js index 89a3d166d6..0c16bcbc7b 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/bow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/bow.js @@ -183,7 +183,6 @@ }, releaseEquip: function(entityID, args) { - // print('RELEASE GRAB EVENT') Messages.sendMessage('Hifi-Hand-Disabler', "none") this.stringDrawn = false; @@ -201,7 +200,6 @@ }, createArrow: function() { - // print('create arrow') this.playArrowNotchSound(); var arrow = Entities.addEntity({ @@ -226,25 +224,24 @@ var makeArrowStick = function(entityA, entityB, collision) { Entities.editEntity(entityA, { - angularVelocity: { - x: 0, - y: 0, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - gravity: { - x: 0, - y: 0, - z: 0 - }, - position: collision.contactPoint, - dynamic: false - }) - // print('ARROW COLLIDED WITH::' + entityB); + angularVelocity: { + x: 0, + y: 0, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + gravity: { + x: 0, + y: 0, + z: 0 + }, + position: collision.contactPoint, + dynamic: false + }) Script.removeEventHandler(arrow, "collisionWithEntity", makeArrowStick) } @@ -300,7 +297,6 @@ }, updateStringPositions: function() { - // print('update string positions!!!') var upVector = Quat.getUp(this.bowProperties.rotation); var upOffset = Vec3.multiply(upVector, TOP_NOTCH_OFFSET); var downVector = Vec3.multiply(-1, Quat.getUp(this.bowProperties.rotation)); @@ -371,7 +367,6 @@ if (this.triggerValue < DRAW_STRING_THRESHOLD && this.stringDrawn === true) { // firing the arrow - // print('HIT RELEASE LOOP IN CHECK'); this.drawStrings(); this.hasArrowNotched = false; @@ -381,7 +376,6 @@ } else if (this.triggerValue > DRAW_STRING_THRESHOLD && this.stringDrawn === true) { - // print('HIT CONTINUE LOOP IN CHECK') //continuing to aim the arrow this.aiming = true; @@ -389,7 +383,6 @@ this.updateArrowPositionInNotch(); } else if (this.triggerValue > DRAW_STRING_THRESHOLD && this.stringDrawn === false) { - // print('HIT START LOOP IN CHECK'); this.arrow = this.createArrow(); this.playStringPullSound(); diff --git a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js index 4daeba320a..f1ed9eb263 100644 --- a/unpublishedScripts/DomainContent/Toybox/bow/createBow.js +++ b/unpublishedScripts/DomainContent/Toybox/bow/createBow.js @@ -62,7 +62,7 @@ function makeBow() { shapeType: 'compound', compoundShapeURL: COLLISION_HULL_URL, script: SCRIPT_URL, - collidesWith: 'dynamic,kinetmatic,static', + collidesWith: 'dynamic,kinematic,static', userData: JSON.stringify({ grabbableKey: { invertSolidWhileHeld: true From b0422106373e13dcf22ca181fde8853c0a5edf3e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 24 Jun 2016 15:08:55 -0700 Subject: [PATCH 51/77] Addition of equipHotspots --- .../system/controllers/handControllerGrab.js | 103 ++++++++++++++---- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index f86ff158f6..e971450aff 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -324,6 +324,14 @@ EntityPropertiesCache.prototype.getWearableProps = function(entityID) { return undefined; } }; +EntityPropertiesCache.prototype.getEquipHotspotsProps = function(entityID) { + var props = this.cache[entityID]; + if (props) { + return props.userData.equipHotspots ? props.userData.equipHotspots : {}; + } else { + return undefined; + } +}; function MyController(hand) { this.hand = hand; @@ -1083,8 +1091,8 @@ function MyController(hand) { }; this.entityIsEquippableWithDistanceCheck = function (entityID, handPosition) { + var distance, handJointName; var props = this.entityPropertyCache.getProps(entityID); - var distance = Vec3.distance(props.position, handPosition); var grabProps = this.entityPropertyCache.getGrabProps(entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); @@ -1096,30 +1104,81 @@ function MyController(hand) { return false; } - if (distance > EQUIP_RADIUS) { - if (debug) { - print("equip is skipping '" + props.name + "': too far away, " + distance + " meters"); - } - return false; - } + var equipHotspotsProps = this.entityPropertyCache.getEquipHotspotsProps(entityID); + if (equipHotspotsProps && equipHotspotsProps.length > 0) { + var i, length = equipHotspotsProps.length; + for (i = 0; i < length; i++) { + var hotspot = equipHotspotsProps[i]; + if (!hotspot.position) { + if (debug) { + print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing a position"); + } + continue; + } - var wearableProps = this.entityPropertyCache.getWearableProps(entityID); - if (!wearableProps || !wearableProps.joints) { - if (debug) { - print("equip is skipping '" + props.name + "': no wearable attach-point"); - } - return false; - } + if (!hotspot.radius) { + if (debug) { + print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing a radius"); + } + continue; + } - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (!wearableProps.joints[handJointName]) { - if (debug) { - print("equip is skipping '" + props.name + "': no wearable joint for " + handJointName); - } - return false; - } + distance = Vec3.distance(hotspot.position, handPosition); + if (distance > hotspot.radius) { + if (debug) { + print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is too far away, " + distance + " meters"); + } + continue; + } - return true; + if (!hotspot.joints) { + if (debug) { + print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing joints"); + } + continue; + } + + handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; + if (!hotspot.joints[handJointName]) { + if (debug) { + print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing joint." + handJointName); + } + continue; + } + + return true; + } + + return false; + + } else { + + distance = Vec3.distance(props.position, handPosition); + if (distance > EQUIP_RADIUS) { + if (debug) { + print("equip is skipping '" + props.name + "': too far away, " + distance + " meters"); + } + return false; + } + + var wearableProps = this.entityPropertyCache.getWearableProps(entityID); + if (!wearableProps || !wearableProps.joints) { + if (debug) { + print("equip is skipping '" + props.name + "': no wearable attach-point"); + } + return false; + } + + handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; + if (!wearableProps.joints[handJointName]) { + if (debug) { + print("equip is skipping '" + props.name + "': no wearable joint for " + handJointName); + } + return false; + } + + return true; + } }; this.entityIsGrabbable = function (entityID) { From 1b98c7347324c78aa069004c6dc47105e282ea0b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 24 Jun 2016 18:08:25 -0700 Subject: [PATCH 52/77] WIP, equip-points work but they don't use the proper attach point. --- .../system/controllers/handControllerGrab.js | 177 ++++++++---------- scripts/system/libraries/Xform.js | 8 + 2 files changed, 82 insertions(+), 103 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index e971450aff..c814b4396f 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -10,9 +10,10 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, Reticle, Messages, setEntityCustomData, getEntityCustomData, vec3toStr */ +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, Reticle, Messages, setEntityCustomData, getEntityCustomData, vec3toStr, Xform */ Script.include("/~/system/libraries/utils.js"); +Script.include("../libraries/Xform.js"); // // add lines where the hand ray picking is happening @@ -931,7 +932,8 @@ function MyController(hand) { this.hotspotOverlays.push({ entityID: undefined, overlay: overlay, - type: "hand" + type: "hand", + localPosition: {x: 0, y: 0, z: 0} }); } @@ -941,35 +943,38 @@ function MyController(hand) { var _this = this; this.entityPropertyCache.getEntities().forEach(function (entityID) { + var props = _this.entityPropertyCache.getProps(entityID); if (_this.entityIsEquippableWithoutDistanceCheck(entityID)) { - props = _this.entityPropertyCache.getProps(entityID); + var equipHotspots = _this.collectEquipHotspots(entityID); + var entityXform = new Xform(props.rotation, props.position); + var i, length = equipHotspots.length; + for (i = 0; i < length; i++) { + var hotspot = equipHotspots[i]; + overlay = Overlays.addOverlay("sphere", { + position: entityXform.xformPoint(hotspot.position), + size: hotspot.radius * 2, + color: EQUIP_SPHERE_COLOR, + alpha: EQUIP_SPHERE_ALPHA, + solid: true, + visible: true, + ignoreRayIntersection: true, + drawInFront: false + }); - overlay = Overlays.addOverlay("sphere", { - rotation: props.rotation, - position: props.position, - size: EQUIP_RADIUS * 2, - color: EQUIP_SPHERE_COLOR, - alpha: EQUIP_SPHERE_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false - }); - - _this.hotspotOverlays.push({ - entityID: entityID, - overlay: overlay, - type: "equip" - }); + _this.hotspotOverlays.push({ + entityID: entityID, + overlay: overlay, + type: "equip", + localPosition: hotspot.position + }); + } } if (DRAW_GRAB_BOXES && _this.entityIsGrabbable(entityID)) { - props = _this.entityPropertyCache.getProps(entityID); - overlay = Overlays.addOverlay("cube", { rotation: props.rotation, position: props.position, - size: props.dimensions, //{x: props.dimensions.x, y: props.dimensions.y, z: props.dimensions.z}, + size: props.dimensions, color: GRAB_BOX_COLOR, alpha: GRAB_BOX_ALPHA, solid: true, @@ -981,7 +986,8 @@ function MyController(hand) { _this.hotspotOverlays.push({ entityID: entityID, overlay: overlay, - type: "near" + type: "near", + localPosition: {x: 0, y: 0, z: 0} }); } }); @@ -996,7 +1002,8 @@ function MyController(hand) { } else if (overlayInfo.type === "equip") { _this.entityPropertyCache.updateEntity(overlayInfo.entityID); props = _this.entityPropertyCache.getProps(overlayInfo.entityID); - Overlays.editOverlay(overlayInfo.overlay, { position: props.position, rotation: props.rotation }); + var entityXform = new Xform(props.rotation, props.position); + Overlays.editOverlay(overlayInfo.overlay, { position: entityXform.xformPoint(overlayInfo.localPosition), rotation: props.rotation }); } else if (overlayInfo.type === "near") { _this.entityPropertyCache.updateEntity(overlayInfo.entityID); props = _this.entityPropertyCache.getProps(overlayInfo.entityID); @@ -1084,17 +1091,41 @@ function MyController(hand) { return grabbableProps && grabbableProps.wantsTrigger; }; - this.entityIsEquippableWithoutDistanceCheck = function (entityID) { - var props = this.entityPropertyCache.getProps(entityID); - var handPosition = props.position; - return this.entityIsEquippableWithDistanceCheck(entityID, handPosition); + this.collectEquipHotspots = function (entityID) { + var result = []; + var equipHotspotsProps = this.entityPropertyCache.getEquipHotspotsProps(entityID); + if (equipHotspotsProps && equipHotspotsProps.length > 0) { + var i, length = equipHotspotsProps.length; + for (i = 0; i < length; i++) { + var hotspot = equipHotspotsProps[i]; + if (hotspot.position && hotspot.radius && hotspot.joints) { + result.push({ + position: hotspot.position, + radius: hotspot.radius, + joints: hotspot.joints + }); + } + } + } else { + var wearableProps = this.entityPropertyCache.getWearableProps(entityID); + if (wearableProps && wearableProps.joints) { + result.push({ + position: {x: 0, y: 0, z: 0}, + radius: EQUIP_RADIUS, + joints: wearableProps.joints + }); + } + } + return result; }; - this.entityIsEquippableWithDistanceCheck = function (entityID, handPosition) { - var distance, handJointName; + this.entityIsEquippableWithDistanceCheck = function (entityID, handPosition, skipDistanceCheck) { + var distance; + var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; var props = this.entityPropertyCache.getProps(entityID); var grabProps = this.entityPropertyCache.getGrabProps(entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); + var entityXform = new Xform(props.rotation, props.position); var refCount = ("refCount" in grabProps) ? grabProps.refCount : 0; if (refCount > 0) { @@ -1104,81 +1135,21 @@ function MyController(hand) { return false; } - var equipHotspotsProps = this.entityPropertyCache.getEquipHotspotsProps(entityID); - if (equipHotspotsProps && equipHotspotsProps.length > 0) { - var i, length = equipHotspotsProps.length; - for (i = 0; i < length; i++) { - var hotspot = equipHotspotsProps[i]; - if (!hotspot.position) { - if (debug) { - print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing a position"); - } - continue; - } - - if (!hotspot.radius) { - if (debug) { - print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing a radius"); - } - continue; - } - - distance = Vec3.distance(hotspot.position, handPosition); - if (distance > hotspot.radius) { - if (debug) { - print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is too far away, " + distance + " meters"); - } - continue; - } - - if (!hotspot.joints) { - if (debug) { - print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing joints"); - } - continue; - } - - handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (!hotspot.joints[handJointName]) { - if (debug) { - print("equip is skipping '" + props.name + "': equip hotspot[" + i + "] is missing joint." + handJointName); - } - continue; - } - + var equipHotspots = this.collectEquipHotspots(entityID); + var i, length = equipHotspots.length; + for (i = 0; i < length; i++) { + var hotspot = equipHotspots[i]; + distance = Vec3.distance(entityXform.xformPoint(hotspot.position), handPosition); + if ((skipDistanceCheck || distance < hotspot.radius) && hotspot.joints[handJointName]) { return true; } - - return false; - - } else { - - distance = Vec3.distance(props.position, handPosition); - if (distance > EQUIP_RADIUS) { - if (debug) { - print("equip is skipping '" + props.name + "': too far away, " + distance + " meters"); - } - return false; - } - - var wearableProps = this.entityPropertyCache.getWearableProps(entityID); - if (!wearableProps || !wearableProps.joints) { - if (debug) { - print("equip is skipping '" + props.name + "': no wearable attach-point"); - } - return false; - } - - handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (!wearableProps.joints[handJointName]) { - if (debug) { - print("equip is skipping '" + props.name + "': no wearable joint for " + handJointName); - } - return false; - } - - return true; } + return false; + }; + + this.entityIsEquippableWithoutDistanceCheck = function (entityID) { + var handPosition = this.getHandPosition(); + return this.entityIsEquippableWithDistanceCheck(entityID, handPosition, true); }; this.entityIsGrabbable = function (entityID) { diff --git a/scripts/system/libraries/Xform.js b/scripts/system/libraries/Xform.js index 75051c4983..1aa43cf30b 100644 --- a/scripts/system/libraries/Xform.js +++ b/scripts/system/libraries/Xform.js @@ -33,6 +33,14 @@ Xform.prototype.mirrorX = function() { {x: -this.pos.x, y: this.pos.y, z: this.pos.z}); }; +Xform.prototype.xformVector = function (vector) { + return Vec3.multiplyQbyV(this.rot, vector); +} + +Xform.prototype.xformPoint = function (point) { + return Vec3.sum(Vec3.multiplyQbyV(this.rot, point), this.pos); +} + Xform.prototype.toString = function() { var rot = this.rot; var pos = this.pos; From 43d4dba4c0323d40bed0186269a6456995607ad9 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 27 Jun 2016 18:05:45 -0700 Subject: [PATCH 53/77] iterate over hotspots not entities. This makes it possible to render multiple hotspots per entity. Also, it will use the same logic to decide how to deal with overlapping entity equip hotspots. --- .../system/controllers/handControllerGrab.js | 145 +++++++++--------- scripts/system/libraries/utils.js | 8 +- 2 files changed, 78 insertions(+), 75 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index c814b4396f..fe95dda596 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -10,7 +10,7 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, Reticle, Messages, setEntityCustomData, getEntityCustomData, vec3toStr, Xform */ +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, Reticle, Messages, setEntityCustomData, getEntityCustomData, vec3toStr, flatten, Xform */ Script.include("/~/system/libraries/utils.js"); Script.include("../libraries/Xform.js"); @@ -879,7 +879,7 @@ function MyController(hand) { }; this.createHotspots = function () { - var props, overlay; + var _this = this; var HAND_EQUIP_SPHERE_COLOR = { red: 90, green: 255, blue: 90 }; var HAND_EQUIP_SPHERE_ALPHA = 0.7; @@ -897,6 +897,7 @@ function MyController(hand) { this.hotspotOverlays = []; + var overlay; if (DRAW_HAND_SPHERES) { // add tiny green sphere around the palm. var handPosition = this.getHandPosition(); @@ -910,7 +911,6 @@ function MyController(hand) { ignoreRayIntersection: true, drawInFront: false }); - this.hotspotOverlays.push({ entityID: undefined, overlay: overlay, @@ -928,7 +928,6 @@ function MyController(hand) { ignoreRayIntersection: true, drawInFront: false }); - this.hotspotOverlays.push({ entityID: undefined, overlay: overlay, @@ -941,55 +940,54 @@ function MyController(hand) { this.entityPropertyCache.clear(); this.entityPropertyCache.findEntities(MyAvatar.position, HOTSPOT_DRAW_DISTANCE); - var _this = this; - this.entityPropertyCache.getEntities().forEach(function (entityID) { - var props = _this.entityPropertyCache.getProps(entityID); - if (_this.entityIsEquippableWithoutDistanceCheck(entityID)) { - var equipHotspots = _this.collectEquipHotspots(entityID); - var entityXform = new Xform(props.rotation, props.position); - var i, length = equipHotspots.length; - for (i = 0; i < length; i++) { - var hotspot = equipHotspots[i]; - overlay = Overlays.addOverlay("sphere", { - position: entityXform.xformPoint(hotspot.position), - size: hotspot.radius * 2, - color: EQUIP_SPHERE_COLOR, - alpha: EQUIP_SPHERE_ALPHA, + if (DRAW_GRAB_BOXES) { + // add blue box overlays for grabbable entities. + this.entityPropertyCache.getEntities().forEach(function (entityID) { + var props = _this.entityPropertyCache.getProps(entityID); + if (_this.entityIsGrabbable(entityID)) { + var overlay = Overlays.addOverlay("cube", { + rotation: props.rotation, + position: props.position, + size: props.dimensions, + color: GRAB_BOX_COLOR, + alpha: GRAB_BOX_ALPHA, solid: true, visible: true, ignoreRayIntersection: true, drawInFront: false }); - _this.hotspotOverlays.push({ entityID: entityID, overlay: overlay, - type: "equip", - localPosition: hotspot.position + type: "near", + localPosition: {x: 0, y: 0, z: 0} }); } - } + }); + } - if (DRAW_GRAB_BOXES && _this.entityIsGrabbable(entityID)) { - overlay = Overlays.addOverlay("cube", { - rotation: props.rotation, - position: props.position, - size: props.dimensions, - color: GRAB_BOX_COLOR, - alpha: GRAB_BOX_ALPHA, - solid: true, - visible: true, - ignoreRayIntersection: true, - drawInFront: false - }); - - _this.hotspotOverlays.push({ - entityID: entityID, - overlay: overlay, - type: "near", - localPosition: {x: 0, y: 0, z: 0} - }); - } + // add green spheres for each equippable hotspot. + flatten(this.entityPropertyCache.getEntities().map(function (entityID) { + return _this.collectEquipHotspots(entityID); + })).filter(function (hotspot) { + return _this.hotspotIsEquippable(hotspot); + }).forEach(function (hotspot) { + var overlay = Overlays.addOverlay("sphere", { + position: hotspot.worldPosition, + size: hotspot.radius * 2, + color: EQUIP_SPHERE_COLOR, + alpha: EQUIP_SPHERE_ALPHA, + solid: true, + visible: true, + ignoreRayIntersection: true, + drawInFront: false + }); + _this.hotspotOverlays.push({ + entityID: hotspot.entityID, + overlay: overlay, + type: "equip", + localPosition: hotspot.localPosition + }); }); }; @@ -1091,8 +1089,18 @@ function MyController(hand) { return grabbableProps && grabbableProps.wantsTrigger; }; + /// @param {UUID} entityID + // @returns {Object[]} array of objects with the following fields. + // * entityID {UUID} + // * localPosition {Vec3} position of the hotspot in object space. + // * worldPosition {vec3} position of the hotspot in world space. + // * radius {number} radius of equip hotspot + // * joints {Object} keys are joint names values are arrays of two elements: + // offset position {Vec3} and offset rotation {Quat}, both are in the coordinate system of the joint. this.collectEquipHotspots = function (entityID) { var result = []; + var props = this.entityPropertyCache.getProps(entityID); + var entityXform = new Xform(props.rotation, props.position); var equipHotspotsProps = this.entityPropertyCache.getEquipHotspotsProps(entityID); if (equipHotspotsProps && equipHotspotsProps.length > 0) { var i, length = equipHotspotsProps.length; @@ -1100,7 +1108,9 @@ function MyController(hand) { var hotspot = equipHotspotsProps[i]; if (hotspot.position && hotspot.radius && hotspot.joints) { result.push({ - position: hotspot.position, + entityID: entityID, + localPosition: hotspot.position, + worldPosition: entityXform.xformPoint(hotspot.position), radius: hotspot.radius, joints: hotspot.joints }); @@ -1110,7 +1120,9 @@ function MyController(hand) { var wearableProps = this.entityPropertyCache.getWearableProps(entityID); if (wearableProps && wearableProps.joints) { result.push({ - position: {x: 0, y: 0, z: 0}, + entityID: entityID, + localPosition: {x: 0, y: 0, z: 0}, + worldPosition: entityXform.pos, radius: EQUIP_RADIUS, joints: wearableProps.joints }); @@ -1119,13 +1131,10 @@ function MyController(hand) { return result; }; - this.entityIsEquippableWithDistanceCheck = function (entityID, handPosition, skipDistanceCheck) { - var distance; - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - var props = this.entityPropertyCache.getProps(entityID); - var grabProps = this.entityPropertyCache.getGrabProps(entityID); + this.hotspotIsEquippable = function (hotspot) { + var props = this.entityPropertyCache.getProps(hotspot.entityID); + var grabProps = this.entityPropertyCache.getGrabProps(hotspot.entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); - var entityXform = new Xform(props.rotation, props.position); var refCount = ("refCount" in grabProps) ? grabProps.refCount : 0; if (refCount > 0) { @@ -1135,21 +1144,7 @@ function MyController(hand) { return false; } - var equipHotspots = this.collectEquipHotspots(entityID); - var i, length = equipHotspots.length; - for (i = 0; i < length; i++) { - var hotspot = equipHotspots[i]; - distance = Vec3.distance(entityXform.xformPoint(hotspot.position), handPosition); - if ((skipDistanceCheck || distance < hotspot.radius) && hotspot.joints[handJointName]) { - return true; - } - } - return false; - }; - - this.entityIsEquippableWithoutDistanceCheck = function (entityID) { - var handPosition = this.getHandPosition(); - return this.entityIsEquippableWithDistanceCheck(entityID, handPosition, true); + return true; }; this.entityIsGrabbable = function (entityID) { @@ -1285,22 +1280,24 @@ function MyController(hand) { this.entityPropertyCache.findEntities(handPosition, NEAR_GRAB_RADIUS); var candidateEntities = this.entityPropertyCache.getEntities(); - var equippableEntities = candidateEntities.filter(function (entity) { - return _this.entityIsEquippableWithDistanceCheck(entity, handPosition); + var equippableHotspots = flatten(candidateEntities.map(function (entityID) { + return _this.collectEquipHotspots(entityID); + })).filter(function (hotspot) { + return _this.hotspotIsEquippable(hotspot) && Vec3.distance(hotspot.worldPosition, handPosition) < hotspot.radius; }); var entity; - if (equippableEntities.length > 0) { + if (equippableHotspots.length > 0) { // sort by distance - equippableEntities.sort(function (a, b) { - var aDistance = Vec3.distance(_this.entityPropertyCache.getProps(a).position, handPosition); - var bDistance = Vec3.distance(_this.entityPropertyCache.getProps(b).position, handPosition); + equippableHotspots.sort(function (a, b) { + var aDistance = Vec3.distance(a.worldPosition, handPosition); + var bDistance = Vec3.distance(b.worldPosition, handPosition); return aDistance - bDistance; }); - entity = equippableEntities[0]; if (this.triggerSmoothedGrab()) { - this.grabbedEntity = entity; - this.setState(STATE_HOLD, "eqipping '" + this.entityPropertyCache.getProps(entity).name + "'"); + this.grabbedHotspot = equippableHotspots[0]; + this.grabbedEntity = equippableHotspots[0].entityID; + this.setState(STATE_HOLD, "eqipping '" + this.entityPropertyCache.getProps(this.grabbedEntity).name + "'"); return; } else { // TODO: highlight the equippable object? diff --git a/scripts/system/libraries/utils.js b/scripts/system/libraries/utils.js index f39f4d7913..b7de9b012c 100644 --- a/scripts/system/libraries/utils.js +++ b/scripts/system/libraries/utils.js @@ -309,5 +309,11 @@ calculateHandSizeRatio = function() { clamp = function(val, min, max){ return Math.max(min, Math.min(max, val)) - } +} +// flattens an array of arrays into a single array +// example: flatten([[1], [3, 4], []) => [1, 3, 4] +// NOTE: only does one level of flattening, it is not recursive. +flatten = function(array) { + return [].concat.apply([], array); +} From 6072487c9c388374e707a17fdb69b7d629e7f37b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 29 Jun 2016 17:28:53 -0700 Subject: [PATCH 54/77] Equip-points attachments work Also made handControllerGrab.js eslint clean. --- .../system/controllers/handControllerGrab.js | 197 ++++++++---------- 1 file changed, 82 insertions(+), 115 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index fe95dda596..d37602f8e6 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -10,7 +10,7 @@ // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, Reticle, Messages, setEntityCustomData, getEntityCustomData, vec3toStr, flatten, Xform */ +/* global setEntityCustomData, getEntityCustomData, vec3toStr, flatten, Xform */ Script.include("/~/system/libraries/utils.js"); Script.include("../libraries/Xform.js"); @@ -139,7 +139,7 @@ var DEFAULT_GRABBABLE_DATA = { var USE_BLACKLIST = true; var blacklist = []; -//we've created various ways of visualizing looking for and moving distant objects +// we've created various ways of visualizing looking for and moving distant objects var USE_ENTITY_LINES_FOR_SEARCHING = false; var USE_OVERLAY_LINES_FOR_SEARCHING = true; @@ -255,7 +255,8 @@ function isIn2DMode() { // In this version, we make our own determination of whether we're aimed a HUD element, // because other scripts (such as handControllerPointer) might be using some other visualization // instead of setting Reticle.visible. - return EXTERNALLY_MANAGED_2D_MINOR_MODE && (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(Reticle.position)); + return (EXTERNALLY_MANAGED_2D_MINOR_MODE && + (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(Reticle.position))); } function restore2DMode() { if (!EXTERNALLY_MANAGED_2D_MINOR_MODE) { @@ -274,7 +275,7 @@ EntityPropertiesCache.prototype.clear = function() { EntityPropertiesCache.prototype.findEntities = function(position, radius) { var entities = Entities.findEntities(position, radius); var _this = this; - entities.forEach(function (x) { + entities.forEach(function(x) { _this.updateEntity(x); }); }; @@ -286,7 +287,7 @@ EntityPropertiesCache.prototype.updateEntity = function(entityID) { if (props.userData) { try { userData = JSON.parse(props.userData); - } catch(err) { + } catch (err) { print("WARNING: malformed userData on " + entityID + ", name = " + props.name + ", error = " + err); } } @@ -296,9 +297,9 @@ EntityPropertiesCache.prototype.updateEntity = function(entityID) { }; EntityPropertiesCache.prototype.getEntities = function() { return Object.keys(this.cache); -} +}; EntityPropertiesCache.prototype.getProps = function(entityID) { - var obj = this.cache[entityID] + var obj = this.cache[entityID]; return obj ? obj : undefined; }; EntityPropertiesCache.prototype.getGrabbableProps = function(entityID) { @@ -346,7 +347,7 @@ function MyController(hand) { this.getHandRotation = function() { var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; return Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation); - } + }; this.actionID = null; // action this script created... this.grabbedEntity = null; // on this entity. @@ -359,11 +360,11 @@ function MyController(hand) { this.rawSecondaryValue = 0; this.rawThumbValue = 0; - //for visualizations + // for visualizations this.overlayLine = null; this.particleBeamObject = null; - //for lights + // for lights this.spotlight = null; this.pointlight = null; this.overlayLine = null; @@ -388,7 +389,7 @@ function MyController(hand) { var _this = this; var suppressedIn2D = [STATE_OFF, STATE_SEARCHING]; - this.ignoreInput = function () { + this.ignoreInput = function() { // We've made the decision to use 'this' for new code, even though it is fragile, // in order to keep/ the code uniform without making any no-op line changes. return (-1 !== suppressedIn2D.indexOf(this.state)) && isIn2DMode(); @@ -419,7 +420,7 @@ function MyController(hand) { this.callEntityMethodOnGrabbed = function(entityMethodName) { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.grabbedEntity, entityMethodName, args); - } + }; this.setState = function(newState, reason) { @@ -517,7 +518,7 @@ function MyController(hand) { ignoreRayIntersection: true, drawInFront: true, // Even when burried inside of something, show it. visible: true - } + }; this.searchSphere = Overlays.addOverlay("sphere", sphereProperties); } else { Overlays.editOverlay(this.searchSphere, { @@ -527,7 +528,7 @@ function MyController(hand) { visible: true }); } - } + }; this.overlayLineOn = function(closePoint, farPoint, color) { if (this.overlayLine === null) { @@ -576,7 +577,7 @@ function MyController(hand) { this.overlayLineOn(handPosition, searchSphereLocation, (this.triggerSmoothedGrab() || this.secondarySqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); } - } + }; this.handleDistantParticleBeam = function(handPosition, objectPosition, color) { @@ -643,7 +644,7 @@ function MyController(hand) { "alphaFinish": 1, "additiveBlending": 0, "textures": "https://hifi-content.s3.amazonaws.com/alan/dev/textures/grabsprite-3.png" - } + }; this.particleBeamObject = Entities.addEntity(particleBeamPropertiesObject); }; @@ -657,7 +658,7 @@ function MyController(hand) { emitSpeed: speed, speedSpread: spread, lifespan: lifespan - }) + }); }; this.evalLightWorldTransform = function(modelPos, modelRot) { @@ -711,9 +712,9 @@ function MyController(hand) { this.spotlight = Entities.addEntity(lightProperties); } else { Entities.editEntity(this.spotlight, { - //without this, this light would maintain rotation with its parent + // without this, this light would maintain rotation with its parent rotation: Quat.fromPitchYawRollDegrees(-90, 0, 0) - }) + }); } }; @@ -777,7 +778,7 @@ function MyController(hand) { Entities.deleteEntity(this.particleBeamObject); this.particleBeamObject = null; } - } + }; this.turnLightsOff = function() { if (this.spotlight !== null) { @@ -853,7 +854,7 @@ function MyController(hand) { this.thumbPress = function(value) { _this.rawThumbValue = value; - } + }; this.thumbPressed = function() { return _this.rawThumbValue > THUMB_ON_VALUE; @@ -878,7 +879,7 @@ function MyController(hand) { } }; - this.createHotspots = function () { + this.createHotspots = function() { var _this = this; var HAND_EQUIP_SPHERE_COLOR = { red: 90, green: 255, blue: 90 }; @@ -942,7 +943,7 @@ function MyController(hand) { if (DRAW_GRAB_BOXES) { // add blue box overlays for grabbable entities. - this.entityPropertyCache.getEntities().forEach(function (entityID) { + this.entityPropertyCache.getEntities().forEach(function(entityID) { var props = _this.entityPropertyCache.getProps(entityID); if (_this.entityIsGrabbable(entityID)) { var overlay = Overlays.addOverlay("cube", { @@ -967,11 +968,11 @@ function MyController(hand) { } // add green spheres for each equippable hotspot. - flatten(this.entityPropertyCache.getEntities().map(function (entityID) { + flatten(this.entityPropertyCache.getEntities().map(function(entityID) { return _this.collectEquipHotspots(entityID); - })).filter(function (hotspot) { + })).filter(function(hotspot) { return _this.hotspotIsEquippable(hotspot); - }).forEach(function (hotspot) { + }).forEach(function(hotspot) { var overlay = Overlays.addOverlay("sphere", { position: hotspot.worldPosition, size: hotspot.radius * 2, @@ -994,14 +995,17 @@ function MyController(hand) { this.updateHotspots = function() { var _this = this; var props; - this.hotspotOverlays.forEach(function (overlayInfo) { + this.hotspotOverlays.forEach(function(overlayInfo) { if (overlayInfo.type === "hand") { Overlays.editOverlay(overlayInfo.overlay, { position: _this.getHandPosition() }); } else if (overlayInfo.type === "equip") { _this.entityPropertyCache.updateEntity(overlayInfo.entityID); props = _this.entityPropertyCache.getProps(overlayInfo.entityID); var entityXform = new Xform(props.rotation, props.position); - Overlays.editOverlay(overlayInfo.overlay, { position: entityXform.xformPoint(overlayInfo.localPosition), rotation: props.rotation }); + Overlays.editOverlay(overlayInfo.overlay, { + position: entityXform.xformPoint(overlayInfo.localPosition), + rotation: props.rotation + }); } else if (overlayInfo.type === "near") { _this.entityPropertyCache.updateEntity(overlayInfo.entityID); props = _this.entityPropertyCache.getProps(overlayInfo.entityID); @@ -1011,7 +1015,7 @@ function MyController(hand) { }; this.destroyHotspots = function() { - this.hotspotOverlays.forEach(function (overlayInfo) { + this.hotspotOverlays.forEach(function(overlayInfo) { Overlays.deleteOverlay(overlayInfo.overlay); }); this.hotspotOverlays = []; @@ -1025,14 +1029,14 @@ function MyController(hand) { this.destroyHotspots(); }; - /// // Performs ray pick test from the hand controller into the world // @param {number} which hand to use, RIGHT_HAND or LEFT_HAND // @returns {object} returns object with two keys entityID and distance // this.calcRayPickInfo = function(hand) { - var pose = Controller.getPoseValue((hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand); + var standardControllerValue = (hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; + var pose = Controller.getPoseValue(standardControllerValue); var worldHandPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation, pose.translation), MyAvatar.position); var worldHandRotation = Quat.multiply(MyAvatar.orientation, pose.rotation); @@ -1071,33 +1075,37 @@ function MyController(hand) { } var overlayIntersection = Overlays.findRayIntersection(pickRayBacked); - if (!intersection.intersects || (overlayIntersection.intersects && (intersection.distance > overlayIntersection.distance))) { + if (!intersection.intersects || + (overlayIntersection.intersects && (intersection.distance > overlayIntersection.distance))) { intersection = overlayIntersection; } if (intersection.intersects) { - return { entityID: intersection.entityID, - searchRay: pickRay, - distance: Vec3.distance(pickRay.origin, intersection.intersection) } + return { + entityID: intersection.entityID, + searchRay: pickRay, + distance: Vec3.distance(pickRay.origin, intersection.intersection) + }; } else { return result; } }; - this.entityWantsTrigger = function (entityID) { + this.entityWantsTrigger = function(entityID) { var grabbableProps = this.entityPropertyCache.getGrabbableProps(entityID); return grabbableProps && grabbableProps.wantsTrigger; }; - /// @param {UUID} entityID - // @returns {Object[]} array of objects with the following fields. + // returns a list of all equip-hotspots assosiated with this entity. + // @param {UUID} entityID + // @returns {Object[]} array of objects with the following fields. // * entityID {UUID} // * localPosition {Vec3} position of the hotspot in object space. // * worldPosition {vec3} position of the hotspot in world space. // * radius {number} radius of equip hotspot // * joints {Object} keys are joint names values are arrays of two elements: // offset position {Vec3} and offset rotation {Quat}, both are in the coordinate system of the joint. - this.collectEquipHotspots = function (entityID) { + this.collectEquipHotspots = function(entityID) { var result = []; var props = this.entityPropertyCache.getProps(entityID); var entityXform = new Xform(props.rotation, props.position); @@ -1131,7 +1139,7 @@ function MyController(hand) { return result; }; - this.hotspotIsEquippable = function (hotspot) { + this.hotspotIsEquippable = function(hotspot) { var props = this.entityPropertyCache.getProps(hotspot.entityID); var grabProps = this.entityPropertyCache.getGrabProps(hotspot.entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); @@ -1147,7 +1155,7 @@ function MyController(hand) { return true; }; - this.entityIsGrabbable = function (entityID) { + this.entityIsGrabbable = function(entityID) { var grabbableProps = this.entityPropertyCache.getGrabbableProps(entityID); var grabProps = this.entityPropertyCache.getGrabProps(entityID); var props = this.entityPropertyCache.getProps(entityID); @@ -1280,16 +1288,16 @@ function MyController(hand) { this.entityPropertyCache.findEntities(handPosition, NEAR_GRAB_RADIUS); var candidateEntities = this.entityPropertyCache.getEntities(); - var equippableHotspots = flatten(candidateEntities.map(function (entityID) { + var equippableHotspots = flatten(candidateEntities.map(function(entityID) { return _this.collectEquipHotspots(entityID); - })).filter(function (hotspot) { + })).filter(function(hotspot) { return _this.hotspotIsEquippable(hotspot) && Vec3.distance(hotspot.worldPosition, handPosition) < hotspot.radius; }); var entity; if (equippableHotspots.length > 0) { // sort by distance - equippableHotspots.sort(function (a, b) { + equippableHotspots.sort(function(a, b) { var aDistance = Vec3.distance(a.worldPosition, handPosition); var bDistance = Vec3.distance(b.worldPosition, handPosition); return aDistance - bDistance; @@ -1304,7 +1312,7 @@ function MyController(hand) { } } - var grabbableEntities = candidateEntities.filter(function (entity) { + var grabbableEntities = candidateEntities.filter(function(entity) { return _this.entityIsNearGrabbable(entity, handPosition, NEAR_GRAB_MAX_DISTANCE); }); @@ -1321,7 +1329,7 @@ function MyController(hand) { if (grabbableEntities.length > 0) { // sort by distance - grabbableEntities.sort(function (a, b) { + grabbableEntities.sort(function(a, b) { var aDistance = Vec3.distance(_this.entityPropertyCache.getProps(a).position, handPosition); var bDistance = Vec3.distance(_this.entityPropertyCache.getProps(b).position, handPosition); return aDistance - bDistance; @@ -1381,9 +1389,11 @@ function MyController(hand) { } } - //search line visualizations + // search line visualizations if (USE_ENTITY_LINES_FOR_SEARCHING === true) { - this.lineOn(rayPickInfo.searchRay.origin, Vec3.multiply(rayPickInfo.searchRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); + this.lineOn(rayPickInfo.searchRay.origin, + Vec3.multiply(rayPickInfo.searchRay.direction, LINE_LENGTH), + NO_INTERSECT_COLOR); } this.searchIndicatorOn(rayPickInfo.searchRay); @@ -1398,11 +1408,11 @@ function MyController(hand) { timeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME; } return timeScale; - } + }; this.getMass = function(dimensions, density) { return (dimensions.x * dimensions.y * dimensions.z) * density; - } + }; this.distanceHoldingEnter = function() { @@ -1529,7 +1539,8 @@ function MyController(hand) { var RADIAL_GRAB_AMPLIFIER = 10.0; if (Math.abs(this.grabRadialVelocity) > 0.0) { - this.grabRadius = this.grabRadius + (this.grabRadialVelocity * deltaObjectTime * this.grabRadius * RADIAL_GRAB_AMPLIFIER); + this.grabRadius = this.grabRadius + (this.grabRadialVelocity * deltaObjectTime * + this.grabRadius * RADIAL_GRAB_AMPLIFIER); } var newTargetPosition = Vec3.multiply(this.grabRadius, Quat.getUp(controllerRotation)); @@ -1557,30 +1568,9 @@ function MyController(hand) { } } - // var defaultConstraintData = { - // axisStart: false, - // axisEnd: false - // } - // - // var constraintData = getEntityCustomData('lightModifierKey', this.grabbedEntity, defaultConstraintData); - // var clampedVector; - // var targetPosition; - // if (constraintData.axisStart !== false) { - // clampedVector = this.projectVectorAlongAxis(this.currentObjectPosition, - // constraintData.axisStart, - // constraintData.axisEnd); - // targetPosition = clampedVector; - // } else { - // targetPosition = { - // x: this.currentObjectPosition.x, - // y: this.currentObjectPosition.y, - // z: this.currentObjectPosition.z - // } - // } - var handPosition = this.getHandPosition(); - //visualizations + // visualizations if (USE_ENTITY_LINES_FOR_MOVING === true) { this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR); } @@ -1588,7 +1578,7 @@ function MyController(hand) { this.overlayLineOn(handPosition, grabbedProperties.position, INTERSECT_COLOR); } if (USE_PARTICLE_BEAM_FOR_MOVING === true) { - this.handleDistantParticleBeam(handPosition, grabbedProperties.position, INTERSECT_COLOR) + this.handleDistantParticleBeam(handPosition, grabbedProperties.position, INTERSECT_COLOR); } if (USE_POINTLIGHT === true) { this.handlePointLight(this.grabbedEntity); @@ -1648,46 +1638,17 @@ function MyController(hand) { scalar = 1; } var projection = Vec3.sum(axisStart, Vec3.multiply(scalar, Vec3.normalize(bPrime))); - return projection + return projection; }; - this.hasPresetOffsets = function() { - var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}}); - if ("joints" in wearableData) { - var allowedJoints = wearableData.joints; - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (handJointName in allowedJoints) { - return true; - } - } - return false; - } - - this.getPresetPosition = function() { - var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}}); - var allowedJoints = wearableData.joints; - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (handJointName in allowedJoints) { - return allowedJoints[handJointName][0]; - } - } - - this.getPresetRotation = function() { - var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}}); - var allowedJoints = wearableData.joints; - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (handJointName in allowedJoints) { - return allowedJoints[handJointName][1]; - } - } - this.dropGestureReset = function() { this.fastHandMoveDetected = false; this.fastHandMoveTimer = 0; }; this.dropGestureProcess = function(deltaTime) { - var pose = Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand); + var standardControllerValue = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; + var pose = Controller.getPoseValue(standardControllerValue); var worldHandVelocity = Vec3.multiplyQbyV(MyAvatar.orientation, pose.velocity); var worldHandRotation = Quat.multiply(MyAvatar.orientation, pose.rotation); @@ -1745,13 +1706,17 @@ function MyController(hand) { var handPosition = this.getHandPosition(); var hasPresetPosition = false; - if (this.state == STATE_HOLD && this.hasPresetOffsets()) { + if (this.state == STATE_HOLD && this.grabbedHotspot) { var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); // if an object is "equipped" and has a predefined offset, use it. this.ignoreIK = grabbableData.ignoreIK ? grabbableData.ignoreIK : false; - this.offsetPosition = this.getPresetPosition(); - this.offsetRotation = this.getPresetRotation(); - hasPresetPosition = true; + + var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; + if (this.grabbedHotspot.joints[handJointName]) { + this.offsetPosition = this.grabbedHotspot.joints[handJointName][0]; + this.offsetRotation = this.grabbedHotspot.joints[handJointName][1]; + hasPresetPosition = true; + } } else { this.ignoreIK = false; @@ -1784,7 +1749,7 @@ function MyController(hand) { var reparentProps = { parentID: MyAvatar.sessionUUID, parentJointIndex: handJointIndex - } + }; if (hasPresetPosition) { reparentProps["localPosition"] = this.offsetPosition; reparentProps["localRotation"] = this.offsetRotation; @@ -2022,6 +1987,7 @@ function MyController(hand) { })); this.grabbedEntity = null; + this.grabbedHotspot = null; if (this.triggerSmoothedGrab()) { this.waitForTriggerRelease = true; @@ -2124,7 +2090,7 @@ function MyController(hand) { print("disconnecting stray child of hand: (" + _this.hand + ") " + childID); Entities.editEntity(childID, {parentID: NULL_UUID}); }); - } + }; this.deactivateEntity = function(entityID, noVelocity) { var deactiveProps; @@ -2149,7 +2115,7 @@ function MyController(hand) { // things that are held by parenting and dropped with no velocity will end up as "static" in bullet. If // it looks like the dropped thing should fall, give it a little velocity. - var props = Entities.getEntityProperties(entityID, ["parentID", "velocity", "dynamic", "shapeType"]) + var props = Entities.getEntityProperties(entityID, ["parentID", "velocity", "dynamic", "shapeType"]); var parentID = props.parentID; var doSetVelocity = false; @@ -2231,7 +2197,8 @@ mapping.from([Controller.Standard.RightPrimaryThumb]).peek().to(rightController. Controller.enableMapping(MAPPING_NAME); -//the section below allows the grab script to listen for messages that disable either one or both hands. useful for two handed items +// the section below allows the grab script to listen for messages +// that disable either one or both hands. useful for two handed items var handToDisable = 'none'; function update(deltaTime) { @@ -2294,7 +2261,7 @@ var handleHandMessages = function(channel, message, sender) { } } } -} +}; Messages.messageReceived.connect(handleHandMessages); From 759b3065fc8693bca06b89134b7a91a87cdccec4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Jun 2016 20:48:19 +1200 Subject: [PATCH 55/77] Distinguish between file name and directory as prompt in file chooser --- interface/resources/qml/dialogs/FileDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/dialogs/FileDialog.qml b/interface/resources/qml/dialogs/FileDialog.qml index 5372028da5..fa5be18cd3 100644 --- a/interface/resources/qml/dialogs/FileDialog.qml +++ b/interface/resources/qml/dialogs/FileDialog.qml @@ -603,7 +603,7 @@ ModalWindow { TextField { id: currentSelection - label: "Path:" + label: selectDirectory ? "Directory:" : "File name:" anchors { left: parent.left right: selectionType.visible ? selectionType.left: parent.right From 1f451269cd7b67bd94554a21f85830fefd92e546 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 13:22:01 -0700 Subject: [PATCH 56/77] Allow scripts to receive a visibility changed signal from their windows --- libraries/ui/src/QmlWindowClass.cpp | 1 + libraries/ui/src/QmlWindowClass.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/ui/src/QmlWindowClass.cpp b/libraries/ui/src/QmlWindowClass.cpp index c0eba4abf3..7d56e51495 100644 --- a/libraries/ui/src/QmlWindowClass.cpp +++ b/libraries/ui/src/QmlWindowClass.cpp @@ -123,6 +123,7 @@ void QmlWindowClass::initQml(QVariantMap properties) { // Forward messages received from QML on to the script connect(_qmlWindow, SIGNAL(sendToScript(QVariant)), this, SLOT(qmlToScript(const QVariant&)), Qt::QueuedConnection); + connect(_qmlWindow, SIGNAL(visibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection); }); } Q_ASSERT(_qmlWindow); diff --git a/libraries/ui/src/QmlWindowClass.h b/libraries/ui/src/QmlWindowClass.h index e1865b133a..c30027df6e 100644 --- a/libraries/ui/src/QmlWindowClass.h +++ b/libraries/ui/src/QmlWindowClass.h @@ -24,7 +24,7 @@ class QmlWindowClass : public QObject { Q_OBJECT Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize NOTIFY sizeChanged) - Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibilityChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) public: static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine); @@ -52,7 +52,7 @@ public slots: void sendToQml(const QVariant& message); signals: - void visibilityChanged(bool visible); // Tool window + void visibleChanged(); void positionChanged(); void sizeChanged(); void moved(glm::vec2 position); From 82b1cba81dcba949e1eaf3095c110a72ad90176e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 30 Jun 2016 13:58:44 -0700 Subject: [PATCH 57/77] equip improvements Allow the user to equip an object while near or far grabbing it from the other hand. --- scripts/system/controllers/handControllerGrab.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index d37602f8e6..7a0bfc85cf 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1144,10 +1144,11 @@ function MyController(hand) { var grabProps = this.entityPropertyCache.getGrabProps(hotspot.entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); + // Controller.Standard.LeftHand var refCount = ("refCount" in grabProps) ? grabProps.refCount : 0; - if (refCount > 0) { + if (refCount > 0 && this.getOtherHandController().grabbedEntity != hotspot.entityID) { if (debug) { - print("equip is skipping '" + props.name + "': it is already grabbed"); + print("equip is skipping '" + props.name + "': grabbed by someone else"); } return false; } @@ -1698,6 +1699,12 @@ function MyController(hand) { this.grabbedEntity = saveGrabbedID; } + var otherHandController = this.getOtherHandController(); + if (otherHandController.grabbedEntity == this.grabbedEntity && + (otherHandController.state == STATE_NEAR_GRABBING || otherHandController.state == STATE_DISTANCE_HOLDING)) { + otherHandController.setState(STATE_OFF, "other hand grabbed this entity"); + } + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); this.activateEntity(this.grabbedEntity, grabbedProperties, false); @@ -1818,7 +1825,6 @@ function MyController(hand) { return; } - var now = Date.now(); if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * CHECK_TOO_FAR_UNEQUIP_TIME) { this.lastUnequipCheckTime = now; @@ -2176,6 +2182,10 @@ function MyController(hand) { } setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); }; + + this.getOtherHandController = function() { + return (this.hand === RIGHT_HAND) ? leftController : rightController; + }; } var rightController = new MyController(RIGHT_HAND); From 5b343c9b82e322f6452c4e3f48244fe55272457e Mon Sep 17 00:00:00 2001 From: Zander Otavka Date: Thu, 30 Jun 2016 14:18:07 -0700 Subject: [PATCH 58/77] Fix eslint descrepencies Prohibit trailing commas, and fix function spacing rule to be more in line with the coding standard. Also prohibit leading decimal points, also specified in coding standard. --- .eslintrc.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index e866713b11..a7f4291257 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -52,13 +52,14 @@ module.exports = { }, "rules": { "brace-style": ["error", "1tbs", { "allowSingleLine": false }], - "comma-dangle": ["error", "only-multiline"], + "comma-dangle": ["error", "never"], "camelcase": ["error"], "curly": ["error", "all"], "indent": ["error", 4, { "SwitchCase": 1 }], "keyword-spacing": ["error", { "before": true, "after": true }], "max-len": ["error", 128, 4], "new-cap": ["error"], + "no-floating-decimal": ["error"], //"no-magic-numbers": ["error", { "ignore": [0, 1], "ignoreArrayIndexes": true }], "no-multiple-empty-lines": ["error"], "no-multi-spaces": ["error"], @@ -67,6 +68,6 @@ module.exports = { "spaced-comment": ["error", "always", { "line": { "markers": ["/"] } }], - "space-before-function-paren": ["error", "never"] + "space-before-function-paren": ["error", {"anonymous": "always", "named": "never"}] } }; From dfb6cb1aa340f04d4116efc8c621fa3d08f08aca Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 14:25:36 -0700 Subject: [PATCH 59/77] Updating entity list --- scripts/system/libraries/entityList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index e9baeac86c..448293a2ac 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -111,8 +111,8 @@ EntityListTool = function(opts) { } }); - webView.visibilityChanged.connect(function (visible) { - if (visible) { + webView.visibleChanged.connect(function () { + if (webView.visible) { that.sendUpdate(); } }); From 38776fe007220cc7b57fdc68e2ac975a359ae22e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 30 Jun 2016 14:35:27 -0700 Subject: [PATCH 60/77] Fix multiple sessions being created for some users If a user didn't have send-data activated they don't have their session id sent in the header of requests, but instead send it inside the request body. The session id being send in the request included curly braces which the server considers invalid. --- interface/src/DiscoverabilityManager.cpp | 6 ++---- libraries/networking/src/AccountManager.h | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index c4d985419e..6550edff18 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -80,8 +80,7 @@ void DiscoverabilityManager::updateLocation() { locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends)); // if we have a session ID add it now, otherwise add a null value - auto sessionID = accountManager->getSessionID(); - rootObject[SESSION_ID_KEY] = sessionID.isNull() ? QJsonValue() : sessionID.toString(); + rootObject[SESSION_ID_KEY] = accountManager->getSessionIDWithoutCurlyBraces(); JSONCallbackParameters callbackParameters; callbackParameters.jsonCallbackReceiver = this; @@ -111,8 +110,7 @@ void DiscoverabilityManager::updateLocation() { callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse"; QJsonObject heartbeatObject; - auto sessionID = accountManager->getSessionID(); - heartbeatObject[SESSION_ID_KEY] = sessionID.isNull() ? QJsonValue() : sessionID.toString(); + heartbeatObject[SESSION_ID_KEY] = accountManager->getSessionIDWithoutCurlyBraces(); accountManager->sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional, QNetworkAccessManager::PutOperation, callbackParameters, diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index c12f663d3e..7a8d2a72fa 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -24,6 +24,8 @@ #include +#include "UUID.h" + class JSONCallbackParameters { public: JSONCallbackParameters(QObject* jsonCallbackReceiver = nullptr, const QString& jsonCallbackMethod = QString(), @@ -86,6 +88,7 @@ public: static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply); + QString getSessionIDWithoutCurlyBraces() const { return uuidStringWithoutCurlyBraces(_sessionID); } QUuid getSessionID() const { return _sessionID; } void setSessionID(const QUuid& sessionID) { _sessionID = sessionID; } From 49da7d9a61beae00f125694ca86dcc45c8a6b526 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 30 Jun 2016 14:43:27 -0700 Subject: [PATCH 61/77] Remove sending of session id in request body in favor of header --- interface/src/DiscoverabilityManager.cpp | 9 +-------- libraries/networking/src/AccountManager.cpp | 8 ++------ libraries/networking/src/AccountManager.h | 1 - 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index 6550edff18..4051bd8a1e 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -79,9 +79,6 @@ void DiscoverabilityManager::updateLocation() { const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only"; locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends)); - // if we have a session ID add it now, otherwise add a null value - rootObject[SESSION_ID_KEY] = accountManager->getSessionIDWithoutCurlyBraces(); - JSONCallbackParameters callbackParameters; callbackParameters.jsonCallbackReceiver = this; callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse"; @@ -109,12 +106,8 @@ void DiscoverabilityManager::updateLocation() { callbackParameters.jsonCallbackReceiver = this; callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse"; - QJsonObject heartbeatObject; - heartbeatObject[SESSION_ID_KEY] = accountManager->getSessionIDWithoutCurlyBraces(); - accountManager->sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional, - QNetworkAccessManager::PutOperation, callbackParameters, - QJsonDocument(heartbeatObject).toJson()); + QNetworkAccessManager::PutOperation, callbackParameters); } } diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index e49bf5d5a5..ed325b8d69 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -220,12 +220,8 @@ void AccountManager::sendRequest(const QString& path, networkRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter()); - // if we're allowed to send usage data, include whatever the current session ID is with this request - auto& activityLogger = UserActivityLogger::getInstance(); - if (activityLogger.isEnabled()) { - networkRequest.setRawHeader(METAVERSE_SESSION_ID_HEADER, - uuidStringWithoutCurlyBraces(_sessionID).toLocal8Bit()); - } + networkRequest.setRawHeader(METAVERSE_SESSION_ID_HEADER, + uuidStringWithoutCurlyBraces(_sessionID).toLocal8Bit()); QUrl requestURL = _authURL; diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 7a8d2a72fa..cdf7e3f1cd 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -88,7 +88,6 @@ public: static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply); - QString getSessionIDWithoutCurlyBraces() const { return uuidStringWithoutCurlyBraces(_sessionID); } QUuid getSessionID() const { return _sessionID; } void setSessionID(const QUuid& sessionID) { _sessionID = sessionID; } From dd73f0c333116a1b78c8553206b8cc6262b15dec Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 30 Jun 2016 14:50:29 -0700 Subject: [PATCH 62/77] Remove unused header from AccountManager.h --- libraries/networking/src/AccountManager.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index cdf7e3f1cd..c12f663d3e 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -24,8 +24,6 @@ #include -#include "UUID.h" - class JSONCallbackParameters { public: JSONCallbackParameters(QObject* jsonCallbackReceiver = nullptr, const QString& jsonCallbackMethod = QString(), From 86f8b578412bf0f905aa9df05f10bf794a72dc9b Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 15:16:28 -0700 Subject: [PATCH 63/77] Highlight controls based on activeFocus, not focus --- interface/resources/qml/controls-uit/SpinBox.qml | 12 ++++++------ interface/resources/qml/controls-uit/TextField.qml | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/interface/resources/qml/controls-uit/SpinBox.qml b/interface/resources/qml/controls-uit/SpinBox.qml index 5d78cfc5a8..a1237d4bc7 100755 --- a/interface/resources/qml/controls-uit/SpinBox.qml +++ b/interface/resources/qml/controls-uit/SpinBox.qml @@ -36,15 +36,15 @@ SpinBox { id: spinStyle background: Rectangle { color: isLightColorScheme - ? (spinBox.focus ? hifi.colors.white : hifi.colors.lightGray) - : (spinBox.focus ? hifi.colors.black : hifi.colors.baseGrayShadow) + ? (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) border.color: spinBoxLabelInside.visible ? spinBoxLabelInside.color : hifi.colors.primaryHighlight - border.width: spinBox.focus ? spinBoxLabelInside.visible ? 2 : 1 : 0 + border.width: spinBox.activeFocus ? spinBoxLabelInside.visible ? 2 : 1 : 0 } textColor: isLightColorScheme - ? (spinBox.focus ? hifi.colors.black : hifi.colors.lightGray) - : (spinBox.focus ? hifi.colors.white : hifi.colors.lightGrayText) + ? (spinBox.activeFocus ? hifi.colors.black : hifi.colors.lightGray) + : (spinBox.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) selectedTextColor: hifi.colors.black selectionColor: hifi.colors.primaryHighlight @@ -96,7 +96,7 @@ SpinBox { anchors.fill: parent propagateComposedEvents: true onWheel: { - if(spinBox.focus) + if(spinBox.activeFocus) wheel.accepted = false else wheel.accepted = true diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index 79027cdc3b..65fab00700 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -36,14 +36,14 @@ TextField { style: TextFieldStyle { textColor: isLightColorScheme - ? (textField.focus ? hifi.colors.black : hifi.colors.lightGray) - : (textField.focus ? hifi.colors.white : hifi.colors.lightGrayText) + ? (textField.activeFocus ? hifi.colors.black : hifi.colors.lightGray) + : (textField.activeFocus ? hifi.colors.white : hifi.colors.lightGrayText) background: Rectangle { color: isLightColorScheme - ? (textField.focus ? hifi.colors.white : hifi.colors.textFieldLightBackground) - : (textField.focus ? hifi.colors.black : hifi.colors.baseGrayShadow) + ? (textField.activeFocus ? hifi.colors.white : hifi.colors.textFieldLightBackground) + : (textField.activeFocus ? hifi.colors.black : hifi.colors.baseGrayShadow) border.color: hifi.colors.primaryHighlight - border.width: textField.focus ? 1 : 0 + border.width: textField.activeFocus ? 1 : 0 radius: isSearchField ? textField.height / 2 : 0 HiFiGlyphs { From ce54f1b1d12dda0ff2b9ea14fff0d6f9d2a01311 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 15:18:14 -0700 Subject: [PATCH 64/77] Improve desktop 'unfocus' functionality --- interface/resources/qml/desktop/Desktop.qml | 26 ++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/desktop/Desktop.qml b/interface/resources/qml/desktop/Desktop.qml index 27fa9692b9..59d5b435ba 100644 --- a/interface/resources/qml/desktop/Desktop.qml +++ b/interface/resources/qml/desktop/Desktop.qml @@ -30,6 +30,7 @@ FocusScope { if (!repositionLocked) { d.handleSizeChanged(); } + } onHeightChanged: d.handleSizeChanged(); @@ -66,7 +67,6 @@ FocusScope { if (desktop.repositionLocked) { return; } - var oldRecommendedRect = recommendedRect; var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect(); var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y, @@ -311,8 +311,8 @@ FocusScope { onPinnedChanged: { if (pinned) { - nullFocus.focus = true; - nullFocus.forceActiveFocus(); + desktop.focus = true; + desktop.forceActiveFocus(); // recalculate our non-pinned children hiddenChildren = d.findMatchingChildren(desktop, function(child){ @@ -486,17 +486,31 @@ FocusScope { } function unfocusWindows() { + // First find the active focus item, and unfocus it, all the way + // up the parent chain to the window + var currentFocus = offscreenWindow.activeFocusItem; + var targetWindow = d.getDesktopWindow(currentFocus); + while (currentFocus) { + if (currentFocus === targetWindow) { + break; + } + currentFocus.focus = false; + currentFocus = currentFocus.parent; + } + + // Unfocus all windows var windows = d.getTopLevelWindows(); for (var i = 0; i < windows.length; ++i) { windows[i].focus = false; } + + // For the desktop to have active focus desktop.focus = true; + desktop.forceActiveFocus(); } FocusHack { id: focusHack; } - FocusScope { id: nullFocus; } - Rectangle { id: focusDebugger; objectName: "focusDebugger" @@ -510,5 +524,5 @@ FocusScope { enabled: DebugQML onTriggered: focusDebugger.visible = !focusDebugger.visible } - + } From 167cb72a0ef03aadef3ba528f15202ee09ed4b14 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 15:18:59 -0700 Subject: [PATCH 65/77] Don't auto-focus the filter field in running scripts --- interface/resources/qml/hifi/dialogs/RunningScripts.qml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/RunningScripts.qml b/interface/resources/qml/hifi/dialogs/RunningScripts.qml index 5457caccf1..3f05a140ae 100644 --- a/interface/resources/qml/hifi/dialogs/RunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/RunningScripts.qml @@ -53,11 +53,6 @@ ScrollingWindow { updateRunningScripts(); } - function setDefaultFocus() { - // Work around FocusScope of scrollable window. - filterEdit.forceActiveFocus(); - } - function updateRunningScripts() { var runningScripts = ScriptDiscoveryService.getRunning(); runningScriptsModel.clear() @@ -276,7 +271,6 @@ ScrollingWindow { isSearchField: true anchors.left: parent.left anchors.right: parent.right - focus: true colorScheme: hifi.colorSchemes.dark placeholderText: "Filter" onTextChanged: scriptsModel.filterRegExp = new RegExp("^.*" + text + ".*$", "i") From 14784a60888b4584d31db40d9c794ae9f653ee21 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 15:22:13 -0700 Subject: [PATCH 66/77] Remove default focus on text fields --- scripts/developer/tests/playaPerformanceTest.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/developer/tests/playaPerformanceTest.qml b/scripts/developer/tests/playaPerformanceTest.qml index cd8171a0f6..028cfc9e1a 100644 --- a/scripts/developer/tests/playaPerformanceTest.qml +++ b/scripts/developer/tests/playaPerformanceTest.qml @@ -125,7 +125,6 @@ Rectangle { TextField { id: addressLine - focus: true anchors { left: parent.left; right: parent.right; top: row.bottom; margins: 16; From 69ffd63ba702417de9edc2b33bd24c05e9dee125 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 30 Jun 2016 15:42:48 -0700 Subject: [PATCH 67/77] fix snapshot sharing window --- interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml | 2 +- interface/src/Application.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml b/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml index 3dacb3b39c..f99b770a78 100644 --- a/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml +++ b/interface/resources/qml/hifi/dialogs/SnapshotShareDialog.qml @@ -7,7 +7,7 @@ import "../../windows" import "../../js/Utils.js" as Utils import "../models" -ScrollingWindow { +Window { id: root resizable: true width: 516 diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5978461dcf..1c9ec94dc4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4998,7 +4998,6 @@ void Application::takeSnapshot() { DependencyManager::get()->load("hifi/dialogs/SnapshotShareDialog.qml", [=](QQmlContext*, QObject* dialog) { dialog->setProperty("source", QUrl::fromLocalFile(fileName)); - connect(dialog, SIGNAL(uploadSnapshot(const QString& snapshot)), this, SLOT(uploadSnapshot(const QString& snapshot))); }); } From d8e5e3cbe4b1c7af668193d738e6ef0f941de7fa Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 30 Jun 2016 16:00:18 -0700 Subject: [PATCH 68/77] equip bug fix you should not be able to equip an object that is already equipped, with your other hand. --- scripts/system/controllers/handControllerGrab.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 7a0bfc85cf..ecece8c4f7 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1144,9 +1144,11 @@ function MyController(hand) { var grabProps = this.entityPropertyCache.getGrabProps(hotspot.entityID); var debug = (WANT_DEBUG_SEARCH_NAME && props.name === WANT_DEBUG_SEARCH_NAME); - // Controller.Standard.LeftHand var refCount = ("refCount" in grabProps) ? grabProps.refCount : 0; - if (refCount > 0 && this.getOtherHandController().grabbedEntity != hotspot.entityID) { + var okToEquipFromOtherHand = ((this.getOtherHandController().state == STATE_NEAR_GRABBING || + this.getOtherHandController().state == STATE_DISTANCE_HOLDING) && + this.getOtherHandController().grabbedEntity == hotspot.entityID); + if (refCount > 0 && !okToEquipFromOtherHand) { if (debug) { print("equip is skipping '" + props.name + "': grabbed by someone else"); } From b7926b8582829bc3ac444b401b5548f7872c21d8 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 16:11:05 -0700 Subject: [PATCH 69/77] Don't render wire geometry with lighting effects --- interface/src/ui/overlays/Circle3DOverlay.cpp | 7 +++++-- interface/src/ui/overlays/Cube3DOverlay.cpp | 6 +++--- interface/src/ui/overlays/Grid3DOverlay.cpp | 5 +++-- interface/src/ui/overlays/Image3DOverlay.cpp | 8 +++++--- interface/src/ui/overlays/Line3DOverlay.cpp | 9 ++++++--- interface/src/ui/overlays/Rectangle3DOverlay.cpp | 8 +++++--- interface/src/ui/overlays/Sphere3DOverlay.cpp | 4 ++-- interface/src/ui/overlays/Web3DOverlay.cpp | 4 +++- libraries/render-utils/src/GeometryCache.cpp | 5 +++++ libraries/render-utils/src/GeometryCache.h | 8 +++++--- 10 files changed, 42 insertions(+), 22 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 8fb3a36919..1abcb0f5c0 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -97,7 +97,7 @@ void Circle3DOverlay::render(RenderArgs* args) { _lastColor = colorX; auto geometryCache = DependencyManager::get(); - + Q_ASSERT(args->_batch); auto& batch = *args->_batch; @@ -149,6 +149,7 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_quadVerticesID, points, color); } + geometryCache->bindSimpleProgram(batch); geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID); } else { @@ -187,6 +188,8 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_lineVerticesID, points, color); } + // Render unlit + geometryCache->bindSimpleProgram(batch, false, false, true); if (getIsDashedLine()) { geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID); } else { @@ -279,7 +282,7 @@ void Circle3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Circle3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 38650f9fda..17894aa091 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -48,7 +48,7 @@ void Cube3DOverlay::render(RenderArgs* args) { auto geometryCache = DependencyManager::get(); auto pipeline = args->_pipeline; if (!pipeline) { - pipeline = geometryCache->getShapePipeline(); + pipeline = _isSolid ? geometryCache->getShapePipeline() : geometryCache->getWireShapePipeline(); } if (_isSolid) { @@ -56,7 +56,7 @@ void Cube3DOverlay::render(RenderArgs* args) { batch->setModelTransform(transform); geometryCache->renderSolidCubeInstance(*batch, cubeColor, pipeline); } else { - + geometryCache->bindSimpleProgram(*batch, false, false, true, true); if (getIsDashedLine()) { transform.setScale(1.0f); batch->setModelTransform(transform); @@ -97,7 +97,7 @@ void Cube3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Cube3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index edc27e35f2..7d86395937 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -75,10 +75,11 @@ void Grid3DOverlay::render(RenderArgs* args) { transform.setScale(glm::vec3(getDimensions(), 1.0f)); transform.setTranslation(position); batch->setModelTransform(transform); - + auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(*batch, false, false, true, true); const float MINOR_GRID_EDGE = 0.0025f; const float MAJOR_GRID_EDGE = 0.005f; - DependencyManager::get()->renderGrid(*batch, minCorner, maxCorner, + geometryCache->renderGrid(*batch, minCorner, maxCorner, _minorGridRowDivisions, _minorGridColDivisions, MINOR_GRID_EDGE, _majorGridRowDivisions, _majorGridColDivisions, MAJOR_GRID_EDGE, gridColor, _drawInFront); diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index fd0d2bcedf..72ae246859 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -92,8 +92,10 @@ void Image3DOverlay::render(RenderArgs* args) { batch->setModelTransform(transform); batch->setResourceTexture(0, _texture->getGPUTexture()); - - DependencyManager::get()->renderQuad( + + auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(*batch, true, false); + geometryCache->renderQuad( *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) ); @@ -102,7 +104,7 @@ void Image3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Image3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (_emissive) { builder.withUnlit(); } diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 3971e91211..d53b287f76 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -54,17 +54,20 @@ void Line3DOverlay::render(RenderArgs* args) { if (batch) { batch->setModelTransform(_transform); + auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(*batch, false, false, true, true); if (getIsDashedLine()) { // TODO: add support for color to renderDashedLine() - DependencyManager::get()->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID); + geometryCache->renderDashedLine(*batch, _start, _end, colorv4, _geometryCacheID); } else { - DependencyManager::get()->renderLine(*batch, _start, _end, colorv4, _geometryCacheID); + + geometryCache->renderLine(*batch, _start, _end, colorv4, _geometryCacheID); } } } const render::ShapeKey Line3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withoutCullFace(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 5a541fd58a..75d7ec565c 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -53,13 +53,15 @@ void Rectangle3DOverlay::render(RenderArgs* args) { transform.setRotation(rotation); batch->setModelTransform(transform); + auto geometryCache = DependencyManager::get(); if (getIsSolid()) { glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); - DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, rectangleColor); + geometryCache->bindSimpleProgram(*batch); + geometryCache->renderQuad(*batch, topLeft, bottomRight, rectangleColor); } else { - auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(*batch, false, false, true, true); if (getIsDashedLine()) { glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); @@ -89,7 +91,7 @@ void Rectangle3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Rectangle3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index d50f2f7285..1dd61611f2 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -46,7 +46,7 @@ void Sphere3DOverlay::render(RenderArgs* args) { auto geometryCache = DependencyManager::get(); auto pipeline = args->_pipeline; if (!pipeline) { - pipeline = geometryCache->getShapePipeline(); + pipeline = _isSolid ? geometryCache->getShapePipeline() : geometryCache->getWireShapePipeline(); } if (_isSolid) { @@ -58,7 +58,7 @@ void Sphere3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Sphere3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder(); + auto builder = render::ShapeKey::Builder().withOwnPipeline(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index f5baecd96a..c9c24d3ab6 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -100,7 +100,9 @@ void Web3DOverlay::render(RenderArgs* args) { } batch.setModelTransform(transform); - DependencyManager::get()->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color); + auto geometryCache = DependencyManager::get(); + geometryCache->bindSimpleProgram(batch, true, false, true, false); + geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color); batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 1154f27ee0..9ea4bd9905 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -309,6 +309,7 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() { } render::ShapePipelinePointer GeometryCache::_simplePipeline; +render::ShapePipelinePointer GeometryCache::_simpleWirePipeline; GeometryCache::GeometryCache() : _nextID(0) @@ -324,6 +325,10 @@ GeometryCache::GeometryCache() : DependencyManager::get()->getNormalFittingTexture()); } ); + GeometryCache::_simpleWirePipeline = + std::make_shared(getSimplePipeline(false, false, true, true), nullptr, + [](const render::ShapePipeline&, gpu::Batch& batch) { } + ); } GeometryCache::~GeometryCache() { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index c46a9bb084..9f18f1644c 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -157,7 +157,8 @@ public: gpu::PipelinePointer getSimplePipeline(bool textured = false, bool culled = true, bool unlit = false, bool depthBias = false); render::ShapePipelinePointer getShapePipeline() { return GeometryCache::_simplePipeline; } - + render::ShapePipelinePointer getWireShapePipeline() { return GeometryCache::_simpleWirePipeline; } + // Static (instanced) geometry void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer); void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer); @@ -179,7 +180,7 @@ public: void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline = _simplePipeline); void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color, - const render::ShapePipelinePointer& pipeline = _simplePipeline) { + const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) { renderWireSphereInstance(batch, glm::vec4(color, 1.0f), pipeline); } @@ -193,7 +194,7 @@ public: void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color, const render::ShapePipelinePointer& pipeline = _simplePipeline); void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color, - const render::ShapePipelinePointer& pipeline = _simplePipeline) { + const render::ShapePipelinePointer& pipeline = _simpleWirePipeline) { renderWireCubeInstance(batch, glm::vec4(color, 1.0f), pipeline); } @@ -401,6 +402,7 @@ private: gpu::ShaderPointer _simpleShader; gpu::ShaderPointer _unlitShader; static render::ShapePipelinePointer _simplePipeline; + static render::ShapePipelinePointer _simpleWirePipeline; QHash _simplePrograms; }; From ff55644fe859a72da6e16e5b15d92f1e5da171b8 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 30 Jun 2016 16:24:11 -0700 Subject: [PATCH 70/77] stateful hud toolbar buttons --- interface/resources/qml/AddressBarDialog.qml | 1 + .../DialogsManagerScriptingInterface.cpp | 2 ++ .../DialogsManagerScriptingInterface.h | 1 + interface/src/ui/AddressBarDialog.cpp | 4 ++++ interface/src/ui/AddressBarDialog.h | 1 + interface/src/ui/DialogsManager.h | 2 ++ scripts/system/examples.js | 18 +++++++++++------- scripts/system/goto.js | 16 +++++++++++----- scripts/system/hmd.js | 19 ++++++++++++------- scripts/system/mute.js | 19 ++++++++++++++----- 10 files changed, 59 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/AddressBarDialog.qml b/interface/resources/qml/AddressBarDialog.qml index a48804faba..dc060b70e1 100644 --- a/interface/resources/qml/AddressBarDialog.qml +++ b/interface/resources/qml/AddressBarDialog.qml @@ -30,6 +30,7 @@ Window { width: addressBarDialog.implicitWidth height: addressBarDialog.implicitHeight + onShownChanged: addressBarDialog.observeShownChanged(shown); Component.onCompleted: { root.parentChanged.connect(center); center(); diff --git a/interface/src/scripting/DialogsManagerScriptingInterface.cpp b/interface/src/scripting/DialogsManagerScriptingInterface.cpp index 80a8b4ac7c..cbca7ff4ff 100644 --- a/interface/src/scripting/DialogsManagerScriptingInterface.cpp +++ b/interface/src/scripting/DialogsManagerScriptingInterface.cpp @@ -18,6 +18,8 @@ DialogsManagerScriptingInterface::DialogsManagerScriptingInterface() { connect(DependencyManager::get().data(), &DialogsManager::addressBarToggled, this, &DialogsManagerScriptingInterface::addressBarToggled); + connect(DependencyManager::get().data(), &DialogsManager::addressBarShown, + this, &DialogsManagerScriptingInterface::addressBarShown); } void DialogsManagerScriptingInterface::toggleAddressBar() { diff --git a/interface/src/scripting/DialogsManagerScriptingInterface.h b/interface/src/scripting/DialogsManagerScriptingInterface.h index ef44e20d61..075b89f0e5 100644 --- a/interface/src/scripting/DialogsManagerScriptingInterface.h +++ b/interface/src/scripting/DialogsManagerScriptingInterface.h @@ -24,6 +24,7 @@ public slots: signals: void addressBarToggled(); + void addressBarShown(bool visible); }; #endif diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index ba0cf18d32..6fb437e312 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -16,6 +16,7 @@ #include "DependencyManager.h" #include "AddressManager.h" +#include "DialogsManager.h" HIFI_QML_DEF(AddressBarDialog) @@ -74,3 +75,6 @@ void AddressBarDialog::displayAddressNotFoundMessage() { OffscreenUi::critical("", "There is no address information for that user or place"); } +void AddressBarDialog::observeShownChanged(bool visible) { + DependencyManager::get()->emitAddressBarShown(visible); +} diff --git a/interface/src/ui/AddressBarDialog.h b/interface/src/ui/AddressBarDialog.h index b2751860cc..bbce52c67c 100644 --- a/interface/src/ui/AddressBarDialog.h +++ b/interface/src/ui/AddressBarDialog.h @@ -38,6 +38,7 @@ protected: Q_INVOKABLE void loadHome(); Q_INVOKABLE void loadBack(); Q_INVOKABLE void loadForward(); + Q_INVOKABLE void observeShownChanged(bool visible); bool _backEnabled; bool _forwardEnabled; diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index b8fa22ec83..c48c6df0e6 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -40,6 +40,7 @@ public: QPointer getHMDToolsDialog() const { return _hmdToolsDialog; } QPointer getLodToolsDialog() const { return _lodToolsDialog; } QPointer getOctreeStatsDialog() const { return _octreeStatsDialog; } + void emitAddressBarShown(bool visible) { emit addressBarShown(visible); } public slots: void toggleAddressBar(); @@ -60,6 +61,7 @@ public slots: signals: void addressBarToggled(); + void addressBarShown(bool visible); private slots: void hmdToolsClosed(); diff --git a/scripts/system/examples.js b/scripts/system/examples.js index a948f9e563..4d838bc8af 100644 --- a/scripts/system/examples.js +++ b/scripts/system/examples.js @@ -55,16 +55,20 @@ var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var browseExamplesButton = toolBar.addButton({ imageURL: toolIconUrl + "examples-01.svg", objectName: "examples", - yOffset: 50, - alpha: 0.9, + buttonState: 1, + alpha: 0.9 }); -var browseExamplesButtonDown = false; - -browseExamplesButton.clicked.connect(function(){ +function onExamplesWindowVisibilityChanged() { + browseExamplesButton.writeProperty('buttonState', examplesWindow.visible ? 0 : 1); +} +function onClick() { toggleExamples(); -}); +} +browseExamplesButton.clicked.connect(onClick); +examplesWindow.visibleChanged.connect(onExamplesWindowVisibilityChanged); Script.scriptEnding.connect(function () { - browseExamplesButton.clicked.disconnect(); + browseExamplesButton.clicked.disconnect(onClick); + examplesWindow.visibleChanged.disconnect(onExamplesWindowVisibilityChanged); }); diff --git a/scripts/system/goto.js b/scripts/system/goto.js index a2ade02a78..4650e72dad 100644 --- a/scripts/system/goto.js +++ b/scripts/system/goto.js @@ -16,14 +16,20 @@ var button = toolBar.addButton({ objectName: "goto", imageURL: Script.resolvePath("assets/images/tools/directory-01.svg"), visible: true, - yOffset: 50, + buttonState: 1, alpha: 0.9, }); - -button.clicked.connect(function(){ + +function onAddressBarShown(visible) { + button.writeProperty('buttonState', visible ? 0 : 1); +} +function onClicked(){ DialogsManager.toggleAddressBar(); -}); +} +button.clicked.connect(onClicked); +DialogsManager.addressBarShown.connect(onAddressBarShown); Script.scriptEnding.connect(function () { - button.clicked.disconnect(); + button.clicked.disconnect(onClicked); + DialogsManager.addressBarShown.disconnect(onAddressBarShown); }); diff --git a/scripts/system/hmd.js b/scripts/system/hmd.js index 2965c0d254..0d6a273975 100644 --- a/scripts/system/hmd.js +++ b/scripts/system/hmd.js @@ -20,23 +20,28 @@ var desktopMenuItemName = "Desktop"; var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var button; - +function onHmdChanged(isHmd) { + button.writeProperty('buttonState', isHmd ? 0 : 1); +} +function onClicked(){ + var isDesktop = Menu.isOptionChecked(desktopMenuItemName); + Menu.setIsOptionChecked(isDesktop ? headset : desktopMenuItemName, true); +} if (headset) { button = toolBar.addButton({ objectName: "hmdToggle", imageURL: Script.resolvePath("assets/images/tools/hmd-switch-01.svg"), visible: true, - yOffset: 50, alpha: 0.9, }); + onHmdChanged(HMD.active); - button.clicked.connect(function(){ - var isDesktop = Menu.isOptionChecked(desktopMenuItemName); - Menu.setIsOptionChecked(isDesktop ? headset : desktopMenuItemName, true); - }); + button.clicked.connect(onClicked); + HMD.displayModeChanged.connect(onHmdChanged); Script.scriptEnding.connect(function () { - button.clicked.disconnect(); + button.clicked.disconnect(onClicked); + HMD.displayModeChanged.disconnect(onHmdChanged); }); } diff --git a/scripts/system/mute.js b/scripts/system/mute.js index f66b6852ea..f91ecbafae 100644 --- a/scripts/system/mute.js +++ b/scripts/system/mute.js @@ -14,16 +14,25 @@ var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var button = toolBar.addButton({ objectName: "mute", - imageURL: Script.resolvePath("assets/images/tools/microphone.svg"), + imageURL: Script.resolvePath("assets/images/tools/mic-01.svg"), visible: true, alpha: 0.9, }); - -button.clicked.connect(function(){ + +function onMuteToggled() { + // We could just toggle state, but we're less likely to get out of wack if we read the AudioDevice. + // muted => "on" button state => buttonState 1 + button.writeProperty('buttonState', AudioDevice.getMuted() ? 1 : 0); +} +onMuteToggled(); +function onClicked(){ var menuItem = "Mute Microphone"; Menu.setIsOptionChecked(menuItem, !Menu.isOptionChecked(menuItem)); -}); +} +button.clicked.connect(onClicked); +AudioDevice.muteToggled.connect(onMuteToggled); Script.scriptEnding.connect(function () { - button.clicked.disconnect(); + button.clicked.disconnect(onClicked); + AudioDevice.muteToggled.disconnect(onMuteToggled); }); From f03f5f3e683a807c989a569272d080c843021362 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Thu, 30 Jun 2016 16:47:10 -0700 Subject: [PATCH 71/77] new icons --- interface/resources/icons/hud-01.svg | 105 ----- interface/resources/icons/hud.svg | 258 ++++++++++++ interface/resources/qml/hifi/Desktop.qml | 2 +- .../assets/images/tools/directory-01.svg | 194 ---------- .../system/assets/images/tools/directory.svg | 366 ++++++++++++++++++ .../system/assets/images/tools/edit-01.svg | 94 ----- scripts/system/assets/images/tools/edit.svg | 234 +++++++++++ .../assets/images/tools/examples-01.svg | 306 --------------- .../assets/images/tools/hmd-switch-01.svg | 124 ------ scripts/system/assets/images/tools/market.svg | 258 ++++++++++++ scripts/system/assets/images/tools/mic.svg | 164 ++++++++ scripts/system/assets/images/tools/switch.svg | 230 +++++++++++ scripts/system/edit.js | 2 +- scripts/system/examples.js | 2 +- scripts/system/goto.js | 2 +- scripts/system/hmd.js | 2 +- scripts/system/mute.js | 2 +- 17 files changed, 1516 insertions(+), 829 deletions(-) delete mode 100644 interface/resources/icons/hud-01.svg create mode 100644 interface/resources/icons/hud.svg delete mode 100644 scripts/system/assets/images/tools/directory-01.svg create mode 100644 scripts/system/assets/images/tools/directory.svg delete mode 100644 scripts/system/assets/images/tools/edit-01.svg create mode 100644 scripts/system/assets/images/tools/edit.svg delete mode 100644 scripts/system/assets/images/tools/examples-01.svg delete mode 100644 scripts/system/assets/images/tools/hmd-switch-01.svg create mode 100644 scripts/system/assets/images/tools/market.svg create mode 100644 scripts/system/assets/images/tools/mic.svg create mode 100644 scripts/system/assets/images/tools/switch.svg diff --git a/interface/resources/icons/hud-01.svg b/interface/resources/icons/hud-01.svg deleted file mode 100644 index 4929389268..0000000000 --- a/interface/resources/icons/hud-01.svg +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/interface/resources/icons/hud.svg b/interface/resources/icons/hud.svg new file mode 100644 index 0000000000..9e77aa6040 --- /dev/null +++ b/interface/resources/icons/hud.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 169542c0f0..7a7a6b63df 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -56,7 +56,7 @@ OriginalDesktop.Desktop { var sysToolbar = desktop.getToolbar("com.highfidelity.interface.toolbar.system"); var toggleHudButton = sysToolbar.addButton({ objectName: "hudToggle", - imageURL: "../../../icons/hud-01.svg", + imageURL: "../../../icons/hud.svg", visible: true, pinned: true, }); diff --git a/scripts/system/assets/images/tools/directory-01.svg b/scripts/system/assets/images/tools/directory-01.svg deleted file mode 100644 index d038611d69..0000000000 --- a/scripts/system/assets/images/tools/directory-01.svg +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/scripts/system/assets/images/tools/directory.svg b/scripts/system/assets/images/tools/directory.svg new file mode 100644 index 0000000000..912243c52e --- /dev/null +++ b/scripts/system/assets/images/tools/directory.svg @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/assets/images/tools/edit-01.svg b/scripts/system/assets/images/tools/edit-01.svg deleted file mode 100644 index c661c6f678..0000000000 --- a/scripts/system/assets/images/tools/edit-01.svg +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/scripts/system/assets/images/tools/edit.svg b/scripts/system/assets/images/tools/edit.svg new file mode 100644 index 0000000000..13389a2b14 --- /dev/null +++ b/scripts/system/assets/images/tools/edit.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/assets/images/tools/examples-01.svg b/scripts/system/assets/images/tools/examples-01.svg deleted file mode 100644 index ec4758dcde..0000000000 --- a/scripts/system/assets/images/tools/examples-01.svg +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/scripts/system/assets/images/tools/hmd-switch-01.svg b/scripts/system/assets/images/tools/hmd-switch-01.svg deleted file mode 100644 index 31389d355c..0000000000 --- a/scripts/system/assets/images/tools/hmd-switch-01.svg +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/scripts/system/assets/images/tools/market.svg b/scripts/system/assets/images/tools/market.svg new file mode 100644 index 0000000000..fa4a3d7256 --- /dev/null +++ b/scripts/system/assets/images/tools/market.svg @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/assets/images/tools/mic.svg b/scripts/system/assets/images/tools/mic.svg new file mode 100644 index 0000000000..f3afccca70 --- /dev/null +++ b/scripts/system/assets/images/tools/mic.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MUTE + + + + + + + + + + + + MUTE + + UNMUTE + + + + + + + + + + + + + + + + + + UNMUTE + + diff --git a/scripts/system/assets/images/tools/switch.svg b/scripts/system/assets/images/tools/switch.svg new file mode 100644 index 0000000000..23655d747d --- /dev/null +++ b/scripts/system/assets/images/tools/switch.svg @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 9d5585e353..6810bae590 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -192,7 +192,7 @@ var toolBar = (function() { }); activeButton = toolBar.addTool({ - imageURL: toolIconUrl + "edit-01.svg", + imageURL: toolIconUrl + "edit.svg", subImage: { x: 0, y: Tool.IMAGE_WIDTH, diff --git a/scripts/system/examples.js b/scripts/system/examples.js index 4d838bc8af..0ec2644f9c 100644 --- a/scripts/system/examples.js +++ b/scripts/system/examples.js @@ -53,7 +53,7 @@ function toggleExamples() { var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var browseExamplesButton = toolBar.addButton({ - imageURL: toolIconUrl + "examples-01.svg", + imageURL: toolIconUrl + "market.svg", objectName: "examples", buttonState: 1, alpha: 0.9 diff --git a/scripts/system/goto.js b/scripts/system/goto.js index 4650e72dad..24c402ab85 100644 --- a/scripts/system/goto.js +++ b/scripts/system/goto.js @@ -14,7 +14,7 @@ var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var button = toolBar.addButton({ objectName: "goto", - imageURL: Script.resolvePath("assets/images/tools/directory-01.svg"), + imageURL: Script.resolvePath("assets/images/tools/directory.svg"), visible: true, buttonState: 1, alpha: 0.9, diff --git a/scripts/system/hmd.js b/scripts/system/hmd.js index 0d6a273975..305557b60c 100644 --- a/scripts/system/hmd.js +++ b/scripts/system/hmd.js @@ -30,7 +30,7 @@ function onClicked(){ if (headset) { button = toolBar.addButton({ objectName: "hmdToggle", - imageURL: Script.resolvePath("assets/images/tools/hmd-switch-01.svg"), + imageURL: Script.resolvePath("assets/images/tools/switch.svg"), visible: true, alpha: 0.9, }); diff --git a/scripts/system/mute.js b/scripts/system/mute.js index f91ecbafae..cd29e8faae 100644 --- a/scripts/system/mute.js +++ b/scripts/system/mute.js @@ -14,7 +14,7 @@ var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var button = toolBar.addButton({ objectName: "mute", - imageURL: Script.resolvePath("assets/images/tools/mic-01.svg"), + imageURL: Script.resolvePath("assets/images/tools/mic.svg"), visible: true, alpha: 0.9, }); From 5288d983763ea57e4e1d33f37cc21384a82c5ba5 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 30 Jun 2016 20:52:41 -0700 Subject: [PATCH 72/77] Using pipelines properly where appropriate --- interface/src/ui/overlays/Circle3DOverlay.cpp | 8 ++++---- interface/src/ui/overlays/Cube3DOverlay.cpp | 6 ++++-- interface/src/ui/overlays/Grid3DOverlay.cpp | 6 ++---- interface/src/ui/overlays/Image3DOverlay.cpp | 6 ++---- interface/src/ui/overlays/Sphere3DOverlay.cpp | 3 +++ 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index 1abcb0f5c0..2896ce711e 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -149,7 +149,6 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_quadVerticesID, points, color); } - geometryCache->bindSimpleProgram(batch); geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID); } else { @@ -188,8 +187,6 @@ void Circle3DOverlay::render(RenderArgs* args) { geometryCache->updateVertices(_lineVerticesID, points, color); } - // Render unlit - geometryCache->bindSimpleProgram(batch, false, false, true); if (getIsDashedLine()) { geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID); } else { @@ -282,10 +279,13 @@ void Circle3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Circle3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withOwnPipeline(); + auto builder = render::ShapeKey::Builder().withoutCullFace(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } + if (!getIsSolid()) { + builder.withUnlit().withDepthBias(); + } return builder.build(); } diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 17894aa091..f72fb8d920 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -44,7 +44,6 @@ void Cube3DOverlay::render(RenderArgs* args) { Transform transform; transform.setTranslation(position); transform.setRotation(rotation); - auto geometryCache = DependencyManager::get(); auto pipeline = args->_pipeline; if (!pipeline) { @@ -97,10 +96,13 @@ void Cube3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Cube3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withOwnPipeline(); + auto builder = render::ShapeKey::Builder(); if (getAlpha() != 1.0f) { builder.withTranslucent(); } + if (!getIsSolid()) { + builder.withUnlit().withDepthBias(); + } return builder.build(); } diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 7d86395937..e9bbcddf59 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -75,11 +75,9 @@ void Grid3DOverlay::render(RenderArgs* args) { transform.setScale(glm::vec3(getDimensions(), 1.0f)); transform.setTranslation(position); batch->setModelTransform(transform); - auto geometryCache = DependencyManager::get(); - geometryCache->bindSimpleProgram(*batch, false, false, true, true); const float MINOR_GRID_EDGE = 0.0025f; const float MAJOR_GRID_EDGE = 0.005f; - geometryCache->renderGrid(*batch, minCorner, maxCorner, + DependencyManager::get()->renderGrid(*batch, minCorner, maxCorner, _minorGridRowDivisions, _minorGridColDivisions, MINOR_GRID_EDGE, _majorGridRowDivisions, _majorGridColDivisions, MAJOR_GRID_EDGE, gridColor, _drawInFront); @@ -87,7 +85,7 @@ void Grid3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Grid3DOverlay::getShapeKey() { - return render::ShapeKey::Builder().withOwnPipeline(); + return render::ShapeKey::Builder().withOwnPipeline().withUnlit().withDepthBias(); } void Grid3DOverlay::setProperties(const QVariantMap& properties) { diff --git a/interface/src/ui/overlays/Image3DOverlay.cpp b/interface/src/ui/overlays/Image3DOverlay.cpp index 72ae246859..d59e552779 100644 --- a/interface/src/ui/overlays/Image3DOverlay.cpp +++ b/interface/src/ui/overlays/Image3DOverlay.cpp @@ -93,9 +93,7 @@ void Image3DOverlay::render(RenderArgs* args) { batch->setModelTransform(transform); batch->setResourceTexture(0, _texture->getGPUTexture()); - auto geometryCache = DependencyManager::get(); - geometryCache->bindSimpleProgram(*batch, true, false); - geometryCache->renderQuad( + DependencyManager::get()->renderQuad( *batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha) ); @@ -104,7 +102,7 @@ void Image3DOverlay::render(RenderArgs* args) { } const render::ShapeKey Image3DOverlay::getShapeKey() { - auto builder = render::ShapeKey::Builder().withOwnPipeline(); + auto builder = render::ShapeKey::Builder().withoutCullFace().withDepthBias(); if (_emissive) { builder.withUnlit(); } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 1dd61611f2..85530d1376 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -62,6 +62,9 @@ const render::ShapeKey Sphere3DOverlay::getShapeKey() { if (getAlpha() != 1.0f) { builder.withTranslucent(); } + if (!getIsSolid()) { + builder.withUnlit().withDepthBias(); + } return builder.build(); } From 804a187a7b81928a386b29270d9b1d7fe0af86f7 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 1 Jul 2016 10:17:17 -0700 Subject: [PATCH 73/77] Mute changes. --- scripts/system/assets/images/tools/mic.svg | 121 +++++++++++------- .../system/assets/images/tools/microphone.svg | 13 -- scripts/system/mute.js | 7 +- 3 files changed, 80 insertions(+), 61 deletions(-) delete mode 100644 scripts/system/assets/images/tools/microphone.svg diff --git a/scripts/system/assets/images/tools/mic.svg b/scripts/system/assets/images/tools/mic.svg index f3afccca70..126bb539fc 100644 --- a/scripts/system/assets/images/tools/mic.svg +++ b/scripts/system/assets/images/tools/mic.svg @@ -10,12 +10,7 @@ .st4{filter:url(#Adobe_OpacityMaskFilter_1_);} .st5{mask:url(#SVGID_2_);} .st6{fill:#1E1E1E;} - .st7{fill:none;stroke:#75FF48;stroke-width:0.25;stroke-miterlimit:10;} - .st8{fill:none;} - .st9{fill:#FFFFFF;} - .st10{font-family:'Raleway-Bold';} - .st11{font-size:9px;} - .st12{fill:#333333;} + .st7{fill:#FFFFFF;} @@ -95,9 +90,7 @@ fIzDR8cN4+ibinDd+4E+1lB91Xov/9k=" transform="matrix(1 0 0 1 -2 148)"> - - - + @@ -106,59 +99,97 @@ fIzDR8cN4+ibinDd+4E+1lB91Xov/9k=" transform="matrix(1 0 0 1 -2 148)"> - - MUTE - - - - - + + + + + + + + + - - - - - + + + + + - - MUTE - - UNMUTE + h-2.3l0-1.8C28.9,78.5,31,76.3,31,73.7z"/> + + + + + + + + + + + + + + - - + + c0.4-0.4,0.4-1.1,0-1.5L26.5,13.9z"/> - - + + h-2.3l0-1.8C28.8,28.6,30.9,26.5,30.9,23.8z"/> - - + + c0.4,0.4,1.1,0.4,1.5,0c0.4-0.4,0.4-1.1,0-1.5L26.5,163.8z"/> - - + + h-2.3l0-1.8C28.8,178.6,30.9,176.4,30.9,173.7z"/> + + + + + + + + - - UNMUTE diff --git a/scripts/system/assets/images/tools/microphone.svg b/scripts/system/assets/images/tools/microphone.svg deleted file mode 100644 index bd5e8afac7..0000000000 --- a/scripts/system/assets/images/tools/microphone.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - image/svg+xml - - - Layer 1 - - - - Mute - - - \ No newline at end of file diff --git a/scripts/system/mute.js b/scripts/system/mute.js index cd29e8faae..1a575efa01 100644 --- a/scripts/system/mute.js +++ b/scripts/system/mute.js @@ -16,13 +16,14 @@ var button = toolBar.addButton({ objectName: "mute", imageURL: Script.resolvePath("assets/images/tools/mic.svg"), visible: true, - alpha: 0.9, + buttonState: 1, + alpha: 0.9 }); function onMuteToggled() { // We could just toggle state, but we're less likely to get out of wack if we read the AudioDevice. - // muted => "on" button state => buttonState 1 - button.writeProperty('buttonState', AudioDevice.getMuted() ? 1 : 0); + // muted => button "on" state => 1. go figure. + button.writeProperty('buttonState', AudioDevice.getMuted() ? 0 : 1); } onMuteToggled(); function onClicked(){ From 43c7fd1e27093ca5577c542919b439d14d6373cf Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 1 Jul 2016 10:34:13 -0700 Subject: [PATCH 74/77] New art. --- interface/resources/icons/hud.svg | 309 ++++--------- .../system/assets/images/tools/directory.svg | 427 +++++++----------- scripts/system/assets/images/tools/edit.svg | 243 +++------- scripts/system/assets/images/tools/market.svg | 249 +++------- scripts/system/assets/images/tools/mic.svg | 221 ++++----- scripts/system/assets/images/tools/switch.svg | 295 +++++------- 6 files changed, 583 insertions(+), 1161 deletions(-) diff --git a/interface/resources/icons/hud.svg b/interface/resources/icons/hud.svg index 9e77aa6040..acfd21b909 100644 --- a/interface/resources/icons/hud.svg +++ b/interface/resources/icons/hud.svg @@ -3,140 +3,29 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -144,115 +33,113 @@ vaK3kSYV8RW8iTCviK3kSYV8RW8iTCiPaa0X/wAJMKhq3ZXV/pkbI0eRJfe0h26v/9k=" transform= - - + + - - + - - - + + + - - + + - - + - - - + + + - - + + - - + - - + + + + + + + + + + + + - - - - - - - - - - - - + c-0.4-0.2-0.7-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.2-0.8-0.2-1.2v-3.4h1.3v3.4c0,0.3,0,0.5,0.1,0.8 + c0.1,0.3,0.1,0.5,0.3,0.7c0.1,0.2,0.3,0.4,0.5,0.5C25,191.7,25.3,191.8,25.6,191.8z"/> + diff --git a/scripts/system/assets/images/tools/directory.svg b/scripts/system/assets/images/tools/directory.svg index 912243c52e..09f3c14bf0 100644 --- a/scripts/system/assets/images/tools/directory.svg +++ b/scripts/system/assets/images/tools/directory.svg @@ -3,364 +3,253 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + - - + + + c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5c-0.2,0.2-0.3,0.4-0.3,0.7C33.7,38.5,33.7,38.8,33.7,39.1z"/> - + C16.6,17.2,16.5,17.1,16.6,17z M16,18.2L16,18.2c0-0.2,0.1-0.2,0.2-0.2l3.3,0.8c0.1,0,0.1,0.1,0.1,0.2l0.1,4.7 + c0,0.1,0,0.1-0.1,0.1h-0.1l0,0h-0.1h-0.1l0,0c-0.1,0-0.3-0.1-0.5-0.1c-1.1-0.3-1.9-0.6-2.6-1.1c-0.4-0.3-0.6-0.6-0.6-1 + C15.6,20.5,15.7,19.3,16,18.2z"/> - + - - + - - + + + c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5c-0.2,0.2-0.3,0.4-0.3,0.7C33.7,88.5,33.7,88.8,33.7,89.1z"/> - + C16.6,67.2,16.5,67.1,16.6,67z M16,68.2L16,68.2c0-0.2,0.1-0.2,0.2-0.2l3.3,0.8c0.1,0,0.1,0.1,0.1,0.2l0.1,4.7 + c0,0.1,0,0.1-0.1,0.1h-0.1l0,0h-0.1h-0.1l0,0c-0.1,0-0.3-0.1-0.5-0.1c-1.1-0.3-1.9-0.6-2.6-1.1c-0.4-0.3-0.6-0.6-0.6-1 + C15.6,70.5,15.7,69.3,16,68.2z"/> - + - - - - + C18.9,138.6,18.9,138.9,18.9,139.2z"/> + + - + c-0.1,0-0.1-0.1-0.1-0.2L25,119.5L25,119.5z M25,125.6c0-0.1,0.1-0.2,0.2-0.2h0.2l3.4-0.2c0,0,0.1,0,0.1,0.1c0,0,0.1,0.1,0,0.1 + v0.1l0,0c0,0,0,0,0,0.1v0.1v0.1c0,0.1,0,0.2-0.1,0.3c-0.1,0.1-0.1,0.3-0.2,0.4l-0.1,0.2c-0.2,0.6-0.5,1.2-0.7,1.8 + c-0.2,0.5-0.6,0.9-0.9,1.3c-0.3,0.3-0.9,0.6-1.5,0.6h-0.2l0,0c0,0-0.1,0-0.1-0.1v-0.1L25,125.6L25,125.6z M21.5,129.5l-0.1,0.1 + l0,0l-0.2-0.1l0,0c-1.8-0.4-4.2-2.6-5.1-5.2v-0.1c0-0.1,0-0.1,0-0.2c0,0,0.1-0.1,0.2,0l0.9,0.3c0.8,0.2,1.6,0.5,2.4,0.7 + c0.2,0.1,0.4,0.1,0.4,0.4c0.3,1.6,0.8,2.8,1.5,3.8l0.1,0.1C21.6,129.4,21.6,129.4,21.5,129.5z M24.2,130.1c0,0.1-0.1,0.1-0.1,0.1 + H24c0,0,0,0-0.1,0c0,0-0.9-0.3-1.3-0.8c-1-1.3-1.5-2.7-1.9-4l0,0v-0.1c0-0.1,0-0.1,0-0.1l0.1-0.1h0.1l1.9,0.2l1.2,0.1 + c0.1,0,0.2,0.1,0.2,0.2L24.2,130.1L24.2,130.1z M22.8,119.3l1.2,0.1c0.1,0,0.2,0.1,0.2,0.2v5c0,0,0,0.1-0.1,0.1H24l0,0 + c0,0-0.9-0.1-1.4-0.1c-0.6,0-1.2-0.1-1.7-0.2c-0.2,0-0.4-0.3-0.4-0.4c-0.1-1.2-0.1-2.3-0.2-3.1c0-0.3,0-1.4,0-1.5s0-0.1,0.1-0.1 + c0,0,0.1-0.1,0.1,0H22.8z M16.4,117.1L16.4,117.1c0.8-2.1,2.8-3.9,5-4.7l0.2-0.1c0.1,0,0.2,0,0.2,0.1s0,0.1,0,0.2l-0.1,0.2 + c-1.2,1.6-1.7,3.5-2,5.3v0.1c0,0,0,0.1-0.1,0.1h-0.1c0,0,0,0-0.1,0h-0.1c-0.4-0.1-0.7-0.2-1.1-0.3c-0.6-0.1-1.2-0.3-1.8-0.5h-0.1 + C16.4,117.3,16.3,117.2,16.4,117.1z M15.8,118.3L15.8,118.3c0-0.2,0.1-0.2,0.2-0.2l3.3,0.8c0.1,0,0.1,0.1,0.1,0.2l0.1,4.7 + c0,0.1,0,0.1-0.1,0.1h-0.1l0,0h-0.1h-0.1l0,0c-0.1,0-0.3-0.1-0.5-0.1c-1.1-0.3-1.9-0.6-2.6-1.1c-0.4-0.3-0.6-0.6-0.6-1 + C15.4,120.6,15.5,119.4,15.8,118.3z"/> - + - - - - + C18.9,188.7,18.9,189,18.9,189.3z"/> + + - + C30,174.1,30,174.1,30,173.9L30,173.9z M30.1,175.1c0.8-0.2,1.5-0.4,2.3-0.6l0.9-0.3c0.1,0,0.1,0,0.2,0.1c0,0,0.1,0.1,0,0.2v0.1 + c-0.5,1.2-1.1,2.2-2,3.1c-0.8,0.9-1.9,1.5-3.1,2.1h-0.1c0,0,0,0-0.1,0h-0.1c-0.1,0-0.1-0.1-0.1-0.2v-0.1l0,0c0,0,0-0.1,0.1-0.2 + c0.4-0.6,1-1.6,1.5-3.7C29.7,175.3,29.8,175.1,30.1,175.1z M25,169.6c0-0.1,0.1-0.2,0.2-0.2h0.2l2.7-0.1l0.9-0.1c0,0,0,0,0.1,0 + l0,0h0.1h0.1c0.1,0,0.1,0.1,0.1,0.2c0,0.1,0,0.2,0,0.4c0,0.1,0,0.3,0,0.4v0.3c0,0.5,0,1,0,1.4v0.2c0,0.4,0,0.8-0.1,1.1 + c0,0.1,0,0.2,0,0.3s0,0.2,0,0.3s0,0.4-0.4,0.5c-0.7,0.1-1.3,0.1-2,0.2h-0.2c-0.2,0-0.5,0-0.8,0.1c-0.4,0-0.5,0.1-0.6,0.1h-0.1 + l-0.2-0.1c-0.1,0-0.1-0.1-0.1-0.2L25,169.6L25,169.6z M25,175.7c0-0.1,0.1-0.2,0.2-0.2h0.2l3.4-0.2c0,0,0.1,0,0.1,0.1 + c0,0,0.1,0.1,0,0.1v0.1l0,0c0,0,0,0,0,0.1v0.1v0.1c0,0.1,0,0.2-0.1,0.3s-0.1,0.3-0.2,0.4l-0.1,0.2c-0.2,0.6-0.5,1.2-0.7,1.8 + c-0.2,0.5-0.6,0.9-0.9,1.3c-0.3,0.3-0.9,0.6-1.5,0.6h-0.2l0,0c0,0-0.1,0-0.1-0.1v-0.1L25,175.7L25,175.7z M21.5,179.6l-0.1,0.1 + l0,0l-0.2-0.1l0,0c-1.8-0.4-4.2-2.6-5.1-5.2v-0.1c0-0.1,0-0.1,0-0.2c0,0,0.1-0.1,0.2,0l0.9,0.3c0.8,0.2,1.6,0.5,2.4,0.7 + c0.2,0.1,0.4,0.1,0.4,0.4c0.3,1.6,0.8,2.8,1.5,3.8l0.1,0.1C21.6,179.5,21.6,179.5,21.5,179.6z M24.2,180.2c0,0.1-0.1,0.1-0.1,0.1 + H24c0,0,0,0-0.1,0c0,0-0.9-0.3-1.3-0.8c-1-1.3-1.5-2.7-1.9-4l0,0v-0.1c0-0.1,0-0.1,0-0.1l0.1-0.1h0.1l1.9,0.2l1.2,0.1 + c0.1,0,0.2,0.1,0.2,0.2L24.2,180.2L24.2,180.2z M22.8,169.4l1.2,0.1c0.1,0,0.2,0.1,0.2,0.2v5c0,0,0,0.1-0.1,0.1H24l0,0 + c0,0-0.9-0.1-1.4-0.1c-0.6,0-1.2-0.1-1.7-0.2c-0.2,0-0.4-0.3-0.4-0.4c-0.1-1.2-0.1-2.3-0.2-3.1c0-0.3,0-1.4,0-1.5 + c0-0.1,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1,0H22.8z M16.4,167.2L16.4,167.2c0.8-2.1,2.8-3.9,5-4.7l0.2-0.1c0.1,0,0.2,0,0.2,0.1 + c0,0.1,0,0.1,0,0.2l-0.1,0.2c-1.2,1.6-1.7,3.5-2,5.3v0.1c0,0,0,0.1-0.1,0.1h-0.1c0,0,0,0-0.1,0h-0.1c-0.4-0.1-0.7-0.2-1.1-0.3 + c-0.6-0.1-1.2-0.3-1.8-0.5h-0.1C16.4,167.4,16.3,167.3,16.4,167.2z M15.8,168.4L15.8,168.4c0-0.2,0.1-0.2,0.2-0.2l3.3,0.8 + c0.1,0,0.1,0.1,0.1,0.2l0.1,4.7c0,0.1,0,0.1-0.1,0.1h-0.1l0,0h-0.1h-0.1l0,0c-0.1,0-0.3-0.1-0.5-0.1c-1.1-0.3-1.9-0.6-2.6-1.1 + c-0.4-0.3-0.6-0.6-0.6-1C15.4,170.7,15.5,169.5,15.8,168.4z"/> - + diff --git a/scripts/system/assets/images/tools/edit.svg b/scripts/system/assets/images/tools/edit.svg index 13389a2b14..f65e0cd84d 100644 --- a/scripts/system/assets/images/tools/edit.svg +++ b/scripts/system/assets/images/tools/edit.svg @@ -3,232 +3,121 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + c0,0,0.1,0,0.1,0c0.1-0.4,0.2-0.8,0.2-1.3C37.2,21.7,33.7,18.9,30.2,19.9z M17.5,11.5c-0.4,0-0.7-0.3-0.7-0.7 + c0-0.4,0.3-0.8,0.7-0.8c0.4,0,0.8,0.4,0.8,0.7C18.3,11.1,17.9,11.5,17.5,11.5z M27.9,13.8c0.3,0.3,0.6,0.7,1,1 + c-0.7,0.7-1.4,1.4-2.1,2.1c-0.3-0.3-0.7-0.7-1-1C26.5,15.2,27.2,14.5,27.9,13.8z"/> - - + - - + c0.2-0.1,0.4-0.3,0.6-0.4s0.3-0.4,0.4-0.7C24.2,39.8,24.2,39.5,24.2,39.2z"/> + + - - - + + + c0,0,0.1,0,0.1,0c0.1-0.4,0.2-0.8,0.2-1.3C37.2,71.7,33.8,68.9,30.3,69.9z M17.6,61.5c-0.4,0-0.7-0.3-0.7-0.7 + c0-0.4,0.3-0.8,0.7-0.8c0.4,0,0.8,0.4,0.8,0.7C18.3,61.1,18,61.5,17.6,61.5z M28,63.8c0.3,0.3,0.6,0.7,1,1 + c-0.7,0.7-1.4,1.4-2.1,2.1c-0.3-0.3-0.7-0.7-1-1C26.6,65.2,27.3,64.5,28,63.8z"/> - - + - - + c0.2-0.1,0.4-0.3,0.6-0.4s0.3-0.4,0.4-0.7C24.2,89.8,24.2,89.5,24.2,89.2z"/> + + - - - + + + c0,0,0.1,0,0.1,0c0.1-0.4,0.2-0.8,0.2-1.3C37.1,121.8,33.7,119,30.2,120z M17.5,111.5c-0.4,0-0.7-0.3-0.7-0.7 + c0-0.4,0.3-0.8,0.7-0.8c0.4,0,0.8,0.4,0.8,0.7C18.2,111.2,17.9,111.5,17.5,111.5z M27.9,113.9c0.3,0.3,0.6,0.7,1,1 + c-0.7,0.7-1.4,1.4-2.1,2.1c-0.3-0.3-0.7-0.7-1-1C26.5,115.3,27.2,114.6,27.9,113.9z"/> - - - - + + + + - - - + + + c0,0,0.1,0,0.1,0c0.1-0.4,0.2-0.8,0.2-1.3C37.1,171.9,33.7,169,30.2,170.1z M17.4,161.6c-0.4,0-0.7-0.3-0.7-0.7 + c0-0.4,0.3-0.8,0.7-0.8c0.4,0,0.8,0.4,0.8,0.7C18.2,161.2,17.8,161.6,17.4,161.6z M27.8,164c0.3,0.3,0.6,0.7,1,1 + c-0.7,0.7-1.4,1.4-2.1,2.1c-0.3-0.3-0.7-0.7-1-1C26.4,165.4,27.1,164.7,27.8,164z"/> - - - - + + + + diff --git a/scripts/system/assets/images/tools/market.svg b/scripts/system/assets/images/tools/market.svg index fa4a3d7256..0cec030933 100644 --- a/scripts/system/assets/images/tools/market.svg +++ b/scripts/system/assets/images/tools/market.svg @@ -3,158 +3,47 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + - - - + c-0.1-0.1-0.2-0.2-0.3-0.2C24,37.1,23.9,37,23.8,37h-1.5V39.1z"/> + + + - - - + c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.2-0.1-0.4-0.2-0.7l-0.2-0.6H32.1z"/> + + - - - + + - - - + c-0.1-0.1-0.2-0.2-0.3-0.2C24,87.1,23.9,87,23.8,87h-1.5V89.1z"/> + + + - - - + c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.2-0.1-0.4-0.2-0.7l-0.2-0.6H32.1z"/> + + - - - + + - - - + c-0.1-0.1-0.2-0.2-0.3-0.2c-0.1-0.1-0.2-0.1-0.3-0.1h-1.5V139.2z"/> + + + - - - + c-0.1-0.6-0.3-1.3-0.5-2c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.2-0.1-0.4-0.2-0.7l-0.2-0.6H32z"/> + + - - - - - - + + + + + + - - - + c-0.1-0.6-0.3-1.3-0.5-2c-0.1-0.2-0.1-0.4-0.2-0.6c-0.1-0.2-0.1-0.4-0.2-0.7l-0.2-0.6H32z"/> + + diff --git a/scripts/system/assets/images/tools/mic.svg b/scripts/system/assets/images/tools/mic.svg index 126bb539fc..0424f3eb49 100644 --- a/scripts/system/assets/images/tools/mic.svg +++ b/scripts/system/assets/images/tools/mic.svg @@ -3,193 +3,124 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + + + - + - - + - - + c-0.4-0.2-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3H22v3.3c0,0.3,0,0.5,0.1,0.8 + c0.1,0.2,0.1,0.5,0.3,0.7c0.1,0.2,0.3,0.3,0.5,0.5S23.2,191.8,23.5,191.8z"/> + + - - - - - + + + + - - - - - + + + + + + h-2.3l0-1.8C28.6,79,30.7,76.9,30.7,74.2z"/> - - + + + + + + + + + - - - - - - - - - - + c0.1,0.2,0.1,0.5,0.3,0.7s0.3,0.3,0.5,0.5S30.1,41.9,30.4,41.9z"/> + + - - + + - - + + c0,2.6,2.1,4.8,4.8,5.2l0,1.8h-2.2c-0.5,0-0.9,0.4-0.9,0.9c0,0.5,0.4,0.9,0.9,0.9H28c0.5,0,0.9-0.4,0.9-0.9c0-0.5-0.4-0.9-0.9-0.9 + h-2.3l0-1.8C28.5,29.2,30.6,27,30.6,24.4z"/> - - + + c0.4,0.4,1.1,0.4,1.5,0c0.4-0.4,0.4-1.1,0-1.5L26.1,164.3z"/> - - + + c0,2.6,2.1,4.8,4.8,5.2l0,1.8h-2.2c-0.5,0-0.9,0.4-0.9,0.9c0,0.5,0.4,0.9,0.9,0.9H28c0.5,0,0.9-0.4,0.9-0.9c0-0.5-0.4-0.9-0.9-0.9 + h-2.3l0-1.8C28.5,179.1,30.6,176.9,30.6,174.3z"/> - - - - + + + - - + s-0.6-0.4-0.9-0.7c-0.2-0.3-0.4-0.6-0.5-1c-0.1-0.4-0.1-0.8-0.1-1.2v-3.3h1.2v3.3c0,0.3,0,0.5,0.1,0.8c0.1,0.2,0.1,0.5,0.3,0.7 + c0.1,0.2,0.3,0.3,0.5,0.5S30,141.9,30.3,141.9z"/> + + diff --git a/scripts/system/assets/images/tools/switch.svg b/scripts/system/assets/images/tools/switch.svg index 23655d747d..e67a9aac04 100644 --- a/scripts/system/assets/images/tools/switch.svg +++ b/scripts/system/assets/images/tools/switch.svg @@ -3,228 +3,165 @@ - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - + + + - - - - + + + + + + + + + + + + + + + - - + + - - - + + + - - - - + + + + - - + + - - - + + + - - - - + + + + - + C31.3,190.2,31.3,189.8,31.3,189.4z"/> + + + From 02cc6cc567150909587d9f09c39882b354f5c4a3 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 1 Jul 2016 12:18:26 -0700 Subject: [PATCH 75/77] hover states --- .../qml/hifi/toolbars/ToolbarButton.qml | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml index a3be4533d2..4356b18253 100644 --- a/interface/resources/qml/hifi/toolbars/ToolbarButton.qml +++ b/interface/resources/qml/hifi/toolbars/ToolbarButton.qml @@ -8,6 +8,7 @@ Item { property var subImage; property int yOffset: 0 property int buttonState: 0 + property int hoverOffset: 0 property var toolbar; property real size: 50 // toolbar ? toolbar.buttonSize : 50 width: size; height: size @@ -36,9 +37,15 @@ Item { } } - + function updateOffset() { + yOffset = size * (buttonState + hoverOffset); + } onButtonStateChanged: { - yOffset = size * buttonState + hoverOffset = 0; // subtle: show the new state without hover. don't wait for mouse to be moved away + // The above is per UX design, but ALSO avoid a subtle issue that would be a problem because + // the hand controllers don't move the mouse when not triggered, so releasing the trigger would + // never show unhovered. + updateOffset(); } Component.onCompleted: { @@ -58,8 +65,18 @@ Item { } MouseArea { + id: mouseArea + hoverEnabled: true anchors.fill: parent onClicked: button.clicked(); + onEntered: { + hoverOffset = 2; + updateOffset(); + } + onExited: { + hoverOffset = 0; + updateOffset(); + } } } From 1ad9cfde99c3a882537f3d39c4f1821939fde12f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 1 Jul 2016 13:54:00 -0700 Subject: [PATCH 76/77] make hud button participate in buttonState just like other toolbar chicklets --- interface/resources/qml/hifi/Desktop.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index 7a7a6b63df..561bd722f2 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -61,8 +61,8 @@ OriginalDesktop.Desktop { pinned: true, }); - toggleHudButton.yOffset = Qt.binding(function(){ - return desktop.pinned ? 50 : 0 + toggleHudButton.buttonState = Qt.binding(function(){ + return desktop.pinned ? 1 : 0 }); toggleHudButton.clicked.connect(function(){ console.log("Clicked on hud button") From 88d28120b683160a65a291884f09704cc6894593 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 1 Jul 2016 15:48:58 -0700 Subject: [PATCH 77/77] Adding missed file --- plugins/openvr/src/OpenVrHelpers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 399712d920..c93a2178b5 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -268,6 +268,7 @@ void handleOpenVrEvents() { case vr::VREvent_KeyboardClosed: _keyboardFocusObject = nullptr; _keyboardShown = false; + DependencyManager::get()->unfocusWindows(); break; default: