diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 807a240763..32dd280502 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -431,13 +431,13 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa _visible = entity->getVisible(); setIsVisibleInSecondaryCamera(entity->isVisibleInSecondaryCamera()); setRenderLayer(entity->getRenderLayer()); - setPrimitiveMode(entity->getPrimitiveMode()); + _primitiveMode = entity->getPrimitiveMode(); _canCastShadow = entity->getCanCastShadow(); setCullWithParent(entity->getCullWithParent()); _cauterized = entity->getCauterized(); if (entity->needsZoneOcclusionUpdate()) { entity->resetNeedsZoneOcclusionUpdate(); - setRenderWithZones(entity->getRenderWithZones()); + _renderWithZones = entity->getRenderWithZones(); } entity->setNeedsRenderUpdate(false); }); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 69fb9aca23..ca3e024338 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -108,18 +108,7 @@ protected: virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; } virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; } - virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; } virtual void setCullWithParent(bool value) { _cullWithParent = value; } - virtual void setRenderWithZones(const QVector& renderWithZones) { _renderWithZones = renderWithZones; } - - template - T withReadLockResult(const std::function& f) { - T result; - withReadLock([&] { - result = f(); - }); - return result; - } signals: void requestRenderUpdate(); diff --git a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp index 7a36ae2707..6928454eb0 100644 --- a/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGizmoEntityItem.cpp @@ -52,14 +52,11 @@ void GizmoEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { bool dirty = false; RingGizmoPropertyGroup ringProperties = entity->getRingProperties(); - withWriteLock([&] { - _gizmoType = entity->getGizmoType(); - if (_ringProperties != ringProperties) { - _ringProperties = ringProperties; - dirty = true; - - } - }); + _gizmoType = entity->getGizmoType(); + if (_ringProperties != ringProperties) { + _ringProperties = ringProperties; + dirty = true; + } if (dirty || _prevPrimitiveMode != _primitiveMode || !_ringGeometryID || !_majorTicksGeometryID || !_minorTicksGeometryID) { _prevPrimitiveMode = _primitiveMode; @@ -242,19 +239,20 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) { if (_gizmoType == GizmoType::RING) { Transform transform; - bool hasTickMarks; - glm::vec4 tickProperties; + bool hasTickMarks = _ringProperties.getHasTickMarks(); + glm::vec4 tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(), + _ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength()); bool forward; + bool wireframe; + bool transparent; withReadLock([&] { transform = _renderTransform; - hasTickMarks = _ringProperties.getHasTickMarks(); - tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(), - _ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength()); + transparent = isTransparent(); + wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; }); - bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES; - geometryCache->bindSimpleProgram(batch, false, isTransparent(), wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE); + geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE); batch.setModelTransform(transform); diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp index 52900d0798..35702c63e4 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.cpp @@ -30,16 +30,6 @@ bool GridEntityRenderer::isTransparent() const { } void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - withWriteLock([&] { - _color = entity->getColor(); - _alpha = entity->getAlpha(); - _pulseProperties = entity->getPulseProperties(); - - _followCamera = entity->getFollowCamera(); - _majorGridEvery = entity->getMajorGridEvery(); - _minorGridEvery = entity->getMinorGridEvery(); - }); - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { withWriteLock([&] { @@ -49,6 +39,16 @@ void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen }); } +void GridEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + _color = entity->getColor(); + _alpha = entity->getAlpha(); + _pulseProperties = entity->getPulseProperties(); + + _followCamera = entity->getFollowCamera(); + _majorGridEvery = entity->getMajorGridEvery(); + _minorGridEvery = entity->getMinorGridEvery(); +} + Item::Bound GridEntityRenderer::getBound() { if (_followCamera) { // This is a UI element that should always be in view, lie to the octree to avoid culling @@ -73,13 +73,12 @@ ShapeKey GridEntityRenderer::getShapeKey() { } void GridEntityRenderer::doRender(RenderArgs* args) { - glm::vec4 color; + glm::vec4 color = glm::vec4(toGlm(_color), _alpha); + color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); glm::vec3 dimensions; Transform renderTransform; bool forward; withReadLock([&] { - color = glm::vec4(toGlm(_color), _alpha); - color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); dimensions = _dimensions; renderTransform = _renderTransform; forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD; diff --git a/libraries/entities-renderer/src/RenderableGridEntityItem.h b/libraries/entities-renderer/src/RenderableGridEntityItem.h index 2ecff01d01..3cd8bab822 100644 --- a/libraries/entities-renderer/src/RenderableGridEntityItem.h +++ b/libraries/entities-renderer/src/RenderableGridEntityItem.h @@ -30,10 +30,11 @@ protected: private: 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; - glm::u8vec3 _color; - float _alpha; + glm::u8vec3 _color { NAN }; + float _alpha { NAN }; PulsePropertyGroup _pulseProperties; bool _followCamera; diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp index 4d19a83ae6..b9b30ea9c7 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.cpp @@ -29,44 +29,7 @@ bool ImageEntityRenderer::isTransparent() const { return Parent::isTransparent() || (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()) || _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; } -bool ImageEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - return !_textureIsLoaded; - })) { - return true; - } - - return Parent::needsRenderUpdate(); -} - void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { - withWriteLock([&] { - auto imageURL = entity->getImageURL(); - if (_imageURL != imageURL) { - _imageURL = imageURL; - if (imageURL.isEmpty()) { - _texture.reset(); - } else { - _texture = DependencyManager::get()->getTexture(_imageURL); - } - _textureIsLoaded = false; - } - - _emissive = entity->getEmissive(); - _keepAspectRatio = entity->getKeepAspectRatio(); - _subImage = entity->getSubImage(); - - _color = entity->getColor(); - _alpha = entity->getAlpha(); - _pulseProperties = entity->getPulseProperties(); - _billboardMode = entity->getBillboardMode(); - - if (!_textureIsLoaded) { - emit requestRenderUpdate(); - } - _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); - }); - void* key = (void*)this; AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { withWriteLock([&] { @@ -76,6 +39,33 @@ void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce }); } +void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + auto imageURL = entity->getImageURL(); + if (_imageURL != imageURL) { + _imageURL = imageURL; + if (imageURL.isEmpty()) { + _texture.reset(); + } else { + _texture = DependencyManager::get()->getTexture(_imageURL); + } + _textureIsLoaded = false; + } + + _emissive = entity->getEmissive(); + _keepAspectRatio = entity->getKeepAspectRatio(); + _subImage = entity->getSubImage(); + + _color = entity->getColor(); + _alpha = entity->getAlpha(); + _pulseProperties = entity->getPulseProperties(); + _billboardMode = entity->getBillboardMode(); + + if (!_textureIsLoaded) { + emit requestRenderUpdate(); + } + _textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed()); +} + Item::Bound ImageEntityRenderer::getBound() { auto bound = Parent::getBound(); if (_billboardMode != BillboardMode::NONE) { @@ -93,33 +83,26 @@ ShapeKey ImageEntityRenderer::getShapeKey() { builder.withTranslucent(); } - withReadLock([&] { - if (_emissive) { - builder.withUnlit(); - } + if (_emissive) { + builder.withUnlit(); + } - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); - } - }); + if (_primitiveMode == PrimitiveMode::LINES) { + builder.withWireframe(); + } return builder.build(); } void ImageEntityRenderer::doRender(RenderArgs* args) { - NetworkTexturePointer texture; - QRect subImage; - glm::vec4 color; + glm::vec4 color = glm::vec4(toGlm(_color), _alpha); + color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); Transform transform; withReadLock([&] { - texture = _texture; - subImage = _subImage; - color = glm::vec4(toGlm(_color), _alpha); - color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created); transform = _renderTransform; }); - if (!_visible || !texture || !texture->isLoaded() || color.a == 0.0f) { + if (!_visible || !_texture || !_texture->isLoaded() || color.a == 0.0f) { return; } @@ -129,28 +112,28 @@ void ImageEntityRenderer::doRender(RenderArgs* args) { transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition())); batch->setModelTransform(transform); - batch->setResourceTexture(0, texture->getGPUTexture()); + batch->setResourceTexture(0, _texture->getGPUTexture()); - float imageWidth = texture->getWidth(); - float imageHeight = texture->getHeight(); + float imageWidth = _texture->getWidth(); + float imageHeight = _texture->getHeight(); QRect fromImage; - if (subImage.width() <= 0) { + if (_subImage.width() <= 0) { fromImage.setX(0); fromImage.setWidth(imageWidth); } else { - float scaleX = imageWidth / texture->getOriginalWidth(); - fromImage.setX(scaleX * subImage.x()); - fromImage.setWidth(scaleX * subImage.width()); + float scaleX = imageWidth / _texture->getOriginalWidth(); + fromImage.setX(scaleX * _subImage.x()); + fromImage.setWidth(scaleX * _subImage.width()); } - if (subImage.height() <= 0) { + if (_subImage.height() <= 0) { fromImage.setY(0); fromImage.setHeight(imageHeight); } else { - float scaleY = imageHeight / texture->getOriginalHeight(); - fromImage.setY(scaleY * subImage.y()); - fromImage.setHeight(scaleY * subImage.height()); + float scaleY = imageHeight / _texture->getOriginalHeight(); + fromImage.setY(scaleY * _subImage.y()); + fromImage.setHeight(scaleY * _subImage.height()); } float maxSize = glm::max(fromImage.width(), fromImage.height()); diff --git a/libraries/entities-renderer/src/RenderableImageEntityItem.h b/libraries/entities-renderer/src/RenderableImageEntityItem.h index d73bc9bc05..35d60a230f 100644 --- a/libraries/entities-renderer/src/RenderableImageEntityItem.h +++ b/libraries/entities-renderer/src/RenderableImageEntityItem.h @@ -29,8 +29,8 @@ protected: bool isTransparent() const override; private: - virtual bool needsRenderUpdate() 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; QString _imageURL; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index c1b024a478..8d9ce24992 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -16,199 +16,186 @@ using namespace render; using namespace render::entities; -bool MaterialEntityRenderer::needsRenderUpdate() const { - if (_retryApply) { - return true; - } - if (!_texturesLoaded) { - return true; - } - return Parent::needsRenderUpdate(); -} - bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { - if (entity->getTransform() != _transform) { - return true; - } - if (entity->getUnscaledDimensions() != _dimensions) { - return true; - } - if (entity->getParentID() != _parentID) { - return true; - } - - return false; + return entity->getParentID() != _parentID; })) { return true; } return false; } -void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { - withWriteLock([&] { - bool deleteNeeded = false; - bool addNeeded = _retryApply; - bool transformChanged = false; - { - MaterialMappingMode mode = entity->getMaterialMappingMode(); - if (mode != _materialMappingMode) { - _materialMappingMode = mode; - transformChanged = true; - } - } - { - bool repeat = entity->getMaterialRepeat(); - if (repeat != _materialRepeat) { - _materialRepeat = repeat; - transformChanged = true; - } - } - { - glm::vec2 mappingPos = entity->getMaterialMappingPos(); - glm::vec2 mappingScale = entity->getMaterialMappingScale(); - float mappingRot = entity->getMaterialMappingRot(); - if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) { - _materialMappingPos = mappingPos; - _materialMappingScale = mappingScale; - _materialMappingRot = mappingRot; - transformChanged |= _materialMappingMode == MaterialMappingMode::UV; - } - } - { - Transform transform = entity->getTransform(); - glm::vec3 dimensions = entity->getUnscaledDimensions(); - if (transform != _transform || dimensions != _dimensions) { - _transform = transform; - _dimensions = dimensions; - transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED; - } - } - - { - auto material = getMaterial(); - // Update the old material regardless of if it's going to change - if (transformChanged && material && !_parentID.isNull()) { - deleteNeeded = true; - addNeeded = true; - applyTextureTransform(material); - } - } - - bool urlChanged = false; - std::string newCurrentMaterialName = _currentMaterialName; - { - QString materialURL = entity->getMaterialURL(); - if (materialURL != _materialURL) { - _materialURL = materialURL; - if (_materialURL.contains("#")) { - auto split = _materialURL.split("#"); - newCurrentMaterialName = split.last().toStdString(); - } else if (_materialURL.contains("?")) { - qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL; - auto split = _materialURL.split("?"); - newCurrentMaterialName = split.last().toStdString(); - } - urlChanged = true; - } - } - - bool usingMaterialData = _materialURL.startsWith("materialData"); - bool materialDataChanged = false; - QUuid oldParentID = _parentID; - QString oldParentMaterialName = _parentMaterialName; - { - QString materialData = entity->getMaterialData(); - if (materialData != _materialData) { - _materialData = materialData; - if (usingMaterialData) { - materialDataChanged = true; - } - } - } - { - QString parentMaterialName = entity->getParentMaterialName(); - if (parentMaterialName != _parentMaterialName) { - _parentMaterialName = parentMaterialName; - deleteNeeded = true; - addNeeded = true; - } - } - { - QUuid parentID = entity->getParentID(); - if (parentID != _parentID) { - _parentID = parentID; - deleteNeeded = true; - addNeeded = true; - } - } - { - quint16 priority = entity->getPriority(); - if (priority != _priority) { - _priority = priority; - deleteNeeded = true; - addNeeded = true; - } - } - - if (urlChanged && !usingMaterialData) { - _networkMaterial = DependencyManager::get()->getMaterial(_materialURL); - auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { - if (success) { - deleteMaterial(oldParentID, oldParentMaterialName); - _texturesLoaded = false; - _parsedMaterials = _networkMaterial->parsedMaterials; - setCurrentMaterialName(newCurrentMaterialName); - applyMaterial(entity); - } else { - deleteMaterial(oldParentID, oldParentMaterialName); - _retryApply = false; - _texturesLoaded = true; - } - }; - if (_networkMaterial) { - if (_networkMaterial->isLoaded()) { - onMaterialRequestFinished(!_networkMaterial->isFailed()); - } else { - connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) { - withWriteLock([&] { - onMaterialRequestFinished(success); - }); - }); - } - } - } else if (materialDataChanged && usingMaterialData) { - deleteMaterial(oldParentID, oldParentMaterialName); - _texturesLoaded = false; - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); - // Since our material changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(newCurrentMaterialName); - applyMaterial(entity); - } else { - if (deleteNeeded) { - deleteMaterial(oldParentID, oldParentMaterialName); - } - if (addNeeded) { - applyMaterial(entity); - } - } - - { - auto material = getMaterial(); - bool newTexturesLoaded = material ? !material->isMissingTexture() : false; - if (!_texturesLoaded && newTexturesLoaded) { - material->checkResetOpacityMap(); - } - _texturesLoaded = newTexturesLoaded; - } - - _renderTransform = getModelTransform(); - const float MATERIAL_ENTITY_SCALE = 0.5f; - _renderTransform.postScale(MATERIAL_ENTITY_SCALE); - _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); +void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { + void* key = (void*)this; + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] { + withWriteLock([&] { + _renderTransform = getModelTransform(); + const float MATERIAL_ENTITY_SCALE = 0.5f; + _renderTransform.postScale(MATERIAL_ENTITY_SCALE); + _renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS); + }); }); } +void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + bool deleteNeeded = false; + bool addNeeded = _retryApply; + bool transformChanged = false; + { + MaterialMappingMode mode = entity->getMaterialMappingMode(); + if (mode != _materialMappingMode) { + _materialMappingMode = mode; + transformChanged = true; + } + } + { + bool repeat = entity->getMaterialRepeat(); + if (repeat != _materialRepeat) { + _materialRepeat = repeat; + transformChanged = true; + } + } + { + glm::vec2 mappingPos = entity->getMaterialMappingPos(); + glm::vec2 mappingScale = entity->getMaterialMappingScale(); + float mappingRot = entity->getMaterialMappingRot(); + if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) { + _materialMappingPos = mappingPos; + _materialMappingScale = mappingScale; + _materialMappingRot = mappingRot; + transformChanged |= _materialMappingMode == MaterialMappingMode::UV; + } + } + { + Transform transform = entity->getTransform(); + glm::vec3 dimensions = entity->getUnscaledDimensions(); + if (transform != _transform || dimensions != _dimensions) { + _transform = transform; + _dimensions = dimensions; + transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED; + } + } + + { + auto material = getMaterial(); + // Update the old material regardless of if it's going to change + if (transformChanged && material && !_parentID.isNull()) { + deleteNeeded = true; + addNeeded = true; + applyTextureTransform(material); + } + } + + bool urlChanged = false; + std::string newCurrentMaterialName = _currentMaterialName; + { + QString materialURL = entity->getMaterialURL(); + if (materialURL != _materialURL) { + _materialURL = materialURL; + if (_materialURL.contains("#")) { + auto split = _materialURL.split("#"); + newCurrentMaterialName = split.last().toStdString(); + } else if (_materialURL.contains("?")) { + qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL; + auto split = _materialURL.split("?"); + newCurrentMaterialName = split.last().toStdString(); + } + urlChanged = true; + } + } + + bool usingMaterialData = _materialURL.startsWith("materialData"); + bool materialDataChanged = false; + QUuid oldParentID = _parentID; + QString oldParentMaterialName = _parentMaterialName; + { + QString materialData = entity->getMaterialData(); + if (materialData != _materialData) { + _materialData = materialData; + if (usingMaterialData) { + materialDataChanged = true; + } + } + } + { + QString parentMaterialName = entity->getParentMaterialName(); + if (parentMaterialName != _parentMaterialName) { + _parentMaterialName = parentMaterialName; + deleteNeeded = true; + addNeeded = true; + } + } + { + QUuid parentID = entity->getParentID(); + if (parentID != _parentID) { + _parentID = parentID; + deleteNeeded = true; + addNeeded = true; + } + } + { + quint16 priority = entity->getPriority(); + if (priority != _priority) { + _priority = priority; + deleteNeeded = true; + addNeeded = true; + } + } + + if (urlChanged && !usingMaterialData) { + _networkMaterial = DependencyManager::get()->getMaterial(_materialURL); + auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { + deleteMaterial(oldParentID, oldParentMaterialName); + if (success) { + _texturesLoaded = false; + _parsedMaterials = _networkMaterial->parsedMaterials; + setCurrentMaterialName(newCurrentMaterialName); + applyMaterial(entity); + emit requestRenderUpdate(); + } else { + _retryApply = false; + _texturesLoaded = true; + } + }; + if (_networkMaterial) { + if (_networkMaterial->isLoaded()) { + onMaterialRequestFinished(!_networkMaterial->isFailed()); + } else { + connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) { + onMaterialRequestFinished(success); + }); + } + } + } else if (materialDataChanged && usingMaterialData) { + deleteMaterial(oldParentID, oldParentMaterialName); + _texturesLoaded = false; + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); + // Since our material changed, the current name might not be valid anymore, so we need to update + setCurrentMaterialName(newCurrentMaterialName); + applyMaterial(entity); + } else { + if (deleteNeeded) { + deleteMaterial(oldParentID, oldParentMaterialName); + } + if (addNeeded) { + applyMaterial(entity); + } + } + + { + auto material = getMaterial(); + bool newTexturesLoaded = material ? !material->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + material->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; + } + + if (!_texturesLoaded || _retryApply) { + emit requestRenderUpdate(); + } +} + ItemKey MaterialEntityRenderer::getKey() { auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); @@ -276,25 +263,26 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { return; } - Transform renderTransform; - graphics::MaterialPointer drawMaterial; + graphics::MaterialPointer drawMaterial = getMaterial(); bool proceduralRender = false; Transform textureTransform; + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); + textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); + + Transform renderTransform; withReadLock([&] { renderTransform = _renderTransform; - drawMaterial = getMaterial(); - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); - textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); - - if (drawMaterial && drawMaterial->isProcedural() && drawMaterial->isReady()) { - proceduralRender = true; - } }); + if (!drawMaterial) { return; } + if (drawMaterial->isProcedural() && drawMaterial->isReady()) { + proceduralRender = true; + } + batch.setModelTransform(renderTransform); if (!proceduralRender) { diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 3a73c988eb..7d455c98de 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -27,8 +27,8 @@ public: ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } private: - virtual bool needsRenderUpdate() const override; 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; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 8c766d0ab8..a508ff7f56 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -53,7 +53,7 @@ ModelPointer ModelEntityWrapper::getModel() const { bool ModelEntityWrapper::isModelLoaded() const { return resultWithReadLock([&] { - return _model.operator bool() && _model->isLoaded(); + return _model && _model->isLoaded(); }); } @@ -69,8 +69,7 @@ EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityI RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) : ModelEntityWrapper(entityItemID), _dimensionsInitialized(dimensionsInitialized) { - - + } RenderableModelEntityItem::~RenderableModelEntityItem() { } @@ -182,20 +181,24 @@ void RenderableModelEntityItem::updateModelBounds() { } bool overridingModelTransform = model->isOverridingModelTransformAndOffset(); + glm::vec3 scaledDimensions = getScaledDimensions(); + glm::vec3 registrationPoint = getRegistrationPoint(); + QString modelURL = getModelURL(); if (!overridingModelTransform && - (model->getScaleToFitDimensions() != getScaledDimensions() || - model->getRegistrationPoint() != getRegistrationPoint() || + (model->getScaleToFitDimensions() != scaledDimensions || + model->getRegistrationPoint() != registrationPoint || + model->getURL() != modelURL || !model->getIsScaledToFit())) { // The machinery for updateModelBounds will give existing models the opportunity to fix their // translation/rotation/scale/registration. The first two are straightforward, but the latter two // have guards to make sure they don't happen after they've already been set. Here we reset those guards. // This doesn't cause the entity values to change -- it just allows the model to match once it comes in. - model->setScaleToFit(false, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); + model->setScaleToFit(false, scaledDimensions); + model->setSnapModelToRegistrationPoint(false, registrationPoint); // now recalculate the bounds and registration - model->setScaleToFit(true, getScaledDimensions()); - model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + model->setScaleToFit(true, scaledDimensions); + model->setSnapModelToRegistrationPoint(true, registrationPoint); updateRenderItems = true; model->scaleToFit(); } @@ -248,8 +251,6 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper } } - - return properties; } @@ -960,13 +961,13 @@ QStringList RenderableModelEntityItem::getJointNames() const { } scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() { - auto model = resultWithReadLock([this]{ return _model; }); + auto model = resultWithReadLock([&] { return _model; }); if (!model || !model->isLoaded()) { return scriptable::ScriptableModelBase(); } - auto result = _model->getScriptableModel(); + auto result = model->getScriptableModel(); result.objectID = getEntity()->getID(); { std::lock_guard lock(_materialsLock); @@ -1054,10 +1055,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare } -void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) { +void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model) { auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); - if (!_cullWithParent && _model && _model->isGroupCulled()) { + if (!_cullWithParent && model && model->isGroupCulled()) { builder.withMetaCullGroup(); } else if (_cullWithParent) { builder.withSubMetaCulled(); @@ -1075,8 +1076,9 @@ ItemKey ModelEntityRenderer::getKey() { } uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const { - if (_model) { - auto metaSubItems = _model->fetchRenderItemIDs(); + auto model = resultWithReadLock([&] { return _model; }); + if (model) { + auto metaSubItems = model->fetchRenderItemIDs(); subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end()); return (uint32_t)metaSubItems.size(); } @@ -1089,8 +1091,9 @@ void ModelEntityRenderer::handleBlendedVertices(int blendshapeNumber, const QVec } void ModelEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) { - if (_model) { - _model->removeFromScene(scene, transaction); + auto model = resultWithReadLock([&] { return _model; }); + if (model) { + model->removeFromScene(scene, transaction); } Parent::removeFromScene(scene, transaction); } @@ -1099,7 +1102,7 @@ void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entit entity->setModel({}); } -void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { +void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelPointer& model) { if (!_animation || !_animation->isLoaded()) { return; } @@ -1124,17 +1127,17 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { _lastKnownCurrentFrame = currentIntegerFrame; } - if (_jointMapping.size() != _model->getJointStateCount()) { + if (_jointMapping.size() != model->getJointStateCount()) { qCWarning(entitiesrenderer) << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch" - << _jointMapping.size() << _model->getJointStateCount(); + << _jointMapping.size() << model->getJointStateCount(); return; } QStringList animationJointNames = _animation->getHFMModel().getJointNames(); auto& hfmJoints = _animation->getHFMModel().joints; - auto& originalHFMJoints = _model->getHFMModel().joints; - auto& originalHFMIndices = _model->getHFMModel().jointIndices; + auto& originalHFMJoints = model->getHFMModel().joints; + auto& originalHFMIndices = model->getHFMModel().jointIndices; bool allowTranslation = entity->getAnimationAllowTranslation(); @@ -1183,90 +1186,39 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { } bool ModelEntityRenderer::needsRenderUpdate() const { - if (resultWithReadLock([&] { - if (_moving || _animating) { - return true; - } + //ModelPointer model = resultWithReadLock([&] { + // return _model; + //}); - if (!_texturesLoaded) { - return true; - } + //if (model) { + // // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating + // // we will watch for that and ask the model to update it's render items + // if (model->needsReload()) { + // return true; + // } - if (!_prevModelLoaded) { - return true; - } - - return false; - })) { - return true; - } - - ModelPointer model; - QUrl parsedModelURL; - withReadLock([&] { - model = _model; - parsedModelURL = _parsedModelURL; - }); - - if (model) { - // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating - // we will watch for that and ask the model to update it's render items - if (parsedModelURL != model->getURL()) { - return true; - } - - if (model->needsReload()) { - return true; - } - - if (model->needsFixupInScene()) { - return true; - } - - if (model->getRenderItemsNeedUpdate()) { - return true; - } - } + // if (model->needsFixupInScene()) { + // return true; + // } + //} return Parent::needsRenderUpdate(); } bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (resultWithReadLock([&] { - if (entity->hasModel() != _hasModel) { - return true; - } + if (entity->blendshapesChanged()) { + return true; + } - // No model to render, early exit - if (!_hasModel) { - return false; - } + // Check to see if we need to update the model bounds + if (entity->needsUpdateModelBounds()) { + return true; + } - if (_animating != entity->isAnimatingSomething()) { - return true; - } - - return false; - })) { return true; } - - ModelPointer model; - withReadLock([&] { - model = _model; + ModelPointer model = resultWithReadLock([&] { + return _model; }); if (model && model->isLoaded()) { - if (!entity->_dimensionsInitialized || entity->_needsInitialSimulation || !entity->_originalTexturesRead) { - return true; - } - - if (entity->blendshapesChanged()) { - return true; - } - - // Check to see if we need to update the model bounds - if (entity->needsUpdateModelBounds()) { - return true; - } - // Check to see if we need to update the model bounds auto transform = entity->getTransform(); if (model->getTranslation() != transform.getTranslation() || @@ -1280,48 +1232,38 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin } } - return false; + return Parent::needsRenderUpdateFromTypedEntity(entity); } -void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); - if (_hasModel != entity->hasModel()) { - withWriteLock([&] { - _hasModel = entity->hasModel(); - }); + + _hasModel = entity->hasModel(); + if (_parsedModelURL != entity->getModelURL()) { + _parsedModelURL = QUrl(entity->getModelURL()); } - withWriteLock([&] { - _animating = entity->isAnimatingSomething(); - if (_parsedModelURL != entity->getModelURL()) { - _parsedModelURL = QUrl(entity->getModelURL()); - } + ModelPointer model = resultWithReadLock([&] { + return _model; }); - ModelPointer model; - withReadLock([&] { model = _model; }); + bool visuallyReady = model && model->isLoaded() && _didLastVisualGeometryRequestSucceed && _texturesLoaded; + entity->setVisuallyReady(visuallyReady); - withWriteLock([&] { - bool visuallyReady = true; - if (_hasModel) { - if (model && _didLastVisualGeometryRequestSucceed) { - visuallyReady = (_prevModelLoaded && _texturesLoaded); - } - } - entity->setVisuallyReady(visuallyReady); - }); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); + render::Transaction transaction; // Check for removal if (!_hasModel) { if (model) { model->removeFromScene(scene, transaction); entity->bumpAncestorChainRenderableVersion(); - withWriteLock([&] { _model.reset(); }); emit DependencyManager::get()-> - modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, _model); + modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model); + withWriteLock([&] { model.reset(); }); } - setKey(false); _didLastVisualGeometryRequestSucceed = false; + setKey(_didLastVisualGeometryRequestSucceed, model); return; } @@ -1330,18 +1272,28 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce model = std::make_shared(nullptr, entity.get(), _created); connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate); connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) { - setKey(didVisualGeometryRequestSucceed); - _model->setTagMask(getTagMask()); - _model->setHifiRenderLayer(getHifiRenderLayer()); - _model->setPrimitiveMode(_primitiveMode); - _model->setCullWithParent(_cullWithParent); - _model->setRenderWithZones(_renderWithZones); - emit requestRenderUpdate(); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); + withWriteLock([&] { + setKey(didVisualGeometryRequestSucceed, _model); + _model->setVisibleInScene(_visible, scene); + _model->setCauterized(_cauterized, scene); + _model->setCanCastShadow(_canCastShadow, scene); + _model->setGroupCulled(entity->getGroupCulled(), scene); + _model->setTagMask(getTagMask(), scene); + _model->setHifiRenderLayer(getHifiRenderLayer(), scene); + _model->setPrimitiveMode(_primitiveMode, scene); + _model->setCullWithParent(_cullWithParent, scene); + _model->setRenderWithZones(_renderWithZones, scene); + }); if (didVisualGeometryRequestSucceed) { emit DependencyManager::get()-> - modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, _model); + modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model); } _didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed; + entity->_dimensionsInitialized = false; + entity->_originalTexturesRead = false; + entity->_needsJointSimulation = true; + emit requestRenderUpdate(); }); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); entity->setModel(model); @@ -1350,24 +1302,15 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce // From here on, we are guaranteed a populated model if (_parsedModelURL != model->getURL()) { - withWriteLock([&] { - _texturesLoaded = false; - _jointMappingCompleted = false; - model->setURL(_parsedModelURL); - }); + _texturesLoaded = false; + _jointMappingCompleted = false; + model->setURL(_parsedModelURL); } // Nothing else to do unless the model is loaded if (!model->isLoaded()) { - withWriteLock([&] { - _prevModelLoaded = false; - }); emit requestRenderUpdate(); return; - } else if (!_prevModelLoaded) { - withWriteLock([&] { - _prevModelLoaded = true; - }); } // Check for initializing the model @@ -1383,6 +1326,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", Qt::QueuedConnection, Q_ARG(QUuid, entity->getEntityItemID()), Q_ARG(EntityItemProperties, properties)); + entity->_dimensionsInitialized = true; } if (!entity->_originalTexturesRead) { @@ -1393,51 +1337,34 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (_textures != entity->getTextures()) { QVariantMap newTextures; - withWriteLock([&] { - _texturesLoaded = false; - _textures = entity->getTextures(); - newTextures = parseTexturesToMap(_textures, entity->_originalTextures); - }); + _texturesLoaded = false; + _textures = entity->getTextures(); + newTextures = parseTexturesToMap(_textures, entity->_originalTextures); model->setTextures(newTextures); } + if (entity->_needsJointSimulation) { entity->copyAnimationJointDataToModel(); } entity->updateModelBounds(); entity->stopModelOverrideIfNoParent(); - if (model->isVisible() != _visible) { - model->setVisibleInScene(_visible, scene); - } - - if (model->isCauterized() != _cauterized) { - model->setCauterized(_cauterized, scene); - } - - render::hifi::Tag tagMask = getTagMask(); - if (model->getTagMask() != tagMask) { - model->setTagMask(tagMask, scene); - } + setKey(_didLastVisualGeometryRequestSucceed, model); + model->setVisibleInScene(_visible, scene); + model->setCauterized(_cauterized, scene); + model->setCanCastShadow(_canCastShadow, scene); + model->setGroupCulled(entity->getGroupCulled(), scene); + model->setTagMask(getTagMask(), scene); + model->setHifiRenderLayer(getHifiRenderLayer(), scene); + model->setPrimitiveMode(_primitiveMode, scene); + model->setCullWithParent(_cullWithParent, scene); + model->setRenderWithZones(_renderWithZones, scene); if (entity->blendshapesChanged()) { model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector()); model->updateBlendshapes(); } - // TODO? early exit here when not visible? - - if (model->canCastShadow() != _canCastShadow) { - model->setCanCastShadow(_canCastShadow, scene); - } - - { - bool groupCulled = entity->getGroupCulled(); - if (model->isGroupCulled() != groupCulled) { - model->setGroupCulled(groupCulled); - setKey(_didLastVisualGeometryRequestSucceed); - } - } - { DETAILED_PROFILE_RANGE(simulation_physics, "Fixup"); if (model->needsFixupInScene()) { @@ -1452,9 +1379,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) { - withWriteLock([&] { - _texturesLoaded = true; - }); + _texturesLoaded = true; model->updateRenderItems(); } else if (!_texturesLoaded) { emit requestRenderUpdate(); @@ -1491,9 +1416,13 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce model->updateRenderItems(); } + scene->enqueueTransaction(transaction); +} + +void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { // The code to deal with the change of properties is now in ModelEntityItem.cpp // That is where _currentFrame and _lastAnimated were updated. - if (_animating) { + if (entity->isAnimatingSomething()) { DETAILED_PROFILE_RANGE(simulation_physics, "Animate"); auto animationURL = entity->getAnimationURL(); @@ -1502,18 +1431,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce _animationURL = animationURL; if (_animation) { - //(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check // the joints have been mapped before but we have a new animation to load _animation.reset(); _jointMappingCompleted = false; } } - + + ModelPointer model = resultWithReadLock([&] { + return _model; + }); if (!_jointMappingCompleted) { mapJoints(entity, model); } - if (entity->readyToAnimate()) { - animate(entity); + if (entity->readyToAnimate() && model && model->isLoaded()) { + animate(entity, model); } emit requestRenderUpdate(); } @@ -1521,40 +1452,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) { Parent::setIsVisibleInSecondaryCamera(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setTagMask(getTagMask()); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } void ModelEntityRenderer::setRenderLayer(RenderLayer value) { Parent::setRenderLayer(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setHifiRenderLayer(getHifiRenderLayer()); - } -} - -void ModelEntityRenderer::setPrimitiveMode(PrimitiveMode value) { - Parent::setPrimitiveMode(value); - if (_model) { - _model->setPrimitiveMode(_primitiveMode); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } void ModelEntityRenderer::setCullWithParent(bool value) { Parent::setCullWithParent(value); - setKey(_didLastVisualGeometryRequestSucceed); - if (_model) { - _model->setCullWithParent(_cullWithParent); - } -} - -void ModelEntityRenderer::setRenderWithZones(const QVector& renderWithZones) { - Parent::setRenderWithZones(renderWithZones); - if (_model) { - _model->setRenderWithZones(renderWithZones); - } + // called within a lock so no need to lock for _model + setKey(_didLastVisualGeometryRequestSucceed, _model); } // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items @@ -1570,9 +1481,8 @@ void ModelEntityRenderer::doRender(RenderArgs* args) { geometryCache->renderWireCubeInstance(args, batch, greenColor, geometryCache->getShapePipelinePointer(false, false, args->_renderMethod == Args::RenderMethod::FORWARD)); #if WANT_EXTRA_DEBUGGING - ModelPointer model; - withReadLock([&] { - model = _model; + ModelPointer model = resultWithReadLock([&] { + return _model; }); if (model) { model->renderDebugMeshBoxes(batch, args->_renderMethod == Args::RenderMethod::FORWARD); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 850617d1af..4cccc327bc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -153,25 +153,24 @@ protected: virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override; virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; - void setKey(bool didVisualGeometryRequestSucceed); + void setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model); virtual ItemKey getKey() override; virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override; virtual void handleBlendedVertices(int blendshapeNumber, const QVector& blendshapeOffsets, const QVector& blendedMeshSizes, const render::ItemIDs& subItemIDs) override; - virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual bool needsRenderUpdate() const override; - virtual void doRender(RenderArgs* args) override; + 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; void setIsVisibleInSecondaryCamera(bool value) override; void setRenderLayer(RenderLayer value) override; - void setPrimitiveMode(PrimitiveMode value) override; void setCullWithParent(bool value) override; - void setRenderWithZones(const QVector& renderWithZones) override; private: - void animate(const TypedEntityPointer& entity); + void animate(const TypedEntityPointer& entity, const ModelPointer& model); void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model); // Transparency is handled in ModelMeshPartPayload @@ -192,14 +191,12 @@ private: bool _jointMappingCompleted { false }; QVector _jointMapping; // domain is index into model-joints, range is index into animation-joints AnimationPointer _animation; - bool _animating { false }; QString _animationURL; uint64_t _lastAnimated { 0 }; render::ItemKey _itemKey { render::ItemKey::Builder().withTypeMeta() }; bool _didLastVisualGeometryRequestSucceed { true }; - bool _prevModelLoaded { false }; void processMaterials(); bool _allProceduralMaterialsLoaded { false }; diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index 715b457bde..0dcb5d125a 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -78,7 +78,14 @@ void LightEntityItem::setFalloffRadius(float value) { } void LightEntityItem::setIsSpotlight(bool value) { - if (value == getIsSpotlight()) { + bool needsRenderUpdate; + withWriteLock([&] { + needsRenderUpdate = value != _isSpotlight; + _needsRenderUpdate |= needsRenderUpdate; + _isSpotlight = value; + }); + + if (!needsRenderUpdate) { return; } @@ -92,25 +99,25 @@ void LightEntityItem::setIsSpotlight(bool value) { newDimensions = glm::vec3(glm::compMax(dimensions)); } - withWriteLock([&] { - _needsRenderUpdate = true; - _isSpotlight = value; - }); setScaledDimensions(newDimensions); } void LightEntityItem::setCutoff(float value) { value = glm::clamp(value, MIN_CUTOFF, MAX_CUTOFF); - if (value == getCutoff()) { + bool needsRenderUpdate; + bool spotlight; + withWriteLock([&] { + needsRenderUpdate = value != _cutoff; + _needsRenderUpdate |= needsRenderUpdate; + _cutoff = value; + spotlight = _isSpotlight; + }); + + if (!needsRenderUpdate) { return; } - withWriteLock([&] { - _needsRenderUpdate = true; - _cutoff = value; - }); - - if (getIsSpotlight()) { + if (spotlight) { // If we are a spotlight, adjusting the cutoff will affect the area we encapsulate, // so update the dimensions to reflect this. const float length = getScaledDimensions().z; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index cd27c1cf36..3a4e96d7bd 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -330,13 +330,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) { }); } -void ModelEntityItem::setAnimationURL(const QString& url) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setURL(url); - }); -} - void ModelEntityItem::setAnimationSettings(const QString& value) { // NOTE: this method only called for old bitstream format @@ -399,20 +392,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) { }); } -void ModelEntityItem::setAnimationIsPlaying(bool value) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setRunning(value); - }); -} - -void ModelEntityItem::setAnimationFPS(float value) { - _flags |= Simulation::DIRTY_UPDATEABLE; - withWriteLock([&] { - _animationProperties.setFPS(value); - }); -} - void ModelEntityItem::resizeJointArrays(int newSize) { if (newSize < 0) { return; @@ -629,61 +608,18 @@ void ModelEntityItem::setAnimationCurrentFrame(float value) { }); } -void ModelEntityItem::setAnimationAllowTranslation(bool value) { - withWriteLock([&] { - _animationProperties.setAllowTranslation(value); - }); -} - bool ModelEntityItem::getAnimationAllowTranslation() const { return resultWithReadLock([&] { return _animationProperties.getAllowTranslation(); }); } -void ModelEntityItem::setAnimationLoop(bool loop) { - withWriteLock([&] { - _animationProperties.setLoop(loop); - }); -} - -bool ModelEntityItem::getAnimationLoop() const { - return resultWithReadLock([&] { - return _animationProperties.getLoop(); - }); -} - - -void ModelEntityItem::setAnimationHold(bool hold) { - withWriteLock([&] { - _animationProperties.setHold(hold); - }); -} - -bool ModelEntityItem::getAnimationHold() const { - return resultWithReadLock([&] { - return _animationProperties.getHold(); - }); -} - -bool ModelEntityItem::getAnimationIsPlaying() const { - return resultWithReadLock([&] { - return _animationProperties.getRunning(); - }); -} - float ModelEntityItem::getAnimationCurrentFrame() const { return resultWithReadLock([&] { return _animationProperties.getCurrentFrame(); }); } -float ModelEntityItem::getAnimationFPS() const { - return resultWithReadLock([&] { - return _animationProperties.getFPS(); - }); -} - bool ModelEntityItem::isAnimatingSomething() const { return resultWithReadLock([&] { return _animationProperties.isValidAndRunning(); @@ -722,6 +658,7 @@ bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProp bool somethingChanged = newProperties != _animationProperties; if (somethingChanged) { _animationProperties = newProperties; + _needsRenderUpdate = true; _flags |= Simulation::DIRTY_UPDATEABLE; } return somethingChanged; diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 795630a72a..59bb6d67cf 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -85,24 +85,12 @@ public: // Animation related items... AnimationPropertyGroup getAnimationProperties() const; - - // TODO: audit and remove unused Animation accessors bool hasAnimation() const; QString getAnimationURL() const; - virtual void setAnimationURL(const QString& url); - void setAnimationCurrentFrame(float value); - void setAnimationIsPlaying(bool value); - void setAnimationFPS(float value); - - void setAnimationAllowTranslation(bool value); + float getAnimationCurrentFrame() const; bool getAnimationAllowTranslation() const; - - void setAnimationLoop(bool loop); - bool getAnimationLoop() const; - - void setAnimationHold(bool hold); - bool getAnimationHold() const; + bool isAnimatingSomething() const; void setRelayParentJoints(bool relayJoints); bool getRelayParentJoints() const; @@ -110,11 +98,6 @@ public: void setGroupCulled(bool value); bool getGroupCulled() const; - bool getAnimationIsPlaying() const; - float getAnimationCurrentFrame() const; - float getAnimationFPS() const; - bool isAnimatingSomething() const; - static const QString DEFAULT_TEXTURES; const QString getTextures() const; void setTextures(const QString& textures); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 182b83762c..e46bdc03b3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -958,16 +958,20 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { } } -void Model::setPrimitiveMode(PrimitiveMode primitiveMode) { +void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene) { if (_primitiveMode != primitiveMode) { _primitiveMode = primitiveMode; - updateRenderItemsKey(nullptr); + updateRenderItemsKey(scene); } } -void Model::setCullWithParent(bool cullWithParent) { +void Model::setCullWithParent(bool cullWithParent, const render::ScenePointer& scene) { if (_cullWithParent != cullWithParent) { _cullWithParent = cullWithParent; + if (!scene) { + _needsFixupInScene = true; + return; + } render::Transaction transaction; auto renderItemsKey = _renderItemKeyGlobalFlags; @@ -977,14 +981,27 @@ void Model::setCullWithParent(bool cullWithParent) { data.updateKey(renderItemsKey); }); } - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + scene->enqueueTransaction(transaction); } } -void Model::setRenderWithZones(const QVector& renderWithZones) { +void Model::setRenderWithZones(const QVector& renderWithZones, const render::ScenePointer& scene) { if (_renderWithZones != renderWithZones) { _renderWithZones = renderWithZones; - setRenderItemsNeedUpdate(); + + if (!scene) { + _needsFixupInScene = true; + return; + } + + render::Transaction transaction; + auto renderItemsKey = _renderItemKeyGlobalFlags; + for (auto item : _modelMeshRenderItemIDs) { + transaction.updateItem(item, [renderWithZones, renderItemsKey](ModelMeshPartPayload& data) { + data.setRenderWithZones(renderWithZones); + }); + } + scene->enqueueTransaction(transaction); } } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 4585ad0009..7372baa2dd 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -116,14 +116,14 @@ public: void setHifiRenderLayer(render::hifi::Layer layer, const render::ScenePointer& scene = nullptr); bool isCauterized() const { return _cauterized; } - void setCauterized(bool value, const render::ScenePointer& scene); + void setCauterized(bool value, const render::ScenePointer& scene = nullptr); - void setPrimitiveMode(PrimitiveMode primitiveMode); + void setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene = nullptr); PrimitiveMode getPrimitiveMode() const { return _primitiveMode; } - void setCullWithParent(bool value); + void setCullWithParent(bool value, const render::ScenePointer& scene = nullptr); - void setRenderWithZones(const QVector& renderWithZones); + void setRenderWithZones(const QVector& renderWithZones, const render::ScenePointer& scene = nullptr); const QVector& getRenderWithZones() const { return _renderWithZones; } // Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model.