From bed2732d342eb0d09310fae2bfdcbc788aad43be Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 14 Feb 2019 12:59:16 -0800 Subject: [PATCH 1/6] start moving materials to rendering only --- interface/src/Application.cpp | 39 +-- .../src/EntityTreeRenderer.cpp | 33 +++ .../src/EntityTreeRenderer.h | 15 + .../src/RenderableEntityItem.cpp | 1 - .../src/RenderableMaterialEntityItem.cpp | 146 ++++++++-- .../src/RenderableMaterialEntityItem.h | 32 ++- libraries/entities/src/EntityItem.cpp | 19 -- libraries/entities/src/EntityItem.h | 10 - libraries/entities/src/EntityTree.cpp | 49 ---- libraries/entities/src/EntityTree.h | 22 -- libraries/entities/src/MaterialEntityItem.cpp | 262 +++++------------- libraries/entities/src/MaterialEntityItem.h | 50 +--- 12 files changed, 285 insertions(+), 393 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1029398794..ca7678c233 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1926,46 +1926,32 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } }); - EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { if (_aboutToQuit) { return false; } - // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->addMaterial(material, parentMaterialName); } - // even if we don't find it, try to find the entity - auto entity = getEntities()->getEntity(entityID); - if (entity) { - entity->addMaterial(material, parentMaterialName); - return true; - } return false; }); - EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { if (_aboutToQuit) { return false; } - // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->removeMaterial(material, parentMaterialName); } - // even if we don't find it, try to find the entity - auto entity = getEntities()->getEntity(entityID); - if (entity) { - entity->removeMaterial(material, parentMaterialName); - return true; - } return false; }); - EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { @@ -1974,7 +1960,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } return false; }); - EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { @@ -1984,23 +1970,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return false; }); - EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - auto overlay = _overlays.getOverlay(overlayID); - if (overlay) { - overlay->addMaterial(material, parentMaterialName); - return true; - } - return false; - }); - EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - auto overlay = _overlays.getOverlay(overlayID); - if (overlay) { - overlay->removeMaterial(material, parentMaterialName); - return true; - } - return false; - }); - // Keyboard focus handling for Web overlays. auto overlays = &(qApp->getOverlays()); connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2b3a915235..c0774c795c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1360,3 +1360,36 @@ EntityEditPacketSender* EntityTreeRenderer::getPacketSender() { EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr; return packetSender; } + +std::function EntityTreeRenderer::_addMaterialToEntityOperator = nullptr; +std::function EntityTreeRenderer::_removeMaterialFromEntityOperator = nullptr; +std::function EntityTreeRenderer::_addMaterialToAvatarOperator = nullptr; +std::function EntityTreeRenderer::_removeMaterialFromAvatarOperator = nullptr; + +bool EntityTreeRenderer::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + if (_addMaterialToEntityOperator) { + return _addMaterialToEntityOperator(entityID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + if (_removeMaterialFromEntityOperator) { + return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + if (_addMaterialToAvatarOperator) { + return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + if (_removeMaterialFromAvatarOperator) { + return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName); + } + return false; +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 725416e2cc..00a78bf9e4 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -123,6 +123,16 @@ public: EntityEditPacketSender* getPacketSender(); + static void setAddMaterialToEntityOperator(std::function addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; } + static void setRemoveMaterialFromEntityOperator(std::function removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; } + static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName); + static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName); + + static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } + static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } + static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName); + static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName); + signals: void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); @@ -259,6 +269,11 @@ private: workload::Transaction::Updates _spaceUpdates; static std::function _getAvatarUpOperator; + + static std::function _addMaterialToEntityOperator; + static std::function _removeMaterialFromEntityOperator; + static std::function _addMaterialToAvatarOperator; + static std::function _removeMaterialFromAvatarOperator; }; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 83f0bdcff3..5c73b9576d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -146,7 +146,6 @@ EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _created(entit _needsRenderUpdate = true; emit requestRenderUpdate(); }); - _materials = entity->getMaterials(); } EntityRenderer::~EntityRenderer() { } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 483f9ffe1c..6cc342f68a 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -14,23 +14,54 @@ using namespace render; using namespace render::entities; -bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (entity->getMaterial() != _drawMaterial) { - return true; - } - if (entity->getParentID() != _parentID) { - return true; - } - if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { +bool MaterialEntityRenderer::needsRenderUpdate() const { + if (_retryApply) { return true; } if (!_texturesLoaded) { return true; } + return Parent::needsRenderUpdate(); +} + +bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + // Could require material re-apply + if (entity->getMaterialURL() != _materialURL) { + return true; + } + if (entity->getMaterialData() != _materialData) { + return true; + } + if (entity->getParentMaterialName() != _parentMaterialName) { + return true; + } + if (entity->getParentID() != _parentID) { + return true; + } + if (entity->getPriority() != _priority) { + return true; + } + + // Won't cause material re-apply + if (entity->getMaterialMappingMode() != _materialMappingMode) { + return true; + } + if (entity->getMaterialRepeat() != _materialRepeat) { + return true; + } + if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { + return true; + } + if (entity->getTransform() != _transform) { + return true; + } + if (entity->getUnscaledDimensions() != _dimensions) { + return true; + } return false; } -void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withWriteLock([&] { if (_drawMaterial != entity->getMaterial()) { _texturesLoaded = false; @@ -61,8 +92,9 @@ ItemKey MaterialEntityRenderer::getKey() { builder.withInvisible(); } - if (_drawMaterial) { - auto matKey = _drawMaterial->getKey(); + const auto& drawMaterial = getMaterial(); + if (drawMaterial) { + auto matKey = drawMaterial->getKey(); if (matKey.isTranslucent()) { builder.withTransparent(); } @@ -73,8 +105,9 @@ ItemKey MaterialEntityRenderer::getKey() { ShapeKey MaterialEntityRenderer::getShapeKey() { graphics::MaterialKey drawMaterialKey; - if (_drawMaterial) { - drawMaterialKey = _drawMaterial->getKey(); + const auto& drawMaterial = getMaterial(); + if (drawMaterial) { + drawMaterialKey = drawMaterial->getKey(); } bool isTranslucent = drawMaterialKey.isTranslucent(); @@ -112,18 +145,24 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { // Don't render if our parent is set or our material is null QUuid parentID; + withReadLock([&] { + parentID = _parentID; + }); + if (!parentID.isNull()) { + return; + } + Transform renderTransform; graphics::MaterialPointer drawMaterial; Transform textureTransform; withReadLock([&] { - parentID = _parentID; renderTransform = _renderTransform; - drawMaterial = _drawMaterial; + drawMaterial = getMaterial(); textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); }); - if (!parentID.isNull() || !drawMaterial) { + if (!drawMaterial) { return; } @@ -142,3 +181,78 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { args->_details._trianglesRendered += (int)DependencyManager::get()->getSphereTriangleCount(); } + +void MaterialEntityRenderer::setCurrentMaterialName(const std::string& currentMaterialName) { + if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) { + _currentMaterialName = currentMaterialName; + } else if (_parsedMaterials.names.size() > 0) { + _currentMaterialName = _parsedMaterials.names[0]; + } +} + +std::shared_ptr MaterialEntityRenderer::getMaterial() const { + auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName); + if (material != _parsedMaterials.networkMaterials.end()) { + return material->second; + } else { + return nullptr; + } +} + +void MaterialEntityRenderer::deleteMaterial() { + std::shared_ptr material = getMaterial(); + if (!material) { + return; + } + QUuid parentID = _parentID; + if (parentID.isNull()) { + return; + } + + // Our parent could be an entity or an avatar + if (EntityTreeRenderer::removeMaterialFromEntity(parentID, material, _parentMaterialName.toStdString())) { + return; + } + + if (EntityTreeRenderer::removeMaterialFromAvatar(parentID, material, _parentMaterialName.toStdString())) { + return; + } + + // if a remove fails, our parent is gone, so we don't need to retry +} + +void MaterialEntityRenderer::applyMaterial() { + _retryApply = false; + std::shared_ptr material = getMaterial(); + QUuid parentID = _parentID; + if (!material || parentID.isNull()) { + return; + } + + Transform textureTransform; + if (_materialMappingMode == MaterialMappingMode::UV) { + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); + textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); + } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + textureTransform = _transform; + textureTransform.postScale(_dimensions); + // Pass the inverse transform here so we don't need to compute it in the shaders + textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); + } + material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); + + graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); + + // Our parent could be an entity or an avatar + if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, _parentMaterialName.toStdString())) { + return; + } + + if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, _parentMaterialName.toStdString())) { + return; + } + + // if we've reached this point, we couldn't find our parent, so we need to try again later + _retryApply = true; +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index c90048ecf5..5ccbb33312 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -13,6 +13,9 @@ #include +#include +#include + class NetworkMaterial; namespace render { namespace entities { @@ -22,22 +25,45 @@ class MaterialEntityRenderer : public TypedEntityRenderer { using Pointer = std::shared_ptr; public: MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} + ~MaterialEntityRenderer() { deleteMaterial(); } 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; ItemKey getKey() override; ShapeKey getShapeKey() override; + QString _materialURL; + QString _materialData; + QString _parentMaterialName; + quint16 _priority; QUuid _parentID; + + MaterialMappingMode _materialMappingMode; + bool _materialRepeat; glm::vec2 _materialMappingPos; glm::vec2 _materialMappingScale; float _materialMappingRot; - bool _texturesLoaded { false }; + Transform _transform; + glm::vec3 _dimensions; + + bool _texturesLoaded { false }; + bool _retryApply { false }; + + std::shared_ptr getMaterial() const; + void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); + void setCurrentMaterialName(const std::string& currentMaterialName); + + void applyMaterial(); + void deleteMaterial(); + + NetworkMaterialResourcePointer _networkMaterial; + NetworkMaterialResource::ParsedMaterials _parsedMaterials; + std::string _currentMaterialName; - std::shared_ptr _drawMaterial; }; } } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7e5be384a7..ad9acb3775 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -3234,25 +3234,6 @@ void EntityItem::setSpaceIndex(int32_t index) { void EntityItem::preDelete() { } -void EntityItem::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { - std::lock_guard lock(_materialsLock); - _materials[parentMaterialName].push(material); -} - -void EntityItem::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { - std::lock_guard lock(_materialsLock); - _materials[parentMaterialName].remove(material); -} - -std::unordered_map EntityItem::getMaterials() { - std::unordered_map toReturn; - { - std::lock_guard lock(_materialsLock); - toReturn = _materials; - } - return toReturn; -} - bool EntityItem::getCloneable() const { bool result; withReadLock([&] { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 27b207b6f3..75fa30b3a3 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -37,8 +37,6 @@ #include "EntityDynamicInterface.h" #include "GrabPropertyGroup.h" -#include "graphics/Material.h" - class EntitySimulation; class EntityTreeElement; class EntityTreeElementExtraEncodeData; @@ -542,10 +540,6 @@ public: virtual void preDelete(); virtual void postParentFixup() {} - void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); - void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); - std::unordered_map getMaterials(); - void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; } uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; } @@ -750,10 +744,6 @@ protected: QHash _grabActions; -private: - std::unordered_map _materials; - std::mutex _materialsLock; - }; #endif // hifi_EntityItem_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 954462a9f2..bf91d71050 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2953,55 +2953,6 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { return entity->getJointNames(); } -std::function EntityTree::_addMaterialToEntityOperator = nullptr; -std::function EntityTree::_removeMaterialFromEntityOperator = nullptr; -std::function EntityTree::_addMaterialToAvatarOperator = nullptr; -std::function EntityTree::_removeMaterialFromAvatarOperator = nullptr; -std::function EntityTree::_addMaterialToOverlayOperator = nullptr; -std::function EntityTree::_removeMaterialFromOverlayOperator = nullptr; - -bool EntityTree::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToEntityOperator) { - return _addMaterialToEntityOperator(entityID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromEntityOperator) { - return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToAvatarOperator) { - return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromAvatarOperator) { - return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToOverlayOperator) { - return _addMaterialToOverlayOperator(overlayID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromOverlayOperator) { - return _removeMaterialFromOverlayOperator(overlayID, material, parentMaterialName); - } - return false; -} - void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, MovingEntitiesOperator& moveOperator, bool force, bool tellServer) { // if the queryBox has changed, tell the entity-server diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index f9b7b8d67f..367af7ba1e 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -262,21 +262,6 @@ public: void setIsServerlessMode(bool value) { _serverlessDomain = value; } bool isServerlessMode() const { return _serverlessDomain; } - static void setAddMaterialToEntityOperator(std::function addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; } - static void setRemoveMaterialFromEntityOperator(std::function removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; } - static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName); - - static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } - static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } - static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName); - - static void setAddMaterialToOverlayOperator(std::function addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; } - static void setRemoveMaterialFromOverlayOperator(std::function removeMaterialFromOverlayOperator) { _removeMaterialFromOverlayOperator = removeMaterialFromOverlayOperator; } - static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName); - std::map getNamedPaths() const { return _namedPaths; } void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, @@ -385,13 +370,6 @@ private: std::shared_ptr _myAvatar{ nullptr }; - static std::function _addMaterialToEntityOperator; - static std::function _removeMaterialFromEntityOperator; - static std::function _addMaterialToAvatarOperator; - static std::function _removeMaterialFromAvatarOperator; - static std::function _addMaterialToOverlayOperator; - static std::function _removeMaterialFromOverlayOperator; - std::vector _staleProxies; bool _serverlessDomain { false }; diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index cec602a5e1..3a363f2e83 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -16,9 +16,6 @@ EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); entity->setProperties(properties); - // When you reload content, setProperties doesn't have any of the propertiesChanged flags set, so it won't trigger a material add - entity->removeMaterial(); - entity->applyMaterial(); return entity; } @@ -27,10 +24,6 @@ MaterialEntityItem::MaterialEntityItem(const EntityItemID& entityItemID) : Entit _type = EntityTypes::Material; } -MaterialEntityItem::~MaterialEntityItem() { - removeMaterial(); -} - EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL); @@ -131,7 +124,6 @@ void MaterialEntityItem::debugDump() const { qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " name:" << _name; qCDebug(entities) << " material url:" << _materialURL; - qCDebug(entities) << " current material name:" << _currentMaterialName.c_str(); qCDebug(entities) << " material mapping mode:" << _materialMappingMode; qCDebug(entities) << " material repeat:" << _materialRepeat; qCDebug(entities) << " priority:" << _priority; @@ -154,216 +146,101 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) { } } -std::shared_ptr MaterialEntityItem::getMaterial() const { - auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName); - if (material != _parsedMaterials.networkMaterials.end()) { - return material->second; - } else { - return nullptr; - } +QString MaterialEntityItem::getMaterialURL() const { + return resultWithReadLock([&] { + return _materialURL; + }); } -void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool materialDataChanged) { - bool usingMaterialData = materialDataChanged || materialURLString.startsWith("materialData"); - if (_materialURL != materialURLString || (usingMaterialData && materialDataChanged)) { - removeMaterial(); - _materialURL = materialURLString; - - if (materialURLString.contains("?")) { - auto split = materialURLString.split("?"); - _currentMaterialName = split.last().toStdString(); - } - - if (usingMaterialData) { - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getMaterialData().toUtf8()), materialURLString); - - // Since our material changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(_currentMaterialName); - applyMaterial(); - } else { - _networkMaterial = MaterialCache::instance().getMaterial(materialURLString); - auto onMaterialRequestFinished = [&](bool success) { - if (success) { - _parsedMaterials = _networkMaterial->parsedMaterials; - - setCurrentMaterialName(_currentMaterialName); - applyMaterial(); - } - }; - if (_networkMaterial) { - if (_networkMaterial->isLoaded()) { - onMaterialRequestFinished(!_networkMaterial->isFailed()); - } else { - connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); - } - } - } - } +void MaterialEntityItem::setMaterialURL(const QString& materialURL) { + withWriteLock([&] { + _materialURL = materialURL; + }); } -void MaterialEntityItem::setCurrentMaterialName(const std::string& currentMaterialName) { - if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) { - _currentMaterialName = currentMaterialName; - } else if (_parsedMaterials.names.size() > 0) { - _currentMaterialName = _parsedMaterials.names[0]; - } +QString MaterialEntityItem::getMaterialData() const { + return resultWithReadLock([&] { + return _materialData; + }); } void MaterialEntityItem::setMaterialData(const QString& materialData) { - if (_materialData != materialData) { + withWriteLock([&] { _materialData = materialData; - if (_materialURL.startsWith("materialData")) { - // Trigger material update when material data changes - setMaterialURL(_materialURL, true); - } - } + }); +} + +MaterialMappingMode MaterialEntityItem::getMaterialMappingMode() const { + return resultWithReadLock([&] { + return _materialMappingMode; + }); } void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) { - if (_materialMappingMode != mode) { - removeMaterial(); + withWriteLock([&] { _materialMappingMode = mode; - setUnscaledDimensions(_desiredDimensions); - applyMaterial(); - } + }); + setUnscaledDimensions(_desiredDimensions); } -void MaterialEntityItem::setMaterialRepeat(bool repeat) { - if (_materialRepeat != repeat) { - removeMaterial(); - _materialRepeat = repeat; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) { - if (_materialMappingPos != materialMappingPos) { - removeMaterial(); - _materialMappingPos = materialMappingPos; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) { - if (_materialMappingScale != materialMappingScale) { - removeMaterial(); - _materialMappingScale = materialMappingScale; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingRot(const float& materialMappingRot) { - if (_materialMappingRot != materialMappingRot) { - removeMaterial(); - _materialMappingRot = materialMappingRot; - applyMaterial(); - } +quint16 MaterialEntityItem::getPriority() const { + return resultWithReadLock([&] { + return _priority; + }); } void MaterialEntityItem::setPriority(quint16 priority) { - if (_priority != priority) { - removeMaterial(); + withWriteLock([&] { _priority = priority; - applyMaterial(); - } + }); +} + +QString MaterialEntityItem::getParentMaterialName() const { + return resultWithReadLock([&] { + return _parentMaterialName; + }); } void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) { - if (_parentMaterialName != parentMaterialName) { - removeMaterial(); + withWriteLock([&] { _parentMaterialName = parentMaterialName; - applyMaterial(); - } + }); } -void MaterialEntityItem::setParentID(const QUuid& parentID) { - if (getParentID() != parentID) { - removeMaterial(); - EntityItem::setParentID(parentID); - applyMaterial(); - } +glm::vec2 MaterialEntityItem::getMaterialMappingPos() const { + return resultWithReadLock([&] { + return _materialMappingPos; + }); } -void MaterialEntityItem::locationChanged(bool tellPhysics) { - EntityItem::locationChanged(); - if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - removeMaterial(); - applyMaterial(); - } +void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) { + withWriteLock([&] { + _materialMappingPos = materialMappingPos; + }); } -void MaterialEntityItem::dimensionsChanged() { - EntityItem::dimensionsChanged(); - if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - removeMaterial(); - applyMaterial(); - } +glm::vec2 MaterialEntityItem::getMaterialMappingScale() const { + return resultWithReadLock([&] { + return _materialMappingScale; + }); } -void MaterialEntityItem::removeMaterial() { - graphics::MaterialPointer material = getMaterial(); - if (!material) { - return; - } - QUuid parentID = getParentID(); - if (parentID.isNull()) { - return; - } - - // Our parent could be an entity, an avatar, or an overlay - if (EntityTree::removeMaterialFromEntity(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::removeMaterialFromAvatar(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::removeMaterialFromOverlay(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - // if a remove fails, our parent is gone, so we don't need to retry +void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) { + withWriteLock([&] { + _materialMappingScale = materialMappingScale; + }); } -void MaterialEntityItem::applyMaterial() { - _retryApply = false; - graphics::MaterialPointer material = getMaterial(); - QUuid parentID = getParentID(); - if (!material || parentID.isNull()) { - return; - } +float MaterialEntityItem::getMaterialMappingRot() const { + return resultWithReadLock([&] { + return _materialMappingRot; + }); +} - Transform textureTransform; - if (_materialMappingMode == MaterialMappingMode::UV) { - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); - textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); - } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - textureTransform = getTransform(); - textureTransform.postScale(getUnscaledDimensions()); - // Pass the inverse transform here so we don't need to compute it in the shaders - textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); - } - material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); - - graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, getPriority()); - - // Our parent could be an entity, an avatar, or an overlay - if (EntityTree::addMaterialToEntity(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::addMaterialToAvatar(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::addMaterialToOverlay(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - // if we've reached this point, we couldn't find our parent, so we need to try again later - _retryApply = true; +void MaterialEntityItem::setMaterialMappingRot(float materialMappingRot) { + withWriteLock([&] { + _materialMappingRot = materialMappingRot; + }); } AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { @@ -380,18 +257,3 @@ AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { } return aaCube; } - -void MaterialEntityItem::postParentFixup() { - removeMaterial(); - _queryAACubeSet = false; // force an update so we contain our parent - updateQueryAACube(); - applyMaterial(); -} - -void MaterialEntityItem::update(const quint64& now) { - if (_retryApply) { - applyMaterial(); - } - - EntityItem::update(now); -} diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index ba142d7719..b9e83a7fe5 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -12,8 +12,6 @@ #include "EntityItem.h" #include "MaterialMappingMode.h" -#include -#include class MaterialEntityItem : public EntityItem { using Pointer = std::shared_ptr; @@ -21,13 +19,9 @@ public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); MaterialEntityItem(const EntityItemID& entityItemID); - ~MaterialEntityItem(); ALLOW_INSTANTIATION // This class can be instantiated - void update(const quint64& now) override; - bool needsToCallUpdate() const override { return true; } - // methods for getting/setting all properties of an entity virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; virtual bool setProperties(const EntityItemProperties& properties) override; @@ -52,44 +46,30 @@ public: virtual void setUnscaledDimensions(const glm::vec3& value) override; - QString getMaterialURL() const { return _materialURL; } - void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); + QString getMaterialURL() const; + void setMaterialURL(const QString& materialURL); - void setCurrentMaterialName(const std::string& currentMaterialName); + QString getMaterialData() const; + void setMaterialData(const QString& materialData); - MaterialMappingMode getMaterialMappingMode() const { return _materialMappingMode; } + MaterialMappingMode getMaterialMappingMode() const; void setMaterialMappingMode(MaterialMappingMode mode); bool getMaterialRepeat() const { return _materialRepeat; } - void setMaterialRepeat(bool repeat); + void setMaterialRepeat(bool repeat) { _materialRepeat = repeat; } - quint16 getPriority() const { return _priority; } + quint16 getPriority() const; void setPriority(quint16 priority); - QString getParentMaterialName() const { return _parentMaterialName; } + QString getParentMaterialName() const; void setParentMaterialName(const QString& parentMaterialName); - glm::vec2 getMaterialMappingPos() const { return _materialMappingPos; } + glm::vec2 getMaterialMappingPos() const; void setMaterialMappingPos(const glm::vec2& materialMappingPos); - glm::vec2 getMaterialMappingScale() const { return _materialMappingScale; } + glm::vec2 getMaterialMappingScale() const; void setMaterialMappingScale(const glm::vec2& materialMappingScale); - float getMaterialMappingRot() const { return _materialMappingRot; } - void setMaterialMappingRot(const float& materialMappingRot); - - QString getMaterialData() const { return _materialData; } - void setMaterialData(const QString& materialData); - - std::shared_ptr getMaterial() const; - - void setParentID(const QUuid& parentID) override; - - void locationChanged(bool tellPhysics) override; - void dimensionsChanged() override; - - void applyMaterial(); - void removeMaterial(); - - void postParentFixup() override; + float getMaterialMappingRot() const; + void setMaterialMappingRot(float materialMappingRot); AACube calculateInitialQueryAACube(bool& success) override; @@ -128,12 +108,6 @@ private: float _materialMappingRot { 0 }; QString _materialData; - NetworkMaterialResourcePointer _networkMaterial; - NetworkMaterialResource::ParsedMaterials _parsedMaterials; - std::string _currentMaterialName; - - bool _retryApply { false }; - }; #endif // hifi_MaterialEntityItem_h From 87ab255115bc8e4bbc25e07d00a28da1f0723b46 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 11:49:20 -0800 Subject: [PATCH 2/6] finish moving materials to rendering --- interface/src/Application.cpp | 8 -- .../src/RenderableMaterialEntityItem.cpp | 132 +++++++++++++----- .../src/RenderableMaterialEntityItem.h | 4 +- 3 files changed, 100 insertions(+), 44 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b8fb05daf4..e7910ddfae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1970,14 +1970,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return renderable->textSize(text); } } - }); - - // Keyboard focus handling for Web overlays. - auto overlays = &(qApp->getOverlays()); - connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { - if (overlayID == _keyboardFocusedOverlay.get()) { - setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); - } return QSizeF(0.0f, 0.0f); }); diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index b986702f5a..31b862000b 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -105,45 +105,106 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } } - auto& material = getMaterial(); - // Update the old material regardless of if it's going to change - if (transformChanged && material && !_parentID.isNull()) { - Transform textureTransform; - if (_materialMappingMode == MaterialMappingMode::UV) { - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); - textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); - } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - textureTransform = _transform; - textureTransform.postScale(_dimensions); - // Pass the inverse transform here so we don't need to compute it in the shaders - textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); + { + auto& material = getMaterial(); + // Update the old material regardless of if it's going to change + if (transformChanged && material && !_parentID.isNull()) { + applyTextureTransform(material); } - material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); } bool deleteNeeded = false; bool addNeeded = _retryApply; + bool urlChanged = false; { QString materialURL = entity->getMaterialURL(); if (materialURL != _materialURL) { _materialURL = materialURL; + if (_materialURL.contains("?")) { + auto split = _materialURL.split("?"); + _currentMaterialName = split.last().toStdString(); + } + urlChanged = true; + } + } + + bool usingMaterialData = _materialURL.startsWith("materialData"); + { + QString materialData = entity->getMaterialData(); + if (materialData != _materialData) { + _materialData = materialData; + if (usingMaterialData) { + _texturesLoaded = false; + deleteNeeded = true; + addNeeded = true; + _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(_currentMaterialName); + } + } + } + { + QString parentMaterialName = entity->getParentMaterialName(); + if (parentMaterialName != _parentMaterialName) { + _parentMaterialName = parentMaterialName; + deleteNeeded = true; + addNeeded = true; + } + } + QUuid oldParentID = _parentID; + { + 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 (_drawMaterial != entity->getMaterial()) { - _texturesLoaded = false; - _drawMaterial = entity->getMaterial(); + if (urlChanged && !usingMaterialData) { + _networkMaterial = MaterialCache::instance().getMaterial(_materialURL); + auto onMaterialRequestFinished = [&, oldParentID](bool success) { + if (success) { + _texturesLoaded = false; + _parsedMaterials = _networkMaterial->parsedMaterials; + setCurrentMaterialName(_currentMaterialName); + deleteMaterial(oldParentID); + applyMaterial(); + } + }; + if (_networkMaterial) { + if (_networkMaterial->isLoaded()) { + onMaterialRequestFinished(!_networkMaterial->isFailed()); + } else { + connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); + } + } + } else { + if (deleteNeeded) { + deleteMaterial(oldParentID); + } + if (addNeeded) { + applyMaterial(); + } } - bool newTexturesLoaded = _drawMaterial ? !_drawMaterial->isMissingTexture() : false; - if (!_texturesLoaded && newTexturesLoaded) { - _drawMaterial->checkResetOpacityMap(); + { + auto& material = getMaterial(); + bool newTexturesLoaded = material ? !material->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + material->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; } - _texturesLoaded = newTexturesLoaded; _renderTransform = getModelTransform(); const float MATERIAL_ENTITY_SCALE = 0.5f; @@ -267,36 +328,28 @@ std::shared_ptr MaterialEntityRenderer::getMaterial() const { } } -void MaterialEntityRenderer::deleteMaterial() { +void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID) { std::shared_ptr material = getMaterial(); if (!material) { return; } - QUuid parentID = _parentID; - if (parentID.isNull()) { + if (oldParentID.isNull()) { return; } // Our parent could be an entity or an avatar - if (EntityTreeRenderer::removeMaterialFromEntity(parentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, _parentMaterialName.toStdString())) { return; } - if (EntityTreeRenderer::removeMaterialFromAvatar(parentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, _parentMaterialName.toStdString())) { return; } // if a remove fails, our parent is gone, so we don't need to retry } -void MaterialEntityRenderer::applyMaterial() { - _retryApply = false; - std::shared_ptr material = getMaterial(); - QUuid parentID = _parentID; - if (!material || parentID.isNull()) { - return; - } - +void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material) { Transform textureTransform; if (_materialMappingMode == MaterialMappingMode::UV) { textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); @@ -309,6 +362,17 @@ void MaterialEntityRenderer::applyMaterial() { textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); } material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); +} + +void MaterialEntityRenderer::applyMaterial() { + _retryApply = false; + std::shared_ptr& material = getMaterial(); + QUuid parentID = _parentID; + if (!material || parentID.isNull()) { + return; + } + + applyTextureTransform(material); graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 5ccbb33312..639cc6c9fe 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -54,11 +54,11 @@ private: bool _retryApply { false }; std::shared_ptr getMaterial() const; - void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); void setCurrentMaterialName(const std::string& currentMaterialName); + void applyTextureTransform(std::shared_ptr& material); void applyMaterial(); - void deleteMaterial(); + void deleteMaterial(const QUuid& oldParentID); NetworkMaterialResourcePointer _networkMaterial; NetworkMaterialResource::ParsedMaterials _parsedMaterials; From 3df231f1e06cf48bdcadf21d217354465c10715d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 14:43:22 -0800 Subject: [PATCH 3/6] it's working! --- interface/src/Application.cpp | 2 + .../src/RenderableMaterialEntityItem.cpp | 58 ++++++++++++------- .../src/RenderableMaterialEntityItem.h | 5 +- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7691e06b5d..1bbe7a814d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1919,6 +1919,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->addMaterial(material, parentMaterialName); + return true; } return false; @@ -1931,6 +1932,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->removeMaterial(material, parentMaterialName); + return true; } return false; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 31b862000b..8f11bdc31f 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -117,30 +117,29 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo bool addNeeded = _retryApply; bool urlChanged = false; + std::string newCurrentMaterialName = _currentMaterialName; { QString materialURL = entity->getMaterialURL(); if (materialURL != _materialURL) { _materialURL = materialURL; if (_materialURL.contains("?")) { auto split = _materialURL.split("?"); - _currentMaterialName = split.last().toStdString(); + 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) { - _texturesLoaded = false; - deleteNeeded = true; - addNeeded = true; - _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(_currentMaterialName); + materialDataChanged = true; } } } @@ -152,7 +151,6 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo addNeeded = true; } } - QUuid oldParentID = _parentID; { QUuid parentID = entity->getParentID(); if (parentID != _parentID) { @@ -172,13 +170,17 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo if (urlChanged && !usingMaterialData) { _networkMaterial = MaterialCache::instance().getMaterial(_materialURL); - auto onMaterialRequestFinished = [&, oldParentID](bool success) { + auto onMaterialRequestFinished = [&, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { if (success) { + deleteMaterial(oldParentID, oldParentMaterialName); _texturesLoaded = false; _parsedMaterials = _networkMaterial->parsedMaterials; - setCurrentMaterialName(_currentMaterialName); - deleteMaterial(oldParentID); + setCurrentMaterialName(newCurrentMaterialName); applyMaterial(); + } else { + deleteMaterial(oldParentID, oldParentMaterialName); + _retryApply = false; + _texturesLoaded = true; } }; if (_networkMaterial) { @@ -188,9 +190,16 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); } } + } 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(); } else { if (deleteNeeded) { - deleteMaterial(oldParentID); + deleteMaterial(oldParentID, oldParentMaterialName); } if (addNeeded) { applyMaterial(); @@ -328,21 +337,21 @@ std::shared_ptr MaterialEntityRenderer::getMaterial() const { } } -void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID) { - std::shared_ptr material = getMaterial(); - if (!material) { - return; - } - if (oldParentID.isNull()) { +void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName) { + std::shared_ptr material = _appliedMaterial; + if (!material || oldParentID.isNull()) { return; } // Our parent could be an entity or an avatar - if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, _parentMaterialName.toStdString())) { + std::string oldParentMaterialNameStd = oldParentMaterialName.toStdString(); + if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, oldParentMaterialNameStd)) { + _appliedMaterial = nullptr; return; } - if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, oldParentMaterialNameStd)) { + _appliedMaterial = nullptr; return; } @@ -366,9 +375,11 @@ void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material = getMaterial(); QUuid parentID = _parentID; if (!material || parentID.isNull()) { + _appliedMaterial = nullptr; return; } @@ -377,11 +388,14 @@ void MaterialEntityRenderer::applyMaterial() { graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); // Our parent could be an entity or an avatar - if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, _parentMaterialName.toStdString())) { + std::string parentMaterialName = _parentMaterialName.toStdString(); + if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, parentMaterialName)) { + _appliedMaterial = material; return; } - if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, parentMaterialName)) { + _appliedMaterial = material; return; } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index b68aee9d48..d714727c7a 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -24,7 +24,7 @@ class MaterialEntityRenderer : public TypedEntityRenderer { using Pointer = std::shared_ptr; public: MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} - ~MaterialEntityRenderer() { deleteMaterial(_parentID); } + ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } private: virtual bool needsRenderUpdate() const override; @@ -57,10 +57,11 @@ private: void applyTextureTransform(std::shared_ptr& material); void applyMaterial(); - void deleteMaterial(const QUuid& oldParentID); + void deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName); NetworkMaterialResourcePointer _networkMaterial; NetworkMaterialResource::ParsedMaterials _parsedMaterials; + std::shared_ptr _appliedMaterial; std::string _currentMaterialName; }; From 6bf154528598efa3ed8509a8f4be0903c9da0367 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 16:44:28 -0800 Subject: [PATCH 4/6] fix build error --- .../src/RenderableMaterialEntityItem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 8f11bdc31f..57d8fd76f7 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -106,7 +106,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } { - auto& material = getMaterial(); + auto material = getMaterial(); // Update the old material regardless of if it's going to change if (transformChanged && material && !_parentID.isNull()) { applyTextureTransform(material); @@ -207,7 +207,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } { - auto& material = getMaterial(); + auto material = getMaterial(); bool newTexturesLoaded = material ? !material->isMissingTexture() : false; if (!_texturesLoaded && newTexturesLoaded) { material->checkResetOpacityMap(); @@ -230,7 +230,7 @@ ItemKey MaterialEntityRenderer::getKey() { builder.withInvisible(); } - const auto& drawMaterial = getMaterial(); + const auto drawMaterial = getMaterial(); if (drawMaterial) { auto matKey = drawMaterial->getKey(); if (matKey.isTranslucent()) { @@ -243,7 +243,7 @@ ItemKey MaterialEntityRenderer::getKey() { ShapeKey MaterialEntityRenderer::getShapeKey() { graphics::MaterialKey drawMaterialKey; - const auto& drawMaterial = getMaterial(); + const auto drawMaterial = getMaterial(); if (drawMaterial) { drawMaterialKey = drawMaterial->getKey(); } @@ -376,7 +376,7 @@ void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material = getMaterial(); + std::shared_ptr material = getMaterial(); QUuid parentID = _parentID; if (!material || parentID.isNull()) { _appliedMaterial = nullptr; From 3e3bd2ffd85be7b474a0ab4b35cd050cc0c838db Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 16:57:29 -0800 Subject: [PATCH 5/6] fix transform properties not changing --- .../src/RenderableMaterialEntityItem.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 57d8fd76f7..2eb877b0e1 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -26,7 +26,6 @@ bool MaterialEntityRenderer::needsRenderUpdate() const { bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { - // Won't cause material re-apply if (entity->getMaterialMappingMode() != _materialMappingMode) { return true; } @@ -43,7 +42,6 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP return true; } - // Could require material re-apply if (entity->getMaterialURL() != _materialURL) { return true; } @@ -69,6 +67,8 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withWriteLock([&] { + bool deleteNeeded = false; + bool addNeeded = _retryApply; bool transformChanged = false; { MaterialMappingMode mode = entity->getMaterialMappingMode(); @@ -109,14 +109,13 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo 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 deleteNeeded = false; - bool addNeeded = _retryApply; bool urlChanged = false; - std::string newCurrentMaterialName = _currentMaterialName; { QString materialURL = entity->getMaterialURL(); From c8ab7ac37f5ff6624c1b8ad6cb74cb02a2357304 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Sat, 16 Feb 2019 18:08:05 -0800 Subject: [PATCH 6/6] fix bad copy --- libraries/entities-renderer/src/EntityTreeRenderer.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 154ad08811..def17ac835 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -265,8 +265,6 @@ private: workload::SpacePointer _space{ new workload::Space() }; workload::Transaction::Updates _spaceUpdates; - static std::function _getAvatarUpOperator; - static std::function _addMaterialToEntityOperator; static std::function _removeMaterialFromEntityOperator; static std::function _addMaterialToAvatarOperator;