start moving materials to rendering only

This commit is contained in:
SamGondelman 2019-02-14 12:59:16 -08:00
parent efe2767f3f
commit bed2732d34
12 changed files with 285 additions and 393 deletions

View file

@ -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) { if (_aboutToQuit) {
return false; return false;
} }
// try to find the renderable
auto renderable = getEntities()->renderableForEntityId(entityID); auto renderable = getEntities()->renderableForEntityId(entityID);
if (renderable) { if (renderable) {
renderable->addMaterial(material, parentMaterialName); 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; 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) { if (_aboutToQuit) {
return false; return false;
} }
// try to find the renderable
auto renderable = getEntities()->renderableForEntityId(entityID); auto renderable = getEntities()->renderableForEntityId(entityID);
if (renderable) { if (renderable) {
renderable->removeMaterial(material, parentMaterialName); 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; 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<AvatarManager>(); auto avatarManager = DependencyManager::get<AvatarManager>();
auto avatar = avatarManager->getAvatarBySessionID(avatarID); auto avatar = avatarManager->getAvatarBySessionID(avatarID);
if (avatar) { if (avatar) {
@ -1974,7 +1960,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
} }
return false; 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<AvatarManager>(); auto avatarManager = DependencyManager::get<AvatarManager>();
auto avatar = avatarManager->getAvatarBySessionID(avatarID); auto avatar = avatarManager->getAvatarBySessionID(avatarID);
if (avatar) { if (avatar) {
@ -1984,23 +1970,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
return false; 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. // Keyboard focus handling for Web overlays.
auto overlays = &(qApp->getOverlays()); auto overlays = &(qApp->getOverlays());
connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) {

View file

@ -1360,3 +1360,36 @@ EntityEditPacketSender* EntityTreeRenderer::getPacketSender() {
EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr; EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr;
return packetSender; return packetSender;
} }
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTreeRenderer::_addMaterialToEntityOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTreeRenderer::_removeMaterialFromEntityOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTreeRenderer::_addMaterialToAvatarOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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;
}

View file

@ -123,6 +123,16 @@ public:
EntityEditPacketSender* getPacketSender(); EntityEditPacketSender* getPacketSender();
static void setAddMaterialToEntityOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; }
static void setRemoveMaterialFromEntityOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; }
static void setRemoveMaterialFromAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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: signals:
void enterEntity(const EntityItemID& entityItemID); void enterEntity(const EntityItemID& entityItemID);
void leaveEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID);
@ -259,6 +269,11 @@ private:
workload::Transaction::Updates _spaceUpdates; workload::Transaction::Updates _spaceUpdates;
static std::function<glm::vec3()> _getAvatarUpOperator; static std::function<glm::vec3()> _getAvatarUpOperator;
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToEntityOperator;
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromEntityOperator;
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToAvatarOperator;
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
}; };

View file

@ -146,7 +146,6 @@ EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _created(entit
_needsRenderUpdate = true; _needsRenderUpdate = true;
emit requestRenderUpdate(); emit requestRenderUpdate();
}); });
_materials = entity->getMaterials();
} }
EntityRenderer::~EntityRenderer() { } EntityRenderer::~EntityRenderer() { }

View file

@ -14,23 +14,54 @@
using namespace render; using namespace render;
using namespace render::entities; using namespace render::entities;
bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { bool MaterialEntityRenderer::needsRenderUpdate() const {
if (entity->getMaterial() != _drawMaterial) { if (_retryApply) {
return true;
}
if (entity->getParentID() != _parentID) {
return true;
}
if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) {
return true; return true;
} }
if (!_texturesLoaded) { if (!_texturesLoaded) {
return true; 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; return false;
} }
void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
withWriteLock([&] { withWriteLock([&] {
if (_drawMaterial != entity->getMaterial()) { if (_drawMaterial != entity->getMaterial()) {
_texturesLoaded = false; _texturesLoaded = false;
@ -61,8 +92,9 @@ ItemKey MaterialEntityRenderer::getKey() {
builder.withInvisible(); builder.withInvisible();
} }
if (_drawMaterial) { const auto& drawMaterial = getMaterial();
auto matKey = _drawMaterial->getKey(); if (drawMaterial) {
auto matKey = drawMaterial->getKey();
if (matKey.isTranslucent()) { if (matKey.isTranslucent()) {
builder.withTransparent(); builder.withTransparent();
} }
@ -73,8 +105,9 @@ ItemKey MaterialEntityRenderer::getKey() {
ShapeKey MaterialEntityRenderer::getShapeKey() { ShapeKey MaterialEntityRenderer::getShapeKey() {
graphics::MaterialKey drawMaterialKey; graphics::MaterialKey drawMaterialKey;
if (_drawMaterial) { const auto& drawMaterial = getMaterial();
drawMaterialKey = _drawMaterial->getKey(); if (drawMaterial) {
drawMaterialKey = drawMaterial->getKey();
} }
bool isTranslucent = drawMaterialKey.isTranslucent(); 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 // Don't render if our parent is set or our material is null
QUuid parentID; QUuid parentID;
withReadLock([&] {
parentID = _parentID;
});
if (!parentID.isNull()) {
return;
}
Transform renderTransform; Transform renderTransform;
graphics::MaterialPointer drawMaterial; graphics::MaterialPointer drawMaterial;
Transform textureTransform; Transform textureTransform;
withReadLock([&] { withReadLock([&] {
parentID = _parentID;
renderTransform = _renderTransform; renderTransform = _renderTransform;
drawMaterial = _drawMaterial; drawMaterial = getMaterial();
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0));
textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot)));
textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); textureTransform.setScale(glm::vec3(_materialMappingScale, 1));
}); });
if (!parentID.isNull() || !drawMaterial) { if (!drawMaterial) {
return; return;
} }
@ -142,3 +181,78 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->getSphereTriangleCount(); args->_details._trianglesRendered += (int)DependencyManager::get<GeometryCache>()->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<NetworkMaterial> 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<NetworkMaterial> 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<NetworkMaterial> 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;
}

View file

@ -13,6 +13,9 @@
#include <MaterialEntityItem.h> #include <MaterialEntityItem.h>
#include <model-networking/ModelCache.h>
#include <model-networking/MaterialCache.h>
class NetworkMaterial; class NetworkMaterial;
namespace render { namespace entities { namespace render { namespace entities {
@ -22,22 +25,45 @@ class MaterialEntityRenderer : public TypedEntityRenderer<MaterialEntityItem> {
using Pointer = std::shared_ptr<MaterialEntityRenderer>; using Pointer = std::shared_ptr<MaterialEntityRenderer>;
public: public:
MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
~MaterialEntityRenderer() { deleteMaterial(); }
private: private:
virtual bool needsRenderUpdate() const override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) 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; virtual void doRender(RenderArgs* args) override;
ItemKey getKey() override; ItemKey getKey() override;
ShapeKey getShapeKey() override; ShapeKey getShapeKey() override;
QString _materialURL;
QString _materialData;
QString _parentMaterialName;
quint16 _priority;
QUuid _parentID; QUuid _parentID;
MaterialMappingMode _materialMappingMode;
bool _materialRepeat;
glm::vec2 _materialMappingPos; glm::vec2 _materialMappingPos;
glm::vec2 _materialMappingScale; glm::vec2 _materialMappingScale;
float _materialMappingRot; float _materialMappingRot;
bool _texturesLoaded { false }; Transform _transform;
glm::vec3 _dimensions;
bool _texturesLoaded { false };
bool _retryApply { false };
std::shared_ptr<NetworkMaterial> 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<NetworkMaterial> _drawMaterial;
}; };
} } } }

View file

@ -3234,25 +3234,6 @@ void EntityItem::setSpaceIndex(int32_t index) {
void EntityItem::preDelete() { void EntityItem::preDelete() {
} }
void EntityItem::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
std::lock_guard<std::mutex> lock(_materialsLock);
_materials[parentMaterialName].push(material);
}
void EntityItem::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {
std::lock_guard<std::mutex> lock(_materialsLock);
_materials[parentMaterialName].remove(material);
}
std::unordered_map<std::string, graphics::MultiMaterial> EntityItem::getMaterials() {
std::unordered_map<std::string, graphics::MultiMaterial> toReturn;
{
std::lock_guard<std::mutex> lock(_materialsLock);
toReturn = _materials;
}
return toReturn;
}
bool EntityItem::getCloneable() const { bool EntityItem::getCloneable() const {
bool result; bool result;
withReadLock([&] { withReadLock([&] {

View file

@ -37,8 +37,6 @@
#include "EntityDynamicInterface.h" #include "EntityDynamicInterface.h"
#include "GrabPropertyGroup.h" #include "GrabPropertyGroup.h"
#include "graphics/Material.h"
class EntitySimulation; class EntitySimulation;
class EntityTreeElement; class EntityTreeElement;
class EntityTreeElementExtraEncodeData; class EntityTreeElementExtraEncodeData;
@ -542,10 +540,6 @@ public:
virtual void preDelete(); virtual void preDelete();
virtual void postParentFixup() {} virtual void postParentFixup() {}
void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
std::unordered_map<std::string, graphics::MultiMaterial> getMaterials();
void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; } void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; }
uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; } uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; }
@ -750,10 +744,6 @@ protected:
QHash<QUuid, EntityDynamicPointer> _grabActions; QHash<QUuid, EntityDynamicPointer> _grabActions;
private:
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
std::mutex _materialsLock;
}; };
#endif // hifi_EntityItem_h #endif // hifi_EntityItem_h

View file

@ -2953,55 +2953,6 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const {
return entity->getJointNames(); return entity->getJointNames();
} }
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToEntityOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromEntityOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToAvatarOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> EntityTree::_removeMaterialFromAvatarOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> EntityTree::_addMaterialToOverlayOperator = nullptr;
std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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, void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,
MovingEntitiesOperator& moveOperator, bool force, bool tellServer) { MovingEntitiesOperator& moveOperator, bool force, bool tellServer) {
// if the queryBox has changed, tell the entity-server // if the queryBox has changed, tell the entity-server

View file

@ -262,21 +262,6 @@ public:
void setIsServerlessMode(bool value) { _serverlessDomain = value; } void setIsServerlessMode(bool value) { _serverlessDomain = value; }
bool isServerlessMode() const { return _serverlessDomain; } bool isServerlessMode() const { return _serverlessDomain; }
static void setAddMaterialToEntityOperator(std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; }
static void setRemoveMaterialFromEntityOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; }
static void setRemoveMaterialFromAvatarOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; }
static void setRemoveMaterialFromOverlayOperator(std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> 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<QString, QString> getNamedPaths() const { return _namedPaths; } std::map<QString, QString> getNamedPaths() const { return _namedPaths; }
void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,
@ -385,13 +370,6 @@ private:
std::shared_ptr<AvatarData> _myAvatar{ nullptr }; std::shared_ptr<AvatarData> _myAvatar{ nullptr };
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToEntityOperator;
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromEntityOperator;
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToAvatarOperator;
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromAvatarOperator;
static std::function<bool(const QUuid&, graphics::MaterialLayer, const std::string&)> _addMaterialToOverlayOperator;
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
std::vector<int32_t> _staleProxies; std::vector<int32_t> _staleProxies;
bool _serverlessDomain { false }; bool _serverlessDomain { false };

View file

@ -16,9 +16,6 @@
EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
entity->setProperties(properties); 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; return entity;
} }
@ -27,10 +24,6 @@ MaterialEntityItem::MaterialEntityItem(const EntityItemID& entityItemID) : Entit
_type = EntityTypes::Material; _type = EntityTypes::Material;
} }
MaterialEntityItem::~MaterialEntityItem() {
removeMaterial();
}
EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const {
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL);
@ -131,7 +124,6 @@ void MaterialEntityItem::debugDump() const {
qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " name:" << _name; qCDebug(entities) << " name:" << _name;
qCDebug(entities) << " material url:" << _materialURL; qCDebug(entities) << " material url:" << _materialURL;
qCDebug(entities) << " current material name:" << _currentMaterialName.c_str();
qCDebug(entities) << " material mapping mode:" << _materialMappingMode; qCDebug(entities) << " material mapping mode:" << _materialMappingMode;
qCDebug(entities) << " material repeat:" << _materialRepeat; qCDebug(entities) << " material repeat:" << _materialRepeat;
qCDebug(entities) << " priority:" << _priority; qCDebug(entities) << " priority:" << _priority;
@ -154,216 +146,101 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) {
} }
} }
std::shared_ptr<NetworkMaterial> MaterialEntityItem::getMaterial() const { QString MaterialEntityItem::getMaterialURL() const {
auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName); return resultWithReadLock<QString>([&] {
if (material != _parsedMaterials.networkMaterials.end()) { return _materialURL;
return material->second; });
} else {
return nullptr;
}
} }
void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool materialDataChanged) { void MaterialEntityItem::setMaterialURL(const QString& materialURL) {
bool usingMaterialData = materialDataChanged || materialURLString.startsWith("materialData"); withWriteLock([&] {
if (_materialURL != materialURLString || (usingMaterialData && materialDataChanged)) { _materialURL = materialURL;
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::setCurrentMaterialName(const std::string& currentMaterialName) { QString MaterialEntityItem::getMaterialData() const {
if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) { return resultWithReadLock<QString>([&] {
_currentMaterialName = currentMaterialName; return _materialData;
} else if (_parsedMaterials.names.size() > 0) { });
_currentMaterialName = _parsedMaterials.names[0];
}
} }
void MaterialEntityItem::setMaterialData(const QString& materialData) { void MaterialEntityItem::setMaterialData(const QString& materialData) {
if (_materialData != materialData) { withWriteLock([&] {
_materialData = materialData; _materialData = materialData;
if (_materialURL.startsWith("materialData")) { });
// Trigger material update when material data changes }
setMaterialURL(_materialURL, true);
} MaterialMappingMode MaterialEntityItem::getMaterialMappingMode() const {
} return resultWithReadLock<MaterialMappingMode>([&] {
return _materialMappingMode;
});
} }
void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) { void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) {
if (_materialMappingMode != mode) { withWriteLock([&] {
removeMaterial();
_materialMappingMode = mode; _materialMappingMode = mode;
setUnscaledDimensions(_desiredDimensions); });
applyMaterial(); setUnscaledDimensions(_desiredDimensions);
}
} }
void MaterialEntityItem::setMaterialRepeat(bool repeat) { quint16 MaterialEntityItem::getPriority() const {
if (_materialRepeat != repeat) { return resultWithReadLock<quint16>([&] {
removeMaterial(); return _priority;
_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();
}
} }
void MaterialEntityItem::setPriority(quint16 priority) { void MaterialEntityItem::setPriority(quint16 priority) {
if (_priority != priority) { withWriteLock([&] {
removeMaterial();
_priority = priority; _priority = priority;
applyMaterial(); });
} }
QString MaterialEntityItem::getParentMaterialName() const {
return resultWithReadLock<QString>([&] {
return _parentMaterialName;
});
} }
void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) { void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) {
if (_parentMaterialName != parentMaterialName) { withWriteLock([&] {
removeMaterial();
_parentMaterialName = parentMaterialName; _parentMaterialName = parentMaterialName;
applyMaterial(); });
}
} }
void MaterialEntityItem::setParentID(const QUuid& parentID) { glm::vec2 MaterialEntityItem::getMaterialMappingPos() const {
if (getParentID() != parentID) { return resultWithReadLock<glm::vec2>([&] {
removeMaterial(); return _materialMappingPos;
EntityItem::setParentID(parentID); });
applyMaterial();
}
} }
void MaterialEntityItem::locationChanged(bool tellPhysics) { void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) {
EntityItem::locationChanged(); withWriteLock([&] {
if (_materialMappingMode == MaterialMappingMode::PROJECTED) { _materialMappingPos = materialMappingPos;
removeMaterial(); });
applyMaterial();
}
} }
void MaterialEntityItem::dimensionsChanged() { glm::vec2 MaterialEntityItem::getMaterialMappingScale() const {
EntityItem::dimensionsChanged(); return resultWithReadLock<glm::vec2>([&] {
if (_materialMappingMode == MaterialMappingMode::PROJECTED) { return _materialMappingScale;
removeMaterial(); });
applyMaterial();
}
} }
void MaterialEntityItem::removeMaterial() { void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) {
graphics::MaterialPointer material = getMaterial(); withWriteLock([&] {
if (!material) { _materialMappingScale = materialMappingScale;
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::applyMaterial() { float MaterialEntityItem::getMaterialMappingRot() const {
_retryApply = false; return resultWithReadLock<float>([&] {
graphics::MaterialPointer material = getMaterial(); return _materialMappingRot;
QUuid parentID = getParentID(); });
if (!material || parentID.isNull()) { }
return;
}
Transform textureTransform; void MaterialEntityItem::setMaterialMappingRot(float materialMappingRot) {
if (_materialMappingMode == MaterialMappingMode::UV) { withWriteLock([&] {
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); _materialMappingRot = materialMappingRot;
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;
} }
AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) {
@ -380,18 +257,3 @@ AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) {
} }
return aaCube; 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);
}

View file

@ -12,8 +12,6 @@
#include "EntityItem.h" #include "EntityItem.h"
#include "MaterialMappingMode.h" #include "MaterialMappingMode.h"
#include <model-networking/ModelCache.h>
#include <model-networking/MaterialCache.h>
class MaterialEntityItem : public EntityItem { class MaterialEntityItem : public EntityItem {
using Pointer = std::shared_ptr<MaterialEntityItem>; using Pointer = std::shared_ptr<MaterialEntityItem>;
@ -21,13 +19,9 @@ public:
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
MaterialEntityItem(const EntityItemID& entityItemID); MaterialEntityItem(const EntityItemID& entityItemID);
~MaterialEntityItem();
ALLOW_INSTANTIATION // This class can be instantiated 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 // methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override;
virtual bool setProperties(const EntityItemProperties& properties) override; virtual bool setProperties(const EntityItemProperties& properties) override;
@ -52,44 +46,30 @@ public:
virtual void setUnscaledDimensions(const glm::vec3& value) override; virtual void setUnscaledDimensions(const glm::vec3& value) override;
QString getMaterialURL() const { return _materialURL; } QString getMaterialURL() const;
void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); 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); void setMaterialMappingMode(MaterialMappingMode mode);
bool getMaterialRepeat() const { return _materialRepeat; } 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); void setPriority(quint16 priority);
QString getParentMaterialName() const { return _parentMaterialName; } QString getParentMaterialName() const;
void setParentMaterialName(const QString& parentMaterialName); void setParentMaterialName(const QString& parentMaterialName);
glm::vec2 getMaterialMappingPos() const { return _materialMappingPos; } glm::vec2 getMaterialMappingPos() const;
void setMaterialMappingPos(const glm::vec2& materialMappingPos); void setMaterialMappingPos(const glm::vec2& materialMappingPos);
glm::vec2 getMaterialMappingScale() const { return _materialMappingScale; } glm::vec2 getMaterialMappingScale() const;
void setMaterialMappingScale(const glm::vec2& materialMappingScale); void setMaterialMappingScale(const glm::vec2& materialMappingScale);
float getMaterialMappingRot() const { return _materialMappingRot; } float getMaterialMappingRot() const;
void setMaterialMappingRot(const float& materialMappingRot); void setMaterialMappingRot(float materialMappingRot);
QString getMaterialData() const { return _materialData; }
void setMaterialData(const QString& materialData);
std::shared_ptr<NetworkMaterial> getMaterial() const;
void setParentID(const QUuid& parentID) override;
void locationChanged(bool tellPhysics) override;
void dimensionsChanged() override;
void applyMaterial();
void removeMaterial();
void postParentFixup() override;
AACube calculateInitialQueryAACube(bool& success) override; AACube calculateInitialQueryAACube(bool& success) override;
@ -128,12 +108,6 @@ private:
float _materialMappingRot { 0 }; float _materialMappingRot { 0 };
QString _materialData; QString _materialData;
NetworkMaterialResourcePointer _networkMaterial;
NetworkMaterialResource::ParsedMaterials _parsedMaterials;
std::string _currentMaterialName;
bool _retryApply { false };
}; };
#endif // hifi_MaterialEntityItem_h #endif // hifi_MaterialEntityItem_h