diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index c0278a6496..b450fbdc05 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -256,15 +256,74 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3 void Base3DOverlay::locationChanged(bool tellPhysics) { SpatiallyNestable::locationChanged(tellPhysics); - auto itemID = getRenderItemID(); + // 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) { + 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(); + 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) { + auto latestTransform = overlay3D->evalRenderTransform(); + overlay3D->setRenderTransform(latestTransform);// evalRenderTransform(); + } + }); + #endif + scene->enqueueTransaction(transaction); + + } + // }); + _renderTransformDirty = false; + } +} + +void Base3DOverlay::notifyRenderTransformChange() const { + _renderTransformDirty = true; +} + +Transform Base3DOverlay::evalRenderTransform() const { + return getTransform(); +} + +void Base3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; +} \ No newline at end of file diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 6377b46d7d..b2167852d4 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -52,6 +52,12 @@ public: virtual AABox getBounds() const override = 0; + void update(float deltatime) override; + + void notifyRenderTransformChange() const; + virtual Transform evalRenderTransform() const; + void setRenderTransform(const Transform& transform); + void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -67,12 +73,15 @@ protected: virtual void locationChanged(bool tellPhysics = true) override; virtual void parentDeleted() override; + mutable Transform _renderTransform; + float _lineWidth; bool _isSolid; bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; bool _isGrabbable { false }; + mutable bool _renderTransformDirty{ true }; QString _name; }; diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 58d72b100b..e2877e1e07 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -66,3 +66,11 @@ 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..2ed90ab4ed 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 104082dee4..fd3763624e 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -184,6 +184,7 @@ void Web3DOverlay::update(float deltatime) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } + Billboard3DOverlay::update(deltatime); } QString Web3DOverlay::pickURL() { @@ -306,19 +307,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()); _texture->setSource(__FUNCTION__); @@ -332,7 +320,8 @@ 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) { geometryCache->bindWebBrowserProgram(batch, true);