From e48c456d246e2f5b0e015ac3e4c098a22292be74 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 6 Sep 2017 17:57:18 -0700 Subject: [PATCH 01/43] Trying to sync the render transform for overlay web at the right time... --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 ++ interface/src/ui/overlays/Base3DOverlay.h | 4 ++ interface/src/ui/overlays/Overlay.h | 1 + interface/src/ui/overlays/Web3DOverlay.cpp | 42 +++++++++++++++++++-- interface/src/ui/overlays/Web3DOverlay.h | 5 +++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index c0278a6496..010be802a9 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -256,6 +256,10 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3 void Base3DOverlay::locationChanged(bool tellPhysics) { SpatiallyNestable::locationChanged(tellPhysics); + // Force the actual update of the render transform now that we notify for the change + // so it s captured for the time of rendering + notifyRenderTransformChange(); + auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 6377b46d7d..3f57f2e577 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -52,6 +52,9 @@ public: virtual AABox getBounds() const override = 0; + void notifyRenderTransformChange() const { _renderTransformDirty = true; } + virtual Transform evalRenderTransform() const { return Transform(); } + void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -73,6 +76,7 @@ protected: bool _ignoreRayIntersection; bool _drawInFront; bool _isGrabbable { false }; + mutable bool _renderTransformDirty{ true }; QString _name; }; diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index db2979b4d5..31846501ec 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -102,6 +102,7 @@ protected: render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID }; + bool _isLoaded; float _alpha; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 104082dee4..a1fd0414ee 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,12 +180,46 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { + if (_renderTransformDirty) { + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + transaction.updateItem(itemID, [](Overlay& data) { + auto web3D = dynamic_cast(&data); + if (web3D) { + web3D->evalRenderTransform(); + } + }); + scene->enqueueTransaction(transaction); + } + } + if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } } +Transform Web3DOverlay::evalRenderTransform() const { + if (_renderTransformDirty) { + _renderTransform = getTransform(); + + // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. + // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? + /* + applyTransformTo(transform, true); + setTransform(transform); + */ + + if (glm::length2(getDimensions()) != 1.0f) { + _renderTransform.postScale(vec3(getDimensions(), 1.0f)); + } + _renderTransformDirty = false; + } + return _renderTransform; +} + QString Web3DOverlay::pickURL() { QUrl sourceUrl(_url); if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || @@ -305,7 +339,7 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - + /* Transform transform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. @@ -314,10 +348,11 @@ void Web3DOverlay::render(RenderArgs* args) { applyTransformTo(transform, true); setTransform(transform); */ - + /* if (glm::length2(getDimensions()) != 1.0f) { transform.postScale(vec3(getDimensions(), 1.0f)); } + */ if (!_texture) { _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); @@ -332,7 +367,8 @@ void Web3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setResourceTexture(0, _texture); - batch.setModelTransform(transform); + // batch.setModelTransform(transform); + batch.setModelTransform(_renderTransform); auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { geometryCache->bindWebBrowserProgram(batch, true); diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 2eae7f33da..721f86019c 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -37,6 +37,9 @@ public: virtual void update(float deltatime) override; + Transform evalRenderTransform() const override; + + QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); void handlePointerEvent(const PointerEvent& event); @@ -92,6 +95,8 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; + mutable Transform _renderTransform; + uint8_t _desiredMaxFPS { 10 }; uint8_t _currentMaxFPS { 0 }; From 73ec095235dd6a5c9daea8a326e9f5751ba61765 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 7 Sep 2017 17:58:16 -0700 Subject: [PATCH 02/43] fooling around with communicating the update transform to render thread through a trasnaction, not the solution yet --- interface/src/ui/overlays/Web3DOverlay.cpp | 15 ++++++++++----- interface/src/ui/overlays/Web3DOverlay.h | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index a1fd0414ee..9ad2cef443 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -181,14 +181,15 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { if (_renderTransformDirty) { + auto updateTransform = evalRenderTransform(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; - transaction.updateItem(itemID, [](Overlay& data) { + transaction.updateItem(itemID, [updateTransform](Overlay& data) { auto web3D = dynamic_cast(&data); if (web3D) { - web3D->evalRenderTransform(); + web3D->setRenderTransform(updateTransform);// evalRenderTransform(); } }); scene->enqueueTransaction(transaction); @@ -203,7 +204,7 @@ void Web3DOverlay::update(float deltatime) { Transform Web3DOverlay::evalRenderTransform() const { if (_renderTransformDirty) { - _renderTransform = getTransform(); + _updateTransform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? @@ -213,11 +214,15 @@ Transform Web3DOverlay::evalRenderTransform() const { */ if (glm::length2(getDimensions()) != 1.0f) { - _renderTransform.postScale(vec3(getDimensions(), 1.0f)); + _updateTransform.postScale(vec3(getDimensions(), 1.0f)); } _renderTransformDirty = false; } - return _renderTransform; + return _updateTransform; +} + +void Web3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; } QString Web3DOverlay::pickURL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 721f86019c..ef40d88333 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -38,7 +38,7 @@ public: virtual void update(float deltatime) override; Transform evalRenderTransform() const override; - + void setRenderTransform(const Transform& transform); QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); @@ -95,6 +95,7 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; + mutable Transform _updateTransform; mutable Transform _renderTransform; uint8_t _desiredMaxFPS { 10 }; From 01e4bfc53e6c7f7054cb707e3c78be116c2ff233 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 11 Sep 2017 17:36:10 -0700 Subject: [PATCH 03/43] Trying to avoid calling getTransform on nestables from render thread --- interface/src/Application.cpp | 2 +- interface/src/ui/overlays/Base3DOverlay.cpp | 32 ++++++++++++++++++--- interface/src/ui/overlays/Base3DOverlay.h | 7 ++++- interface/src/ui/overlays/Web3DOverlay.cpp | 21 ++++++-------- interface/src/ui/overlays/Web3DOverlay.h | 4 --- libraries/render-utils/src/Model.cpp | 11 ++++--- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3650c495f2..63e4069c01 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -427,7 +427,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - deadlockDetectionCrash(); + // deadlockDetectionCrash(); #endif } } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 010be802a9..56fbc8d873 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,13 +191,14 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - auto itemID = getRenderItemID(); + + /* auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - } + }*/ } } @@ -259,16 +260,39 @@ void Base3DOverlay::locationChanged(bool tellPhysics) { // Force the actual update of the render transform now that we notify for the change // so it s captured for the time of rendering notifyRenderTransformChange(); - +/* auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - } + }*/ } void Base3DOverlay::parentDeleted() { qApp->getOverlays().deleteOverlay(getOverlayID()); } + +void Base3DOverlay::update(float duration) { + if (_renderTransformDirty) { + setRenderTransform(evalRenderTransform()); + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + + transaction.updateItem(itemID); + scene->enqueueTransaction(transaction); + } + _renderTransformDirty = false; + } +} + +Transform Base3DOverlay::evalRenderTransform() const { + return getTransform(); +} + +void Base3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 3f57f2e577..fa26993724 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -52,8 +52,11 @@ public: virtual AABox getBounds() const override = 0; + void update(float deltatime) override; + void notifyRenderTransformChange() const { _renderTransformDirty = true; } - virtual Transform evalRenderTransform() const { return Transform(); } + virtual Transform evalRenderTransform() const; + void setRenderTransform(const Transform& transform); void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -70,6 +73,8 @@ protected: virtual void locationChanged(bool tellPhysics = true) override; virtual void parentDeleted() override; + mutable Transform _renderTransform; + float _lineWidth; bool _isSolid; bool _isDashedLine; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 9ad2cef443..490460fdb3 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,7 +180,7 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { - if (_renderTransformDirty) { + /* if (_renderTransformDirty) { auto updateTransform = evalRenderTransform(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { @@ -194,17 +194,19 @@ void Web3DOverlay::update(float deltatime) { }); scene->enqueueTransaction(transaction); } - } + }*/ if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } + + Billboard3DOverlay::update(deltatime); + } Transform Web3DOverlay::evalRenderTransform() const { - if (_renderTransformDirty) { - _updateTransform = getTransform(); + auto transform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? @@ -214,15 +216,10 @@ Transform Web3DOverlay::evalRenderTransform() const { */ if (glm::length2(getDimensions()) != 1.0f) { - _updateTransform.postScale(vec3(getDimensions(), 1.0f)); + transform.postScale(vec3(getDimensions(), 1.0f)); } - _renderTransformDirty = false; - } - return _updateTransform; -} - -void Web3DOverlay::setRenderTransform(const Transform& transform) { - _renderTransform = transform; + + return transform; } QString Web3DOverlay::pickURL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index ef40d88333..7acaf5a430 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -38,7 +38,6 @@ public: virtual void update(float deltatime) override; Transform evalRenderTransform() const override; - void setRenderTransform(const Transform& transform); QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); @@ -95,9 +94,6 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; - mutable Transform _updateTransform; - mutable Transform _renderTransform; - uint8_t _desiredMaxFPS { 10 }; uint8_t _currentMaxFPS { 0 }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 42bb91ce94..5fc7c7a1b1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -235,15 +235,18 @@ void Model::updateRenderItems() { uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; + Transform modelTransform = self->getTransform(); + // Transform modelTransform = model->getTransform(); + modelTransform.setScale(glm::vec3(1.0f)); + render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { - Transform modelTransform = model->getTransform(); - modelTransform.setScale(glm::vec3(1.0f)); + const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; @@ -259,7 +262,7 @@ void Model::updateRenderItems() { // collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); - Transform modelTransform = self->getTransform(); + // Transform modelTransform = self->getTransform(); foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. From 3669e66619f7b8034dc748c15730b231a27c75df Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 12 Sep 2017 00:02:54 -0700 Subject: [PATCH 04/43] trying to update the transform at the right time in overlays --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 +- .../src/ui/overlays/Billboard3DOverlay.cpp | 1 + interface/src/ui/overlays/ModelOverlay.cpp | 48 ++++++++++++------- interface/src/ui/overlays/Planar3DOverlay.cpp | 10 ++++ interface/src/ui/overlays/Planar3DOverlay.h | 4 +- interface/src/ui/overlays/Web3DOverlay.cpp | 48 ------------------- interface/src/ui/overlays/Web3DOverlay.h | 2 - 7 files changed, 48 insertions(+), 68 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 56fbc8d873..af6206e819 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,8 +191,9 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { + notifyRenderTransformChange(); - /* auto itemID = getRenderItemID(); + /*auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index f5668caa71..a333df0821 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -45,3 +45,4 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { } return transformChanged; } + diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 0bed07891e..f65faaca12 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -59,20 +59,6 @@ void ModelOverlay::update(float deltatime) { _model->simulate(deltatime); } _isLoaded = _model->isActive(); -} - -bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { - Volume3DOverlay::addToScene(overlay, scene, transaction); - _model->addToScene(scene, transaction); - return true; -} - -void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { - Volume3DOverlay::removeFromScene(overlay, scene, transaction); - _model->removeFromScene(scene, transaction); -} - -void ModelOverlay::render(RenderArgs* args) { // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene @@ -89,6 +75,35 @@ void ModelOverlay::render(RenderArgs* args) { scene->enqueueTransaction(transaction); } +bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { + Volume3DOverlay::addToScene(overlay, scene, transaction); + _model->addToScene(scene, transaction); + return true; +} + +void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { + Volume3DOverlay::removeFromScene(overlay, scene, transaction); + _model->removeFromScene(scene, transaction); +} + +void ModelOverlay::render(RenderArgs* args) { +/* + // check to see if when we added our model to the scene they were ready, if they were not ready, then + // fix them up in the scene + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + if (_model->needsFixupInScene()) { + _model->removeFromScene(scene, transaction); + _model->addToScene(scene, transaction); + } + + _model->setVisibleInScene(_visible, scene); + _model->setLayeredInFront(getDrawInFront(), scene); + + scene->enqueueTransaction(transaction); + */ +} + void ModelOverlay::setProperties(const QVariantMap& properties) { auto origPosition = getPosition(); auto origRotation = getRotation(); @@ -280,11 +295,12 @@ ModelOverlay* ModelOverlay::createClone() const { void ModelOverlay::locationChanged(bool tellPhysics) { Base3DOverlay::locationChanged(tellPhysics); - +/* if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); - } + }*/ + _updateModel = true; } QString ModelOverlay::getName() const { diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 58d72b100b..a979120dc6 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -66,3 +66,13 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve // FIXME - face and surfaceNormal not being returned return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), getDimensions(), distance); } + +Transform Planar3DOverlay::evalRenderTransform() const { + auto transform = getTransform(); + + if (glm::length2(getDimensions()) != 1.0f) { + transform.postScale(vec3(getDimensions(), 1.0f)); + } + + return transform; +} \ No newline at end of file diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 8127d4ebb9..9e4babae8d 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -32,7 +32,9 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) override; - + + Transform evalRenderTransform() const override; + protected: glm::vec2 _dimensions; }; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 490460fdb3..a1f68add4a 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,22 +180,6 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { - /* if (_renderTransformDirty) { - auto updateTransform = evalRenderTransform(); - auto itemID = getRenderItemID(); - if (render::Item::isValidID(itemID)) { - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - transaction.updateItem(itemID, [updateTransform](Overlay& data) { - auto web3D = dynamic_cast(&data); - if (web3D) { - web3D->setRenderTransform(updateTransform);// evalRenderTransform(); - } - }); - scene->enqueueTransaction(transaction); - } - }*/ - if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); @@ -205,23 +189,6 @@ void Web3DOverlay::update(float deltatime) { } -Transform Web3DOverlay::evalRenderTransform() const { - auto transform = getTransform(); - - // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. - // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? - /* - applyTransformTo(transform, true); - setTransform(transform); - */ - - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - - return transform; -} - QString Web3DOverlay::pickURL() { QUrl sourceUrl(_url); if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || @@ -341,20 +308,6 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - /* - Transform transform = getTransform(); - - // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. - // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? - /* - applyTransformTo(transform, true); - setTransform(transform); - */ - /* - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - */ if (!_texture) { _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); @@ -369,7 +322,6 @@ void Web3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setResourceTexture(0, _texture); - // batch.setModelTransform(transform); batch.setModelTransform(_renderTransform); auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 7acaf5a430..2eae7f33da 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -37,8 +37,6 @@ public: virtual void update(float deltatime) override; - Transform evalRenderTransform() const override; - QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); void handlePointerEvent(const PointerEvent& event); From 10b1e3f561d5994071c51accdf7ee50dabfdf47d Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 12 Sep 2017 14:35:25 -0700 Subject: [PATCH 05/43] Trying to implement differnet solution to the transform updates problem and debug --- interface/src/ui/overlays/Base3DOverlay.cpp | 54 ++++++++++++++++----- interface/src/ui/overlays/Base3DOverlay.h | 2 +- libraries/render-utils/src/Model.cpp | 10 ++-- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index af6206e819..22448cc719 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,15 +191,15 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - notifyRenderTransformChange(); + // notifyRenderTransformChange(); - /*auto itemID = getRenderItemID(); + auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - }*/ + } } } @@ -277,19 +277,51 @@ void Base3DOverlay::parentDeleted() { void Base3DOverlay::update(float duration) { if (_renderTransformDirty) { - setRenderTransform(evalRenderTransform()); - auto itemID = getRenderItemID(); - if (render::Item::isValidID(itemID)) { - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; + auto self = this; + // queue up this work for later processing, at the end of update and just before rendering. + // the application will ensure only the last lambda is actually invoked. + /* void* key = (void*)this; + std::weak_ptr weakSelf = shared_from_this(); + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf]() { + // do nothing, if the model has already been destroyed. + auto spatiallyNestableSelf = weakSelf.lock(); + if (!spatiallyNestableSelf) { + return; + } + auto self = std::dynamic_pointer_cast(spatiallyNestableSelf); + */ +#ifdef UpdateInMain + self->setRenderTransform(self->evalRenderTransform()); +#else + auto renderTransform = self->evalRenderTransform(); +#endif + auto itemID = self->getRenderItemID(); - transaction.updateItem(itemID); - scene->enqueueTransaction(transaction); - } + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + +#ifdef UpdateInMain + transaction.updateItem(itemID); +#else + transaction.updateItem(itemID, [renderTransform](Overlay& data) { + auto overlay3D = dynamic_cast(&data); + if (overlay3D) { + overlay3D->setRenderTransform(renderTransform);// evalRenderTransform(); + } + }); +#endif + scene->enqueueTransaction(transaction); + } + // }); _renderTransformDirty = false; } } +void Base3DOverlay::notifyRenderTransformChange() const { + _renderTransformDirty = true; +} + Transform Base3DOverlay::evalRenderTransform() const { return getTransform(); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index fa26993724..b40727a807 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -54,7 +54,7 @@ public: void update(float deltatime) override; - void notifyRenderTransformChange() const { _renderTransformDirty = true; } + void notifyRenderTransformChange() const; virtual Transform evalRenderTransform() const; void setRenderTransform(const Transform& transform); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 5fc7c7a1b1..9e552859e3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -235,18 +235,20 @@ void Model::updateRenderItems() { uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; - Transform modelTransform = self->getTransform(); + // Transform modelTransform = self->getTransform(); // Transform modelTransform = model->getTransform(); - modelTransform.setScale(glm::vec3(1.0f)); + // modelTransform.setScale(glm::vec3(1.0f)); render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter /*, modelTransform*/](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { + Transform modelTransform = model->getTransform(); + modelTransform.setScale(glm::vec3(1.0f)); const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; @@ -262,7 +264,7 @@ void Model::updateRenderItems() { // collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); - // Transform modelTransform = self->getTransform(); + Transform modelTransform = self->getTransform(); foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. From a70f7dfc878de238c92ade1b452d30f493f631cb Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 13 Sep 2017 22:05:20 -0700 Subject: [PATCH 06/43] put updateCamera in its function --- interface/src/Application.cpp | 112 +++++++++++++++++++++++++++++++++- interface/src/Application.h | 2 + 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 63e4069c01..4efad9000b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2371,6 +2371,111 @@ void Application::initializeUi() { offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); } +void Application::updateCamera(RenderArgs& renderArgs) { + + glm::vec3 boomOffset; + { + PROFILE_RANGE(render, "/updateCamera"); + { + PerformanceTimer perfTimer("CameraUpdates"); + + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + renderArgs._boomOffset = boomOffset; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glm::quat_cast(camMat)); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } + else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } + else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); + } + } + } + else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } + else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } + else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } + } + } +} + void Application::paintGL() { // Some plugins process message events, allowing paintGL to be called reentrantly. if (_aboutToQuit || _window->isMinimized()) { @@ -2457,7 +2562,9 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - glm::vec3 boomOffset; + updateCamera(renderArgs); + + /* glm::vec3 boomOffset; { PROFILE_RANGE(render, "/updateCamera"); { @@ -2549,7 +2656,7 @@ void Application::paintGL() { } } } - + */ { PROFILE_RANGE(render, "/updateCompositor"); getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform()); @@ -2570,7 +2677,6 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/mainRender"); PerformanceTimer perfTimer("mainRender"); - renderArgs._boomOffset = boomOffset; // FIXME is this ever going to be different from the size previously set in the render args // in the overlay render? // Viewport is assigned to the size of the framebuffer diff --git a/interface/src/Application.h b/interface/src/Application.h index c7f83ad28f..3a6a183512 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -147,6 +147,8 @@ public: void initializeGL(); void initializeUi(); + + void updateCamera(RenderArgs& renderArgs); void paintGL(); void resizeGL(); From bff578b283d17d5d2c21050db34015e2cb4c6adc Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 14 Sep 2017 17:07:50 -0700 Subject: [PATCH 07/43] Working version that fixes the web overlay / tablet --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 ++- libraries/render-utils/src/Model.cpp | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 22448cc719..7d6fa40989 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -307,7 +307,8 @@ void Base3DOverlay::update(float duration) { transaction.updateItem(itemID, [renderTransform](Overlay& data) { auto overlay3D = dynamic_cast(&data); if (overlay3D) { - overlay3D->setRenderTransform(renderTransform);// evalRenderTransform(); + auto latestTransform = overlay3D->evalRenderTransform(); + overlay3D->setRenderTransform(latestTransform);// evalRenderTransform(); } }); #endif diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9e552859e3..5041f953a1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -234,21 +234,28 @@ void Model::updateRenderItems() { self->updateClusterMatrices(); uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; - - // Transform modelTransform = self->getTransform(); +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY + Transform modelTransform = self->getTransform(); // Transform modelTransform = model->getTransform(); - // modelTransform.setScale(glm::vec3(1.0f)); - + modelTransform.setScale(glm::vec3(1.0f)); +#endif render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter /*, modelTransform*/](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY + , modelTransform +#endif + ](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY +#else Transform modelTransform = model->getTransform(); modelTransform.setScale(glm::vec3(1.0f)); +#endif const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; From eed099502aa469bb6536ac222624115192be6f60 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 21 Sep 2017 17:20:32 -0700 Subject: [PATCH 08/43] minimise the changes compared to upstream --- interface/src/ui/overlays/Base3DOverlay.cpp | 5 +++-- interface/src/ui/overlays/Base3DOverlay.h | 1 - .../src/ui/overlays/Billboard3DOverlay.cpp | 1 - interface/src/ui/overlays/ModelOverlay.cpp | 18 +----------------- interface/src/ui/overlays/Overlay.h | 1 - libraries/render-utils/src/Model.cpp | 1 + 6 files changed, 5 insertions(+), 22 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 6fb2bac6ed..f5e43db6b5 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,7 +191,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - // notifyRenderTransformChange(); + notifyRenderTransformChange(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { @@ -266,7 +266,8 @@ void Base3DOverlay::parentDeleted() { qApp->getOverlays().deleteOverlay(getOverlayID()); } -void Base3DOverlay::update(float duration) { +void Base3DOverlay::update(float duration) { + // In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true. // then the correct transform used for rendering is computed in the update transaction and assigned. // TODO: Fix the value to be computed in main thread now and passed by value to the render item. diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index df1d3d2875..55b55ed16f 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -72,7 +72,6 @@ protected: virtual void parentDeleted() override; mutable Transform _renderTransform; - virtual Transform evalRenderTransform() const; virtual void setRenderTransform(const Transform& transform); const Transform& getRenderTransform() const { return _renderTransform; } diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index a333df0821..f5668caa71 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -45,4 +45,3 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { } return transformChanged; } - diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 34bb50994f..74819689e9 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -63,20 +63,6 @@ void ModelOverlay::update(float deltatime) { _model->simulate(deltatime); } _isLoaded = _model->isActive(); - - // check to see if when we added our model to the scene they were ready, if they were not ready, then - // fix them up in the scene - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - if (_model->needsFixupInScene()) { - _model->removeFromScene(scene, transaction); - _model->addToScene(scene, transaction); - } - - _model->setVisibleInScene(_visible, scene); - _model->setLayeredInFront(getDrawInFront(), scene); - - scene->enqueueTransaction(transaction); } bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { @@ -91,7 +77,6 @@ void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::Scene } void ModelOverlay::render(RenderArgs* args) { -/* // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene render::ScenePointer scene = qApp->getMain3DScene(); @@ -105,7 +90,6 @@ void ModelOverlay::render(RenderArgs* args) { _model->setLayeredInFront(getDrawInFront(), scene); scene->enqueueTransaction(transaction); - */ } void ModelOverlay::setProperties(const QVariantMap& properties) { @@ -300,11 +284,11 @@ ModelOverlay* ModelOverlay::createClone() const { void ModelOverlay::locationChanged(bool tellPhysics) { Base3DOverlay::locationChanged(tellPhysics); + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); } - _updateModel = true; } QString ModelOverlay::getName() const { diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 31846501ec..db2979b4d5 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -102,7 +102,6 @@ protected: render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID }; - bool _isLoaded; float _alpha; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 051858afca..eec3a7b8fe 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -246,6 +246,7 @@ void Model::updateRenderItems() { if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { + const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; if (state.clusterMatrices.size() == 1) { From 4a67e0421f4de185f3dec0151ee17c57d1798302 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 21 Sep 2017 17:33:50 -0700 Subject: [PATCH 09/43] minimise the changes compared to upstream --- interface/src/ui/overlays/ModelOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 74819689e9..e2a7df7ae6 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -77,6 +77,7 @@ void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::Scene } void ModelOverlay::render(RenderArgs* args) { + // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene render::ScenePointer scene = qApp->getMain3DScene(); From 11c55755d5010c8bcac2678927fe2fc165de518c Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 25 Sep 2017 15:10:40 -0700 Subject: [PATCH 10/43] Removing unused call --- interface/src/Application.cpp | 5 ----- interface/src/Application.h | 2 -- libraries/render-utils/src/AbstractViewStateInterface.h | 3 --- tests/render-perf/src/main.cpp | 5 ----- 4 files changed, 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9402cba7bc..6552141665 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5648,11 +5648,6 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const { - QMutexLocker viewLocker(&_viewMutex); - viewOut = _shadowViewFrustum; -} - // WorldBox Render Data & rendering functions class WorldBoxRenderData { diff --git a/interface/src/Application.h b/interface/src/Application.h index dc5c6a47d5..3a1f756893 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -175,7 +175,6 @@ public: // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc void copyDisplayViewFrustum(ViewFrustum& viewOut) const; - void copyShadowViewFrustum(ViewFrustum& viewOut) const override; const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } QSharedPointer getEntities() const { return DependencyManager::get(); } QUndoStack* getUndoStack() { return &_undoStack; } @@ -556,7 +555,6 @@ private: ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels) ViewFrustum _displayViewFrustum; - ViewFrustum _shadowViewFrustum; quint64 _lastQueriedTime; OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 4570ead9e1..96e9f4d222 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -31,9 +31,6 @@ public: /// copies the current view frustum for rendering the view state virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const = 0; - /// copies the shadow view frustum for rendering the view state - virtual void copyShadowViewFrustum(ViewFrustum& viewOut) const = 0; - virtual QThread* getMainThread() = 0; virtual PickRay computePickRay(float x, float y) const = 0; diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 58eb4d16f9..c70a74cd7f 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -443,10 +443,6 @@ protected: viewOut = _viewFrustum; } - void copyShadowViewFrustum(ViewFrustum& viewOut) const override { - viewOut = _shadowViewFrustum; - } - QThread* getMainThread() override { return QThread::currentThread(); } @@ -1118,7 +1114,6 @@ private: RenderThread _renderThread; QWindowCamera _camera; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. - ViewFrustum _shadowViewFrustum; // current state of view frustum, perspective, orientation, etc. model::SunSkyStage _sunSkyStage; model::LightPointer _globalLight { std::make_shared() }; bool _ready { false }; From 157b4f2e133d39173d053354aa39c113846955f4 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 25 Sep 2017 18:28:33 -0700 Subject: [PATCH 11/43] Moving some of the updates on the camera and the avatar out from render to game loop --- interface/src/Application.cpp | 55 +++++++++++++++++++++++++++-------- interface/src/Application.h | 7 +++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6552141665..cf4a103ad4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2373,6 +2373,11 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { + // load the view frustum + { + QMutexLocker viewLocker(&_viewMutex); + _myCamera.loadViewFrustum(_displayViewFrustum); + } glm::vec3 boomOffset; { @@ -2474,6 +2479,25 @@ void Application::updateCamera(RenderArgs& renderArgs) { } } } + + renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK + + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + auto myAvatar = getMyAvatar(); + myAvatar->preDisplaySide(&renderArgs); + + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs.setViewFrustum(_displayViewFrustum); + } +} + +void Application::editRenderArgs(RenderArgsEditor editor) { + QMutexLocker viewLocker(&_renderArgsMutex); + editor(_renderArgs); + } void Application::paintGL() { @@ -2518,6 +2542,10 @@ void Application::paintGL() { auto lodManager = DependencyManager::get(); RenderArgs renderArgs; + { + QMutexLocker viewLocker(&_renderArgsMutex); + renderArgs = _renderArgs; + } float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); { @@ -2570,7 +2598,7 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - updateCamera(renderArgs); + // updateCamera(renderArgs); /* glm::vec3 boomOffset; { @@ -5336,6 +5364,7 @@ void Application::update(float deltaTime) { avatarManager->postUpdate(deltaTime, getMain3DScene()); + { PROFILE_RANGE_EX(app, "PreRenderLambdas", 0xffff0000, (uint64_t)0); @@ -5346,6 +5375,10 @@ void Application::update(float deltaTime) { _postUpdateLambdas.clear(); } + editRenderArgs([this](RenderArgs& renderArgs) { + this->updateCamera(renderArgs); + }); + AnimDebugDraw::getInstance().update(); DependencyManager::get()->update(); @@ -5679,20 +5712,18 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. - auto myAvatar = getMyAvatar(); - myAvatar->preDisplaySide(renderArgs); + // auto myAvatar = getMyAvatar(); + // myAvatar->preDisplaySide(renderArgs); PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // load the view frustum - { - QMutexLocker viewLocker(&_viewMutex); - theCamera.loadViewFrustum(_displayViewFrustum); - } - - // TODO fix shadows and make them use the GPU library + // { + // QMutexLocker viewLocker(&_viewMutex); + // theCamera.loadViewFrustum(_displayViewFrustum); + // } // The pending changes collecting the changes here render::Transaction transaction; @@ -5740,11 +5771,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se { PerformanceTimer perfTimer("EngineRun"); - { + /* { QMutexLocker viewLocker(&_viewMutex); renderArgs->setViewFrustum(_displayViewFrustum); - } - renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK + }*/ + // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; diff --git a/interface/src/Application.h b/interface/src/Application.h index 3a1f756893..edb356fcef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -625,6 +625,13 @@ private: render::EnginePointer _renderEngine{ new render::Engine() }; gpu::ContextPointer _gpuContext; // initialized during window creation + mutable QMutex _renderArgsMutex{ QMutex::Recursive }; + render::Args _renderArgs; + + using RenderArgsEditor = std::function ; + void editRenderArgs(RenderArgsEditor editor); + + Overlays _overlays; ApplicationOverlay _applicationOverlay; OverlayConductor _overlayConductor; From 953614fe65579f1cb8c0652dde9bc6adae0c210a Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 25 Sep 2017 23:43:32 -0700 Subject: [PATCH 12/43] More stuff out of render to the gameloop --- interface/src/Application.cpp | 72 ++++++++++++++++++++++++++--------- interface/src/Application.h | 10 ++++- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cf4a103ad4..10e6356a83 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2482,12 +2482,6 @@ void Application::updateCamera(RenderArgs& renderArgs) { renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - auto myAvatar = getMyAvatar(); - myAvatar->preDisplaySide(&renderArgs); - { QMutexLocker viewLocker(&_viewMutex); renderArgs.setViewFrustum(_displayViewFrustum); @@ -2495,8 +2489,8 @@ void Application::updateCamera(RenderArgs& renderArgs) { } void Application::editRenderArgs(RenderArgsEditor editor) { - QMutexLocker viewLocker(&_renderArgsMutex); - editor(_renderArgs); + QMutexLocker renderLocker(&_renderArgsMutex); + editor(_appRenderArgs); } @@ -2534,19 +2528,19 @@ void Application::paintGL() { } // update the avatar with a fresh HMD pose - { - PROFILE_RANGE(render, "/updateAvatar"); - getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - } + // { + // PROFILE_RANGE(render, "/updateAvatar"); + // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); + // } - auto lodManager = DependencyManager::get(); + // auto lodManager = DependencyManager::get(); RenderArgs renderArgs; { QMutexLocker viewLocker(&_renderArgsMutex); - renderArgs = _renderArgs; + renderArgs = _appRenderArgs._renderArgs; } - +/* float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); @@ -2568,7 +2562,7 @@ void Application::paintGL() { renderArgs.setViewFrustum(_viewFrustum); } } - +*/ { PROFILE_RANGE(render, "/resizeGL"); PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); @@ -2579,6 +2573,7 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/gpuContextReset"); + // _gpuContext->beginFrame(getHMDSensorPose()); _gpuContext->beginFrame(getHMDSensorPose()); // Reset the gpu::Context Stages // Back to the default framebuffer; @@ -5375,8 +5370,49 @@ void Application::update(float deltaTime) { _postUpdateLambdas.clear(); } - editRenderArgs([this](RenderArgs& renderArgs) { - this->updateCamera(renderArgs); + editRenderArgs([this](AppRenderArgs& appRenderArgs) { + + appRenderArgs._eyeToWorld = getHMDSensorPose(); + + auto myAvatar = getMyAvatar(); + + + // update the avatar with a fresh HMD pose + { + PROFILE_RANGE(render, "/updateAvatar"); + myAvatar->updateFromHMDSensorMatrix(appRenderArgs._eyeToWorld); + } + + auto lodManager = DependencyManager::get(); + + float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + { + PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + { + QMutexLocker viewLocker(&_viewMutex); + // adjust near clip plane to account for sensor scaling. + auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + _viewFrustum.getAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + _viewFrustum.getFarClip()); + _viewFrustum.setProjection(adjustedProjection); + _viewFrustum.calculate(); + } + appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + { + QMutexLocker viewLocker(&_viewMutex); + appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); + } + } + + this->updateCamera(appRenderArgs._renderArgs); + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + myAvatar->preDisplaySide(&appRenderArgs._renderArgs); + }); AnimDebugDraw::getInstance().update(); diff --git a/interface/src/Application.h b/interface/src/Application.h index edb356fcef..45393cfbea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -626,9 +626,15 @@ private: gpu::ContextPointer _gpuContext; // initialized during window creation mutable QMutex _renderArgsMutex{ QMutex::Recursive }; - render::Args _renderArgs; + struct AppRenderArgs { + render::Args _renderArgs; + glm::mat4 _eyeToWorld; + glm::mat4 _sensorToWorld; + }; + AppRenderArgs _appRenderArgs; - using RenderArgsEditor = std::function ; + + using RenderArgsEditor = std::function ; void editRenderArgs(RenderArgsEditor editor); From 669af73a961c67b66ba86b64a36a6cbc1a9340e3 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 26 Sep 2017 10:47:24 -0700 Subject: [PATCH 13/43] Bringing as much as possible out from render to game --- interface/src/Application.cpp | 7 ++++++- interface/src/Application.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 10e6356a83..d4c0837989 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2536,9 +2536,13 @@ void Application::paintGL() { // auto lodManager = DependencyManager::get(); RenderArgs renderArgs; + float sensorToWorldScale; + glm::mat4 HMDSensorPose; { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; + HMDSensorPose = _appRenderArgs._eyeToWorld; + sensorToWorldScale = _appRenderArgs._sensorToWorldScale; } /* float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); @@ -2574,7 +2578,7 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/gpuContextReset"); // _gpuContext->beginFrame(getHMDSensorPose()); - _gpuContext->beginFrame(getHMDSensorPose()); + _gpuContext->beginFrame(HMDSensorPose); // Reset the gpu::Context Stages // Back to the default framebuffer; gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { @@ -5386,6 +5390,7 @@ void Application::update(float deltaTime) { auto lodManager = DependencyManager::get(); float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + appRenderArgs._sensorToWorldScale = sensorToWorldScale; { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); { diff --git a/interface/src/Application.h b/interface/src/Application.h index 45393cfbea..be3fa19400 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -630,6 +630,7 @@ private: render::Args _renderArgs; glm::mat4 _eyeToWorld; glm::mat4 _sensorToWorld; + float _sensorToWorldScale { 1.0f }; }; AppRenderArgs _appRenderArgs; From 40ca98214bb9a4908a346b765f373d4d065a0740 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 27 Sep 2017 17:58:43 -0700 Subject: [PATCH 14/43] Moving all of the camera and avatar eval to game loop --- interface/src/Application.cpp | 221 ++++++++----------------- interface/src/Application.h | 5 +- interface/src/ui/overlays/Overlays.cpp | 2 +- 3 files changed, 70 insertions(+), 158 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2dba980fb1..465c066bec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2374,11 +2374,7 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { - // load the view frustum - { - QMutexLocker viewLocker(&_viewMutex); - _myCamera.loadViewFrustum(_displayViewFrustum); - } + glm::vec3 boomOffset; { @@ -2481,12 +2477,7 @@ void Application::updateCamera(RenderArgs& renderArgs) { } } - renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK - - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_displayViewFrustum); - } + renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } void Application::editRenderArgs(RenderArgsEditor editor) { @@ -2539,42 +2530,46 @@ void Application::paintGL() { RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; + glm::mat4 eyeToWorld; + glm::mat4 sensorToWorld; { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._eyeToWorld; + HMDSensorPose = _appRenderArgs._headPose; + eyeToWorld = _appRenderArgs._eyeToWorld; + sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; } -/* - float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - { - PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - { - QMutexLocker viewLocker(&_viewMutex); - // adjust near clip plane to account for sensor scaling. - auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - _viewFrustum.getAspectRatio(), - DEFAULT_NEAR_CLIP * sensorToWorldScale, - _viewFrustum.getFarClip()); - _viewFrustum.setProjection(adjustedProjection); - _viewFrustum.calculate(); - } - renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_viewFrustum); - } - } -*/ - { - PROFILE_RANGE(render, "/resizeGL"); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::paintGL()"); - resizeGL(); - } + + //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + //{ + // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + // { + // QMutexLocker viewLocker(&_viewMutex); + // // adjust near clip plane to account for sensor scaling. + // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + // _viewFrustum.getAspectRatio(), + // DEFAULT_NEAR_CLIP * sensorToWorldScale, + // _viewFrustum.getFarClip()); + // _viewFrustum.setProjection(adjustedProjection); + // _viewFrustum.calculate(); + // } + // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + // { + // QMutexLocker viewLocker(&_viewMutex); + // renderArgs.setViewFrustum(_viewFrustum); + // } + //} + + //{ + // PROFILE_RANGE(render, "/resizeGL"); + // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + // PerformanceWarning warn(showWarnings, "Application::paintGL()"); + // resizeGL(); + //} { PROFILE_RANGE(render, "/gpuContextReset"); @@ -2599,103 +2594,10 @@ void Application::paintGL() { } // updateCamera(renderArgs); - - /* glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); - - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); - } - } - } - */ { PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } gpu::FramebufferPointer finalFramebuffer; @@ -2761,7 +2663,8 @@ void Application::paintGL() { renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); } renderArgs._blitFramebuffer = finalFramebuffer; - displaySide(&renderArgs, _myCamera); + // displaySide(&renderArgs, _myCamera); + runRenderFrame(&renderArgs); } gpu::Batch postCompositeBatch; @@ -5367,7 +5270,7 @@ void Application::update(float deltaTime) { editRenderArgs([this](AppRenderArgs& appRenderArgs) { - appRenderArgs._eyeToWorld = getHMDSensorPose(); + appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); @@ -5375,7 +5278,7 @@ void Application::update(float deltaTime) { // update the avatar with a fresh HMD pose { PROFILE_RANGE(render, "/updateAvatar"); - myAvatar->updateFromHMDSensorMatrix(appRenderArgs._eyeToWorld); + myAvatar->updateFromHMDSensorMatrix(appRenderArgs._headPose); } auto lodManager = DependencyManager::get(); @@ -5402,13 +5305,31 @@ void Application::update(float deltaTime) { appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); } } + { + PROFILE_RANGE(render, "/resizeGL"); + PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::paintGL()"); + resizeGL(); + } this->updateCamera(appRenderArgs._renderArgs); + + // HACK + // load the view frustum // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. myAvatar->preDisplaySide(&appRenderArgs._renderArgs); + { + QMutexLocker viewLocker(&_viewMutex); + _myCamera.loadViewFrustum(_displayViewFrustum); + } + { + QMutexLocker viewLocker(&_viewMutex); + appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); + } }); AnimDebugDraw::getInstance().update(); @@ -5740,7 +5661,7 @@ namespace render { } } -void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { +void Application::runRenderFrame(RenderArgs* renderArgs) { // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. @@ -5749,7 +5670,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); // load the view frustum // { @@ -5761,12 +5682,13 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se render::Transaction transaction; // Assuming nothing gets rendered through that - if (!selfAvatarOnly) { + //if (!selfAvatarOnly) { + { if (DependencyManager::get()->shouldRenderEntities()) { // render models... PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... entities..."); + "Application::runRenderFrame() ... entities..."); RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; @@ -5775,7 +5697,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se static_cast(RenderArgs::RENDER_DEBUG_HULLS)); } renderArgs->_debugFlags = renderDebugFlags; - //ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, transaction); } } @@ -5788,17 +5709,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se WorldBoxRenderData::_item = _main3DScene->allocateID(); transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); - } else { - transaction.updateItem(WorldBoxRenderData::_item, - [](WorldBoxRenderData& payload) { - payload._val++; - }); - } - - { _main3DScene->enqueueTransaction(transaction); } + // For now every frame pass the renderContext { PerformanceTimer perfTimer("EngineRun"); @@ -7861,5 +7775,4 @@ void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { _avatarOverrideUrl = url; _saveAvatarOverrideUrl = save; } - #include "Application.moc" diff --git a/interface/src/Application.h b/interface/src/Application.h index 3cd0ea07bc..edb615794c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -470,8 +470,6 @@ private: void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions, bool forceResend = false); - void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool isZoomed); - int sendNackPackets(); void sendAvatarViewFrustum(); @@ -481,7 +479,7 @@ private: void initializeAcceptedFiles(); - void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false); + void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/); bool importJSONFromURL(const QString& urlString); bool importSVOFromURL(const QString& urlString); @@ -628,6 +626,7 @@ private: struct AppRenderArgs { render::Args _renderArgs; glm::mat4 _eyeToWorld; + glm::mat4 _headPose; glm::mat4 _sensorToWorld; float _sensorToWorldScale { 1.0f }; }; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index c93d225718..e9cb1f2973 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -152,7 +152,7 @@ void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) { foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) { // Reset necessary batch pipeline settings between overlays batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this?? - batch.setModelTransform(Transform()); + // batch.setModelTransform(Transform()); renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey()); thisOverlay->render(renderArgs); From 4f907aba1e1100ccc02ed15eb0f4accdfcebd734 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 28 Sep 2017 14:49:48 +0200 Subject: [PATCH 15/43] sign in reworked --- interface/resources/qml/LoginDialog.qml | 4 + .../qml/LoginDialog/LinkAccountBody.qml | 194 ++++++------ .../resources/qml/LoginDialog/SignInBody.qml | 6 +- .../resources/qml/LoginDialog/SignUpBody.qml | 5 +- .../TabletLoginDialog/CompleteProfileBody.qml | 124 -------- .../qml/TabletLoginDialog/LinkAccountBody.qml | 296 ------------------ .../qml/TabletLoginDialog/SignInBody.qml | 109 ------- .../qml/TabletLoginDialog/SignUpBody.qml | 276 ---------------- .../UsernameCollisionBody.qml | 157 ---------- .../qml/TabletLoginDialog/WelcomeBody.qml | 79 ----- .../resources/qml/controls-uit/TextField.qml | 1 + .../qml/dialogs/TabletLoginDialog.qml | 195 ++++++++---- 12 files changed, 248 insertions(+), 1198 deletions(-) delete mode 100644 interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml delete mode 100644 interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml delete mode 100644 interface/resources/qml/TabletLoginDialog/SignInBody.qml delete mode 100644 interface/resources/qml/TabletLoginDialog/SignUpBody.qml delete mode 100644 interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml delete mode 100644 interface/resources/qml/TabletLoginDialog/WelcomeBody.qml diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 2e7ff39ed6..315cda3551 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -35,6 +35,10 @@ ModalWindow { keyboardOverride: true // Disable ModalWindow's keyboard. + function tryDestroy() { + root.destroy() + } + LoginDialog { id: loginDialog diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index e27635dbbd..7f69e41958 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -9,7 +9,7 @@ // import Hifi 1.0 -import QtQuick 2.4 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 as OriginalStyles @@ -56,6 +56,7 @@ Item { parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y); + console.log("sign in h:", targetHeight, parent.height) } } @@ -108,30 +109,27 @@ Item { Column { id: form + width: parent.width + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + anchors { top: mainTextContainer.bottom - left: parent.left - margins: 0 topMargin: 2 * hifi.dimensions.contentSpacing.y } spacing: 2 * hifi.dimensions.contentSpacing.y - Row { - spacing: hifi.dimensions.contentSpacing.x - TextField { - id: usernameField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 + TextField { + id: usernameField + width: parent.width - label: "Username or Email" - } + label: "Username or Email" ShortcutText { anchors { - verticalCenter: parent.verticalCenter + verticalCenter: usernameField.textFieldLabel.verticalCenter + left: usernameField.textFieldLabel.right + leftMargin: 10 } text: "Forgot Username?" @@ -143,23 +141,19 @@ Item { onLinkActivated: loginDialog.openUrl(link) } } - Row { - spacing: hifi.dimensions.contentSpacing.x - TextField { - id: passwordField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 + TextField { + id: passwordField + width: parent.width - label: "Password" - echoMode: TextInput.Password - } + label: "Password" + echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password ShortcutText { anchors { - verticalCenter: parent.verticalCenter + verticalCenter: passwordField.textFieldLabel.verticalCenter + left: passwordField.textFieldLabel.right + leftMargin: 10 } text: "Forgot Password?" @@ -172,25 +166,86 @@ Item { } } - } - - InfoItem { - id: additionalInformation - anchors { - top: form.bottom - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y + CheckBoxQQC2 { + id: showPassword + text: "Show password" } - visible: loginDialog.isSteamRunning() + InfoItem { + id: additionalInformation + anchors { + left: parent.left + margins: 0 + topMargin: hifi.dimensions.contentSpacing.y + } - text: qsTr("Your steam account informations will not be exposed to other users.") - wrapMode: Text.WordWrap - color: hifi.colors.baseGrayHighlight - lineHeight: 1 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter + visible: loginDialog.isSteamRunning() + + text: qsTr("Your steam account informations will not be exposed to other users.") + wrapMode: Text.WordWrap + color: hifi.colors.baseGrayHighlight + lineHeight: 1 + lineHeightMode: Text.ProportionalHeight + horizontalAlignment: Text.AlignHCenter + } + + Column { + //width: parent.width + spacing: hifi.dimensions.contentSpacing.y*2 + anchors.horizontalCenter: parent.horizontalCenter + //padding: 10 + + Row { + id: buttons + spacing: hifi.dimensions.contentSpacing.y*2 + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + anchors.horizontalCenter: parent.horizontalCenter + + Button { + id: linkAccountButton + anchors.verticalCenter: parent.verticalCenter + width: 200 + + text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") + color: hifi.buttons.blue + + onClicked: linkAccountBody.login() + } + + Button { + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Cancel") + onClicked: root.tryDestroy() + } + } + + Row { + id: leftButton + + anchors.horizontalCenter: parent.horizontalCenter + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + + RalewaySemiBold { + size: hifi.fontSizes.inputLabel + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Don't have an account?") + } + + Button { + anchors.verticalCenter: parent.verticalCenter + + text: qsTr("Sign Up") + visible: !loginDialog.isSteamRunning() + + onClicked: { + bodyLoader.setSource("SignUpBody.qml") + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } + } + } } // Override ScrollingWindow's keyboard that would be at very bottom of dialog. @@ -200,65 +255,12 @@ Item { anchors { left: parent.left right: parent.right - bottom: buttons.top + bottom: parent.bottom bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 } } - Row { - id: leftButton - anchors { - left: parent.left - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Sign Up") - visible: !loginDialog.isSteamRunning() - - onClicked: { - bodyLoader.setSource("SignUpBody.qml") - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height - } - } - } - - Row { - id: buttons - anchors { - right: parent.right - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - id: linkAccountButton - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") - color: hifi.buttons.blue - - onClicked: linkAccountBody.login() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel") - - onClicked: root.destroy() - } - } Component.onCompleted: { root.title = qsTr("Sign Into High Fidelity") diff --git a/interface/resources/qml/LoginDialog/SignInBody.qml b/interface/resources/qml/LoginDialog/SignInBody.qml index 167ed1640a..71ec03f7ff 100644 --- a/interface/resources/qml/LoginDialog/SignInBody.qml +++ b/interface/resources/qml/LoginDialog/SignInBody.qml @@ -9,7 +9,7 @@ // import Hifi 1.0 -import QtQuick 2.4 +import QtQuick 2.7 import QtQuick.Controls.Styles 1.4 as OriginalStyles import "../controls-uit" @@ -18,8 +18,8 @@ import "../styles-uit" Item { id: signInBody clip: true - width: root.pane.width height: root.pane.height + width: root.pane.width property bool required: false @@ -29,7 +29,7 @@ Item { } function cancel() { - root.destroy() + root.tryDestroy() } QtObject { diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index c0ff2d77cb..c7bfa8cfcd 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -9,7 +9,7 @@ // import Hifi 1.0 -import QtQuick 2.4 +import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 as OriginalStyles @@ -50,6 +50,7 @@ Item { parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : 0); + //console.log("sign up h:", parent.height) } } @@ -237,7 +238,7 @@ Item { text: qsTr("Cancel") - onClicked: root.destroy() + onClicked: root.tryDestroy() } } diff --git a/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml b/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml deleted file mode 100644 index 6024563bcf..0000000000 --- a/interface/resources/qml/TabletLoginDialog/CompleteProfileBody.qml +++ /dev/null @@ -1,124 +0,0 @@ -// -// CompleteProfileBody.qml -// -// Created by Clement on 7/18/16 -// 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 -// - -import Hifi 1.0 -import QtQuick 2.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles - -import "../controls-uit" -import "../styles-uit" - -Item { - id: completeProfileBody - clip: true - - QtObject { - id: d - function resize() {} - } - - Row { - id: buttons - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr("Create your profile") - color: hifi.buttons.blue - - onClicked: loginDialog.createAccountFromStream() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel") - - onClicked: bodyLoader.popup() - } - } - - ShortcutText { - id: additionalTextContainer - anchors { - top: buttons.bottom - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - text: "Already have a High Fidelity profile? Link to an existing profile here." - - wrapMode: Text.WordWrap - lineHeight: 2 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - - onLinkActivated: { - bodyLoader.setSource("LinkAccountBody.qml") - } - } - - InfoItem { - id: termsContainer - anchors { - top: additionalTextContainer.bottom - left: parent.left - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - - text: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") - wrapMode: Text.WordWrap - color: hifi.colors.baseGrayHighlight - lineHeight: 1 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - - onLinkActivated: loginDialog.openUrl(link) - } - - Component.onCompleted: { - loginDialogRoot.title = qsTr("Complete Your Profile") - loginDialogRoot.iconText = "<" - d.resize(); - } - - Connections { - target: loginDialog - onHandleCreateCompleted: { - console.log("Create Succeeded") - - loginDialog.loginThroughSteam() - } - onHandleCreateFailed: { - console.log("Create Failed: " + error) - - bodyLoadersetSource("UsernameCollisionBody.qml") - } - onHandleLoginCompleted: { - console.log("Login Succeeded") - - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false }) - } - onHandleLoginFailed: { - console.log("Login Failed") - } - } -} diff --git a/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml b/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml deleted file mode 100644 index 8010a34250..0000000000 --- a/interface/resources/qml/TabletLoginDialog/LinkAccountBody.qml +++ /dev/null @@ -1,296 +0,0 @@ -// -// LinkAccountBody.qml -// -// Created by Clement on 7/18/16 -// 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 -// - -import Hifi 1.0 -import QtQuick 2.4 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles - -import "../controls-uit" -import "../styles-uit" - -Item { - id: linkAccountBody - clip: true - height: parent.height - width: parent.width - property bool failAfterSignUp: false - - function login() { - mainTextContainer.visible = false - toggleLoading(true) - loginDialog.login(usernameField.text, passwordField.text) - } - - property bool keyboardEnabled: false - property bool keyboardRaised: false - property bool punctuationMode: false - - onKeyboardRaisedChanged: d.resize(); - - QtObject { - id: d - function resize() {} - } - - function toggleLoading(isLoading) { - linkAccountSpinner.visible = isLoading - form.visible = !isLoading - - if (loginDialog.isSteamRunning()) { - additionalInformation.visible = !isLoading - } - - leftButton.visible = !isLoading - buttons.visible = !isLoading - } - - BusyIndicator { - id: linkAccountSpinner - - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - topMargin: hifi.dimensions.contentSpacing.y - } - - visible: false - running: true - - width: 48 - height: 48 - } - - ShortcutText { - id: mainTextContainer - anchors { - top: parent.top - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - visible: false - - text: qsTr("Username or password incorrect.") - wrapMode: Text.WordWrap - color: hifi.colors.redAccent - lineHeight: 1 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } - - Column { - id: form - anchors { - top: mainTextContainer.bottom - left: parent.left - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: 2 * hifi.dimensions.contentSpacing.y - - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: usernameField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Username or Email" - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: "Forgot Username?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - } - } - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: passwordField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Password" - echoMode: TextInput.Password - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: "Forgot Password?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - } - } - - } - - InfoItem { - id: additionalInformation - anchors { - top: form.bottom - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - visible: loginDialog.isSteamRunning() - - text: qsTr("Your steam account informations will not be exposed to other users.") - wrapMode: Text.WordWrap - color: hifi.colors.baseGrayHighlight - lineHeight: 1 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } - - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. - Keyboard { - raised: keyboardEnabled && keyboardRaised - numeric: punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: buttons.top - bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 - } - } - - Row { - id: leftButton - anchors { - left: parent.left - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Sign Up") - visible: !loginDialog.isSteamRunning() - - onClicked: { - bodyLoader.setSource("SignUpBody.qml") - } - } - } - - Row { - id: buttons - anchors { - right: parent.right - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - id: linkAccountButton - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") - color: hifi.buttons.blue - - onClicked: linkAccountBody.login() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Cancel") - onClicked: { - bodyLoader.popup() - } - } - } - - Component.onCompleted: { - loginDialogRoot.title = qsTr("Sign Into High Fidelity") - loginDialogRoot.iconText = "<" - keyboardEnabled = HMD.active; - d.resize(); - - if (failAfterSignUp) { - mainTextContainer.text = "Account created successfully." - mainTextContainer.visible = true - } - - usernameField.forceActiveFocus(); - } - - Connections { - target: loginDialog - onHandleLoginCompleted: { - console.log("Login Succeeded, linking steam account") - - if (loginDialog.isSteamRunning()) { - loginDialog.linkSteam() - } else { - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) - } - } - onHandleLoginFailed: { - console.log("Login Failed") - mainTextContainer.visible = true - toggleLoading(false) - } - onHandleLinkCompleted: { - console.log("Link Succeeded") - - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) - } - onHandleLinkFailed: { - console.log("Link Failed") - toggleLoading(false) - } - } - - Keys.onPressed: { - if (!visible) { - return - } - - switch (event.key) { - case Qt.Key_Enter: - case Qt.Key_Return: - event.accepted = true - linkAccountBody.login() - break - } - } -} diff --git a/interface/resources/qml/TabletLoginDialog/SignInBody.qml b/interface/resources/qml/TabletLoginDialog/SignInBody.qml deleted file mode 100644 index 9cdf69c7bc..0000000000 --- a/interface/resources/qml/TabletLoginDialog/SignInBody.qml +++ /dev/null @@ -1,109 +0,0 @@ -// -// SignInBody.qml -// -// Created by Clement on 7/18/16 -// 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 -// - -import Hifi 1.0 -import QtQuick 2.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles - -import "../controls-uit" -import "../styles-uit" - -Item { - id: signInBody - clip: true - - property bool required: false - - function login() { - console.log("Trying to log in") - loginDialog.loginThroughSteam() - } - - function cancel() { - bodyLoader.popup() - } - - QtObject { - id: d - function resize() {} - } - - InfoItem { - id: mainTextContainer - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - text: required ? qsTr("This domain's owner requires that you sign in:") - : qsTr("Sign in to access your user account:") - wrapMode: Text.WordWrap - color: hifi.colors.baseGrayHighlight - lineHeight: 2 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } - - Row { - id: buttons - anchors { - top: mainTextContainer.bottom - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - width: undefined // invalidate so that the image's size sets the width - height: undefined // invalidate so that the image's size sets the height - focus: true - - style: OriginalStyles.ButtonStyle { - background: Image { - id: buttonImage - source: "../../images/steam-sign-in.png" - } - } - onClicked: signInBody.login() - } - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel"); - - onClicked: signInBody.cancel() - } - } - - Component.onCompleted: { - loginDialogRoot.title = required ? qsTr("Sign In Required") - : qsTr("Sign In") - loginDialogRoot.iconText = "" - d.resize(); - } - - Connections { - target: loginDialog - onHandleLoginCompleted: { - console.log("Login Succeeded") - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : true }) - } - onHandleLoginFailed: { - console.log("Login Failed") - bodyLoader.setSource("CompleteProfileBody.qml") - } - } -} diff --git a/interface/resources/qml/TabletLoginDialog/SignUpBody.qml b/interface/resources/qml/TabletLoginDialog/SignUpBody.qml deleted file mode 100644 index 2cfc0e736a..0000000000 --- a/interface/resources/qml/TabletLoginDialog/SignUpBody.qml +++ /dev/null @@ -1,276 +0,0 @@ -// -// SignUpBody.qml -// -// Created by Stephen Birarda on 7 Dec 2016 -// Copyright 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 -// - -import Hifi 1.0 -import QtQuick 2.4 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles - -import "../controls-uit" -import "../styles-uit" - -Item { - id: signupBody - clip: true -// height: parent.height -// width: parent.width - - function signup() { - mainTextContainer.visible = false - toggleLoading(true) - loginDialog.signup(emailField.text, usernameField.text, passwordField.text) - } - - property bool keyboardEnabled: false - property bool keyboardRaised: false - property bool punctuationMode: false - - onKeyboardRaisedChanged: d.resize(); - - QtObject { - id: d - function resize() {} - } - - function toggleLoading(isLoading) { - linkAccountSpinner.visible = isLoading - form.visible = !isLoading - - leftButton.visible = !isLoading - buttons.visible = !isLoading - } - - BusyIndicator { - id: linkAccountSpinner - - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - topMargin: hifi.dimensions.contentSpacing.y - } - - visible: false - running: true - - width: 48 - height: 48 - } - - ShortcutText { - id: mainTextContainer - anchors { - top: parent.top - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - visible: false - - text: qsTr("There was an unknown error while creating your account.") - wrapMode: Text.WordWrap - color: hifi.colors.redAccent - horizontalAlignment: Text.AlignLeft - } - - Column { - id: form - anchors { - top: mainTextContainer.bottom - left: parent.left - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: 2 * hifi.dimensions.contentSpacing.y - - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: emailField - anchors { - verticalCenter: parent.verticalCenter - } - width: 300 - - label: "Email" - } - } - - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: usernameField - anchors { - verticalCenter: parent.verticalCenter - } - width: 300 - - label: "Username" - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: qsTr("No spaces / special chars.") - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - - color: hifi.colors.blueAccent - } - } - - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: passwordField - anchors { - verticalCenter: parent.verticalCenter - } - width: 300 - - label: "Password" - echoMode: TextInput.Password - } - - ShortcutText { - anchors { - verticalCenter: parent.verticalCenter - } - - text: qsTr("At least 6 characters") - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - - color: hifi.colors.blueAccent - } - } - - } - - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. - Keyboard { - raised: keyboardEnabled && keyboardRaised - numeric: punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: buttons.top - bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 - } - } - - Row { - id: leftButton - anchors { - left: parent.left - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Existing User") - - onClicked: { - bodyLoader.setSource("LinkAccountBody.qml") - } - } - } - - Row { - id: buttons - anchors { - right: parent.right - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - id: linkAccountButton - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr("Sign Up") - color: hifi.buttons.blue - - onClicked: signupBody.signup() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel") - - onClicked: bodyLoader.popup() - } - } - - Component.onCompleted: { - loginDialogRoot.title = qsTr("Create an Account") - loginDialogRoot.iconText = "<" - keyboardEnabled = HMD.active; - d.resize(); - - emailField.forceActiveFocus(); - } - - Connections { - target: loginDialog - onHandleSignupCompleted: { - console.log("Sign Up Succeeded"); - - // now that we have an account, login with that username and password - loginDialog.login(usernameField.text, passwordField.text) - } - onHandleSignupFailed: { - console.log("Sign Up Failed") - toggleLoading(false) - - mainTextContainer.text = errorString - mainTextContainer.visible = true - - d.resize(); - } - onHandleLoginCompleted: { - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack": false }) - } - onHandleLoginFailed: { - // we failed to login, show the LoginDialog so the user will try again - bodyLoader.setSource("LinkAccountBody.qml", { "failAfterSignUp": true }) - } - } - - Keys.onPressed: { - if (!visible) { - return - } - - switch (event.key) { - case Qt.Key_Enter: - case Qt.Key_Return: - event.accepted = true - signupBody.signup() - break - } - } -} diff --git a/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml deleted file mode 100644 index 9e5b01d339..0000000000 --- a/interface/resources/qml/TabletLoginDialog/UsernameCollisionBody.qml +++ /dev/null @@ -1,157 +0,0 @@ -// -// UsernameCollisionBody.qml -// -// Created by Clement on 7/18/16 -// 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 -// - -import Hifi 1.0 -import QtQuick 2.4 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 as OriginalStyles - -import "../controls-uit" -import "../styles-uit" - -Item { - id: usernameCollisionBody - clip: true - width: parent.width - height: parent.height - - function create() { - mainTextContainer.visible = false - loginDialog.createAccountFromStream(textField.text) - } - - - property bool keyboardEnabled: false - property bool keyboardRaised: false - property bool punctuationMode: false - - onKeyboardRaisedChanged: d.resize(); - - QtObject { - id: d - function resize() {} - } - - ShortcutText { - id: mainTextContainer - anchors { - top: parent.top - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - text: qsTr("Your Steam username is not available.") - wrapMode: Text.WordWrap - color: hifi.colors.redAccent - lineHeight: 1 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } - - - TextField { - id: textField - anchors { - top: mainTextContainer.bottom - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - width: 250 - - placeholderText: "Choose your own" - } - - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. - Keyboard { - raised: keyboardEnabled && keyboardRaised - numeric: punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: buttons.top - bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 - } - } - - Row { - id: buttons - anchors { - bottom: parent.bottom - right: parent.right - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr("Create your profile") - color: hifi.buttons.blue - - onClicked: usernameCollisionBody.create() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel") - onClicked: bodyLoader.popup() - } - } - - Component.onCompleted: { - loginDialogRoot.title = qsTr("Complete Your Profile") - loginDialogRoot.iconText = "<" - keyboardEnabled = HMD.active; - d.resize(); - } - - Connections { - target: loginDialog - onHandleCreateCompleted: { - console.log("Create Succeeded") - - loginDialog.loginThroughSteam() - } - onHandleCreateFailed: { - console.log("Create Failed: " + error) - - mainTextContainer.visible = true - mainTextContainer.text = "\"" + textField.text + qsTr("\" is invalid or already taken.") - } - onHandleLoginCompleted: { - console.log("Login Succeeded") - - bodyLoader.setSource("WelcomeBody.qml", { "welcomeBack" : false }) - } - onHandleLoginFailed: { - console.log("Login Failed") - } - } - - Keys.onPressed: { - if (!visible) { - return - } - - switch (event.key) { - case Qt.Key_Enter: - case Qt.Key_Return: - event.accepted = true - usernameCollisionBody.create() - break - } - } -} diff --git a/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml b/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml deleted file mode 100644 index 5ec259ca96..0000000000 --- a/interface/resources/qml/TabletLoginDialog/WelcomeBody.qml +++ /dev/null @@ -1,79 +0,0 @@ -// -// WelcomeBody.qml -// -// Created by Clement on 7/18/16 -// 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 -// - -import Hifi 1.0 -import QtQuick 2.4 - -import "../controls-uit" -import "../styles-uit" - -Item { - id: welcomeBody - clip: true - - property bool welcomeBack: false - - function setTitle() { - loginDialogRoot.title = (welcomeBack ? qsTr("Welcome back ") : qsTr("Welcome ")) + Account.username + qsTr("!") - loginDialogRoot.iconText = "" - d.resize(); - } - - QtObject { - id: d - function resize() {} - } - - InfoItem { - id: mainTextContainer - anchors { - top: parent.top - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - text: qsTr("You are now signed into High Fidelity") - wrapMode: Text.WordWrap - color: hifi.colors.baseGrayHighlight - lineHeight: 2 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } - - Row { - id: buttons - anchors { - top: mainTextContainer.bottom - horizontalCenter: parent.horizontalCenter - margins: 0 - topMargin: 2 * hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Close"); - - onClicked: bodyLoader.popup() - } - } - - Component.onCompleted: { - welcomeBody.setTitle() - } - - Connections { - target: Account - onUsernameChanged: welcomeBody.setTitle() - } -} diff --git a/interface/resources/qml/controls-uit/TextField.qml b/interface/resources/qml/controls-uit/TextField.qml index 65fab00700..a1c98b54d4 100644 --- a/interface/resources/qml/controls-uit/TextField.qml +++ b/interface/resources/qml/controls-uit/TextField.qml @@ -31,6 +31,7 @@ TextField { font.pixelSize: hifi.fontSizes.textFieldInput font.italic: textField.text == "" height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered. + property alias textFieldLabel: textFieldLabel y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0 diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 36ca480b24..ae00cb3d40 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -16,48 +16,63 @@ import "../controls-uit" import "../styles-uit" import "../windows" +import "../LoginDialog" + TabletModalWindow { - id: loginDialogRoot + id: realRoot objectName: "LoginDialog" signal sendToScript(var message); property bool isHMD: false property bool gotoPreviousApp: false; color: hifi.colors.baseGray + title: qsTr("Sign in to High Fidelity") + property alias titleWidth: root.titleWidth + + //fake root for shared components expecting root here + property var root: QtObject { + id: root + property alias title: realRoot.title + + property real width: realRoot.width + property real height: realRoot.height + + property int titleWidth: 0 + property string iconText: hifi.glyphs.avatar + property int iconSize: 35 + + property var pane: QtObject { + property real width: root.width + property real height: root.height + } + + function tryDestroy() { + canceled() + } + } + + //property int colorScheme: hifi.colorSchemes.dark - property int colorScheme: hifi.colorSchemes.dark - property int titleWidth: 0 - property string iconText: "" - property int icon: hifi.icons.none - property int iconSize: 35 MouseArea { - width: parent.width - height: parent.height + width: realRoot.width + height: realRoot.height } property bool keyboardOverride: true - onIconChanged: updateIcon(); property var items; property string label: "" - onTitleWidthChanged: d.resize(); + //onTitleWidthChanged: d.resize(); property bool keyboardEnabled: false property bool keyboardRaised: false property bool punctuationMode: false - onKeyboardRaisedChanged: d.resize(); + //onKeyboardRaisedChanged: d.resize(); signal canceled(); - function updateIcon() { - if (!root) { - return; - } - iconText = hifi.glyphForIcon(root.icon); - } - property alias bodyLoader: bodyLoader property alias loginDialog: loginDialog property alias hifi: hifi @@ -65,9 +80,10 @@ TabletModalWindow { HifiConstants { id: hifi } onCanceled: { - if (loginDialogRoot.Stack.view) { - loginDialogRoot.Stack.view.pop(); - } else if (gotoPreviousApp) { + if (bodyLoader.active === true) { + bodyLoader.active = false + } + if (gotoPreviousApp) { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); tablet.returnToPreviousApp(); } else { @@ -75,45 +91,112 @@ TabletModalWindow { } } - LoginDialog { - id: loginDialog - width: parent.width - height: parent.height - StackView { - id: bodyLoader - property var item: currentItem - property var props - property string source: "" - onCurrentItemChanged: { - //cleanup source for future usage - source = "" + TabletModalFrame { + id: mfRoot + + width: root.width + height: root.height + frameMarginTop + + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + onHeightChanged: console.log("tablet mf h:", height) + + LoginDialog { + id: loginDialog + + anchors { + fill: parent + topMargin: parent.frameMarginTop + leftMargin: hifi.dimensions.contentMargin.x + rightMargin: hifi.dimensions.contentMargin.x + horizontalCenter: parent.horizontalCenter } - function setSource(src, props) { - source = "../TabletLoginDialog/" + src - bodyLoader.props = props - } - function popup() { - bodyLoader.pop() - - //check if last screen, if yes, dialog is popped out - if (depth === 1) - loginDialogRoot.canceled() - } - - anchors.fill: parent - anchors.margins: 10 - onSourceChanged: { - if (source !== "") { - bodyLoader.push(Qt.resolvedUrl(source), props) - } - } - Component.onCompleted: { - setSource(loginDialog.isSteamRunning() ? - "SignInBody.qml" : - "LinkAccountBody.qml") + Loader { + id: bodyLoader + anchors.fill: parent + anchors.horizontalCenter: parent.horizontalCenter + source: loginDialog.isSteamRunning() ? "../LoginDialog/SignInBody.qml" : "../LoginDialog/LinkAccountBody.qml" } } } + + Keys.onPressed: { + if (!visible) { + return + } + + if (event.modifiers === Qt.ControlModifier) + switch (event.key) { + case Qt.Key_A: + event.accepted = true + detailedText.selectAll() + break + case Qt.Key_C: + event.accepted = true + detailedText.copy() + break + case Qt.Key_Period: + if (Qt.platform.os === "osx") { + event.accepted = true + content.reject() + } + break + } else switch (event.key) { + case Qt.Key_Escape: + case Qt.Key_Back: + event.accepted = true + destroy() + break + + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true + break + } + } +// LoginDialog { +// id: loginDialog +// width: parent.width +// height: parent.height +// StackView { +// id: bodyLoader +// property var item: currentItem +// property var props +// property string source: "" + +// onCurrentItemChanged: { +// //cleanup source for future usage +// source = "" +// } + +// function setSource(src, props) { +// source = "../TabletLoginDialog/" + src +// bodyLoader.props = props +// } +// function popup() { +// bodyLoader.pop() + +// //check if last screen, if yes, dialog is popped out +// if (depth === 1) +// loginDialogRoot.canceled() +// } + +// anchors.fill: parent +// anchors.margins: 10 +// onSourceChanged: { +// if (source !== "") { +// bodyLoader.push(Qt.resolvedUrl(source), props) +// } +// } +// Component.onCompleted: { +// setSource(loginDialog.isSteamRunning() ? +// "SignInBody.qml" : +// "LinkAccountBody.qml") +// } +// } +// } } From 769c57208c3307ad88761e14b3efab6f91abb557 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 28 Sep 2017 21:35:41 +0200 Subject: [PATCH 16/43] Signup ready --- .../qml/LoginDialog/LinkAccountBody.qml | 104 +++++------ .../resources/qml/LoginDialog/SignUpBody.qml | 170 ++++++++---------- .../qml/dialogs/TabletLoginDialog.qml | 2 +- interface/src/main.cpp | 4 +- 4 files changed, 120 insertions(+), 160 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 7f69e41958..26e90eb9a6 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -45,8 +45,8 @@ Item { function resize() { var targetWidth = Math.max(titleWidth, form.contentWidth); var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + - 4 * hifi.dimensions.contentSpacing.y + form.height + - hifi.dimensions.contentSpacing.y + buttons.height; + 4 * hifi.dimensions.contentSpacing.y + form.height/* + + hifi.dimensions.contentSpacing.y + buttons.height*/; if (additionalInformation.visible) { targetWidth = Math.max(targetWidth, additionalInformation.width); @@ -56,7 +56,7 @@ Item { parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y); - console.log("sign in h:", targetHeight, parent.height) + console.log("sign in h:", targetHeight, parent.height, form.height) } } @@ -67,9 +67,6 @@ Item { if (loginDialog.isSteamRunning()) { additionalInformation.visible = !isLoading } - - leftButton.visible = !isLoading - buttons.visible = !isLoading } BusyIndicator { @@ -173,11 +170,6 @@ Item { InfoItem { id: additionalInformation - anchors { - left: parent.left - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } visible: loginDialog.isSteamRunning() @@ -189,65 +181,59 @@ Item { horizontalAlignment: Text.AlignHCenter } - Column { - //width: parent.width + Row { + id: buttons spacing: hifi.dimensions.contentSpacing.y*2 + onHeightChanged: d.resize(); onWidthChanged: d.resize(); anchors.horizontalCenter: parent.horizontalCenter - //padding: 10 - Row { - id: buttons - spacing: hifi.dimensions.contentSpacing.y*2 - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - anchors.horizontalCenter: parent.horizontalCenter + Button { + id: linkAccountButton + anchors.verticalCenter: parent.verticalCenter + width: 200 - Button { - id: linkAccountButton - anchors.verticalCenter: parent.verticalCenter - width: 200 + text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") + color: hifi.buttons.blue - text: qsTr(loginDialog.isSteamRunning() ? "Link Account" : "Login") - color: hifi.buttons.blue - - onClicked: linkAccountBody.login() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Cancel") - onClicked: root.tryDestroy() - } + onClicked: linkAccountBody.login() } - Row { - id: leftButton + Button { + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Cancel") + onClicked: root.tryDestroy() + } + } - anchors.horizontalCenter: parent.horizontalCenter - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); + Row { + id: leftButton - RalewaySemiBold { - size: hifi.fontSizes.inputLabel - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Don't have an account?") - } + anchors.horizontalCenter: parent.horizontalCenter + spacing: hifi.dimensions.contentSpacing.y*2 + onHeightChanged: d.resize(); onWidthChanged: d.resize(); - Button { - anchors.verticalCenter: parent.verticalCenter + RalewaySemiBold { + size: hifi.fontSizes.inputLabel + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Don't have an account?") + } - text: qsTr("Sign Up") - visible: !loginDialog.isSteamRunning() + Button { + anchors.verticalCenter: parent.verticalCenter - onClicked: { - bodyLoader.setSource("SignUpBody.qml") - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height - } + text: qsTr("Sign Up") + visible: !loginDialog.isSteamRunning() + + onClicked: { + bodyLoader.setSource("SignUpBody.qml") + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height } } } } + // Override ScrollingWindow's keyboard that would be at very bottom of dialog. Keyboard { raised: keyboardEnabled && keyboardRaised @@ -266,7 +252,7 @@ Item { root.title = qsTr("Sign Into High Fidelity") root.iconText = "<" keyboardEnabled = HMD.active; - d.resize(); + //d.resize(); if (failAfterSignUp) { mainTextContainer.text = "Account created successfully." @@ -313,11 +299,11 @@ Item { } switch (event.key) { - case Qt.Key_Enter: - case Qt.Key_Return: - event.accepted = true - linkAccountBody.login() - break + case Qt.Key_Enter: + case Qt.Key_Return: + event.accepted = true + linkAccountBody.login() + break } } } diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index c7bfa8cfcd..aef20c7a61 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -44,13 +44,13 @@ Item { function resize() { var targetWidth = Math.max(titleWidth, form.contentWidth); var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + - 4 * hifi.dimensions.contentSpacing.y + form.height + - hifi.dimensions.contentSpacing.y + buttons.height; + 4 * hifi.dimensions.contentSpacing.y + form.height/* + + hifi.dimensions.contentSpacing.y + buttons.height*/; parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : 0); - //console.log("sign up h:", parent.height) + console.log("sign up h:", parent.height, targetHeight, form.height) } } @@ -97,44 +97,31 @@ Item { Column { id: form + width: parent.width + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + anchors { top: mainTextContainer.bottom - left: parent.left - margins: 0 topMargin: 2 * hifi.dimensions.contentSpacing.y } spacing: 2 * hifi.dimensions.contentSpacing.y - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: emailField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Email" - } + TextField { + id: emailField + width: parent.width + label: "Email" } - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: usernameField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Username" - } + TextField { + id: usernameField + width: parent.width + label: "Username" ShortcutText { anchors { - verticalCenter: parent.verticalCenter + verticalCenter: parent.textFieldLabel.verticalCenter + left: parent.textFieldLabel.right + leftMargin: 10 } text: qsTr("No spaces / special chars.") @@ -146,23 +133,17 @@ Item { } } - Row { - spacing: hifi.dimensions.contentSpacing.x - - TextField { - id: passwordField - anchors { - verticalCenter: parent.verticalCenter - } - width: 350 - - label: "Password" - echoMode: TextInput.Password - } + TextField { + id: passwordField + width: parent.width + label: "Password" + echoMode: TextInput.Password ShortcutText { anchors { - verticalCenter: parent.verticalCenter + verticalCenter: parent.textFieldLabel.verticalCenter + left: parent.textFieldLabel.right + leftMargin: 10 } text: qsTr("At least 6 characters") @@ -174,6 +155,51 @@ Item { } } + Row { + id: leftButton + anchors.horizontalCenter: parent.horizontalCenter + + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + + Button { + anchors.verticalCenter: parent.verticalCenter + + text: qsTr("Existing User") + + onClicked: { + bodyLoader.setSource("LinkAccountBody.qml") + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } + } + } + + Row { + id: buttons + anchors.horizontalCenter: parent.horizontalCenter + spacing: hifi.dimensions.contentSpacing.x + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + + Button { + id: linkAccountButton + anchors.verticalCenter: parent.verticalCenter + width: 200 + + text: qsTr("Sign Up") + color: hifi.buttons.blue + + onClicked: signupBody.signup() + } + + Button { + anchors.verticalCenter: parent.verticalCenter + + text: qsTr("Cancel") + + onClicked: root.tryDestroy() + } + } } // Override ScrollingWindow's keyboard that would be at very bottom of dialog. @@ -183,65 +209,11 @@ Item { anchors { left: parent.left right: parent.right - bottom: buttons.top + bottom: parent.bottom bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 } } - Row { - id: leftButton - anchors { - left: parent.left - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Existing User") - - onClicked: { - bodyLoader.setSource("LinkAccountBody.qml") - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height - } - } - } - - Row { - id: buttons - anchors { - right: parent.right - bottom: parent.bottom - bottomMargin: hifi.dimensions.contentSpacing.y - } - spacing: hifi.dimensions.contentSpacing.x - onHeightChanged: d.resize(); onWidthChanged: d.resize(); - - Button { - id: linkAccountButton - anchors.verticalCenter: parent.verticalCenter - width: 200 - - text: qsTr("Sign Up") - color: hifi.buttons.blue - - onClicked: signupBody.signup() - } - - Button { - anchors.verticalCenter: parent.verticalCenter - - text: qsTr("Cancel") - - onClicked: root.tryDestroy() - } - } - Component.onCompleted: { root.title = qsTr("Create an Account") root.iconText = "<" diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index ae00cb3d40..78221ab6cb 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -96,7 +96,7 @@ TabletModalWindow { id: mfRoot width: root.width - height: root.height + frameMarginTop + height: root.height //+ frameMarginTop anchors { horizontalCenter: parent.horizontalCenter diff --git a/interface/src/main.cpp b/interface/src/main.cpp index cb90160cfe..334715ef04 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -48,7 +48,9 @@ int main(int argc, const char* argv[]) { static QString BUG_SPLAT_APPLICATION_NAME = "Interface"; CrashReporter crashReporter { BUG_SPLAT_DATABASE, BUG_SPLAT_APPLICATION_NAME, BuildInfo::VERSION }; #endif - +#ifdef Q_OS_UNIX + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); +#endif disableQtBearerPoll(); // Fixes wifi ping spikes QElapsedTimer startupTime; From 4023c4014957f9163543aaea9744a2ff513b7f57 Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 28 Sep 2017 22:55:01 +0200 Subject: [PATCH 17/43] Cleanup --- .../qml/LoginDialog/CompleteProfileBody.qml | 2 +- .../qml/LoginDialog/LinkAccountBody.qml | 2 - .../resources/qml/LoginDialog/SignUpBody.qml | 1 - .../qml/LoginDialog/UsernameCollisionBody.qml | 2 +- .../resources/qml/LoginDialog/WelcomeBody.qml | 2 +- .../qml/dialogs/TabletLoginDialog.qml | 48 ++----------------- 6 files changed, 7 insertions(+), 50 deletions(-) diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml index e06ce239ab..2c6bc1082a 100644 --- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml +++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml @@ -65,7 +65,7 @@ Item { text: qsTr("Cancel") - onClicked: root.destroy() + onClicked: root.tryDestroy() } } diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 26e90eb9a6..13462804c3 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -56,7 +56,6 @@ Item { parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y); - console.log("sign in h:", targetHeight, parent.height, form.height) } } @@ -233,7 +232,6 @@ Item { } } - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. Keyboard { raised: keyboardEnabled && keyboardRaised diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index aef20c7a61..c4056422dd 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -50,7 +50,6 @@ Item { parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + (keyboardEnabled && keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : 0); - console.log("sign up h:", parent.height, targetHeight, form.height) } } diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index 18c831b3a9..b049d7f8bb 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -122,7 +122,7 @@ Item { text: qsTr("Cancel") - onClicked: root.destroy() + onClicked: root.tryDestroy() } } diff --git a/interface/resources/qml/LoginDialog/WelcomeBody.qml b/interface/resources/qml/LoginDialog/WelcomeBody.qml index eb91956532..551ec263b7 100644 --- a/interface/resources/qml/LoginDialog/WelcomeBody.qml +++ b/interface/resources/qml/LoginDialog/WelcomeBody.qml @@ -77,7 +77,7 @@ Item { text: qsTr("Close"); - onClicked: root.destroy() + onClicked: root.tryDestroy() } } diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 78221ab6cb..6cf7394cf0 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -47,8 +47,10 @@ TabletModalWindow { } function tryDestroy() { + console.log("tryDestroy") canceled() } + Component.onDestruction: console.log("root dying") } //property int colorScheme: hifi.colorSchemes.dark @@ -81,7 +83,7 @@ TabletModalWindow { onCanceled: { if (bodyLoader.active === true) { - bodyLoader.active = false + //bodyLoader.active = false } if (gotoPreviousApp) { var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); @@ -96,13 +98,12 @@ TabletModalWindow { id: mfRoot width: root.width - height: root.height //+ frameMarginTop + height: root.height + frameMarginTop + hifi.dimensions.contentMargin.x anchors { horizontalCenter: parent.horizontalCenter verticalCenter: parent.verticalCenter } - onHeightChanged: console.log("tablet mf h:", height) LoginDialog { id: loginDialog @@ -158,45 +159,4 @@ TabletModalWindow { break } } -// LoginDialog { -// id: loginDialog -// width: parent.width -// height: parent.height -// StackView { -// id: bodyLoader -// property var item: currentItem -// property var props -// property string source: "" - -// onCurrentItemChanged: { -// //cleanup source for future usage -// source = "" -// } - -// function setSource(src, props) { -// source = "../TabletLoginDialog/" + src -// bodyLoader.props = props -// } -// function popup() { -// bodyLoader.pop() - -// //check if last screen, if yes, dialog is popped out -// if (depth === 1) -// loginDialogRoot.canceled() -// } - -// anchors.fill: parent -// anchors.margins: 10 -// onSourceChanged: { -// if (source !== "") { -// bodyLoader.push(Qt.resolvedUrl(source), props) -// } -// } -// Component.onCompleted: { -// setSource(loginDialog.isSteamRunning() ? -// "SignInBody.qml" : -// "LinkAccountBody.qml") -// } -// } -// } } From c112a3baf16f3be42fd940798ed29eaa4a762d6b Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 28 Sep 2017 15:09:49 -0700 Subject: [PATCH 18/43] Seting up of camera and avatar correctly in game loop, not in render loop --- interface/src/Application.cpp | 159 ++++++++++++++++++++++++---------- interface/src/Application.h | 3 + 2 files changed, 116 insertions(+), 46 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 596917da28..284cc5056a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2536,6 +2536,11 @@ void Application::paintGL() { glm::mat4 HMDSensorPose; glm::mat4 eyeToWorld; glm::mat4 sensorToWorld; + + bool isStereo; + glm::mat4 stereoEyeOffsets[2]; + glm::mat4 stereoEyeProjections[2]; + { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; @@ -2543,6 +2548,11 @@ void Application::paintGL() { eyeToWorld = _appRenderArgs._eyeToWorld; sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + isStereo = _appRenderArgs._isStereo; + for_each_eye([&](Eye eye) { + stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; + stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; + }); } //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); @@ -2615,57 +2625,65 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - auto hmdInterface = DependencyManager::get(); - float ipdScale = hmdInterface->getIPDScale(); + //auto hmdInterface = DependencyManager::get(); + //float ipdScale = hmdInterface->getIPDScale(); - // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - ipdScale *= sensorToWorldScale; + //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + //ipdScale *= sensorToWorldScale; { - PROFILE_RANGE(render, "/mainRender"); - PerformanceTimer perfTimer("mainRender"); - // FIXME is this ever going to be different from the size previously set in the render args - // in the overlay render? - // Viewport is assigned to the size of the framebuffer - renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - auto baseProjection = renderArgs.getViewFrustum().getProjection(); - if (displayPlugin->isStereo()) { - // Stereo modes will typically have a larger projection matrix overall, - // so we ask for the 'mono' projection matrix, which for stereo and HMD - // plugins will imply the combined projection for both eyes. - // - // This is properly implemented for the Oculus plugins, but for OpenVR - // and Stereo displays I'm not sure how to get / calculate it, so we're - // just relying on the left FOV in each case and hoping that the - // overall culling margin of error doesn't cause popping in the - // right eye. There are FIXMEs in the relevant plugins - _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + //PROFILE_RANGE(render, "/mainRender"); + //PerformanceTimer perfTimer("mainRender"); + //// FIXME is this ever going to be different from the size previously set in the render args + //// in the overlay render? + //// Viewport is assigned to the size of the framebuffer + //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + //auto baseProjection = renderArgs.getViewFrustum().getProjection(); + //if (displayPlugin->isStereo()) { + // // Stereo modes will typically have a larger projection matrix overall, + // // so we ask for the 'mono' projection matrix, which for stereo and HMD + // // plugins will imply the combined projection for both eyes. + // // + // // This is properly implemented for the Oculus plugins, but for OpenVR + // // and Stereo displays I'm not sure how to get / calculate it, so we're + // // just relying on the left FOV in each case and hoping that the + // // overall culling margin of error doesn't cause popping in the + // // right eye. There are FIXMEs in the relevant plugins + // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + // renderArgs._context->enableStereo(true); + // mat4 eyeOffsets[2]; + // mat4 eyeProjections[2]; + + // // FIXME we probably don't need to set the projection matrix every frame, + // // only when the display plugin changes (or in non-HMD modes when the user + // // changes the FOV manually, which right now I don't think they can. + // for_each_eye([&](Eye eye) { + // // For providing the stereo eye views, the HMD head pose has already been + // // applied to the avatar, so we need to get the difference between the head + // // pose applied to the avatar and the per eye pose, and use THAT as + // // the per-eye stereo matrix adjustment. + // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // // Grab the translation + // vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // // Apply IPD scaling + // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + // eyeOffsets[eye] = eyeOffsetTransform; + // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + // }); + // renderArgs._context->setStereoProjections(eyeProjections); + // renderArgs._context->setStereoViews(eyeOffsets); + + // // Configure the type of display / stereo + // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + //} + + if (isStereo) { renderArgs._context->enableStereo(true); - mat4 eyeOffsets[2]; - mat4 eyeProjections[2]; - - // FIXME we probably don't need to set the projection matrix every frame, - // only when the display plugin changes (or in non-HMD modes when the user - // changes the FOV manually, which right now I don't think they can. - for_each_eye([&](Eye eye) { - // For providing the stereo eye views, the HMD head pose has already been - // applied to the avatar, so we need to get the difference between the head - // pose applied to the avatar and the per eye pose, and use THAT as - // the per-eye stereo matrix adjustment. - mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // Grab the translation - vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // Apply IPD scaling - mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - eyeOffsets[eye] = eyeOffsetTransform; - eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - }); - renderArgs._context->setStereoProjections(eyeProjections); - renderArgs._context->setStereoViews(eyeOffsets); - - // Configure the type of display / stereo - renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + // renderArgs._displayMode } + renderArgs._blitFramebuffer = finalFramebuffer; // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); @@ -5320,7 +5338,55 @@ void Application::update(float deltaTime) { } this->updateCamera(appRenderArgs._renderArgs); + appRenderArgs._isStereo = false; + { + auto hmdInterface = DependencyManager::get(); + float ipdScale = hmdInterface->getIPDScale(); + + // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + ipdScale *= sensorToWorldScale; + + auto baseProjection = appRenderArgs._renderArgs.getViewFrustum().getProjection(); + if (getActiveDisplayPlugin()->isStereo()) { + // Stereo modes will typically have a larger projection matrix overall, + // so we ask for the 'mono' projection matrix, which for stereo and HMD + // plugins will imply the combined projection for both eyes. + // + // This is properly implemented for the Oculus plugins, but for OpenVR + // and Stereo displays I'm not sure how to get / calculate it, so we're + // just relying on the left FOV in each case and hoping that the + // overall culling margin of error doesn't cause popping in the + // right eye. There are FIXMEs in the relevant plugins + _myCamera.setProjection(getActiveDisplayPlugin()->getCullingProjection(baseProjection)); + appRenderArgs._isStereo = true; + + auto& eyeOffsets = appRenderArgs._eyeOffsets; + auto& eyeProjections = appRenderArgs._eyeProjections; + + // FIXME we probably don't need to set the projection matrix every frame, + // only when the display plugin changes (or in non-HMD modes when the user + // changes the FOV manually, which right now I don't think they can. + for_each_eye([&](Eye eye) { + // For providing the stereo eye views, the HMD head pose has already been + // applied to the avatar, so we need to get the difference between the head + // pose applied to the avatar and the per eye pose, and use THAT as + // the per-eye stereo matrix adjustment. + mat4 eyeToHead = getActiveDisplayPlugin()->getEyeToHeadTransform(eye); + // Grab the translation + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + eyeOffsets[eye] = eyeOffsetTransform; + eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection); + }); + //renderArgs._context->setStereoProjections(eyeProjections); + //renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + } + } // HACK // load the view frustum @@ -5332,6 +5398,7 @@ void Application::update(float deltaTime) { QMutexLocker viewLocker(&_viewMutex); _myCamera.loadViewFrustum(_displayViewFrustum); } + { QMutexLocker viewLocker(&_viewMutex); appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); diff --git a/interface/src/Application.h b/interface/src/Application.h index 377a31fb2c..3f4c55999e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -626,9 +626,12 @@ private: struct AppRenderArgs { render::Args _renderArgs; glm::mat4 _eyeToWorld; + glm::mat4 _eyeOffsets[2]; + glm::mat4 _eyeProjections[2]; glm::mat4 _headPose; glm::mat4 _sensorToWorld; float _sensorToWorldScale { 1.0f }; + bool _isStereo{ false }; }; AppRenderArgs _appRenderArgs; From e637842f8afbf126c6fb1113d1c1976551e2210c Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 28 Sep 2017 17:45:50 -0700 Subject: [PATCH 19/43] Separating some of the code sepecific to render in its own cpp --- interface/src/Application_render.cpp | 320 +++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 interface/src/Application_render.cpp diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp new file mode 100644 index 0000000000..ee3267284a --- /dev/null +++ b/interface/src/Application_render.cpp @@ -0,0 +1,320 @@ +// +// Application_render.cpp +// interface/src +// +// Copyright 2013 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 +// + +#ifdef tryingSOmething + +void Application::paintGL() { + // Some plugins process message events, allowing paintGL to be called reentrantly. + if (_aboutToQuit || _window->isMinimized()) { + return; + } + + _frameCount++; + _lastTimeRendered.start(); + + auto lastPaintBegin = usecTimestampNow(); + PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); + PerformanceTimer perfTimer("paintGL"); + + if (nullptr == _displayPlugin) { + return; + } + + DisplayPluginPointer displayPlugin; + { + PROFILE_RANGE(render, "/getActiveDisplayPlugin"); + displayPlugin = getActiveDisplayPlugin(); + } + + { + PROFILE_RANGE(render, "/pluginBeginFrameRender"); + // If a display plugin loses it's underlying support, it + // needs to be able to signal us to not use it + if (!displayPlugin->beginFrameRender(_frameCount)) { + updateDisplayMode(); + return; + } + } + + // update the avatar with a fresh HMD pose + // { + // PROFILE_RANGE(render, "/updateAvatar"); + // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); + // } + + // auto lodManager = DependencyManager::get(); + + RenderArgs renderArgs; + float sensorToWorldScale; + glm::mat4 HMDSensorPose; + { + QMutexLocker viewLocker(&_renderArgsMutex); + renderArgs = _appRenderArgs._renderArgs; + HMDSensorPose = _appRenderArgs._eyeToWorld; + sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + } + /* + float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + { + PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + { + QMutexLocker viewLocker(&_viewMutex); + // adjust near clip plane to account for sensor scaling. + auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + _viewFrustum.getAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + _viewFrustum.getFarClip()); + _viewFrustum.setProjection(adjustedProjection); + _viewFrustum.calculate(); + } + renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs.setViewFrustum(_viewFrustum); + } + } + */ + { + PROFILE_RANGE(render, "/resizeGL"); + PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::paintGL()"); + resizeGL(); + } + + { + PROFILE_RANGE(render, "/gpuContextReset"); + // _gpuContext->beginFrame(getHMDSensorPose()); + _gpuContext->beginFrame(HMDSensorPose); + // Reset the gpu::Context Stages + // Back to the default framebuffer; + gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { + batch.resetStages(); + }); + } + + + { + PROFILE_RANGE(render, "/renderOverlay"); + PerformanceTimer perfTimer("renderOverlay"); + // NOTE: There is no batch associated with this renderArgs + // the ApplicationOverlay class assumes it's viewport is setup to be the device size + QSize size = getDeviceSize(); + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); + _applicationOverlay.renderOverlay(&renderArgs); + } + + // updateCamera(renderArgs); + + /* glm::vec3 boomOffset; + { + PROFILE_RANGE(render, "/updateCamera"); + { + PerformanceTimer perfTimer("CameraUpdates"); + + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glmExtractRotation(camMat)); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); + } + } + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } + } + } + */ + { + PROFILE_RANGE(render, "/updateCompositor"); + getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + } + + gpu::FramebufferPointer finalFramebuffer; + QSize finalFramebufferSize; + { + PROFILE_RANGE(render, "/getOutputFramebuffer"); + // Primary rendering pass + auto framebufferCache = DependencyManager::get(); + finalFramebufferSize = framebufferCache->getFrameBufferSize(); + // Final framebuffer that will be handled to the display-plugin + finalFramebuffer = framebufferCache->getFramebuffer(); + } + + auto hmdInterface = DependencyManager::get(); + float ipdScale = hmdInterface->getIPDScale(); + + // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + ipdScale *= sensorToWorldScale; + + { + PROFILE_RANGE(render, "/mainRender"); + PerformanceTimer perfTimer("mainRender"); + // FIXME is this ever going to be different from the size previously set in the render args + // in the overlay render? + // Viewport is assigned to the size of the framebuffer + renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + auto baseProjection = renderArgs.getViewFrustum().getProjection(); + if (displayPlugin->isStereo()) { + // Stereo modes will typically have a larger projection matrix overall, + // so we ask for the 'mono' projection matrix, which for stereo and HMD + // plugins will imply the combined projection for both eyes. + // + // This is properly implemented for the Oculus plugins, but for OpenVR + // and Stereo displays I'm not sure how to get / calculate it, so we're + // just relying on the left FOV in each case and hoping that the + // overall culling margin of error doesn't cause popping in the + // right eye. There are FIXMEs in the relevant plugins + _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + renderArgs._context->enableStereo(true); + mat4 eyeOffsets[2]; + mat4 eyeProjections[2]; + + // FIXME we probably don't need to set the projection matrix every frame, + // only when the display plugin changes (or in non-HMD modes when the user + // changes the FOV manually, which right now I don't think they can. + for_each_eye([&](Eye eye) { + // For providing the stereo eye views, the HMD head pose has already been + // applied to the avatar, so we need to get the difference between the head + // pose applied to the avatar and the per eye pose, and use THAT as + // the per-eye stereo matrix adjustment. + mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // Grab the translation + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + eyeOffsets[eye] = eyeOffsetTransform; + eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + }); + renderArgs._context->setStereoProjections(eyeProjections); + renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + } + renderArgs._blitFramebuffer = finalFramebuffer; + // displaySide(&renderArgs, _myCamera); + runRenderFrame(&renderArgs); + } + + gpu::Batch postCompositeBatch; + { + PROFILE_RANGE(render, "/postComposite"); + PerformanceTimer perfTimer("postComposite"); + renderArgs._batch = &postCompositeBatch; + renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); + renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); + _overlays.render3DHUDOverlays(&renderArgs); + } + + auto frame = _gpuContext->endFrame(); + frame->frameIndex = _frameCount; + frame->framebuffer = finalFramebuffer; + frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { + DependencyManager::get()->releaseFramebuffer(framebuffer); + }; + frame->overlay = _applicationOverlay.getOverlayTexture(); + frame->postCompositeBatch = postCompositeBatch; + // deliver final scene rendering commands to the display plugin + { + PROFILE_RANGE(render, "/pluginOutput"); + PerformanceTimer perfTimer("pluginOutput"); + _frameCounter.increment(); + displayPlugin->submitFrame(frame); + } + + // Reset the framebuffer and stereo state + renderArgs._blitFramebuffer.reset(); + renderArgs._context->enableStereo(false); + + { + Stats::getInstance()->setRenderDetails(renderArgs._details); + } + + uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; + _frameTimingsScriptingInterface.addValue(lastPaintDuration); +} +#endif \ No newline at end of file From d3cd034d614cc9285baf4ca7bb975c721ba07ae9 Mon Sep 17 00:00:00 2001 From: vladest Date: Fri, 29 Sep 2017 16:33:52 +0200 Subject: [PATCH 20/43] Cleanup --- interface/resources/qml/dialogs/TabletLoginDialog.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 6cf7394cf0..f4f7a5848c 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -47,10 +47,8 @@ TabletModalWindow { } function tryDestroy() { - console.log("tryDestroy") canceled() } - Component.onDestruction: console.log("root dying") } //property int colorScheme: hifi.colorSchemes.dark From 577378f5392ee1e37f9da71abf3755e4157711cd Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 29 Sep 2017 17:45:10 -0700 Subject: [PATCH 21/43] Adding stuff that seems to break? --- interface/src/Application.cpp | 3 ++ libraries/render/src/render/Scene.cpp | 60 +++++++++++++++++++-------- libraries/render/src/render/Scene.h | 12 ++++++ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 218c1eb5eb..5bf5f52a53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5400,6 +5400,9 @@ void Application::update(float deltaTime) { AnimDebugDraw::getInstance().update(); DependencyManager::get()->update(); + + // Game loopis done, mark the end of the frame for the scene transactions + getMain3DScene()->enqueueFrame(); } void Application::sendAvatarViewFrustum() { diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index d2d3ad6de6..714be2a8c6 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -15,9 +15,6 @@ #include "Logging.h" #include "TransitionStage.h" -// Comment this to disable transitions (fades) -#define SCENE_ENABLE_TRANSITIONS - using namespace render; void Transaction::resetItem(ItemID id, const PayloadPointer& payload) { @@ -101,16 +98,46 @@ void consolidateTransaction(TransactionQueue& queue, Transaction& singleBatch) { queue.pop(); }; } - -void Scene::processTransactionQueue() { + +uint32_t Scene::enqueueFrame() { PROFILE_RANGE(render, __FUNCTION__); Transaction consolidatedTransaction; - { std::unique_lock lock(_transactionQueueMutex); consolidateTransaction(_transactionQueue, consolidatedTransaction); } - + + uint32_t frameNumber = 0; + { + std::unique_lock lock(_transactionFramesMutex); + _transactionFrames.push_back(consolidatedTransaction); + _transactionFrameNumber++; + frameNumber = _transactionFrameNumber; + } + + return frameNumber; +} + + +void Scene::processTransactionQueue() { + PROFILE_RANGE(render, __FUNCTION__); + + TransactionFrames queuedFrames; + { + // capture the queued frames and clear the queue + std::unique_lock lock(_transactionFramesMutex); + queuedFrames = _transactionFrames; + _transactionFrames.clear(); + } + + // go through the queue of frames and process them + for (auto& frame : queuedFrames) { + processTransactionFrame(frame); + } +} + +void Scene::processTransactionFrame(const Transaction& transaction) { + PROFILE_RANGE(render, __FUNCTION__); { std::unique_lock lock(_itemsMutex); // Here we should be able to check the value of last ItemID allocated @@ -123,32 +150,31 @@ void Scene::processTransactionQueue() { // capture anything coming from the transaction // resets and potential NEW items - resetItems(consolidatedTransaction._resetItems); + resetItems(transaction._resetItems); // Update the numItemsAtomic counter AFTER the reset changes went through _numAllocatedItems.exchange(maxID); // updates - updateItems(consolidatedTransaction._updatedItems); + updateItems(transaction._updatedItems); // removes - removeItems(consolidatedTransaction._removedItems); + removeItems(transaction._removedItems); -#ifdef SCENE_ENABLE_TRANSITIONS // add transitions - transitionItems(consolidatedTransaction._addedTransitions); - reApplyTransitions(consolidatedTransaction._reAppliedTransitions); - queryTransitionItems(consolidatedTransaction._queriedTransitions); -#endif + transitionItems(transaction._addedTransitions); + reApplyTransitions(transaction._reAppliedTransitions); + queryTransitionItems(transaction._queriedTransitions); + // Update the numItemsAtomic counter AFTER the pending changes went through _numAllocatedItems.exchange(maxID); } - if (consolidatedTransaction.touchTransactions()) { + if (transaction.touchTransactions()) { std::unique_lock lock(_selectionsMutex); // resets and potential NEW items - resetSelections(consolidatedTransaction._resetSelections); + resetSelections(transaction._resetSelections); } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 3b61a20f24..fef2077897 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -117,6 +117,9 @@ public: // Enqueue transaction to the scene void enqueueTransaction(const Transaction& transaction); + // Enqueue end of frame transactions boundary + uint32_t enqueueFrame(); + // Process the pending transactions queued void processTransactionQueue(); @@ -162,6 +165,15 @@ protected: std::mutex _transactionQueueMutex; TransactionQueue _transactionQueue; + + std::mutex _transactionFramesMutex; + using TransactionFrames = std::list; + TransactionFrames _transactionFrames; + uint32_t _transactionFrameNumber{ 0 }; + + // Process one transaction frame + void processTransactionFrame(const Transaction& transaction); + // The actual database // database of items is protected for editing by a mutex std::mutex _itemsMutex; From 44cc6deac227b738fa91ae56418004723421b8f6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 12:55:44 -0700 Subject: [PATCH 22/43] moving render specific code from Application.cpp to Application_render.cpp --- interface/src/Application.cpp | 678 +++++++++++++-------------- interface/src/Application_render.cpp | 388 ++++++++------- 2 files changed, 553 insertions(+), 513 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5bf5f52a53..5ce63441aa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2483,249 +2483,249 @@ void Application::updateCamera(RenderArgs& renderArgs) { renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } - -void Application::editRenderArgs(RenderArgsEditor editor) { - QMutexLocker renderLocker(&_renderArgsMutex); - editor(_appRenderArgs); - -} - -void Application::paintGL() { - // Some plugins process message events, allowing paintGL to be called reentrantly. - if (_aboutToQuit || _window->isMinimized()) { - return; - } - - _frameCount++; - _lastTimeRendered.start(); - - auto lastPaintBegin = usecTimestampNow(); - PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); - PerformanceTimer perfTimer("paintGL"); - - if (nullptr == _displayPlugin) { - return; - } - - DisplayPluginPointer displayPlugin; - { - PROFILE_RANGE(render, "/getActiveDisplayPlugin"); - displayPlugin = getActiveDisplayPlugin(); - } - - { - PROFILE_RANGE(render, "/pluginBeginFrameRender"); - // If a display plugin loses it's underlying support, it - // needs to be able to signal us to not use it - if (!displayPlugin->beginFrameRender(_frameCount)) { - updateDisplayMode(); - return; - } - } - - // update the avatar with a fresh HMD pose - // { - // PROFILE_RANGE(render, "/updateAvatar"); - // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - // } - - // auto lodManager = DependencyManager::get(); - - RenderArgs renderArgs; - float sensorToWorldScale; - glm::mat4 HMDSensorPose; - glm::mat4 eyeToWorld; - glm::mat4 sensorToWorld; - - bool isStereo; - glm::mat4 stereoEyeOffsets[2]; - glm::mat4 stereoEyeProjections[2]; - - { - QMutexLocker viewLocker(&_renderArgsMutex); - renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._headPose; - eyeToWorld = _appRenderArgs._eyeToWorld; - sensorToWorld = _appRenderArgs._sensorToWorld; - sensorToWorldScale = _appRenderArgs._sensorToWorldScale; - isStereo = _appRenderArgs._isStereo; - for_each_eye([&](Eye eye) { - stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; - stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; - }); - } - - //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - //{ - // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - // { - // QMutexLocker viewLocker(&_viewMutex); - // // adjust near clip plane to account for sensor scaling. - // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - // _viewFrustum.getAspectRatio(), - // DEFAULT_NEAR_CLIP * sensorToWorldScale, - // _viewFrustum.getFarClip()); - // _viewFrustum.setProjection(adjustedProjection); - // _viewFrustum.calculate(); - // } - // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - // { - // QMutexLocker viewLocker(&_viewMutex); - // renderArgs.setViewFrustum(_viewFrustum); - // } - //} - - //{ - // PROFILE_RANGE(render, "/resizeGL"); - // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - // PerformanceWarning warn(showWarnings, "Application::paintGL()"); - // resizeGL(); - //} - - { - PROFILE_RANGE(render, "/gpuContextReset"); - // _gpuContext->beginFrame(getHMDSensorPose()); - _gpuContext->beginFrame(HMDSensorPose); - // Reset the gpu::Context Stages - // Back to the default framebuffer; - gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { - batch.resetStages(); - }); - } - - - { - PROFILE_RANGE(render, "/renderOverlay"); - PerformanceTimer perfTimer("renderOverlay"); - // NOTE: There is no batch associated with this renderArgs - // the ApplicationOverlay class assumes it's viewport is setup to be the device size - QSize size = getDeviceSize(); - renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); - _applicationOverlay.renderOverlay(&renderArgs); - } - - // updateCamera(renderArgs); - { - PROFILE_RANGE(render, "/updateCompositor"); - // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); - getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); - } - - gpu::FramebufferPointer finalFramebuffer; - QSize finalFramebufferSize; - { - PROFILE_RANGE(render, "/getOutputFramebuffer"); - // Primary rendering pass - auto framebufferCache = DependencyManager::get(); - finalFramebufferSize = framebufferCache->getFrameBufferSize(); - // Final framebuffer that will be handled to the display-plugin - finalFramebuffer = framebufferCache->getFramebuffer(); - } - - //auto hmdInterface = DependencyManager::get(); - //float ipdScale = hmdInterface->getIPDScale(); - - //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - //ipdScale *= sensorToWorldScale; - - { - //PROFILE_RANGE(render, "/mainRender"); - //PerformanceTimer perfTimer("mainRender"); - //// FIXME is this ever going to be different from the size previously set in the render args - //// in the overlay render? - //// Viewport is assigned to the size of the framebuffer - //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - //auto baseProjection = renderArgs.getViewFrustum().getProjection(); - //if (displayPlugin->isStereo()) { - // // Stereo modes will typically have a larger projection matrix overall, - // // so we ask for the 'mono' projection matrix, which for stereo and HMD - // // plugins will imply the combined projection for both eyes. - // // - // // This is properly implemented for the Oculus plugins, but for OpenVR - // // and Stereo displays I'm not sure how to get / calculate it, so we're - // // just relying on the left FOV in each case and hoping that the - // // overall culling margin of error doesn't cause popping in the - // // right eye. There are FIXMEs in the relevant plugins - // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); - // renderArgs._context->enableStereo(true); - // mat4 eyeOffsets[2]; - // mat4 eyeProjections[2]; - - // // FIXME we probably don't need to set the projection matrix every frame, - // // only when the display plugin changes (or in non-HMD modes when the user - // // changes the FOV manually, which right now I don't think they can. - // for_each_eye([&](Eye eye) { - // // For providing the stereo eye views, the HMD head pose has already been - // // applied to the avatar, so we need to get the difference between the head - // // pose applied to the avatar and the per eye pose, and use THAT as - // // the per-eye stereo matrix adjustment. - // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // // Grab the translation - // vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // // Apply IPD scaling - // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - // eyeOffsets[eye] = eyeOffsetTransform; - // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - // }); - // renderArgs._context->setStereoProjections(eyeProjections); - // renderArgs._context->setStereoViews(eyeOffsets); - - // // Configure the type of display / stereo - // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); - //} - - if (isStereo) { - renderArgs._context->enableStereo(true); - renderArgs._context->setStereoProjections(stereoEyeProjections); - renderArgs._context->setStereoViews(stereoEyeOffsets); - // renderArgs._displayMode - } - - renderArgs._blitFramebuffer = finalFramebuffer; - // displaySide(&renderArgs, _myCamera); - runRenderFrame(&renderArgs); - } - - gpu::Batch postCompositeBatch; - { - PROFILE_RANGE(render, "/postComposite"); - PerformanceTimer perfTimer("postComposite"); - renderArgs._batch = &postCompositeBatch; - renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); - renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); - _overlays.render3DHUDOverlays(&renderArgs); - } - - auto frame = _gpuContext->endFrame(); - frame->frameIndex = _frameCount; - frame->framebuffer = finalFramebuffer; - frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ - DependencyManager::get()->releaseFramebuffer(framebuffer); - }; - frame->overlay = _applicationOverlay.getOverlayTexture(); - frame->postCompositeBatch = postCompositeBatch; - // deliver final scene rendering commands to the display plugin - { - PROFILE_RANGE(render, "/pluginOutput"); - PerformanceTimer perfTimer("pluginOutput"); - _frameCounter.increment(); - displayPlugin->submitFrame(frame); - } - - // Reset the framebuffer and stereo state - renderArgs._blitFramebuffer.reset(); - renderArgs._context->enableStereo(false); - - { - Stats::getInstance()->setRenderDetails(renderArgs._details); - } - - uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; - _frameTimingsScriptingInterface.addValue(lastPaintDuration); -} +// +//void Application::editRenderArgs(RenderArgsEditor editor) { +// QMutexLocker renderLocker(&_renderArgsMutex); +// editor(_appRenderArgs); +// +//} +// +//void Application::paintGL() { +// // Some plugins process message events, allowing paintGL to be called reentrantly. +// if (_aboutToQuit || _window->isMinimized()) { +// return; +// } +// +// _frameCount++; +// _lastTimeRendered.start(); +// +// auto lastPaintBegin = usecTimestampNow(); +// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); +// PerformanceTimer perfTimer("paintGL"); +// +// if (nullptr == _displayPlugin) { +// return; +// } +// +// DisplayPluginPointer displayPlugin; +// { +// PROFILE_RANGE(render, "/getActiveDisplayPlugin"); +// displayPlugin = getActiveDisplayPlugin(); +// } +// +// { +// PROFILE_RANGE(render, "/pluginBeginFrameRender"); +// // If a display plugin loses it's underlying support, it +// // needs to be able to signal us to not use it +// if (!displayPlugin->beginFrameRender(_frameCount)) { +// updateDisplayMode(); +// return; +// } +// } +// +// // update the avatar with a fresh HMD pose +// // { +// // PROFILE_RANGE(render, "/updateAvatar"); +// // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); +// // } +// +// // auto lodManager = DependencyManager::get(); +// +// RenderArgs renderArgs; +// float sensorToWorldScale; +// glm::mat4 HMDSensorPose; +// glm::mat4 eyeToWorld; +// glm::mat4 sensorToWorld; +// +// bool isStereo; +// glm::mat4 stereoEyeOffsets[2]; +// glm::mat4 stereoEyeProjections[2]; +// +// { +// QMutexLocker viewLocker(&_renderArgsMutex); +// renderArgs = _appRenderArgs._renderArgs; +// HMDSensorPose = _appRenderArgs._headPose; +// eyeToWorld = _appRenderArgs._eyeToWorld; +// sensorToWorld = _appRenderArgs._sensorToWorld; +// sensorToWorldScale = _appRenderArgs._sensorToWorldScale; +// isStereo = _appRenderArgs._isStereo; +// for_each_eye([&](Eye eye) { +// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; +// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; +// }); +// } +// +// //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); +// //{ +// // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // // adjust near clip plane to account for sensor scaling. +// // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), +// // _viewFrustum.getAspectRatio(), +// // DEFAULT_NEAR_CLIP * sensorToWorldScale, +// // _viewFrustum.getFarClip()); +// // _viewFrustum.setProjection(adjustedProjection); +// // _viewFrustum.calculate(); +// // } +// // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), +// // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, +// // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // renderArgs.setViewFrustum(_viewFrustum); +// // } +// //} +// +// //{ +// // PROFILE_RANGE(render, "/resizeGL"); +// // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); +// // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); +// // PerformanceWarning warn(showWarnings, "Application::paintGL()"); +// // resizeGL(); +// //} +// +// { +// PROFILE_RANGE(render, "/gpuContextReset"); +// // _gpuContext->beginFrame(getHMDSensorPose()); +// _gpuContext->beginFrame(HMDSensorPose); +// // Reset the gpu::Context Stages +// // Back to the default framebuffer; +// gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { +// batch.resetStages(); +// }); +// } +// +// +// { +// PROFILE_RANGE(render, "/renderOverlay"); +// PerformanceTimer perfTimer("renderOverlay"); +// // NOTE: There is no batch associated with this renderArgs +// // the ApplicationOverlay class assumes it's viewport is setup to be the device size +// QSize size = getDeviceSize(); +// renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); +// _applicationOverlay.renderOverlay(&renderArgs); +// } +// +// // updateCamera(renderArgs); +// { +// PROFILE_RANGE(render, "/updateCompositor"); +// // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); +// getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); +// } +// +// gpu::FramebufferPointer finalFramebuffer; +// QSize finalFramebufferSize; +// { +// PROFILE_RANGE(render, "/getOutputFramebuffer"); +// // Primary rendering pass +// auto framebufferCache = DependencyManager::get(); +// finalFramebufferSize = framebufferCache->getFrameBufferSize(); +// // Final framebuffer that will be handled to the display-plugin +// finalFramebuffer = framebufferCache->getFramebuffer(); +// } +// +// //auto hmdInterface = DependencyManager::get(); +// //float ipdScale = hmdInterface->getIPDScale(); +// +// //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. +// //ipdScale *= sensorToWorldScale; +// +// { +// //PROFILE_RANGE(render, "/mainRender"); +// //PerformanceTimer perfTimer("mainRender"); +// //// FIXME is this ever going to be different from the size previously set in the render args +// //// in the overlay render? +// //// Viewport is assigned to the size of the framebuffer +// //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); +// //auto baseProjection = renderArgs.getViewFrustum().getProjection(); +// //if (displayPlugin->isStereo()) { +// // // Stereo modes will typically have a larger projection matrix overall, +// // // so we ask for the 'mono' projection matrix, which for stereo and HMD +// // // plugins will imply the combined projection for both eyes. +// // // +// // // This is properly implemented for the Oculus plugins, but for OpenVR +// // // and Stereo displays I'm not sure how to get / calculate it, so we're +// // // just relying on the left FOV in each case and hoping that the +// // // overall culling margin of error doesn't cause popping in the +// // // right eye. There are FIXMEs in the relevant plugins +// // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); +// // renderArgs._context->enableStereo(true); +// // mat4 eyeOffsets[2]; +// // mat4 eyeProjections[2]; +// +// // // FIXME we probably don't need to set the projection matrix every frame, +// // // only when the display plugin changes (or in non-HMD modes when the user +// // // changes the FOV manually, which right now I don't think they can. +// // for_each_eye([&](Eye eye) { +// // // For providing the stereo eye views, the HMD head pose has already been +// // // applied to the avatar, so we need to get the difference between the head +// // // pose applied to the avatar and the per eye pose, and use THAT as +// // // the per-eye stereo matrix adjustment. +// // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); +// // // Grab the translation +// // vec3 eyeOffset = glm::vec3(eyeToHead[3]); +// // // Apply IPD scaling +// // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); +// // eyeOffsets[eye] = eyeOffsetTransform; +// // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); +// // }); +// // renderArgs._context->setStereoProjections(eyeProjections); +// // renderArgs._context->setStereoViews(eyeOffsets); +// +// // // Configure the type of display / stereo +// // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); +// //} +// +// if (isStereo) { +// renderArgs._context->enableStereo(true); +// renderArgs._context->setStereoProjections(stereoEyeProjections); +// renderArgs._context->setStereoViews(stereoEyeOffsets); +// // renderArgs._displayMode +// } +// +// renderArgs._blitFramebuffer = finalFramebuffer; +// // displaySide(&renderArgs, _myCamera); +// runRenderFrame(&renderArgs); +// } +// +// gpu::Batch postCompositeBatch; +// { +// PROFILE_RANGE(render, "/postComposite"); +// PerformanceTimer perfTimer("postComposite"); +// renderArgs._batch = &postCompositeBatch; +// renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); +// renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); +// _overlays.render3DHUDOverlays(&renderArgs); +// } +// +// auto frame = _gpuContext->endFrame(); +// frame->frameIndex = _frameCount; +// frame->framebuffer = finalFramebuffer; +// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ +// DependencyManager::get()->releaseFramebuffer(framebuffer); +// }; +// frame->overlay = _applicationOverlay.getOverlayTexture(); +// frame->postCompositeBatch = postCompositeBatch; +// // deliver final scene rendering commands to the display plugin +// { +// PROFILE_RANGE(render, "/pluginOutput"); +// PerformanceTimer perfTimer("pluginOutput"); +// _frameCounter.increment(); +// displayPlugin->submitFrame(frame); +// } +// +// // Reset the framebuffer and stereo state +// renderArgs._blitFramebuffer.reset(); +// renderArgs._context->enableStereo(false); +// +// { +// Stats::getInstance()->setRenderDetails(renderArgs._details); +// } +// +// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; +// _frameTimingsScriptingInterface.addValue(lastPaintDuration); +//} void Application::runTests() { runTimingTests(); @@ -5401,7 +5401,7 @@ void Application::update(float deltaTime) { DependencyManager::get()->update(); - // Game loopis done, mark the end of the frame for the scene transactions + // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over getMain3DScene()->enqueueFrame(); } @@ -5692,101 +5692,101 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -// WorldBox Render Data & rendering functions - -class WorldBoxRenderData { -public: - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - int _val = 0; - static render::ItemID _item; // unique WorldBoxRenderData -}; - -render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; - -namespace render { - template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } - template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } - template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { - if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { - PerformanceTimer perfTimer("worldBox"); - - auto& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch); - renderWorldBox(args, batch); - } - } -} - -void Application::runRenderFrame(RenderArgs* renderArgs) { - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - // auto myAvatar = getMyAvatar(); - // myAvatar->preDisplaySide(renderArgs); - - PROFILE_RANGE(render, __FUNCTION__); - PerformanceTimer perfTimer("display"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - - // load the view frustum - // { - // QMutexLocker viewLocker(&_viewMutex); - // theCamera.loadViewFrustum(_displayViewFrustum); - // } - - // The pending changes collecting the changes here - render::Transaction transaction; - - // Assuming nothing gets rendered through that - //if (!selfAvatarOnly) { - { - if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - PerformanceTimer perfTimer("entities"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::runRenderFrame() ... entities..."); - - RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - - if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { - renderDebugFlags = static_cast(renderDebugFlags | - static_cast(RenderArgs::RENDER_DEBUG_HULLS)); - } - renderArgs->_debugFlags = renderDebugFlags; - } - } - - // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities - // Make sure the WorldBox is in the scene - if (!render::Item::isValidID(WorldBoxRenderData::_item)) { - auto worldBoxRenderData = make_shared(); - auto worldBoxRenderPayload = make_shared(worldBoxRenderData); - - WorldBoxRenderData::_item = _main3DScene->allocateID(); - - transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); - _main3DScene->enqueueTransaction(transaction); - } - - - // For now every frame pass the renderContext - { - PerformanceTimer perfTimer("EngineRun"); - - /* { - QMutexLocker viewLocker(&_viewMutex); - renderArgs->setViewFrustum(_displayViewFrustum); - }*/ - // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK - renderArgs->_scene = getMain3DScene(); - _renderEngine->getRenderContext()->args = renderArgs; - - // Before the deferred pass, let's try to use the render engine - _renderEngine->run(); - } -} +//// WorldBox Render Data & rendering functions +// +//class WorldBoxRenderData { +//public: +// typedef render::Payload Payload; +// typedef Payload::DataPointer Pointer; +// +// int _val = 0; +// static render::ItemID _item; // unique WorldBoxRenderData +//}; +// +//render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; +// +//namespace render { +// template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } +// template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } +// template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { +// if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { +// PerformanceTimer perfTimer("worldBox"); +// +// auto& batch = *args->_batch; +// DependencyManager::get()->bindSimpleProgram(batch); +// renderWorldBox(args, batch); +// } +// } +//} +// +//void Application::runRenderFrame(RenderArgs* renderArgs) { +// +// // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. +// // Then we can move this logic into the Avatar::simulate call. +// // auto myAvatar = getMyAvatar(); +// // myAvatar->preDisplaySide(renderArgs); +// +// PROFILE_RANGE(render, __FUNCTION__); +// PerformanceTimer perfTimer("display"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); +// +// // load the view frustum +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // theCamera.loadViewFrustum(_displayViewFrustum); +// // } +// +// // The pending changes collecting the changes here +// render::Transaction transaction; +// +// // Assuming nothing gets rendered through that +// //if (!selfAvatarOnly) { +// { +// if (DependencyManager::get()->shouldRenderEntities()) { +// // render models... +// PerformanceTimer perfTimer("entities"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), +// "Application::runRenderFrame() ... entities..."); +// +// RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; +// +// if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { +// renderDebugFlags = static_cast(renderDebugFlags | +// static_cast(RenderArgs::RENDER_DEBUG_HULLS)); +// } +// renderArgs->_debugFlags = renderDebugFlags; +// } +// } +// +// // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities +// // Make sure the WorldBox is in the scene +// if (!render::Item::isValidID(WorldBoxRenderData::_item)) { +// auto worldBoxRenderData = make_shared(); +// auto worldBoxRenderPayload = make_shared(worldBoxRenderData); +// +// WorldBoxRenderData::_item = _main3DScene->allocateID(); +// +// transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); +// _main3DScene->enqueueTransaction(transaction); +// } +// +// +// // For now every frame pass the renderContext +// { +// PerformanceTimer perfTimer("EngineRun"); +// +// /* { +// QMutexLocker viewLocker(&_viewMutex); +// renderArgs->setViewFrustum(_displayViewFrustum); +// }*/ +// // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK +// renderArgs->_scene = getMain3DScene(); +// _renderEngine->getRenderContext()->args = renderArgs; +// +// // Before the deferred pass, let's try to use the render engine +// _renderEngine->run(); +// } +//} void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index ee3267284a..51d55a2bd8 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -8,7 +8,22 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifdef tryingSOmething +#include "Application.h" +#include + +#include +#include +#include "ui/Stats.h" +#include "FrameTimingsScriptingInterface.h" + +// Statically provided display and input plugins +extern DisplayPluginList getDisplayPlugins(); + +void Application::editRenderArgs(RenderArgsEditor editor) { + QMutexLocker renderLocker(&_renderArgsMutex); + editor(_appRenderArgs); + +} void Application::paintGL() { // Some plugins process message events, allowing paintGL to be called reentrantly. @@ -54,42 +69,56 @@ void Application::paintGL() { RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; + glm::mat4 eyeToWorld; + glm::mat4 sensorToWorld; + + bool isStereo; + glm::mat4 stereoEyeOffsets[2]; + glm::mat4 stereoEyeProjections[2]; + { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._eyeToWorld; + HMDSensorPose = _appRenderArgs._headPose; + eyeToWorld = _appRenderArgs._eyeToWorld; + sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + isStereo = _appRenderArgs._isStereo; + for_each_eye([&](Eye eye) { + stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; + stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; + }); } - /* - float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - { - PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - { - QMutexLocker viewLocker(&_viewMutex); - // adjust near clip plane to account for sensor scaling. - auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - _viewFrustum.getAspectRatio(), - DEFAULT_NEAR_CLIP * sensorToWorldScale, - _viewFrustum.getFarClip()); - _viewFrustum.setProjection(adjustedProjection); - _viewFrustum.calculate(); - } - renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_viewFrustum); - } - } - */ - { - PROFILE_RANGE(render, "/resizeGL"); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::paintGL()"); - resizeGL(); - } + + //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + //{ + // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + // { + // QMutexLocker viewLocker(&_viewMutex); + // // adjust near clip plane to account for sensor scaling. + // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + // _viewFrustum.getAspectRatio(), + // DEFAULT_NEAR_CLIP * sensorToWorldScale, + // _viewFrustum.getFarClip()); + // _viewFrustum.setProjection(adjustedProjection); + // _viewFrustum.calculate(); + // } + // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + // { + // QMutexLocker viewLocker(&_viewMutex); + // renderArgs.setViewFrustum(_viewFrustum); + // } + //} + + //{ + // PROFILE_RANGE(render, "/resizeGL"); + // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + // PerformanceWarning warn(showWarnings, "Application::paintGL()"); + // resizeGL(); + //} { PROFILE_RANGE(render, "/gpuContextReset"); @@ -114,103 +143,10 @@ void Application::paintGL() { } // updateCamera(renderArgs); - - /* glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); - - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); - } - } - } - */ { PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } gpu::FramebufferPointer finalFramebuffer; @@ -224,57 +160,65 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - auto hmdInterface = DependencyManager::get(); - float ipdScale = hmdInterface->getIPDScale(); + //auto hmdInterface = DependencyManager::get(); + //float ipdScale = hmdInterface->getIPDScale(); - // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - ipdScale *= sensorToWorldScale; + //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + //ipdScale *= sensorToWorldScale; { - PROFILE_RANGE(render, "/mainRender"); - PerformanceTimer perfTimer("mainRender"); - // FIXME is this ever going to be different from the size previously set in the render args - // in the overlay render? - // Viewport is assigned to the size of the framebuffer - renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - auto baseProjection = renderArgs.getViewFrustum().getProjection(); - if (displayPlugin->isStereo()) { - // Stereo modes will typically have a larger projection matrix overall, - // so we ask for the 'mono' projection matrix, which for stereo and HMD - // plugins will imply the combined projection for both eyes. - // - // This is properly implemented for the Oculus plugins, but for OpenVR - // and Stereo displays I'm not sure how to get / calculate it, so we're - // just relying on the left FOV in each case and hoping that the - // overall culling margin of error doesn't cause popping in the - // right eye. There are FIXMEs in the relevant plugins - _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + //PROFILE_RANGE(render, "/mainRender"); + //PerformanceTimer perfTimer("mainRender"); + //// FIXME is this ever going to be different from the size previously set in the render args + //// in the overlay render? + //// Viewport is assigned to the size of the framebuffer + //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + //auto baseProjection = renderArgs.getViewFrustum().getProjection(); + //if (displayPlugin->isStereo()) { + // // Stereo modes will typically have a larger projection matrix overall, + // // so we ask for the 'mono' projection matrix, which for stereo and HMD + // // plugins will imply the combined projection for both eyes. + // // + // // This is properly implemented for the Oculus plugins, but for OpenVR + // // and Stereo displays I'm not sure how to get / calculate it, so we're + // // just relying on the left FOV in each case and hoping that the + // // overall culling margin of error doesn't cause popping in the + // // right eye. There are FIXMEs in the relevant plugins + // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + // renderArgs._context->enableStereo(true); + // mat4 eyeOffsets[2]; + // mat4 eyeProjections[2]; + + // // FIXME we probably don't need to set the projection matrix every frame, + // // only when the display plugin changes (or in non-HMD modes when the user + // // changes the FOV manually, which right now I don't think they can. + // for_each_eye([&](Eye eye) { + // // For providing the stereo eye views, the HMD head pose has already been + // // applied to the avatar, so we need to get the difference between the head + // // pose applied to the avatar and the per eye pose, and use THAT as + // // the per-eye stereo matrix adjustment. + // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // // Grab the translation + // vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // // Apply IPD scaling + // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + // eyeOffsets[eye] = eyeOffsetTransform; + // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + // }); + // renderArgs._context->setStereoProjections(eyeProjections); + // renderArgs._context->setStereoViews(eyeOffsets); + + // // Configure the type of display / stereo + // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + //} + + if (isStereo) { renderArgs._context->enableStereo(true); - mat4 eyeOffsets[2]; - mat4 eyeProjections[2]; - - // FIXME we probably don't need to set the projection matrix every frame, - // only when the display plugin changes (or in non-HMD modes when the user - // changes the FOV manually, which right now I don't think they can. - for_each_eye([&](Eye eye) { - // For providing the stereo eye views, the HMD head pose has already been - // applied to the avatar, so we need to get the difference between the head - // pose applied to the avatar and the per eye pose, and use THAT as - // the per-eye stereo matrix adjustment. - mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // Grab the translation - vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // Apply IPD scaling - mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - eyeOffsets[eye] = eyeOffsetTransform; - eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - }); - renderArgs._context->setStereoProjections(eyeProjections); - renderArgs._context->setStereoViews(eyeOffsets); - - // Configure the type of display / stereo - renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + // renderArgs._displayMode } + renderArgs._blitFramebuffer = finalFramebuffer; // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); @@ -317,4 +261,100 @@ void Application::paintGL() { uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; _frameTimingsScriptingInterface.addValue(lastPaintDuration); } -#endif \ No newline at end of file + + +// WorldBox Render Data & rendering functions + +class WorldBoxRenderData { +public: + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + int _val = 0; + static render::ItemID _item; // unique WorldBoxRenderData +}; + +render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID }; + +namespace render { + template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } + template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } + template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { + if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { + PerformanceTimer perfTimer("worldBox"); + + auto& batch = *args->_batch; + DependencyManager::get()->bindSimpleProgram(batch); + renderWorldBox(args, batch); + } + } +} + +void Application::runRenderFrame(RenderArgs* renderArgs) { + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + // auto myAvatar = getMyAvatar(); + // myAvatar->preDisplaySide(renderArgs); + + PROFILE_RANGE(render, __FUNCTION__); + PerformanceTimer perfTimer("display"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); + + // load the view frustum + // { + // QMutexLocker viewLocker(&_viewMutex); + // theCamera.loadViewFrustum(_displayViewFrustum); + // } + + // The pending changes collecting the changes here + render::Transaction transaction; + + // Assuming nothing gets rendered through that + //if (!selfAvatarOnly) { + { + if (DependencyManager::get()->shouldRenderEntities()) { + // render models... + PerformanceTimer perfTimer("entities"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::runRenderFrame() ... entities..."); + + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; + + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { + renderDebugFlags = static_cast(renderDebugFlags | + static_cast(RenderArgs::RENDER_DEBUG_HULLS)); + } + renderArgs->_debugFlags = renderDebugFlags; + } + } + + // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities + // Make sure the WorldBox is in the scene + if (!render::Item::isValidID(WorldBoxRenderData::_item)) { + auto worldBoxRenderData = make_shared(); + auto worldBoxRenderPayload = make_shared(worldBoxRenderData); + + WorldBoxRenderData::_item = _main3DScene->allocateID(); + + transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); + _main3DScene->enqueueTransaction(transaction); + } + + + // For now every frame pass the renderContext + { + PerformanceTimer perfTimer("EngineRun"); + + /* { + QMutexLocker viewLocker(&_viewMutex); + renderArgs->setViewFrustum(_displayViewFrustum); + }*/ + // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK + renderArgs->_scene = getMain3DScene(); + _renderEngine->getRenderContext()->args = renderArgs; + + // Before the deferred pass, let's try to use the render engine + _renderEngine->run(); + } +} From aa10c29609d90942915791e9bae1514d888fa7d1 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 1 Oct 2017 17:16:10 -0700 Subject: [PATCH 23/43] Cleaning up the changed code --- interface/src/Application.cpp | 535 +++++---------------------- interface/src/Application_render.cpp | 150 +------- 2 files changed, 112 insertions(+), 573 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5ce63441aa..3f87d72c88 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -188,7 +188,7 @@ #include "InterfaceParentFinder.h" #include "ui/OctreeStatsProvider.h" -#include "FrameTimingsScriptingInterface.h" +//#include "FrameTimingsScriptingInterface.h" #include #include #include @@ -2018,7 +2018,7 @@ void Application::cleanupBeforeQuit() { // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual // removal of the items. // See https://highfidelity.fogbugz.com/f/cases/5328 - _main3DScene->processTransactionQueue(); + // _main3DScene->processTransactionQueue(); // first stop all timers directly or by invokeMethod // depending on what thread they run in @@ -2216,7 +2216,7 @@ void Application::initializeGL() { update(0); } -FrameTimingsScriptingInterface _frameTimingsScriptingInterface; +//FrameTimingsScriptingInterface _frameTimingsScriptingInterface; extern void setupPreferences(); @@ -2272,7 +2272,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); - surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); + //surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); // TODO: Remove this Context Property ? i don;t see anywhere surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); @@ -2378,354 +2378,105 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { - + PROFILE_RANGE(render, "/updateCamera"); + PerformanceTimer perfTimer("CameraUpdates"); glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } - else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glmExtractRotation(camMat)); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } + else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } + else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); } - else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } - else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } - else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } - else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } - else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } - else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } - else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); } } } + else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } + else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } + else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } -// -//void Application::editRenderArgs(RenderArgsEditor editor) { -// QMutexLocker renderLocker(&_renderArgsMutex); -// editor(_appRenderArgs); -// -//} -// -//void Application::paintGL() { -// // Some plugins process message events, allowing paintGL to be called reentrantly. -// if (_aboutToQuit || _window->isMinimized()) { -// return; -// } -// -// _frameCount++; -// _lastTimeRendered.start(); -// -// auto lastPaintBegin = usecTimestampNow(); -// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); -// PerformanceTimer perfTimer("paintGL"); -// -// if (nullptr == _displayPlugin) { -// return; -// } -// -// DisplayPluginPointer displayPlugin; -// { -// PROFILE_RANGE(render, "/getActiveDisplayPlugin"); -// displayPlugin = getActiveDisplayPlugin(); -// } -// -// { -// PROFILE_RANGE(render, "/pluginBeginFrameRender"); -// // If a display plugin loses it's underlying support, it -// // needs to be able to signal us to not use it -// if (!displayPlugin->beginFrameRender(_frameCount)) { -// updateDisplayMode(); -// return; -// } -// } -// -// // update the avatar with a fresh HMD pose -// // { -// // PROFILE_RANGE(render, "/updateAvatar"); -// // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); -// // } -// -// // auto lodManager = DependencyManager::get(); -// -// RenderArgs renderArgs; -// float sensorToWorldScale; -// glm::mat4 HMDSensorPose; -// glm::mat4 eyeToWorld; -// glm::mat4 sensorToWorld; -// -// bool isStereo; -// glm::mat4 stereoEyeOffsets[2]; -// glm::mat4 stereoEyeProjections[2]; -// -// { -// QMutexLocker viewLocker(&_renderArgsMutex); -// renderArgs = _appRenderArgs._renderArgs; -// HMDSensorPose = _appRenderArgs._headPose; -// eyeToWorld = _appRenderArgs._eyeToWorld; -// sensorToWorld = _appRenderArgs._sensorToWorld; -// sensorToWorldScale = _appRenderArgs._sensorToWorldScale; -// isStereo = _appRenderArgs._isStereo; -// for_each_eye([&](Eye eye) { -// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; -// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; -// }); -// } -// -// //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); -// //{ -// // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // // adjust near clip plane to account for sensor scaling. -// // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), -// // _viewFrustum.getAspectRatio(), -// // DEFAULT_NEAR_CLIP * sensorToWorldScale, -// // _viewFrustum.getFarClip()); -// // _viewFrustum.setProjection(adjustedProjection); -// // _viewFrustum.calculate(); -// // } -// // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), -// // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, -// // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // renderArgs.setViewFrustum(_viewFrustum); -// // } -// //} -// -// //{ -// // PROFILE_RANGE(render, "/resizeGL"); -// // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); -// // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); -// // PerformanceWarning warn(showWarnings, "Application::paintGL()"); -// // resizeGL(); -// //} -// -// { -// PROFILE_RANGE(render, "/gpuContextReset"); -// // _gpuContext->beginFrame(getHMDSensorPose()); -// _gpuContext->beginFrame(HMDSensorPose); -// // Reset the gpu::Context Stages -// // Back to the default framebuffer; -// gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { -// batch.resetStages(); -// }); -// } -// -// -// { -// PROFILE_RANGE(render, "/renderOverlay"); -// PerformanceTimer perfTimer("renderOverlay"); -// // NOTE: There is no batch associated with this renderArgs -// // the ApplicationOverlay class assumes it's viewport is setup to be the device size -// QSize size = getDeviceSize(); -// renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); -// _applicationOverlay.renderOverlay(&renderArgs); -// } -// -// // updateCamera(renderArgs); -// { -// PROFILE_RANGE(render, "/updateCompositor"); -// // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); -// getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); -// } -// -// gpu::FramebufferPointer finalFramebuffer; -// QSize finalFramebufferSize; -// { -// PROFILE_RANGE(render, "/getOutputFramebuffer"); -// // Primary rendering pass -// auto framebufferCache = DependencyManager::get(); -// finalFramebufferSize = framebufferCache->getFrameBufferSize(); -// // Final framebuffer that will be handled to the display-plugin -// finalFramebuffer = framebufferCache->getFramebuffer(); -// } -// -// //auto hmdInterface = DependencyManager::get(); -// //float ipdScale = hmdInterface->getIPDScale(); -// -// //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. -// //ipdScale *= sensorToWorldScale; -// -// { -// //PROFILE_RANGE(render, "/mainRender"); -// //PerformanceTimer perfTimer("mainRender"); -// //// FIXME is this ever going to be different from the size previously set in the render args -// //// in the overlay render? -// //// Viewport is assigned to the size of the framebuffer -// //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); -// //auto baseProjection = renderArgs.getViewFrustum().getProjection(); -// //if (displayPlugin->isStereo()) { -// // // Stereo modes will typically have a larger projection matrix overall, -// // // so we ask for the 'mono' projection matrix, which for stereo and HMD -// // // plugins will imply the combined projection for both eyes. -// // // -// // // This is properly implemented for the Oculus plugins, but for OpenVR -// // // and Stereo displays I'm not sure how to get / calculate it, so we're -// // // just relying on the left FOV in each case and hoping that the -// // // overall culling margin of error doesn't cause popping in the -// // // right eye. There are FIXMEs in the relevant plugins -// // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); -// // renderArgs._context->enableStereo(true); -// // mat4 eyeOffsets[2]; -// // mat4 eyeProjections[2]; -// -// // // FIXME we probably don't need to set the projection matrix every frame, -// // // only when the display plugin changes (or in non-HMD modes when the user -// // // changes the FOV manually, which right now I don't think they can. -// // for_each_eye([&](Eye eye) { -// // // For providing the stereo eye views, the HMD head pose has already been -// // // applied to the avatar, so we need to get the difference between the head -// // // pose applied to the avatar and the per eye pose, and use THAT as -// // // the per-eye stereo matrix adjustment. -// // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); -// // // Grab the translation -// // vec3 eyeOffset = glm::vec3(eyeToHead[3]); -// // // Apply IPD scaling -// // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); -// // eyeOffsets[eye] = eyeOffsetTransform; -// // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); -// // }); -// // renderArgs._context->setStereoProjections(eyeProjections); -// // renderArgs._context->setStereoViews(eyeOffsets); -// -// // // Configure the type of display / stereo -// // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); -// //} -// -// if (isStereo) { -// renderArgs._context->enableStereo(true); -// renderArgs._context->setStereoProjections(stereoEyeProjections); -// renderArgs._context->setStereoViews(stereoEyeOffsets); -// // renderArgs._displayMode -// } -// -// renderArgs._blitFramebuffer = finalFramebuffer; -// // displaySide(&renderArgs, _myCamera); -// runRenderFrame(&renderArgs); -// } -// -// gpu::Batch postCompositeBatch; -// { -// PROFILE_RANGE(render, "/postComposite"); -// PerformanceTimer perfTimer("postComposite"); -// renderArgs._batch = &postCompositeBatch; -// renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); -// renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); -// _overlays.render3DHUDOverlays(&renderArgs); -// } -// -// auto frame = _gpuContext->endFrame(); -// frame->frameIndex = _frameCount; -// frame->framebuffer = finalFramebuffer; -// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ -// DependencyManager::get()->releaseFramebuffer(framebuffer); -// }; -// frame->overlay = _applicationOverlay.getOverlayTexture(); -// frame->postCompositeBatch = postCompositeBatch; -// // deliver final scene rendering commands to the display plugin -// { -// PROFILE_RANGE(render, "/pluginOutput"); -// PerformanceTimer perfTimer("pluginOutput"); -// _frameCounter.increment(); -// displayPlugin->submitFrame(frame); -// } -// -// // Reset the framebuffer and stereo state -// renderArgs._blitFramebuffer.reset(); -// renderArgs._context->enableStereo(false); -// -// { -// Stats::getInstance()->setRenderDetails(renderArgs._details); -// } -// -// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; -// _frameTimingsScriptingInterface.addValue(lastPaintDuration); -//} void Application::runTests() { runTimingTests(); @@ -5286,11 +5037,12 @@ void Application::update(float deltaTime) { editRenderArgs([this](AppRenderArgs& appRenderArgs) { + appRenderArgs._renderArgs._scene = getMain3DScene(); + appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); - // update the avatar with a fresh HMD pose { PROFILE_RANGE(render, "/updateAvatar"); @@ -5372,8 +5124,6 @@ void Application::update(float deltaTime) { eyeOffsets[eye] = eyeOffsetTransform; eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection); }); - //renderArgs._context->setStereoProjections(eyeProjections); - //renderArgs._context->setStereoViews(eyeOffsets); // Configure the type of display / stereo appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); @@ -5461,7 +5211,6 @@ int Application::sendNackPackets() { } }); - return packetsSent; } @@ -5692,102 +5441,6 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -//// WorldBox Render Data & rendering functions -// -//class WorldBoxRenderData { -//public: -// typedef render::Payload Payload; -// typedef Payload::DataPointer Pointer; -// -// int _val = 0; -// static render::ItemID _item; // unique WorldBoxRenderData -//}; -// -//render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; -// -//namespace render { -// template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } -// template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } -// template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { -// if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { -// PerformanceTimer perfTimer("worldBox"); -// -// auto& batch = *args->_batch; -// DependencyManager::get()->bindSimpleProgram(batch); -// renderWorldBox(args, batch); -// } -// } -//} -// -//void Application::runRenderFrame(RenderArgs* renderArgs) { -// -// // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. -// // Then we can move this logic into the Avatar::simulate call. -// // auto myAvatar = getMyAvatar(); -// // myAvatar->preDisplaySide(renderArgs); -// -// PROFILE_RANGE(render, __FUNCTION__); -// PerformanceTimer perfTimer("display"); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); -// -// // load the view frustum -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // theCamera.loadViewFrustum(_displayViewFrustum); -// // } -// -// // The pending changes collecting the changes here -// render::Transaction transaction; -// -// // Assuming nothing gets rendered through that -// //if (!selfAvatarOnly) { -// { -// if (DependencyManager::get()->shouldRenderEntities()) { -// // render models... -// PerformanceTimer perfTimer("entities"); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), -// "Application::runRenderFrame() ... entities..."); -// -// RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; -// -// if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { -// renderDebugFlags = static_cast(renderDebugFlags | -// static_cast(RenderArgs::RENDER_DEBUG_HULLS)); -// } -// renderArgs->_debugFlags = renderDebugFlags; -// } -// } -// -// // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities -// // Make sure the WorldBox is in the scene -// if (!render::Item::isValidID(WorldBoxRenderData::_item)) { -// auto worldBoxRenderData = make_shared(); -// auto worldBoxRenderPayload = make_shared(worldBoxRenderData); -// -// WorldBoxRenderData::_item = _main3DScene->allocateID(); -// -// transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); -// _main3DScene->enqueueTransaction(transaction); -// } -// -// -// // For now every frame pass the renderContext -// { -// PerformanceTimer perfTimer("EngineRun"); -// -// /* { -// QMutexLocker viewLocker(&_viewMutex); -// renderArgs->setViewFrustum(_displayViewFrustum); -// }*/ -// // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK -// renderArgs->_scene = getMain3DScene(); -// _renderEngine->getRenderContext()->args = renderArgs; -// -// // Before the deferred pass, let's try to use the render engine -// _renderEngine->run(); -// } -//} - void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); DependencyManager::get()->reset(); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 51d55a2bd8..43e1d7a9e1 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -15,6 +15,10 @@ #include #include "ui/Stats.h" #include "FrameTimingsScriptingInterface.h" +#include +#include "Util.h" + +FrameTimingsScriptingInterface _frameTimingsScriptingInterface; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); @@ -58,14 +62,6 @@ void Application::paintGL() { } } - // update the avatar with a fresh HMD pose - // { - // PROFILE_RANGE(render, "/updateAvatar"); - // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - // } - - // auto lodManager = DependencyManager::get(); - RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; @@ -90,39 +86,8 @@ void Application::paintGL() { }); } - //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - //{ - // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - // { - // QMutexLocker viewLocker(&_viewMutex); - // // adjust near clip plane to account for sensor scaling. - // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - // _viewFrustum.getAspectRatio(), - // DEFAULT_NEAR_CLIP * sensorToWorldScale, - // _viewFrustum.getFarClip()); - // _viewFrustum.setProjection(adjustedProjection); - // _viewFrustum.calculate(); - // } - // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - // { - // QMutexLocker viewLocker(&_viewMutex); - // renderArgs.setViewFrustum(_viewFrustum); - // } - //} - - //{ - // PROFILE_RANGE(render, "/resizeGL"); - // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - // PerformanceWarning warn(showWarnings, "Application::paintGL()"); - // resizeGL(); - //} - { PROFILE_RANGE(render, "/gpuContextReset"); - // _gpuContext->beginFrame(getHMDSensorPose()); _gpuContext->beginFrame(HMDSensorPose); // Reset the gpu::Context Stages // Back to the default framebuffer; @@ -160,67 +125,14 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - //auto hmdInterface = DependencyManager::get(); - //float ipdScale = hmdInterface->getIPDScale(); - - //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - //ipdScale *= sensorToWorldScale; - { - //PROFILE_RANGE(render, "/mainRender"); - //PerformanceTimer perfTimer("mainRender"); - //// FIXME is this ever going to be different from the size previously set in the render args - //// in the overlay render? - //// Viewport is assigned to the size of the framebuffer - //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - //auto baseProjection = renderArgs.getViewFrustum().getProjection(); - //if (displayPlugin->isStereo()) { - // // Stereo modes will typically have a larger projection matrix overall, - // // so we ask for the 'mono' projection matrix, which for stereo and HMD - // // plugins will imply the combined projection for both eyes. - // // - // // This is properly implemented for the Oculus plugins, but for OpenVR - // // and Stereo displays I'm not sure how to get / calculate it, so we're - // // just relying on the left FOV in each case and hoping that the - // // overall culling margin of error doesn't cause popping in the - // // right eye. There are FIXMEs in the relevant plugins - // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); - // renderArgs._context->enableStereo(true); - // mat4 eyeOffsets[2]; - // mat4 eyeProjections[2]; - - // // FIXME we probably don't need to set the projection matrix every frame, - // // only when the display plugin changes (or in non-HMD modes when the user - // // changes the FOV manually, which right now I don't think they can. - // for_each_eye([&](Eye eye) { - // // For providing the stereo eye views, the HMD head pose has already been - // // applied to the avatar, so we need to get the difference between the head - // // pose applied to the avatar and the per eye pose, and use THAT as - // // the per-eye stereo matrix adjustment. - // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // // Grab the translation - // vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // // Apply IPD scaling - // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - // eyeOffsets[eye] = eyeOffsetTransform; - // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - // }); - // renderArgs._context->setStereoProjections(eyeProjections); - // renderArgs._context->setStereoViews(eyeOffsets); - - // // Configure the type of display / stereo - // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); - //} - if (isStereo) { renderArgs._context->enableStereo(true); renderArgs._context->setStereoProjections(stereoEyeProjections); renderArgs._context->setStereoViews(stereoEyeOffsets); - // renderArgs._displayMode } renderArgs._blitFramebuffer = finalFramebuffer; - // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); } @@ -291,49 +203,34 @@ namespace render { } void Application::runRenderFrame(RenderArgs* renderArgs) { - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - // auto myAvatar = getMyAvatar(); - // myAvatar->preDisplaySide(renderArgs); - PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - // load the view frustum - // { - // QMutexLocker viewLocker(&_viewMutex); - // theCamera.loadViewFrustum(_displayViewFrustum); - // } - // The pending changes collecting the changes here render::Transaction transaction; - // Assuming nothing gets rendered through that - //if (!selfAvatarOnly) { - { - if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - PerformanceTimer perfTimer("entities"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::runRenderFrame() ... entities..."); + if (DependencyManager::get()->shouldRenderEntities()) { + // render models... + PerformanceTimer perfTimer("entities"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::runRenderFrame() ... entities..."); - RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { - renderDebugFlags = static_cast(renderDebugFlags | - static_cast(RenderArgs::RENDER_DEBUG_HULLS)); - } - renderArgs->_debugFlags = renderDebugFlags; + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { + renderDebugFlags = static_cast(renderDebugFlags | + static_cast(RenderArgs::RENDER_DEBUG_HULLS)); } + renderArgs->_debugFlags = renderDebugFlags; } - // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities // Make sure the WorldBox is in the scene + // For the record, this one RenderItem is the first one we created and added to the scene. + // We could meoee that code elsewhere but you know... if (!render::Item::isValidID(WorldBoxRenderData::_item)) { - auto worldBoxRenderData = make_shared(); - auto worldBoxRenderPayload = make_shared(worldBoxRenderData); + auto worldBoxRenderData = std::make_shared(); + auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); WorldBoxRenderData::_item = _main3DScene->allocateID(); @@ -341,20 +238,9 @@ void Application::runRenderFrame(RenderArgs* renderArgs) { _main3DScene->enqueueTransaction(transaction); } - - // For now every frame pass the renderContext { PerformanceTimer perfTimer("EngineRun"); - - /* { - QMutexLocker viewLocker(&_viewMutex); - renderArgs->setViewFrustum(_displayViewFrustum); - }*/ - // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK - renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; - - // Before the deferred pass, let's try to use the render engine _renderEngine->run(); } } From 0cbf19bcf141765c153befda56705359272b7c58 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 1 Oct 2017 17:47:35 -0700 Subject: [PATCH 24/43] Removing comments --- interface/src/Application.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3f87d72c88..efa18f36df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -429,7 +429,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - // deadlockDetectionCrash(); + deadlockDetectionCrash(); #endif } } @@ -5036,9 +5036,6 @@ void Application::update(float deltaTime) { } editRenderArgs([this](AppRenderArgs& appRenderArgs) { - - appRenderArgs._renderArgs._scene = getMain3DScene(); - appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); @@ -5068,6 +5065,8 @@ void Application::update(float deltaTime) { appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + appRenderArgs._renderArgs._scene = getMain3DScene(); + { QMutexLocker viewLocker(&_viewMutex); appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); From 6c510bc18f297842fac4c4c3e77dc20041a3b65c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 20:05:48 -0700 Subject: [PATCH 25/43] fine tuning the changes to respect clean up --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index efa18f36df..35fc0049a8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2018,7 +2018,8 @@ void Application::cleanupBeforeQuit() { // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual // removal of the items. // See https://highfidelity.fogbugz.com/f/cases/5328 - // _main3DScene->processTransactionQueue(); + _main3DScene->enqueueFrame(); // flush all the transactions + _main3DScene->processTransactionQueue(); // process and apply deletions // first stop all timers directly or by invokeMethod // depending on what thread they run in From ec10d38983f813e37ff123486602f0ea14fa2add Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 22:28:04 -0700 Subject: [PATCH 26/43] more cleaning --- interface/src/Application_render.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 43e1d7a9e1..1c82c95a8a 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -63,7 +63,6 @@ void Application::paintGL() { } RenderArgs renderArgs; - float sensorToWorldScale; glm::mat4 HMDSensorPose; glm::mat4 eyeToWorld; glm::mat4 sensorToWorld; @@ -78,7 +77,6 @@ void Application::paintGL() { HMDSensorPose = _appRenderArgs._headPose; eyeToWorld = _appRenderArgs._eyeToWorld; sensorToWorld = _appRenderArgs._sensorToWorld; - sensorToWorldScale = _appRenderArgs._sensorToWorldScale; isStereo = _appRenderArgs._isStereo; for_each_eye([&](Eye eye) { stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; @@ -110,7 +108,6 @@ void Application::paintGL() { // updateCamera(renderArgs); { PROFILE_RANGE(render, "/updateCompositor"); - // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } From bf39eb9a77dadd889f6593b9ae39c97ba2235c83 Mon Sep 17 00:00:00 2001 From: vladest Date: Mon, 2 Oct 2017 20:02:55 +0200 Subject: [PATCH 27/43] Test Tablet keyboard specific --- interface/resources/qml/LoginDialog.qml | 2 ++ .../qml/LoginDialog/LinkAccountBody.qml | 11 ++++++--- .../qml/dialogs/TabletLoginDialog.qml | 24 +++++++++++++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index 315cda3551..e21e8b7354 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -27,6 +27,8 @@ ModalWindow { destroyOnHidden: true visible: true + readonly property bool isTablet: false + property string iconText: "" property int iconSize: 50 diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 13462804c3..dd38b641bb 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -244,12 +244,17 @@ Item { } } - - Component.onCompleted: { root.title = qsTr("Sign Into High Fidelity") root.iconText = "<" - keyboardEnabled = HMD.active; + + //dont rise local keyboard + keyboardEnabled = !root.isTablet && HMD.active; + //but rise Tablet's one instead for Tablet interface + if (root.isTablet) { + root.keyboardEnabled = HMD.active; + root.keyboardRaised = Qt.binding( function() { return keyboardRaised; }) + } //d.resize(); if (failAfterSignUp) { diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index f4f7a5848c..334cb9304f 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -32,8 +32,14 @@ TabletModalWindow { //fake root for shared components expecting root here property var root: QtObject { id: root - property alias title: realRoot.title + property bool keyboardEnabled: false + property bool keyboardRaised: false + property bool punctuationMode: false + + readonly property bool isTablet: true + + property alias title: realRoot.title property real width: realRoot.width property real height: realRoot.height @@ -65,10 +71,6 @@ TabletModalWindow { //onTitleWidthChanged: d.resize(); - property bool keyboardEnabled: false - property bool keyboardRaised: false - property bool punctuationMode: false - //onKeyboardRaisedChanged: d.resize(); signal canceled(); @@ -123,6 +125,18 @@ TabletModalWindow { } } + Keyboard { + raised: root.keyboardEnabled && root.keyboardRaised + numeric: root.punctuationMode + enabled: true + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + bottomMargin: root.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 + } + } + Keys.onPressed: { if (!visible) { return From f150d77d318517975fa32996cb162eca8f9158e5 Mon Sep 17 00:00:00 2001 From: Liv Date: Mon, 2 Oct 2017 11:08:07 -0700 Subject: [PATCH 28/43] Updating placeholder.js to use a url that points to example scripts --- domain-server/resources/web/assignment/placeholder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index 2c1d8253aa..bf64539bea 100644 --- a/domain-server/resources/web/assignment/placeholder.js +++ b/domain-server/resources/web/assignment/placeholder.js @@ -1,3 +1,3 @@ // Here you can put a script that will be run by an assignment-client (AC) -// For examples, please go to http://public.highfidelity.io/scripts +// For examples, please go to https://github.com/highfidelity/hifi/tree/master/script-archive/acScripts // The directory named acScripts contains assignment-client specific scripts you can try. From 97b09d680ca7bbff215a7765d082f909deed5d73 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 2 Oct 2017 13:17:53 -0700 Subject: [PATCH 29/43] fix and improve laser pointer locking --- interface/src/raypick/LaserPointer.h | 3 + interface/src/raypick/LaserPointerManager.cpp | 105 ++++++++++-------- interface/src/raypick/LaserPointerManager.h | 2 - interface/src/raypick/RayPick.h | 5 + interface/src/raypick/RayPickManager.cpp | 76 +++++++------ interface/src/raypick/RayPickManager.h | 2 - 6 files changed, 108 insertions(+), 85 deletions(-) diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 5467a8233e..fa7d396ae8 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -75,6 +75,8 @@ public: void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair(objectID, isOverlay); } + QReadWriteLock* getLock() { return &_lock; } + void update(); private: @@ -89,6 +91,7 @@ private: std::pair _objectLockEnd { std::pair(QUuid(), false)}; QUuid _rayPickUID; + QReadWriteLock _lock; void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState); diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index b19ecc14f0..387f88724e 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -17,7 +17,6 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La QWriteLocker containsLock(&_containsLock); QUuid id = QUuid::createUuid(); _laserPointers[id] = laserPointer; - _laserPointerLocks[id] = std::make_shared(); return id; } return QUuid(); @@ -26,46 +25,50 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La void LaserPointerManager::removeLaserPointer(const QUuid uid) { QWriteLocker lock(&_containsLock); _laserPointers.remove(uid); - _laserPointerLocks.remove(uid); } void LaserPointerManager::enableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->enable(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->enable(); } } void LaserPointerManager::disableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->disable(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->disable(); } } void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setRenderState(renderState); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setRenderState(renderState); } } void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->editRenderState(state, startProps, pathProps, endProps); } } const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QReadLocker laserLock(_laserPointerLocks[uid].get()); - return _laserPointers[uid]->getPrevRayPickResult(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QReadLocker laserLock(laserPointer.value()->getLock()); + return laserPointer.value()->getPrevRayPickResult(); } return RayPickResult(); } @@ -74,79 +77,89 @@ void LaserPointerManager::update() { QReadLocker lock(&_containsLock); for (QUuid& uid : _laserPointers.keys()) { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts - QReadLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->update(); + auto laserPointer = _laserPointers.find(uid); + QReadLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->update(); } } void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setPrecisionPicking(precisionPicking); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setPrecisionPicking(precisionPicking); } } void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setLaserLength(laserLength); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setLaserLength(laserLength); } } void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreEntities(ignoreEntities); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreEntities(ignoreEntities); } } void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeEntities(includeEntities); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeEntities(includeEntities); } } void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreOverlays(ignoreOverlays); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreOverlays(ignoreOverlays); } } void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeOverlays(includeOverlays); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeOverlays(includeOverlays); } } void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreAvatars(ignoreAvatars); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreAvatars(ignoreAvatars); } } void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeAvatars(includeAvatars); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeAvatars(includeAvatars); } } void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setLockEndUUID(objectID, isOverlay); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setLockEndUUID(objectID, isOverlay); } } diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index 6494bb7056..b841877578 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -13,7 +13,6 @@ #include #include -#include #include "LaserPointer.h" @@ -46,7 +45,6 @@ public: private: QHash> _laserPointers; - QHash> _laserPointerLocks; QReadWriteLock _containsLock; }; diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 0686a05718..428e44d670 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -16,6 +16,7 @@ #include "EntityItemID.h" #include "ui/overlays/Overlay.h" +#include class RayPickFilter { public: @@ -127,6 +128,8 @@ public: void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); } void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); } + QReadWriteLock* getLock() { return &_lock; } + private: RayPickFilter _filter; float _maxDistance; @@ -139,6 +142,8 @@ private: QVector _includeOverlays; QVector _ignoreAvatars; QVector _includeAvatars; + + QReadWriteLock _lock; }; #endif // hifi_RayPick_h diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index bfc6e3fcb2..65f82dcd5f 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -47,6 +47,7 @@ void RayPickManager::update() { RayPickCache results; for (auto& uid : _rayPicks.keys()) { std::shared_ptr rayPick = _rayPicks[uid]; + QWriteLocker lock(rayPick->getLock()); if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) { continue; } @@ -114,7 +115,6 @@ void RayPickManager::update() { } } - QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) { rayPick->setRayPickResult(res); } else { @@ -127,7 +127,6 @@ QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } @@ -135,7 +134,6 @@ QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float max QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } @@ -143,93 +141,101 @@ QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(position, direction, filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } void RayPickManager::removeRayPick(const QUuid uid) { QWriteLocker lock(&_containsLock); _rayPicks.remove(uid); - _rayPickLocks.remove(uid); } void RayPickManager::enableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker rayPickLock(_rayPickLocks[uid].get()); - _rayPicks[uid]->enable(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker rayPickLock(rayPick.value()->getLock()); + rayPick.value()->enable(); } } void RayPickManager::disableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker rayPickLock(_rayPickLocks[uid].get()); - _rayPicks[uid]->disable(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker rayPickLock(rayPick.value()->getLock()); + rayPick.value()->disable(); } } const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QReadLocker lock(_rayPickLocks[uid].get()); - return _rayPicks[uid]->getPrevRayPickResult(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QReadLocker lock(rayPick.value()->getLock()); + return rayPick.value()->getPrevRayPickResult(); } return RayPickResult(); } void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setPrecisionPicking(precisionPicking); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setPrecisionPicking(precisionPicking); } } void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreEntities(ignoreEntities); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreEntities(ignoreEntities); } } void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeEntities(includeEntities); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeEntities(includeEntities); } } void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreOverlays(ignoreOverlays); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreOverlays(ignoreOverlays); } } void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeOverlays(includeOverlays); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeOverlays(includeOverlays); } } void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreAvatars(ignoreAvatars); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreAvatars(ignoreAvatars); } } void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeAvatars(includeAvatars); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeAvatars(includeAvatars); } } \ No newline at end of file diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h index 9717767f19..974022eb4d 100644 --- a/interface/src/raypick/RayPickManager.h +++ b/interface/src/raypick/RayPickManager.h @@ -15,7 +15,6 @@ #include #include -#include #include "RegisteredMetaTypes.h" @@ -47,7 +46,6 @@ public: private: QHash> _rayPicks; - QHash> _rayPickLocks; QReadWriteLock _containsLock; typedef QHash, std::unordered_map> RayPickCache; From bb99f68d40ec7e0a67bb366067380d2638377a59 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 2 Oct 2017 17:04:00 -0700 Subject: [PATCH 30/43] Avoiding the need for the GLobal frameTiing Scriptiong interface and just a regular member of APplication instead --- interface/src/Application.cpp | 5 +---- interface/src/Application.h | 3 +++ interface/src/Application_render.cpp | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 35fc0049a8..97d621478d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -188,7 +188,6 @@ #include "InterfaceParentFinder.h" #include "ui/OctreeStatsProvider.h" -//#include "FrameTimingsScriptingInterface.h" #include #include #include @@ -2217,8 +2216,6 @@ void Application::initializeGL() { update(0); } -//FrameTimingsScriptingInterface _frameTimingsScriptingInterface; - extern void setupPreferences(); void Application::initializeUi() { @@ -2273,7 +2270,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); - //surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); // TODO: Remove this Context Property ? i don;t see anywhere + surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); diff --git a/interface/src/Application.h b/interface/src/Application.h index 77ae840274..3966d1c50d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -76,6 +76,7 @@ #include #include #include +#include "FrameTimingsScriptingInterface.h" #include "Sound.h" @@ -537,6 +538,8 @@ private: RateCounter<> _avatarSimCounter; RateCounter<> _simCounter; + FrameTimingsScriptingInterface _frameTimingsScriptingInterface; + QTimer _minimizedWindowTimer; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 1c82c95a8a..b09705c300 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -14,11 +14,9 @@ #include #include #include "ui/Stats.h" -#include "FrameTimingsScriptingInterface.h" #include #include "Util.h" -FrameTimingsScriptingInterface _frameTimingsScriptingInterface; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); From acb99592eeb266688c373a3395119d221c4fabe0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 21:31:30 -0700 Subject: [PATCH 31/43] fixing th e bug on exit due to the debug anim draw of the avatars --- libraries/render-utils/src/AnimDebugDraw.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 4f7f9ef5c4..c22e99cbbc 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -144,6 +144,7 @@ void AnimDebugDraw::shutdown() { if (scene && _itemID) { render::Transaction transaction; transaction.removeItem(_itemID); + render::Item::clearID(_itemID); scene->enqueueTransaction(transaction); } } @@ -316,7 +317,9 @@ void AnimDebugDraw::update() { if (!scene) { return; } - + if (!render::Item::isValidID(_itemID)) { + return; + } render::Transaction transaction; transaction.updateItem(_itemID, [&](AnimDebugDrawData& data) { From 895e3d0430017be666ddd4a6f81fd1b6c37b5e6c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 21:46:52 -0700 Subject: [PATCH 32/43] more cleanups --- interface/src/Application_render.cpp | 1 - interface/src/ui/overlays/Overlays.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index b09705c300..ac9aecf66c 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -103,7 +103,6 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - // updateCamera(renderArgs); { PROFILE_RANGE(render, "/updateCompositor"); getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e9cb1f2973..c93d225718 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -152,7 +152,7 @@ void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) { foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) { // Reset necessary batch pipeline settings between overlays batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this?? - // batch.setModelTransform(Transform()); + batch.setModelTransform(Transform()); renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey()); thisOverlay->render(renderArgs); From 64f70f1ebbd3dcf69b772f5b2076466738ba2484 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 22:00:41 -0700 Subject: [PATCH 33/43] more cleanups --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 4d4f2c3a1c..4210e76097 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - notifyRenderTransformChange(); - auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); @@ -267,7 +265,6 @@ void Base3DOverlay::parentDeleted() { } void Base3DOverlay::update(float duration) { - // In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true. // then the correct transform used for rendering is computed in the update transaction and assigned. if (_renderTransformDirty) { From ef326a38518969dff000d550717b40027394cfc1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Oct 2017 11:59:25 -0700 Subject: [PATCH 34/43] expose performance hot spot in stats details --- .../src/EntityTreeRenderer.cpp | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0cb25a2e2f..e42a307d96 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -260,12 +260,24 @@ void EntityTreeRenderer::update(bool simulate) { } } - auto scene = _viewState->getMain3DScene(); - if (scene) { - render::Transaction transaction; - addPendingEntities(scene, transaction); - updateChangedEntities(scene, transaction); - scene->enqueueTransaction(transaction); + { + PerformanceTimer sceneTimer("scene"); + auto scene = _viewState->getMain3DScene(); + if (scene) { + render::Transaction transaction; + { + PerformanceTimer foo("add"); + addPendingEntities(scene, transaction); + } + { + PerformanceTimer foo("change"); + updateChangedEntities(scene, transaction); + } + { + PerformanceTimer foo("enqueue"); + scene->enqueueTransaction(transaction); + } + } } } } @@ -1078,4 +1090,4 @@ void EntityTreeRenderer::onEntityChanged(const EntityItemID& id) { _changedEntitiesGuard.withWriteLock([&] { _changedEntities.insert(id); }); -} \ No newline at end of file +} From 46e809bbb25e64e912daf64ecd89b478c2645fec Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Oct 2017 12:19:19 -0700 Subject: [PATCH 35/43] use a better variable name --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e42a307d96..67fcc5cc69 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -266,15 +266,15 @@ void EntityTreeRenderer::update(bool simulate) { if (scene) { render::Transaction transaction; { - PerformanceTimer foo("add"); + PerformanceTimer pt("add"); addPendingEntities(scene, transaction); } { - PerformanceTimer foo("change"); + PerformanceTimer pt("change"); updateChangedEntities(scene, transaction); } { - PerformanceTimer foo("enqueue"); + PerformanceTimer pt("enqueue"); scene->enqueueTransaction(transaction); } } From 0a505617df86a58ee95460e10c7bb40b716dbc44 Mon Sep 17 00:00:00 2001 From: vladest Date: Wed, 4 Oct 2017 19:33:36 +0200 Subject: [PATCH 36/43] Implemented single keyboard instance for all Tablet login dialog items --- .../qml/LoginDialog/CompleteProfileBody.qml | 24 ++++++++++--------- .../qml/LoginDialog/LinkAccountBody.qml | 13 +++++----- .../resources/qml/LoginDialog/SignInBody.qml | 6 +++-- .../resources/qml/LoginDialog/SignUpBody.qml | 23 ++++++++++++------ .../qml/LoginDialog/UsernameCollisionBody.qml | 13 +++++++--- .../qml/dialogs/TabletLoginDialog.qml | 5 ++-- 6 files changed, 52 insertions(+), 32 deletions(-) diff --git a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml index 2c6bc1082a..fe4c511f1d 100644 --- a/interface/resources/qml/LoginDialog/CompleteProfileBody.qml +++ b/interface/resources/qml/LoginDialog/CompleteProfileBody.qml @@ -29,11 +29,12 @@ Item { readonly property int maxHeight: 720 function resize() { - var targetWidth = Math.max(titleWidth, Math.max(additionalTextContainer.contentWidth, - termsContainer.contentWidth)) + if (root.isTablet === false) { + var targetWidth = Math.max(titleWidth, Math.max(additionalTextContainer.contentWidth, + termsContainer.contentWidth)) + parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)) + } var targetHeight = 5 * hifi.dimensions.contentSpacing.y + buttons.height + additionalTextContainer.height + termsContainer.height - - parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)) parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) } } @@ -61,10 +62,7 @@ Item { Button { anchors.verticalCenter: parent.verticalCenter - text: qsTr("Cancel") - - onClicked: root.tryDestroy() } } @@ -96,17 +94,19 @@ Item { id: termsContainer anchors { top: additionalTextContainer.bottom - left: parent.left margins: 0 topMargin: 2 * hifi.dimensions.contentSpacing.y + horizontalCenter: parent.horizontalCenter } + width: parent.width text: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") wrapMode: Text.WordWrap color: hifi.colors.baseGrayHighlight lineHeight: 1 lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter + fontSizeMode: Text.HorizontalFit + horizontalAlignment: Text.AlignVCenter onLinkActivated: loginDialog.openUrl(link) } @@ -128,8 +128,10 @@ Item { console.log("Create Failed: " + error) bodyLoader.source = "UsernameCollisionBody.qml" - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height + if (!root.isTablet) { + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } onHandleLoginCompleted: { console.log("Login Succeeded") diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index dd38b641bb..c73aab08c3 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -45,8 +45,7 @@ Item { function resize() { var targetWidth = Math.max(titleWidth, form.contentWidth); var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + - 4 * hifi.dimensions.contentSpacing.y + form.height/* + - hifi.dimensions.contentSpacing.y + buttons.height*/; + 4 * hifi.dimensions.contentSpacing.y + form.height; if (additionalInformation.visible) { targetWidth = Math.max(targetWidth, additionalInformation.width); @@ -118,7 +117,7 @@ Item { TextField { id: usernameField width: parent.width - + focus: true label: "Username or Email" ShortcutText { @@ -225,8 +224,10 @@ Item { onClicked: { bodyLoader.setSource("SignUpBody.qml") - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height + if (!root.isTablet) { + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } } } @@ -255,7 +256,7 @@ Item { root.keyboardEnabled = HMD.active; root.keyboardRaised = Qt.binding( function() { return keyboardRaised; }) } - //d.resize(); + d.resize(); if (failAfterSignUp) { mainTextContainer.text = "Account created successfully." diff --git a/interface/resources/qml/LoginDialog/SignInBody.qml b/interface/resources/qml/LoginDialog/SignInBody.qml index 71ec03f7ff..c4b6c2aee1 100644 --- a/interface/resources/qml/LoginDialog/SignInBody.qml +++ b/interface/resources/qml/LoginDialog/SignInBody.qml @@ -121,8 +121,10 @@ Item { console.log("Login Failed") bodyLoader.source = "CompleteProfileBody.qml" - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height + if (!root.isTablet) { + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } } } diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index c4056422dd..f6cf40db8e 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -44,8 +44,7 @@ Item { function resize() { var targetWidth = Math.max(titleWidth, form.contentWidth); var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + - 4 * hifi.dimensions.contentSpacing.y + form.height/* + - hifi.dimensions.contentSpacing.y + buttons.height*/; + 4 * hifi.dimensions.contentSpacing.y + form.height; parent.width = root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); parent.height = root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) @@ -168,8 +167,10 @@ Item { onClicked: { bodyLoader.setSource("LinkAccountBody.qml") - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height + if (!root.isTablet) { + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } } } @@ -216,7 +217,13 @@ Item { Component.onCompleted: { root.title = qsTr("Create an Account") root.iconText = "<" - keyboardEnabled = HMD.active; + //dont rise local keyboard + keyboardEnabled = !root.isTablet && HMD.active; + //but rise Tablet's one instead for Tablet interface + if (root.isTablet) { + root.keyboardEnabled = HMD.active; + root.keyboardRaised = Qt.binding( function() { return keyboardRaised; }) + } d.resize(); emailField.forceActiveFocus(); @@ -247,8 +254,10 @@ Item { onHandleLoginFailed: { // we failed to login, show the LoginDialog so the user will try again bodyLoader.setSource("LinkAccountBody.qml", { "failAfterSignUp": true }) - bodyLoader.item.width = root.pane.width - bodyLoader.item.height = root.pane.height + if (!root.isTablet) { + bodyLoader.item.width = root.pane.width + bodyLoader.item.height = root.pane.height + } } } diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index b049d7f8bb..5c212578b8 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -79,7 +79,7 @@ Item { margins: 0 topMargin: hifi.dimensions.contentSpacing.y } - width: 250 + width: parent.width placeholderText: "Choose your own" } @@ -102,7 +102,7 @@ Item { bottom: parent.bottom right: parent.right margins: 0 - topMargin: hifi.dimensions.contentSpacing.y + bottomMargin: hifi.dimensions.contentSpacing.y } spacing: hifi.dimensions.contentSpacing.x onHeightChanged: d.resize(); onWidthChanged: d.resize(); @@ -129,7 +129,14 @@ Item { Component.onCompleted: { root.title = qsTr("Complete Your Profile") root.iconText = "<" - keyboardEnabled = HMD.active; + //dont rise local keyboard + keyboardEnabled = !root.isTablet && HMD.active; + //but rise Tablet's one instead for Tablet interface + if (root.isTablet) { + root.keyboardEnabled = HMD.active; + root.keyboardRaised = Qt.binding( function() { return keyboardRaised; }) + } + d.resize(); } diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 334cb9304f..29276a2ccf 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -93,7 +93,6 @@ TabletModalWindow { } } - TabletModalFrame { id: mfRoot @@ -103,6 +102,7 @@ TabletModalWindow { anchors { horizontalCenter: parent.horizontalCenter verticalCenter: parent.verticalCenter + verticalCenterOffset: -loginKeyboard.height / 2 } LoginDialog { @@ -126,14 +126,13 @@ TabletModalWindow { } Keyboard { + id: loginKeyboard raised: root.keyboardEnabled && root.keyboardRaised numeric: root.punctuationMode - enabled: true anchors { left: parent.left right: parent.right bottom: parent.bottom - bottomMargin: root.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 } } From 86e8076362ce1f39547aa6845d14231c7c916df3 Mon Sep 17 00:00:00 2001 From: vladest Date: Wed, 4 Oct 2017 20:30:25 +0200 Subject: [PATCH 37/43] Fix puntuation mode --- interface/resources/qml/dialogs/TabletLoginDialog.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 29276a2ccf..9722f31144 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -28,6 +28,7 @@ TabletModalWindow { color: hifi.colors.baseGray title: qsTr("Sign in to High Fidelity") property alias titleWidth: root.titleWidth + property alias punctuationMode: root.punctuationMode //fake root for shared components expecting root here property var root: QtObject { From f8aa3d72de9a5020b67e8ca039259fe3deef978e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 4 Oct 2017 15:20:47 -0700 Subject: [PATCH 38/43] Update macOS build guide --- BUILD_OSX.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 586f81def3..6b66863534 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -1,28 +1,28 @@ -Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file. +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this file. ### Homebrew -[Homebrew](https://brew.sh/) is an excellent package manager for OS X. It makes install of some High Fidelity dependencies very simple. +[Homebrew](https://brew.sh/) is an excellent package manager for macOS. It makes install of some High Fidelity dependencies very simple. - brew install cmake openssl + brew install cmake openssl qt ### OpenSSL Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations. For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR: - export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/ + export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2l Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. ### Qt -Download and install the [Qt 5.6.2 for macOS](http://download.qt.io/official_releases/qt/5.6/5.6.2/qt-opensource-mac-x64-clang-5.6.2.dmg). +Assuming you've installed Qt using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installations. +For Qt installed via homebrew, set QT_CMAKE_PREFIX_PATH: -Keep the default components checked when going through the installer. + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1/lib/cmake -Once Qt is installed, you need to manually configure the following: -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt5.6.2/5.6/clang_64/lib/cmake/` directory. +Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. ### Xcode From 193dc83b99878a9aeea73b5688c78b0db13080bf Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 5 Oct 2017 13:59:42 +0200 Subject: [PATCH 39/43] Fix alignment of audio devices input header --- interface/resources/qml/hifi/audio/Audio.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index b1f80ac5e8..12c2ec1835 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -167,6 +167,9 @@ Rectangle { } RalewayRegular { anchors.verticalCenter: parent.verticalCenter; + width: margins.sizeText + margins.sizeLevel + anchors.left: parent.left + anchors.leftMargin: margins.sizeCheckBox size: 16; color: hifi.colors.lightGrayText; text: qsTr("CHOOSE INPUT DEVICE"); From de2c1aabac887a96f303e2aa918c6e506f82fa7b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 26 Sep 2017 15:37:14 -0700 Subject: [PATCH 40/43] Add removal of temporary files in FBXBaker --- libraries/baking/src/Baker.h | 2 ++ libraries/baking/src/FBXBaker.cpp | 11 +++++++++++ libraries/baking/src/FBXBaker.h | 1 + 3 files changed, 14 insertions(+) diff --git a/libraries/baking/src/Baker.h b/libraries/baking/src/Baker.h index 2da315c9fc..c1b2ddf959 100644 --- a/libraries/baking/src/Baker.h +++ b/libraries/baking/src/Baker.h @@ -18,6 +18,8 @@ class Baker : public QObject { Q_OBJECT public: + virtual ~Baker() = default; + bool shouldStop(); bool hasErrors() const { return !_errorList.isEmpty(); } diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 3ef291af22..017f11c680 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -56,6 +56,17 @@ FBXBaker::FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGet } +FBXBaker::~FBXBaker() { + if (_tempDir.exists()) { + if (!_tempDir.remove(_originalFBXFilePath)) { + qCWarning(model_baking) << "Failed to remove temporary copy of fbx file:" << _originalFBXFilePath; + } + if (!_tempDir.rmdir(".")) { + qCWarning(model_baking) << "Failed to remove temporary directory:" << _tempDir; + } + } +} + void FBXBaker::abort() { Baker::abort(); diff --git a/libraries/baking/src/FBXBaker.h b/libraries/baking/src/FBXBaker.h index ad8284bfa8..a6034ee2b7 100644 --- a/libraries/baking/src/FBXBaker.h +++ b/libraries/baking/src/FBXBaker.h @@ -35,6 +35,7 @@ class FBXBaker : public Baker { public: FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGetter, const QString& bakedOutputDir, const QString& originalOutputDir = ""); + ~FBXBaker() override; QUrl getFBXUrl() const { return _fbxURL; } QString getBakedFBXFilePath() const { return _bakedFBXFilePath; } From a6d148475bea71e881ccc785c7146ac831f905eb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 27 Sep 2017 14:52:21 -0700 Subject: [PATCH 41/43] Add removal of temporary baked files in AssetServer --- assignment-client/src/assets/AssetServer.cpp | 13 ++++++++- assignment-client/src/assets/AssetServer.h | 3 +- .../src/assets/BakeAssetTask.cpp | 29 +++++++++++++++++-- assignment-client/src/assets/BakeAssetTask.h | 2 +- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 9df606c227..c03721d097 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -1162,7 +1162,8 @@ void AssetServer::handleFailedBake(QString originalAssetHash, QString assetPath, _pendingBakes.remove(originalAssetHash); } -void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, QVector bakedFilePaths) { +void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, + QString bakedTempOutputDir, QVector bakedFilePaths) { bool errorCompletingBake { false }; QString errorReason; @@ -1234,6 +1235,16 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina } } + for (auto& filePath : bakedFilePaths) { + QFile file(filePath); + if (!file.remove()) { + qWarning() << "Failed to remove temporary file:" << filePath; + } + } + if (!QDir(bakedTempOutputDir).rmdir(".")) { + qWarning() << "Failed to remove temporary directory:" << bakedTempOutputDir; + } + if (!errorCompletingBake) { // create the meta file to store which version of the baking process we just completed writeMetaFile(originalAssetHash); diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index 94be560c9b..aeb40a416f 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -100,7 +100,8 @@ private: void bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath); /// Move baked content for asset to baked directory and update baked status - void handleCompletedBake(QString originalAssetHash, QString assetPath, QVector bakedFilePaths); + void handleCompletedBake(QString originalAssetHash, QString assetPath, QString bakedTempOutputDir, + QVector bakedFilePaths); void handleFailedBake(QString originalAssetHash, QString assetPath, QString errors); void handleAbortedBake(QString originalAssetHash, QString assetPath); diff --git a/assignment-client/src/assets/BakeAssetTask.cpp b/assignment-client/src/assets/BakeAssetTask.cpp index 9073510f79..94a0739612 100644 --- a/assignment-client/src/assets/BakeAssetTask.cpp +++ b/assignment-client/src/assets/BakeAssetTask.cpp @@ -24,20 +24,39 @@ BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetP } +void cleanupTempFiles(QString tempOutputDir, std::vector files) { + for (const auto& filename : files) { + QFile f { filename }; + if (!f.remove()) { + qDebug() << "Failed to remove:" << filename; + } + } + if (!tempOutputDir.isEmpty()) { + QDir dir { tempOutputDir }; + if (!dir.rmdir(".")) { + qDebug() << "Failed to remove temporary directory:" << tempOutputDir; + } + } +}; + void BakeAssetTask::run() { _isBaking.store(true); qRegisterMetaType >("QVector"); TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); }; + QString tempOutputDir; + if (_assetPath.endsWith(".fbx")) { + tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { - new FBXBaker(QUrl("file:///" + _filePath), fn, PathUtils::generateTemporaryDir()) + new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir) }; } else { + tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE, - PathUtils::generateTemporaryDir()) + tempOutputDir) }; } @@ -52,6 +71,8 @@ void BakeAssetTask::run() { _wasAborted.store(true); + cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); + emit bakeAborted(_assetHash, _assetPath); } else if (_baker->hasErrors()) { qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors(); @@ -60,6 +81,8 @@ void BakeAssetTask::run() { _didFinish.store(true); + cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); + emit bakeFailed(_assetHash, _assetPath, errors); } else { auto vectorOutputFiles = QVector::fromStdVector(_baker->getOutputFiles()); @@ -68,7 +91,7 @@ void BakeAssetTask::run() { _didFinish.store(true); - emit bakeComplete(_assetHash, _assetPath, vectorOutputFiles); + emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles); } } diff --git a/assignment-client/src/assets/BakeAssetTask.h b/assignment-client/src/assets/BakeAssetTask.h index 45e7ec8702..90458ac223 100644 --- a/assignment-client/src/assets/BakeAssetTask.h +++ b/assignment-client/src/assets/BakeAssetTask.h @@ -35,7 +35,7 @@ public: bool didFinish() const { return _didFinish.load(); } signals: - void bakeComplete(QString assetHash, QString assetPath, QVector outputFiles); + void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector outputFiles); void bakeFailed(QString assetHash, QString assetPath, QString errors); void bakeAborted(QString assetHash, QString assetPath); From f0c9badbd6a4912a1a4340db8945b5d39349b7d6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 27 Sep 2017 15:56:04 -0700 Subject: [PATCH 42/43] Fix misspelling in lost-connection-to-atp error --- interface/resources/qml/hifi/AssetServer.qml | 2 +- interface/resources/qml/hifi/dialogs/TabletAssetServer.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/AssetServer.qml b/interface/resources/qml/hifi/AssetServer.qml index 6b60cbff7b..5358ad1adc 100644 --- a/interface/resources/qml/hifi/AssetServer.qml +++ b/interface/resources/qml/hifi/AssetServer.qml @@ -171,7 +171,7 @@ ScrollingWindow { } function handleGetMappingsError(errorString) { - errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); + errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString); } function addToWorld() { diff --git a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml index 44cd700eac..a02496a252 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml @@ -172,7 +172,7 @@ Rectangle { } function handleGetMappingsError(errorString) { - errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); + errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString); } function addToWorld() { From 6b02cbb9112923e90fd92baa91304f1bbd3ebe93 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 5 Oct 2017 13:17:57 -0700 Subject: [PATCH 43/43] move locking inside laserpointer and raypick --- interface/src/raypick/LaserPointer.cpp | 56 +++++++++++++++++++ interface/src/raypick/LaserPointer.h | 20 +++---- interface/src/raypick/LaserPointerManager.cpp | 16 ------ interface/src/raypick/RayPick.cpp | 44 +++++++++++++++ interface/src/raypick/RayPick.h | 18 +++--- interface/src/raypick/RayPickManager.cpp | 10 ---- 6 files changed, 119 insertions(+), 45 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 55ddd01123..0e0f13cd6c 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -49,11 +49,13 @@ LaserPointer::~LaserPointer() { } void LaserPointer::enable() { + QWriteLocker lock(getLock()); DependencyManager::get()->enableRayPick(_rayPickUID); _renderingEnabled = true; } void LaserPointer::disable() { + QWriteLocker lock(getLock()); DependencyManager::get()->disableRayPick(_rayPickUID); _renderingEnabled = false; if (!_currentRenderState.empty()) { @@ -67,6 +69,7 @@ void LaserPointer::disable() { } void LaserPointer::setRenderState(const std::string& state) { + QWriteLocker lock(getLock()); if (!_currentRenderState.empty() && state != _currentRenderState) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); @@ -79,6 +82,7 @@ void LaserPointer::setRenderState(const std::string& state) { } void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { + QWriteLocker lock(getLock()); updateRenderStateOverlay(_renderStates[state].getStartID(), startProps); updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps); updateRenderStateOverlay(_renderStates[state].getEndID(), endProps); @@ -92,6 +96,11 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } } +const RayPickResult LaserPointer::getPrevRayPickResult() { + QReadLocker lock(getLock()); + return DependencyManager::get()->getPrevRayPickResult(_rayPickUID); +} + void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) { if (!renderState.getStartID().isNull()) { QVariantMap startProps; @@ -183,6 +192,8 @@ void LaserPointer::disableRenderState(const RenderState& renderState) { } void LaserPointer::update() { + // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts + QReadLocker lock(getLock()); RayPickResult prevRayPickResult = DependencyManager::get()->getPrevRayPickResult(_rayPickUID); if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { @@ -198,6 +209,51 @@ void LaserPointer::update() { } } +void LaserPointer::setPrecisionPicking(const bool precisionPicking) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); +} + +void LaserPointer::setLaserLength(const float laserLength) { + QWriteLocker lock(getLock()); + _laserLength = laserLength; +} + +void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { + QWriteLocker lock(getLock()); + _objectLockEnd = std::pair(objectID, isOverlay); +} + +void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); +} + +void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); +} + +void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); +} + +void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeOverlays(_rayPickUID, includeOverlays); +} + +void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); +} + +void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); +} + RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : _startID(startID), _pathID(pathID), _endID(endID) { diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index fa7d396ae8..01dfe01cfd 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -58,22 +58,22 @@ public: QUuid getRayUID() { return _rayPickUID; } void enable(); void disable(); - const RayPickResult getPrevRayPickResult() { return DependencyManager::get()->getPrevRayPickResult(_rayPickUID); } + const RayPickResult getPrevRayPickResult(); void setRenderState(const std::string& state); // You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays. void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); - void setPrecisionPicking(const bool precisionPicking) { DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); } - void setLaserLength(const float laserLength) { _laserLength = laserLength; } - void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); } - void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); } - void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); } - void setIncludeOverlays(const QScriptValue& includeOverlays) { DependencyManager::get()->setIncludeOverlays(_rayPickUID, includeOverlays); } - void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); } - void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); } + void setPrecisionPicking(const bool precisionPicking); + void setLaserLength(const float laserLength); + void setLockEndUUID(QUuid objectID, const bool isOverlay); - void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair(objectID, isOverlay); } + void setIgnoreEntities(const QScriptValue& ignoreEntities); + void setIncludeEntities(const QScriptValue& includeEntities); + void setIgnoreOverlays(const QScriptValue& ignoreOverlays); + void setIncludeOverlays(const QScriptValue& includeOverlays); + void setIgnoreAvatars(const QScriptValue& ignoreAvatars); + void setIncludeAvatars(const QScriptValue& includeAvatars); QReadWriteLock* getLock() { return &_lock; } diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 387f88724e..8615a96c3f 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -31,7 +31,6 @@ void LaserPointerManager::enableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->enable(); } } @@ -40,7 +39,6 @@ void LaserPointerManager::disableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->disable(); } } @@ -49,7 +47,6 @@ void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderSta QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setRenderState(renderState); } } @@ -58,7 +55,6 @@ void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, c QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->editRenderState(state, startProps, pathProps, endProps); } } @@ -67,7 +63,6 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QReadLocker laserLock(laserPointer.value()->getLock()); return laserPointer.value()->getPrevRayPickResult(); } return RayPickResult(); @@ -76,9 +71,7 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { void LaserPointerManager::update() { QReadLocker lock(&_containsLock); for (QUuid& uid : _laserPointers.keys()) { - // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts auto laserPointer = _laserPointers.find(uid); - QReadLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->update(); } } @@ -87,7 +80,6 @@ void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPic QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setPrecisionPicking(precisionPicking); } } @@ -96,7 +88,6 @@ void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setLaserLength(laserLength); } } @@ -105,7 +96,6 @@ void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignor QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreEntities(ignoreEntities); } } @@ -114,7 +104,6 @@ void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& incl QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeEntities(includeEntities); } } @@ -123,7 +112,6 @@ void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignor QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreOverlays(ignoreOverlays); } } @@ -132,7 +120,6 @@ void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& incl QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeOverlays(includeOverlays); } } @@ -141,7 +128,6 @@ void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignore QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreAvatars(ignoreAvatars); } } @@ -150,7 +136,6 @@ void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& inclu QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeAvatars(includeAvatars); } } @@ -159,7 +144,6 @@ void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool i QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setLockEndUUID(objectID, isOverlay); } } diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 70170a8f85..a5b1299210 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -16,3 +16,47 @@ RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const boo _enabled(enabled) { } +void RayPick::enable() { + QWriteLocker lock(getLock()); + _enabled = true; +} + +void RayPick::disable() { + QWriteLocker lock(getLock()); + _enabled = false; +} + +const RayPickResult& RayPick::getPrevRayPickResult() { + QReadLocker lock(getLock()); + return _prevResult; +} + +void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) { + QWriteLocker lock(getLock()); + _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); +} + +void RayPick::setIncludeEntities(const QScriptValue& includeEntities) { + QWriteLocker lock(getLock()); + _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); +} + +void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { + QWriteLocker lock(getLock()); + _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); +} + +void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) { + QWriteLocker lock(getLock()); + _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); +} + +void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { + QWriteLocker lock(getLock()); + _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); +} + +void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) { + QWriteLocker lock(getLock()); + _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); +} \ No newline at end of file diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 428e44d670..6dacc084b4 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -103,13 +103,13 @@ public: virtual const PickRay getPickRay(bool& valid) const = 0; - void enable() { _enabled = true; } - void disable() { _enabled = false; } + void enable(); + void disable(); const RayPickFilter& getFilter() { return _filter; } float getMaxDistance() { return _maxDistance; } bool isEnabled() { return _enabled; } - const RayPickResult& getPrevRayPickResult() { return _prevResult; } + const RayPickResult& getPrevRayPickResult(); void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); } @@ -121,12 +121,12 @@ public: const QVector& getIncludeOverlays() { return _includeOverlays; } const QVector& getIgnoreAvatars() { return _ignoreAvatars; } const QVector& getIncludeAvatars() { return _includeAvatars; } - void setIgnoreEntities(const QScriptValue& ignoreEntities) { _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); } - void setIncludeEntities(const QScriptValue& includeEntities) { _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); } - void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); } - void setIncludeOverlays(const QScriptValue& includeOverlays) { _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); } - void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); } - void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); } + void setIgnoreEntities(const QScriptValue& ignoreEntities); + void setIncludeEntities(const QScriptValue& includeEntities); + void setIgnoreOverlays(const QScriptValue& ignoreOverlays); + void setIncludeOverlays(const QScriptValue& includeOverlays); + void setIgnoreAvatars(const QScriptValue& ignoreAvatars); + void setIncludeAvatars(const QScriptValue& includeAvatars); QReadWriteLock* getLock() { return &_lock; } diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index 65f82dcd5f..1728ecd01a 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -153,7 +153,6 @@ void RayPickManager::enableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker rayPickLock(rayPick.value()->getLock()); rayPick.value()->enable(); } } @@ -162,7 +161,6 @@ void RayPickManager::disableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker rayPickLock(rayPick.value()->getLock()); rayPick.value()->disable(); } } @@ -171,7 +169,6 @@ const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QReadLocker lock(rayPick.value()->getLock()); return rayPick.value()->getPrevRayPickResult(); } return RayPickResult(); @@ -181,7 +178,6 @@ void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setPrecisionPicking(precisionPicking); } } @@ -190,7 +186,6 @@ void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEnti QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreEntities(ignoreEntities); } } @@ -199,7 +194,6 @@ void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEn QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeEntities(includeEntities); } } @@ -208,7 +202,6 @@ void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOver QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreOverlays(ignoreOverlays); } } @@ -217,7 +210,6 @@ void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOv QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeOverlays(includeOverlays); } } @@ -226,7 +218,6 @@ void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvata QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreAvatars(ignoreAvatars); } } @@ -235,7 +226,6 @@ void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAva QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeAvatars(includeAvatars); } } \ No newline at end of file