diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 6ff2ff576c..e8f57ea834 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -363,6 +363,14 @@ bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity return false; } +void EntityRenderer::updateModelTransform() { + bool success = false; + auto newModelTransform = _entity->getTransformToCenter(success); + if (success) { + _modelTransform = newModelTransform; + } +} + void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); withWriteLock([&] { @@ -419,4 +427,4 @@ void EntityRenderer::addMaterial(graphics::MaterialLayer material, const std::st void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { std::lock_guard lock(_materialsLock); _materials[parentMaterialName].remove(material); -} \ No newline at end of file +} diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index e1ce2ed39e..40966c4f41 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -97,6 +97,7 @@ protected: virtual void doRender(RenderArgs* args) = 0; bool isFading() const { return _isFading; } + void updateModelTransform(); virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; } inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; } @@ -140,6 +141,7 @@ protected: bool _needsRenderUpdate { false }; // Only touched on the rendering thread bool _renderUpdateQueued{ false }; + Transform _renderTransform; std::unordered_map _materials; std::mutex _materialsLock; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 96c720f79f..168041a842 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -35,7 +35,6 @@ private: glm::vec2 _materialMappingPos; glm::vec2 _materialMappingScale; float _materialMappingRot; - Transform _renderTransform; std::shared_ptr _drawMaterial; }; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 2fb4877ed3..a6a6dc05f2 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -122,6 +122,14 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi }); } } + + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] () { + withWriteLock([&] { + updateModelTransform(); + _renderTransform = getModelTransform(); + }); + }); } void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { @@ -319,7 +327,10 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) { // In trail mode, the particles are created in world space. // so we only set a transform if they're not in trail mode if (!_particleProperties.emission.shouldTrail) { - transform = getModelTransform(); + + withReadLock([&] { + transform = _renderTransform; + }); transform.setScale(vec3(1)); } batch.setModelTransform(transform); diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 69068b81d2..2e0656ab81 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -97,16 +97,25 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce addMaterial(graphics::MaterialLayer(_material, 0), "0"); _shape = entity->getShape(); - _position = entity->getWorldPosition(); - _dimensions = entity->getScaledDimensions(); - _orientation = entity->getWorldOrientation(); - _renderTransform = getModelTransform(); + }); - if (_shape == entity::Sphere) { - _renderTransform.postScale(SPHERE_ENTITY_SCALE); - } + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this] () { + withWriteLock([&] { + auto entity = getEntity(); + _position = entity->getWorldPosition(); + _dimensions = entity->getScaledDimensions(); + _orientation = entity->getWorldOrientation(); + bool success = false; + auto newModelTransform = entity->getTransformToCenter(success); + _renderTransform = success ? newModelTransform : getModelTransform(); - _renderTransform.postScale(_dimensions); + if (_shape == entity::Sphere) { + _renderTransform.postScale(SPHERE_ENTITY_SCALE); + } + + _renderTransform.postScale(_dimensions); + });; }); } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.h b/libraries/entities-renderer/src/RenderableShapeEntityItem.h index 463ef187fc..7700aa6ef0 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.h +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.h @@ -40,7 +40,6 @@ private: Procedural _procedural; QString _lastUserData; - Transform _renderTransform; entity::Shape _shape { entity::Sphere }; std::shared_ptr _material; glm::vec3 _position; diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index e58eb540e8..ce4b6d9175 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -20,6 +20,7 @@ #include "GLMHelpers.h" +using namespace render; using namespace render::entities; static const int FIXED_FONT_POINT_SIZE = 40; @@ -64,10 +65,20 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint return false; } +void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () { + withWriteLock([&] { + _dimensions = entity->getScaledDimensions(); + updateModelTransform(); + _renderTransform = getModelTransform(); + }); + }); +} + void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _textColor = toGlm(entity->getTextColorX()); _backgroundColor = toGlm(entity->getBackgroundColorX()); - _dimensions = entity->getScaledDimensions(); _faceCamera = entity->getFaceCamera(); _lineHeight = entity->getLineHeight(); _text = entity->getText(); @@ -76,24 +87,28 @@ void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe void TextEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); - + + Transform modelTransform; + glm::vec3 dimensions; + withReadLock([&] { + modelTransform = _renderTransform; + dimensions = _dimensions; + }); static const float SLIGHTLY_BEHIND = -0.005f; float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; bool transparent = fadeRatio < 1.0f; glm::vec4 textColor = glm::vec4(_textColor, fadeRatio); glm::vec4 backgroundColor = glm::vec4(_backgroundColor, fadeRatio); - const glm::vec3& dimensions = _dimensions; - + // Render background glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, SLIGHTLY_BEHIND); glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, SLIGHTLY_BEHIND); - - + + // Batch render calls Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - const auto& modelTransform = getModelTransform(); auto transformToTopLeft = modelTransform; if (_faceCamera) { //rotate about vertical to face the camera @@ -105,7 +120,7 @@ void TextEntityRenderer::doRender(RenderArgs* args) { } transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed - + batch.setModelTransform(transformToTopLeft); auto geometryCache = DependencyManager::get(); if (!_geometryID) { @@ -113,11 +128,11 @@ void TextEntityRenderer::doRender(RenderArgs* args) { } geometryCache->bindSimpleProgram(batch, false, transparent, false, false, false); geometryCache->renderQuad(batch, minCorner, maxCorner, backgroundColor, _geometryID); - + float scale = _lineHeight / _textRenderer->getFontSize(); transformToTopLeft.setScale(scale); // Scale to have the correct line height batch.setModelTransform(transformToTopLeft); - + float leftMargin = 0.1f * _lineHeight, topMargin = 0.1f * _lineHeight; glm::vec2 bounds = glm::vec2(dimensions.x - 2.0f * leftMargin, dimensions.y - 2.0f * topMargin); diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index b0a72cf253..ac7f2b620f 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -27,6 +27,7 @@ public: ~TextEntityRenderer(); private: virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; + virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; int _geometryID{ 0 }; @@ -39,6 +40,6 @@ private: float _lineHeight; }; -} } +} } #endif // hifi_RenderableTextEntityItem_h diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 693e3d0cf4..17d6d58781 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -149,8 +149,8 @@ void WebEntityRenderer::onTimeout() { } void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - // If the content type has changed, or the old content type was QML, we need to - // destroy the existing surface (because surfaces don't support changing the root + // If the content type has changed, or the old content type was QML, we need to + // destroy the existing surface (because surfaces don't support changing the root // object, so subsequent loads of content just overlap the existing content bool urlChanged = false; { @@ -187,24 +187,30 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene if (!hasWebSurface() && !buildWebSurface(entity)) { return; } - + if (urlChanged && _contentType == ContentType::HtmlContent) { _webSurface->getRootItem()->setProperty(URL_PROPERTY, _lastSourceUrl); } - if (_contextPosition != entity->getWorldPosition()) { - // update globalPosition - _contextPosition = entity->getWorldPosition(); - _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(_contextPosition)); - } + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] () { + withWriteLock([&] { + if (_contextPosition != entity->getWorldPosition()) { + // update globalPosition + _contextPosition = entity->getWorldPosition(); + _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(_contextPosition)); + } - _lastDPI = entity->getDPI(); - _lastLocked = entity->getLocked(); + _lastDPI = entity->getDPI(); + _lastLocked = entity->getLocked(); - glm::vec2 windowSize = getWindowSize(entity); - _webSurface->resize(QSize(windowSize.x, windowSize.y)); - _renderTransform = getModelTransform(); - _renderTransform.postScale(entity->getScaledDimensions()); + glm::vec2 windowSize = getWindowSize(entity); + _webSurface->resize(QSize(windowSize.x, windowSize.y)); + updateModelTransform(); + _renderTransform = getModelTransform(); + _renderTransform.postScale(entity->getScaledDimensions()); + }); + }); }); } @@ -297,7 +303,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) { if (_contentType == ContentType::HtmlContent) { // We special case YouTube URLs since we know they are videos that we should play with at least 30 FPS. - // FIXME this doesn't handle redirects or shortened URLs, consider using a signaling method from the + // FIXME this doesn't handle redirects or shortened URLs, consider using a signaling method from the // web entity if (QUrl(_lastSourceUrl).host().endsWith("youtube.com", Qt::CaseInsensitive)) { _webSurface->setMaxFps(YOUTUBE_MAX_FPS); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 3100014e9b..1ba8ed0ec7 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -68,7 +68,6 @@ private: bool _lastLocked; QTimer _timer; uint64_t _lastRenderTime { 0 }; - Transform _renderTransform; }; } } // namespace diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index 2f8fd47b79..c48679e5d4 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -123,7 +123,6 @@ private: bool _pendingSkyboxTexture{ false }; QString _proceduralUserData; - Transform _renderTransform; }; } } // namespace