diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index 5e7a3c1700..1470249bf3 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -21,12 +21,7 @@ #include "AssetUtils.h" #include "ReceivedMessage.h" -namespace std { - template <> - struct hash { - size_t operator()(const QString& v) const { return qHash(v); } - }; -} +#include "RegisteredMetaTypes.h" struct AssetMeta { AssetMeta() { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f8fa8f9b17..ce4027945d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1587,37 +1587,37 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } }); - EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID) { + EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { - avatar->addMaterial(material, shapeID); + avatar->addMaterial(material, parentMaterialID); return true; } return false; }); - EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID) { + EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { - avatar->removeMaterial(material, shapeID); + avatar->removeMaterial(material, parentMaterialID); return true; } return false; }); - EntityTree::setAddMaterialToOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID) { + EntityTree::setAddMaterialToOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID) { auto overlay = _overlays.getOverlay(overlayID); if (overlay) { - overlay->addMaterial(material, shapeID); + overlay->addMaterial(material, parentMaterialID); return true; } return false; }); - EntityTree::setRemoveMaterialFromOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID) { + EntityTree::setRemoveMaterialFromOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID) { auto overlay = _overlays.getOverlay(overlayID); if (overlay) { - overlay->removeMaterial(material, shapeID); + overlay->removeMaterial(material, parentMaterialID); return true; } return false; diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index bf95494d19..ab7f55d6e7 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -633,17 +633,17 @@ uint32_t ModelOverlay::fetchMetaSubItems(render::ItemIDs& subItems) const { return 0; } -void ModelOverlay::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { - Overlay::addMaterial(material, shapeID); +void ModelOverlay::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + Overlay::addMaterial(material, parentMaterialID); if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->addMaterial(material, shapeID); + _model->addMaterial(material, parentMaterialID); } } -void ModelOverlay::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { - Overlay::removeMaterial(material, shapeID); +void ModelOverlay::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + Overlay::removeMaterial(material, parentMaterialID); if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->removeMaterial(material, shapeID); + _model->removeMaterial(material, parentMaterialID); } } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 827f7f2d5b..6761b1508c 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -59,8 +59,8 @@ public: void setDrawInFront(bool drawInFront) override; void setDrawHUDLayer(bool drawHUDLayer) override; - void addMaterial(graphics::MaterialPointer material, quint16 shapeID) override; - void removeMaterial(graphics::MaterialPointer material, quint16 shapeID) override; + void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; + void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; protected: Transform evalRenderTransform() override; diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index 368ed04062..04d6c2fe4d 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -236,12 +236,12 @@ QVector qVectorOverlayIDFromScriptValue(const QScriptValue& array) { return newVector; } -void Overlay::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void Overlay::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].push(material); + _materials[parentMaterialID].push(material); } -void Overlay::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void Overlay::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].remove(material); + _materials[parentMaterialID].remove(material); } \ No newline at end of file diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 4cb3f7c84d..bd9f7942fd 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -91,8 +91,8 @@ public: unsigned int getStackOrder() const { return _stackOrder; } void setStackOrder(unsigned int stackOrder) { _stackOrder = stackOrder; } - virtual void addMaterial(graphics::MaterialPointer material, quint16 shapeID); - virtual void removeMaterial(graphics::MaterialPointer material, quint16 shapeID); + virtual void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); + virtual void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); protected: float updatePulse(); @@ -120,7 +120,7 @@ protected: static const xColor DEFAULT_OVERLAY_COLOR; static const float DEFAULT_ALPHA; - std::unordered_map _materials; + std::unordered_map _materials; std::mutex _materialsLock; private: diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 4cd9bbedd7..3276a8fe89 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1763,19 +1763,19 @@ float Avatar::getUnscaledEyeHeightFromSkeleton() const { } } -void Avatar::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void Avatar::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].push(material); + _materials[parentMaterialID].push(material); if (_skeletonModel && _skeletonModel->fetchRenderItemIDs().size() > 0) { - _skeletonModel->addMaterial(material, shapeID); + _skeletonModel->addMaterial(material, parentMaterialID); } } -void Avatar::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void Avatar::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].remove(material); + _materials[parentMaterialID].remove(material); if (_skeletonModel && _skeletonModel->fetchRenderItemIDs().size() > 0) { - _skeletonModel->removeMaterial(material, shapeID); + _skeletonModel->removeMaterial(material, parentMaterialID); } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 9c355159d8..49aa664a9f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -272,8 +272,8 @@ public: virtual void setAvatarEntityDataChanged(bool value) override; - void addMaterial(graphics::MaterialPointer material, quint16 shapeID) override; - void removeMaterial(graphics::MaterialPointer material, quint16 shapeID) override; + void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; + void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; public slots: @@ -401,7 +401,7 @@ protected: ThreadSafeValueCache _unscaledEyeHeightCache { DEFAULT_AVATAR_EYE_HEIGHT }; - std::unordered_map _materials; + std::unordered_map _materials; std::mutex _materialsLock; void processMaterials(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index fbd586f153..832585a483 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -696,8 +696,8 @@ public: bool getIsReplicated() const { return _isReplicated; } - virtual void addMaterial(graphics::MaterialPointer material, quint16 shapeID) {} - virtual void removeMaterial(graphics::MaterialPointer material, quint16 shapeID) {} + virtual void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) {} + virtual void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) {} signals: void displayNameChanged(); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 2f92790d18..81d7dceb0d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -404,12 +404,12 @@ void EntityRenderer::onRemoveFromScene(const EntityItemPointer& entity) { QObject::disconnect(this, &EntityRenderer::requestRenderUpdate, this, nullptr); } -void EntityRenderer::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void EntityRenderer::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].push(material); + _materials[parentMaterialID].push(material); } -void EntityRenderer::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].remove(material); + _materials[parentMaterialID].remove(material); } \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index f58b540aef..6247a97c21 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -102,8 +102,8 @@ protected: } public slots: - virtual void addMaterial(graphics::MaterialPointer material, quint16 shapeID); - virtual void removeMaterial(graphics::MaterialPointer material, quint16 shapeID); + virtual void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); + virtual void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); signals: void requestRenderUpdate(); @@ -133,7 +133,7 @@ protected: // Only touched on the rendering thread bool _renderUpdateQueued{ false }; - std::unordered_map _materials; + std::unordered_map _materials; std::mutex _materialsLock; private: diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index d541d99c4c..ad17202d8e 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -102,10 +102,10 @@ void MaterialEntityRenderer::addVertex(std::vector& buffer, const glm::ve void MaterialEntityRenderer::addTriangleFan(std::vector& buffer, int stack, int step) { float v1 = ((float)stack) / STACKS; - float theta1 = v1 * M_PI; + float theta1 = v1 * (float)M_PI; glm::vec3 tip = getVertexPos(0, theta1); float v2 = ((float)(stack + step)) / STACKS; - float theta2 = v2 * M_PI; + float theta2 = v2 * (float)M_PI; for (int i = 0; i < SLICES; i++) { float u1 = ((float)i) / SLICES; float u2 = ((float)(i + step)) / SLICES; @@ -169,8 +169,8 @@ void MaterialEntityRenderer::generateMesh() { for (int j = 1; j < STACKS - 1; j++) { float v1 = ((float)j) / STACKS; float v2 = ((float)(j + 1)) / STACKS; - float theta1 = v1 * M_PI; - float theta2 = v2 * M_PI; + float theta1 = v1 * (float)M_PI; + float theta2 = v2 * (float)M_PI; for (int i = 0; i < SLICES; i++) { float u1 = ((float)i) / SLICES; float u2 = ((float)(i + 1)) / SLICES; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 739ccd9738..e28ba797d5 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1467,17 +1467,17 @@ void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const QStr } } -void ModelEntityRenderer::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { - Parent::addMaterial(material, shapeID); +void ModelEntityRenderer::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + Parent::addMaterial(material, parentMaterialID); if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->addMaterial(material, shapeID); + _model->addMaterial(material, parentMaterialID); } } -void ModelEntityRenderer::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { - Parent::removeMaterial(material, shapeID); +void ModelEntityRenderer::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + Parent::removeMaterial(material, parentMaterialID); if (_model && _model->fetchRenderItemIDs().size() > 0) { - _model->removeMaterial(material, shapeID); + _model->removeMaterial(material, parentMaterialID); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 75c6639902..3951deaa2d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -144,8 +144,8 @@ public: ModelEntityRenderer(const EntityItemPointer& entity); public slots: - void addMaterial(graphics::MaterialPointer material, quint16 shapeID) override; - void removeMaterial(graphics::MaterialPointer material, quint16 shapeID) override; + void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; + void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) override; protected: virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override; diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 8bed9c70ee..5c5df38350 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -77,9 +77,9 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce _procedural.setProceduralData(ProceduralData::parse(_lastUserData)); } - removeMaterial(_material, 0); + removeMaterial(_material, "0"); _material = entity->getMaterial(); - addMaterial(_material, 0); + addMaterial(_material, "0"); _shape = entity->getShape(); _position = entity->getWorldPosition(); @@ -127,7 +127,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { withReadLock([&] { geometryShape = geometryCache->getShapeForEntityShape(_shape); batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation - mat = _materials[0].top(); + mat = _materials["0"].top(); if (mat) { outColor = glm::vec4(mat->getAlbedo(), mat->getOpacity()); if (_procedural.isReady()) { diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 43510864ba..3ea81e5a36 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2940,20 +2940,20 @@ void EntityItem::preDelete() { } } -void EntityItem::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void EntityItem::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].push(material); - emit addMaterialToRenderItem(material, shapeID); + _materials[parentMaterialID].push(material); + emit addMaterialToRenderItem(material, parentMaterialID); } -void EntityItem::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { +void EntityItem::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { std::lock_guard lock(_materialsLock); - _materials[shapeID].remove(material); - emit removeMaterialFromRenderItem(material, shapeID); + _materials[parentMaterialID].remove(material); + emit removeMaterialFromRenderItem(material, parentMaterialID); } -std::unordered_map EntityItem::getMaterials() { - std::unordered_map toReturn; +std::unordered_map EntityItem::getMaterials() { + std::unordered_map toReturn; { std::lock_guard lock(_materialsLock); toReturn = _materials; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index b2804a2e86..97d2f32a04 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -482,14 +482,14 @@ public: virtual void preDelete(); virtual void postParentFixup() {} - void addMaterial(graphics::MaterialPointer material, quint16 shapeID); - void removeMaterial(graphics::MaterialPointer material, quint16 shapeID); - std::unordered_map getMaterials(); + void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); + void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); + std::unordered_map getMaterials(); signals: void requestRenderUpdate(); - void addMaterialToRenderItem(graphics::MaterialPointer material, quint16 shapeID); - void removeMaterialFromRenderItem(graphics::MaterialPointer material, quint16 shapeID); + void addMaterialToRenderItem(graphics::MaterialPointer material, const QString& parentMaterialID); + void removeMaterialFromRenderItem(graphics::MaterialPointer material, const QString& parentMaterialID); protected: QHash _changeHandlers; @@ -644,7 +644,7 @@ protected: bool _cauterized { false }; // if true, don't draw because it would obscure 1st-person camera private: - std::unordered_map _materials; + std::unordered_map _materials; std::mutex _materialsLock; }; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 19aa6990db..450d0727f9 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -357,9 +357,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_URL, materialURL); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_TYPE, materialMode); - CHECK_PROPERTY_CHANGE(PROP_MATERIAL_BLEND_FACTOR, blendFactor); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_PRIORITY, priority); - CHECK_PROPERTY_CHANGE(PROP_PARENT_SHAPE_ID, shapeID); + CHECK_PROPERTY_CHANGE(PROP_PARENT_MATERIAL_ID, parentMaterialID); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_POS, materialPos); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_SCALE, materialScale); CHECK_PROPERTY_CHANGE(PROP_MATERIAL_ROT, materialRot); @@ -663,9 +662,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool if (_type == EntityTypes::Material) { COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_URL, materialURL); COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_MATERIAL_TYPE, materialMode, getMaterialModeAsString()); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_BLEND_FACTOR, blendFactor); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_PRIORITY, priority); - COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_SHAPE_ID, shapeID); + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_PARENT_MATERIAL_ID, parentMaterialID); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_POS, materialPos); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_SCALE, materialScale); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_MATERIAL_ROT, materialRot); @@ -806,9 +804,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialURL, QString, setMaterialURL); COPY_PROPERTY_FROM_QSCRIPTVALUE_ENUM(materialMode, MaterialMode); - COPY_PROPERTY_FROM_QSCRIPTVALUE(blendFactor, float, setBlendFactor); COPY_PROPERTY_FROM_QSCRIPTVALUE(priority, quint16, setPriority); - COPY_PROPERTY_FROM_QSCRIPTVALUE(shapeID, quint16, setShapeID); + COPY_PROPERTY_FROM_QSCRIPTVALUE(parentMaterialID, QString, setParentMaterialID); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialPos, glmVec2, setMaterialPos); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialScale, glmVec2, setMaterialScale); COPY_PROPERTY_FROM_QSCRIPTVALUE(materialRot, float, setMaterialRot); @@ -1168,9 +1165,8 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue ADD_PROPERTY_TO_MAP(PROP_MATERIAL_URL, MaterialURL, materialURL, QString); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_TYPE, MaterialMode, materialMode, MaterialMode); - ADD_PROPERTY_TO_MAP(PROP_MATERIAL_BLEND_FACTOR, BlendFactor, blendFactor, float); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_PRIORITY, Priority, priority, quint16); - ADD_PROPERTY_TO_MAP(PROP_PARENT_SHAPE_ID, ShapeID, shapeID, quint16); + ADD_PROPERTY_TO_MAP(PROP_PARENT_MATERIAL_ID, ParentMaterialID, parentMaterialID, QString); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_POS, MaterialPos, materialPos, glmVec2); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_SCALE, MaterialScale, materialScale, glmVec2); ADD_PROPERTY_TO_MAP(PROP_MATERIAL_ROT, MaterialRot, materialRot, float); @@ -1562,9 +1558,8 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy if (properties.getType() == EntityTypes::Material) { APPEND_ENTITY_PROPERTY(PROP_MATERIAL_URL, properties.getMaterialURL()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_TYPE, (uint32_t)properties.getMaterialMode()); - APPEND_ENTITY_PROPERTY(PROP_MATERIAL_BLEND_FACTOR, properties.getBlendFactor()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_PRIORITY, properties.getPriority()); - APPEND_ENTITY_PROPERTY(PROP_PARENT_SHAPE_ID, properties.getShapeID()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_MATERIAL_ID, properties.getParentMaterialID()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_POS, properties.getMaterialPos()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_SCALE, properties.getMaterialScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_ROT, properties.getMaterialRot()); @@ -1930,9 +1925,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int if (properties.getType() == EntityTypes::Material) { READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_URL, QString, setMaterialURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_TYPE, MaterialMode, setMaterialMode); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_BLEND_FACTOR, float, setBlendFactor); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_PRIORITY, quint16, setPriority); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_SHAPE_ID, quint16, setShapeID); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_MATERIAL_ID, QString, setParentMaterialID); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_POS, glmVec2, setMaterialPos); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_SCALE, glmVec2, setMaterialScale); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MATERIAL_ROT, float, setMaterialRot); @@ -2113,9 +2107,8 @@ void EntityItemProperties::markAllChanged() { _materialURLChanged = true; _materialModeChanged = true; - _blendFactorChanged = true; _priorityChanged = true; - _shapeIDChanged = true; + _parentMaterialIDChanged = true; _materialPosChanged = true; _materialScaleChanged = true; _materialRotChanged = true; @@ -2449,14 +2442,11 @@ QList EntityItemProperties::listChangedProperties() { if (materialModeChanged()) { out += "materialMode"; } - if (blendFactorChanged()) { - out += "blendFactor"; - } if (priorityChanged()) { out += "priority"; } - if (shapeIDChanged()) { - out += "shapeID"; + if (parentMaterialIDChanged()) { + out += "parentMaterialID"; } if (materialPosChanged()) { out += "materialPos"; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index a8a79b6303..daa2272e36 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -224,9 +224,8 @@ public: DEFINE_PROPERTY_REF(PROP_MATERIAL_URL, MaterialURL, materialURL, QString, ""); DEFINE_PROPERTY_REF_ENUM(PROP_MATERIAL_TYPE, MaterialMode, materialMode, MaterialMode, UV); - DEFINE_PROPERTY_REF(PROP_MATERIAL_BLEND_FACTOR, BlendFactor, blendFactor, float, 1.0f); DEFINE_PROPERTY_REF(PROP_MATERIAL_PRIORITY, Priority, priority, quint16, 0); - DEFINE_PROPERTY_REF(PROP_PARENT_SHAPE_ID, ShapeID, shapeID, quint16, 0); + DEFINE_PROPERTY_REF(PROP_PARENT_MATERIAL_ID, ParentMaterialID, parentMaterialID, QString, "0"); DEFINE_PROPERTY_REF(PROP_MATERIAL_POS, MaterialPos, materialPos, glmVec2, glm::vec2(0, 0)); DEFINE_PROPERTY_REF(PROP_MATERIAL_SCALE, MaterialScale, materialScale, glmVec2, glm::vec2(1, 1)); DEFINE_PROPERTY_REF(PROP_MATERIAL_ROT, MaterialRot, materialRot, float, 0); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 17ebddbe9d..6ed2186760 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -229,9 +229,8 @@ enum EntityPropertyList { PROP_MATERIAL_URL, PROP_MATERIAL_TYPE, - PROP_MATERIAL_BLEND_FACTOR, PROP_MATERIAL_PRIORITY, - PROP_PARENT_SHAPE_ID, + PROP_PARENT_MATERIAL_ID, PROP_MATERIAL_POS, PROP_MATERIAL_SCALE, PROP_MATERIAL_ROT, diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 775b3bd2f7..9935718568 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2382,35 +2382,35 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { return entity->getJointNames(); } -std::function EntityTree::_addMaterialToAvatarOperator = nullptr; -std::function EntityTree::_removeMaterialFromAvatarOperator = nullptr; -std::function EntityTree::_addMaterialToOverlayOperator = nullptr; -std::function EntityTree::_removeMaterialFromOverlayOperator = nullptr; +std::function EntityTree::_addMaterialToAvatarOperator = nullptr; +std::function EntityTree::_removeMaterialFromAvatarOperator = nullptr; +std::function EntityTree::_addMaterialToOverlayOperator = nullptr; +std::function EntityTree::_removeMaterialFromOverlayOperator = nullptr; -bool EntityTree::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID) { +bool EntityTree::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID) { if (_addMaterialToAvatarOperator) { - return _addMaterialToAvatarOperator(avatarID, material, shapeID); + return _addMaterialToAvatarOperator(avatarID, material, parentMaterialID); } return false; } -bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID) { +bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID) { if (_removeMaterialFromAvatarOperator) { - return _removeMaterialFromAvatarOperator(avatarID, material, shapeID); + return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialID); } return false; } -bool EntityTree::addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID) { +bool EntityTree::addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID) { if (_addMaterialToOverlayOperator) { - return _addMaterialToOverlayOperator(overlayID, material, shapeID); + return _addMaterialToOverlayOperator(overlayID, material, parentMaterialID); } return false; } -bool EntityTree::removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID) { +bool EntityTree::removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID) { if (_removeMaterialFromOverlayOperator) { - return _removeMaterialFromOverlayOperator(overlayID, material, shapeID); + return _removeMaterialFromOverlayOperator(overlayID, material, parentMaterialID); } return false; } \ No newline at end of file diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index a02ce900ff..a532f64fc9 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -280,15 +280,15 @@ public: void setMyAvatar(std::shared_ptr myAvatar) { _myAvatar = myAvatar; } - static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } - static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } - static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID); - static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, quint16 shapeID); + static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } + static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } + static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID); + static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const QString& parentMaterialID); - static void setAddMaterialToOverlayOperator(std::function addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; } - static void setRemoveMaterialFromOverlayOperator(std::function removeMaterialFromOverlayOperator) { _removeMaterialFromOverlayOperator = removeMaterialFromOverlayOperator; } - static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID); - static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, quint16 shapeID); + static void setAddMaterialToOverlayOperator(std::function addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; } + static void setRemoveMaterialFromOverlayOperator(std::function removeMaterialFromOverlayOperator) { _removeMaterialFromOverlayOperator = removeMaterialFromOverlayOperator; } + static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID); + static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const QString& parentMaterialID); signals: void deletingEntity(const EntityItemID& entityID); @@ -398,10 +398,10 @@ private: std::shared_ptr _myAvatar{ nullptr }; - static std::function _addMaterialToAvatarOperator; - static std::function _removeMaterialFromAvatarOperator; - static std::function _addMaterialToOverlayOperator; - static std::function _removeMaterialFromOverlayOperator; + static std::function _addMaterialToAvatarOperator; + static std::function _removeMaterialFromAvatarOperator; + static std::function _addMaterialToOverlayOperator; + static std::function _removeMaterialFromOverlayOperator; }; #endif // hifi_EntityTree_h diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index 7026da117c..1ebaa4f21a 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -31,9 +31,8 @@ EntityItemProperties MaterialEntityItem::getProperties(EntityPropertyFlags desir EntityItemProperties properties = EntityItem::getProperties(desiredProperties); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialMode, getMaterialMode); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(blendFactor, getBlendFactor); COPY_ENTITY_PROPERTY_TO_PROPERTIES(priority, getPriority); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeID, getShapeID); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(parentMaterialID, getParentMaterialID); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialPos, getMaterialPos); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialScale, getMaterialScale); COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialRot, getMaterialRot); @@ -45,9 +44,8 @@ bool MaterialEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialURL, setMaterialURL); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialMode, setMaterialMode); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(blendFactor, setBlendFactor); SET_ENTITY_PROPERTY_FROM_PROPERTIES(priority, setPriority); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeID, setShapeID); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(parentMaterialID, setParentMaterialID); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialPos, setMaterialPos); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialScale, setMaterialScale); SET_ENTITY_PROPERTY_FROM_PROPERTIES(materialRot, setMaterialRot); @@ -65,139 +63,6 @@ bool MaterialEntityItem::setProperties(const EntityItemProperties& properties) { return somethingChanged; } -bool MaterialEntityItem::parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB) { - if (array.isArray()) { - QJsonArray colorArray = array.toArray(); - if (colorArray.size() >= 3 && colorArray[0].isDouble() && colorArray[1].isDouble() && colorArray[2].isDouble()) { - isSRGB = true; - if (colorArray.size() >= 4) { - if (colorArray[3].isBool()) { - isSRGB = colorArray[3].toBool(); - } - } - color = glm::vec3(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble()); - return true; - } - } - return false; -} - -void MaterialEntityItem::parseJSONMaterial(const QJsonObject& materialJSON) { - QString name = ""; - std::shared_ptr material = std::make_shared(); - for (auto& key : materialJSON.keys()) { - if (key == "name") { - auto nameJSON = materialJSON.value(key); - if (nameJSON.isString()) { - name = nameJSON.toString(); - } - } else if (key == "emissive") { - glm::vec3 color; - bool isSRGB; - bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); - if (valid) { - material->setEmissive(color, isSRGB); - } - } else if (key == "opacity") { - auto value = materialJSON.value(key); - if (value.isDouble()) { - material->setOpacity(value.toDouble()); - } - } else if (key == "albedo") { - glm::vec3 color; - bool isSRGB; - bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); - if (valid) { - material->setAlbedo(color, isSRGB); - } - } else if (key == "roughness") { - auto value = materialJSON.value(key); - if (value.isDouble()) { - material->setRoughness(value.toDouble()); - } - } else if (key == "fresnel") { - glm::vec3 color; - bool isSRGB; - bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); - if (valid) { - material->setFresnel(color, isSRGB); - } - } else if (key == "metallic") { - auto value = materialJSON.value(key); - if (value.isDouble()) { - material->setMetallic(value.toDouble()); - } - } else if (key == "scattering") { - auto value = materialJSON.value(key); - if (value.isDouble()) { - material->setScattering(value.toDouble()); - } - } else if (key == "emissiveMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setEmissiveMap(value.toString()); - } - } else if (key == "albedoMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - bool useAlphaChannel = false; - auto opacityMap = materialJSON.find("opacityMap"); - if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == value.toString()) { - useAlphaChannel = true; - } - material->setAlbedoMap(value.toString(), useAlphaChannel); - } - } else if (key == "roughnessMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setRoughnessMap(value.toString(), false); - } - } else if (key == "glossMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setRoughnessMap(value.toString(), true); - } - } else if (key == "metallicMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setMetallicMap(value.toString(), false); - } - } else if (key == "specularMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setMetallicMap(value.toString(), true); - } - } else if (key == "normalMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setNormalMap(value.toString(), false); - } - } else if (key == "bumpMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setNormalMap(value.toString(), true); - } - } else if (key == "occlusionMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setOcclusionMap(value.toString()); - } - } else if (key == "scatteringMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setScatteringMap(value.toString()); - } - } else if (key == "lightMap") { - auto value = materialJSON.value(key); - if (value.isString()) { - material->setLightmapMap(value.toString()); - } - } - } - _materials[name] = material; - _materialNames.push_back(name); -} - int MaterialEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, @@ -208,9 +73,8 @@ int MaterialEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da READ_ENTITY_PROPERTY(PROP_MATERIAL_URL, QString, setMaterialURL); READ_ENTITY_PROPERTY(PROP_MATERIAL_TYPE, MaterialMode, setMaterialMode); - READ_ENTITY_PROPERTY(PROP_MATERIAL_BLEND_FACTOR, float, setBlendFactor); READ_ENTITY_PROPERTY(PROP_MATERIAL_PRIORITY, quint16, setPriority); - READ_ENTITY_PROPERTY(PROP_PARENT_SHAPE_ID, quint16, setShapeID); + READ_ENTITY_PROPERTY(PROP_PARENT_MATERIAL_ID, QString, setParentMaterialID); READ_ENTITY_PROPERTY(PROP_MATERIAL_POS, glm::vec2, setMaterialPos); READ_ENTITY_PROPERTY(PROP_MATERIAL_SCALE, glm::vec2, setMaterialScale); READ_ENTITY_PROPERTY(PROP_MATERIAL_ROT, float, setMaterialRot); @@ -224,9 +88,8 @@ EntityPropertyFlags MaterialEntityItem::getEntityProperties(EncodeBitstreamParam EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += PROP_MATERIAL_URL; requestedProperties += PROP_MATERIAL_TYPE; - requestedProperties += PROP_MATERIAL_BLEND_FACTOR; requestedProperties += PROP_MATERIAL_PRIORITY; - requestedProperties += PROP_PARENT_SHAPE_ID; + requestedProperties += PROP_PARENT_MATERIAL_ID; requestedProperties += PROP_MATERIAL_POS; requestedProperties += PROP_MATERIAL_SCALE; requestedProperties += PROP_MATERIAL_ROT; @@ -244,9 +107,8 @@ void MaterialEntityItem::appendSubclassData(OctreePacketData* packetData, Encode bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_MATERIAL_URL, getMaterialURL()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_TYPE, (uint32_t)getMaterialMode()); - APPEND_ENTITY_PROPERTY(PROP_MATERIAL_BLEND_FACTOR, getBlendFactor()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_PRIORITY, getPriority()); - APPEND_ENTITY_PROPERTY(PROP_PARENT_SHAPE_ID, getShapeID()); + APPEND_ENTITY_PROPERTY(PROP_PARENT_MATERIAL_ID, getParentMaterialID()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_POS, getMaterialPos()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_SCALE, getMaterialScale()); APPEND_ENTITY_PROPERTY(PROP_MATERIAL_ROT, getMaterialRot()); @@ -259,9 +121,8 @@ void MaterialEntityItem::debugDump() const { qCDebug(entities) << " material json:" << _materialURL; qCDebug(entities) << " current material name:" << _currentMaterialName; qCDebug(entities) << " material type:" << _materialMode; - qCDebug(entities) << " blend factor:" << _blendFactor; qCDebug(entities) << " priority:" << _priority; - qCDebug(entities) << " parent shape ID:" << _shapeID; + qCDebug(entities) << " parent material ID:" << _parentMaterialID; qCDebug(entities) << " material pos:" << _materialPos; qCDebug(entities) << " material scale:" << _materialRot; qCDebug(entities) << " material rot:" << _materialScale; @@ -290,6 +151,8 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u removeMaterial(); _materialURL = materialURLString; + // TODO: if URL ends with ?string, try to set _currentMaterialName = string + if (usingUserData) { QJsonDocument materialJSON = QJsonDocument::fromJson(getUserData().toUtf8()); _materials.clear(); @@ -299,22 +162,39 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u QJsonArray materials = materialJSON.array(); for (auto material : materials) { if (!material.isNull() && material.isObject()) { - parseJSONMaterial(material.toObject()); + auto networkMaterial = NetworkMaterialResource::parseJSONMaterial(material.toObject()); + _materials[networkMaterial.first] = networkMaterial.second; + _materialNames.push_back(networkMaterial.first); } } } else if (materialJSON.isObject()) { - parseJSONMaterial(materialJSON.object()); + auto networkMaterial = NetworkMaterialResource::parseJSONMaterial(materialJSON.object()); + _materials[networkMaterial.first] = networkMaterial.second; + _materialNames.push_back(networkMaterial.first); } } + // Since our material changed, the current name might not be valid anymore, so we need to update + setCurrentMaterialName(_currentMaterialName); + applyMaterial(); } else { - // get material via network request + _networkMaterial = MaterialCache::instance().getMaterial(materialURLString); + auto onMaterialRequestFinished = [&](bool success) { + if (success) { + _materials[_networkMaterial->name] = _networkMaterial->networkMaterial; + _materialNames.push_back(_networkMaterial->name); + + setCurrentMaterialName(_currentMaterialName); + applyMaterial(); + } + }; + if (_networkMaterial) { + if (_networkMaterial->isLoaded()) { + onMaterialRequestFinished(!_networkMaterial->isFailed()); + } else { + connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); + } + } } - - // TODO: if URL ends with ?string, try to set _currentMaterialName = string - - // Since our JSON changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(_currentMaterialName); - applyMaterial(); } } @@ -361,14 +241,6 @@ void MaterialEntityItem::setMaterialRot(const float& materialRot) { } } -void MaterialEntityItem::setBlendFactor(float blendFactor) { - if (_blendFactor != blendFactor) { - removeMaterial(); - _blendFactor = blendFactor; - applyMaterial(); - } -} - void MaterialEntityItem::setPriority(quint16 priority) { if (_priority != priority) { removeMaterial(); @@ -377,10 +249,10 @@ void MaterialEntityItem::setPriority(quint16 priority) { } } -void MaterialEntityItem::setShapeID(quint16 shapeID) { - if (_shapeID != shapeID) { +void MaterialEntityItem::setParentMaterialID(const QString& parentMaterialID) { + if (_parentMaterialID != parentMaterialID) { removeMaterial(); - _shapeID = shapeID; + _parentMaterialID = parentMaterialID; applyMaterial(); } } @@ -421,16 +293,16 @@ void MaterialEntityItem::removeMaterial() { if (tree) { EntityItemPointer entity = tree->findEntityByEntityItemID(parentID); if (entity) { - entity->removeMaterial(material, getShapeID()); + entity->removeMaterial(material, getParentMaterialID()); return; } } - if (EntityTree::removeMaterialFromAvatar(parentID, material, getShapeID())) { + if (EntityTree::removeMaterialFromAvatar(parentID, material, getParentMaterialID())) { return; } - if (EntityTree::removeMaterialFromOverlay(parentID, material, getShapeID())) { + if (EntityTree::removeMaterialFromOverlay(parentID, material, getParentMaterialID())) { return; } @@ -449,7 +321,6 @@ void MaterialEntityItem::applyMaterial() { textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialRot))); textureTransform.setScale(glm::vec3(_materialScale, 1)); material->setTextureTransforms(textureTransform); - material->setBlendFactor(getBlendFactor()); material->setPriority(getPriority()); // Our parent could be an entity, an avatar, or an overlay @@ -457,16 +328,16 @@ void MaterialEntityItem::applyMaterial() { if (tree) { EntityItemPointer entity = tree->findEntityByEntityItemID(parentID); if (entity) { - entity->addMaterial(material, getShapeID()); + entity->addMaterial(material, getParentMaterialID()); return; } } - if (EntityTree::addMaterialToAvatar(parentID, material, getShapeID())) { + if (EntityTree::addMaterialToAvatar(parentID, material, getParentMaterialID())) { return; } - if (EntityTree::addMaterialToOverlay(parentID, material, getShapeID())) { + if (EntityTree::addMaterialToOverlay(parentID, material, getParentMaterialID())) { return; } diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index 40137acf22..dde9b60da9 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -13,6 +13,7 @@ #include "MaterialMode.h" #include +#include class MaterialEntityItem : public EntityItem { using Pointer = std::shared_ptr; @@ -60,14 +61,11 @@ public: MaterialMode getMaterialMode() const { return _materialMode; } void setMaterialMode(MaterialMode mode) { _materialMode = mode; } - float getBlendFactor() const { return _blendFactor; } - void setBlendFactor(float blendFactor); - quint16 getPriority() const { return _priority; } void setPriority(quint16 priority); - quint16 getShapeID() const { return _shapeID; } - void setShapeID(quint16 shapeID); + QString getParentMaterialID() const { return _parentMaterialID; } + void setParentMaterialID(const QString& parentMaterialID); glm::vec2 getMaterialPos() const { return _materialPos; } void setMaterialPos(const glm::vec2& materialPos); @@ -93,22 +91,19 @@ public: private: QString _materialURL; MaterialMode _materialMode { UV }; - float _blendFactor { 1.0f }; quint16 _priority { 0 }; - quint16 _shapeID { 0 }; + QString _parentMaterialID { "0" }; glm::vec2 _materialPos { 0, 0 }; glm::vec2 _materialScale { 1, 1 }; float _materialRot { 0 }; + NetworkMaterialResourcePointer _networkMaterial; QHash> _materials; std::vector _materialNames; QString _currentMaterialName; bool _retryApply { false }; - void parseJSONMaterial(const QJsonObject& materialJSON); - static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB); - }; #endif // hifi_MaterialEntityItem_h diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 6731d544b8..5b3396dfc5 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -354,9 +354,6 @@ public: size_t getTextureSize() const { calculateMaterialInfo(); return _textureSize; } bool hasTextureInfo() const { return _hasCalculatedTextureInfo; } - void setBlendFactor(float blendFactor) { _blendFactor = blendFactor; } - float getBlendFactor() { return _blendFactor; } - void setPriority(quint16 priority) { _priority = priority; } quint16 getPriority() { return _priority; } @@ -375,7 +372,6 @@ private: mutable bool _hasCalculatedTextureInfo { false }; bool calculateMaterialInfo() const; - float _blendFactor { 1.0f }; quint16 _priority { 0 }; }; diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp new file mode 100644 index 0000000000..723448f65a --- /dev/null +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -0,0 +1,175 @@ +// +// Created by Sam Gondelman on 2/9/2018 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "MaterialCache.h" + +#include "QJsonObject" +#include "QJsonDocument" +#include "QJsonArray" + +NetworkMaterialResource::NetworkMaterialResource(const QUrl& url) : + Resource(url) {} + +void NetworkMaterialResource::downloadFinished(const QByteArray& data) { + if (_url.toString().endsWith(".json")) { + QJsonDocument materialJSON = QJsonDocument::fromJson(data); + if (!materialJSON.isNull() && materialJSON.isObject()) { + auto parsedMaterial = parseJSONMaterial(materialJSON.object()); + name = parsedMaterial.first; + networkMaterial = parsedMaterial.second; + } + } + + // TODO: parse other material types + + finishedLoading(true); +} + +bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB) { + if (array.isArray()) { + QJsonArray colorArray = array.toArray(); + if (colorArray.size() >= 3 && colorArray[0].isDouble() && colorArray[1].isDouble() && colorArray[2].isDouble()) { + isSRGB = true; + if (colorArray.size() >= 4) { + if (colorArray[3].isBool()) { + isSRGB = colorArray[3].toBool(); + } + } + color = glm::vec3(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble()); + return true; + } + } + return false; +} + +std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON) { + QString name = ""; + std::shared_ptr material = std::make_shared(); + for (auto& key : materialJSON.keys()) { + if (key == "name") { + auto nameJSON = materialJSON.value(key); + if (nameJSON.isString()) { + name = nameJSON.toString(); + } + } else if (key == "emissive") { + glm::vec3 color; + bool isSRGB; + bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); + if (valid) { + material->setEmissive(color, isSRGB); + } + } else if (key == "opacity") { + auto value = materialJSON.value(key); + if (value.isDouble()) { + material->setOpacity(value.toDouble()); + } + } else if (key == "albedo") { + glm::vec3 color; + bool isSRGB; + bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); + if (valid) { + material->setAlbedo(color, isSRGB); + } + } else if (key == "roughness") { + auto value = materialJSON.value(key); + if (value.isDouble()) { + material->setRoughness(value.toDouble()); + } + } else if (key == "fresnel") { + glm::vec3 color; + bool isSRGB; + bool valid = parseJSONColor(materialJSON.value(key), color, isSRGB); + if (valid) { + material->setFresnel(color, isSRGB); + } + } else if (key == "metallic") { + auto value = materialJSON.value(key); + if (value.isDouble()) { + material->setMetallic(value.toDouble()); + } + } else if (key == "scattering") { + auto value = materialJSON.value(key); + if (value.isDouble()) { + material->setScattering(value.toDouble()); + } + } else if (key == "emissiveMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setEmissiveMap(value.toString()); + } + } else if (key == "albedoMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + bool useAlphaChannel = false; + auto opacityMap = materialJSON.find("opacityMap"); + if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == value.toString()) { + useAlphaChannel = true; + } + material->setAlbedoMap(value.toString(), useAlphaChannel); + } + } else if (key == "roughnessMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setRoughnessMap(value.toString(), false); + } + } else if (key == "glossMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setRoughnessMap(value.toString(), true); + } + } else if (key == "metallicMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setMetallicMap(value.toString(), false); + } + } else if (key == "specularMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setMetallicMap(value.toString(), true); + } + } else if (key == "normalMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setNormalMap(value.toString(), false); + } + } else if (key == "bumpMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setNormalMap(value.toString(), true); + } + } else if (key == "occlusionMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setOcclusionMap(value.toString()); + } + } else if (key == "scatteringMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setScatteringMap(value.toString()); + } + } else if (key == "lightMap") { + auto value = materialJSON.value(key); + if (value.isString()) { + material->setLightmapMap(value.toString()); + } + } + } + return std::pair>(name, material); +} + +MaterialCache& MaterialCache::instance() { + static MaterialCache _instance; + return _instance; +} + +NetworkMaterialResourcePointer MaterialCache::getMaterial(const QUrl& url) { + return ResourceCache::getResource(url, QUrl(), nullptr).staticCast(); +} + +QSharedPointer MaterialCache::createResource(const QUrl& url, const QSharedPointer& fallback, const void* extra) { + return QSharedPointer(new NetworkMaterialResource(url), &Resource::deleter); +} \ No newline at end of file diff --git a/libraries/model-networking/src/model-networking/MaterialCache.h b/libraries/model-networking/src/model-networking/MaterialCache.h new file mode 100644 index 0000000000..1b0f1c577c --- /dev/null +++ b/libraries/model-networking/src/model-networking/MaterialCache.h @@ -0,0 +1,46 @@ +// +// Created by Sam Gondelman on 2/9/2018 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_MaterialCache_h +#define hifi_MaterialCache_h + +#include + +#include "glm/glm.hpp" + +#include "ModelCache.h" + +class NetworkMaterialResource : public Resource { +public: + NetworkMaterialResource(const QUrl& url); + + QString getType() const override { return "NetworkMaterial"; } + + virtual void downloadFinished(const QByteArray& data) override; + + QString name { "" }; + std::shared_ptr networkMaterial { nullptr }; + + static std::pair> parseJSONMaterial(const QJsonObject& materialJSON); + +private: + static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB); +}; + +using NetworkMaterialResourcePointer = QSharedPointer; + +class MaterialCache : public ResourceCache { +public: + static MaterialCache& instance(); + + NetworkMaterialResourcePointer getMaterial(const QUrl& url); + +protected: + virtual QSharedPointer createResource(const QUrl& url, const QSharedPointer& fallback, const void* extra) override; +}; + +#endif diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 32deba3687..739f401ee7 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -495,8 +495,8 @@ NetworkMaterial::NetworkMaterial(const NetworkMaterial& m) : Material(m), _textures(m._textures), _albedoTransform(m._albedoTransform), - _lightmapParams(m._lightmapParams), _lightmapTransform(m._lightmapTransform), + _lightmapParams(m._lightmapParams), _isOriginal(m._isOriginal) {} diff --git a/libraries/networking/src/ResourceRequest.cpp b/libraries/networking/src/ResourceRequest.cpp index 5d39583c9e..115e665b77 100644 --- a/libraries/networking/src/ResourceRequest.cpp +++ b/libraries/networking/src/ResourceRequest.cpp @@ -23,7 +23,7 @@ void ResourceRequest::send() { QMetaObject::invokeMethod(this, "send", Qt::QueuedConnection); return; } - + Q_ASSERT(_state == NotStarted); _state = InProgress; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 805995edfb..3a9ea45d77 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1524,48 +1524,62 @@ bool Model::isRenderable() const { return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); } -void Model::addMaterial(graphics::MaterialPointer material, quint16 shapeID) { - if (shapeID < _modelMeshRenderItemIDs.size()) { - render::Transaction transaction; - auto itemID = _modelMeshRenderItemIDs[shapeID]; - bool visible = isVisible(); - uint8_t viewTagBits = getViewTagBits(); - bool layeredInFront = isLayeredInFront(); - bool layeredInHUD = isLayeredInHUD(); - bool wireframe = isWireframe(); - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; - bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); - transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, - invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) { - data.addMaterial(material); - // if the material changed, we might need to update our item key or shape key - data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits); - data.setShapeKey(invalidatePayloadShapeKey, wireframe); - }); - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); - } +std::vector Model::getMeshIDsFromMaterialID(const QString& parentMaterialID) { + std::vector toReturn; + // TODO: first, try to find all meshes with materials that match parentMaterialID as a string + // if none, return parentMaterialID as a uint + toReturn.push_back(parentMaterialID.toUInt()); + return toReturn; } -void Model::removeMaterial(graphics::MaterialPointer material, quint16 shapeID) { - if (shapeID < _modelMeshRenderItemIDs.size()) { - render::Transaction transaction; - auto itemID = _modelMeshRenderItemIDs[shapeID]; - bool visible = isVisible(); - uint8_t viewTagBits = getViewTagBits(); - bool layeredInFront = isLayeredInFront(); - bool layeredInHUD = isLayeredInHUD(); - bool wireframe = isWireframe(); - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; - bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); - transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, - invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) { - data.removeMaterial(material); - // if the material changed, we might need to update our item key or shape key - data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits); - data.setShapeKey(invalidatePayloadShapeKey, wireframe); - }); - AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); +void Model::addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + std::vector shapeIDs = getMeshIDsFromMaterialID(parentMaterialID); + render::Transaction transaction; + for (auto shapeID : shapeIDs) { + if (shapeID < _modelMeshRenderItemIDs.size()) { + auto itemID = _modelMeshRenderItemIDs[shapeID]; + bool visible = isVisible(); + uint8_t viewTagBits = getViewTagBits(); + bool layeredInFront = isLayeredInFront(); + bool layeredInHUD = isLayeredInHUD(); + bool wireframe = isWireframe(); + auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); + transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, + invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) { + data.addMaterial(material); + // if the material changed, we might need to update our item key or shape key + data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits); + data.setShapeKey(invalidatePayloadShapeKey, wireframe); + }); + } } + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); +} + +void Model::removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID) { + std::vector shapeIDs = getMeshIDsFromMaterialID(parentMaterialID); + render::Transaction transaction; + for (auto shapeID : shapeIDs) { + if (shapeID < _modelMeshRenderItemIDs.size()) { + auto itemID = _modelMeshRenderItemIDs[shapeID]; + bool visible = isVisible(); + uint8_t viewTagBits = getViewTagBits(); + bool layeredInFront = isLayeredInFront(); + bool layeredInHUD = isLayeredInHUD(); + bool wireframe = isWireframe(); + auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); + transaction.updateItem(itemID, [material, visible, layeredInFront, layeredInHUD, viewTagBits, + invalidatePayloadShapeKey, wireframe](ModelMeshPartPayload& data) { + data.removeMaterial(material); + // if the material changed, we might need to update our item key or shape key + data.updateKey(visible, layeredInFront || layeredInHUD, viewTagBits); + data.setShapeKey(invalidatePayloadShapeKey, wireframe); + }); + } + } + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); } class CollisionRenderGeometry : public Geometry { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 80067aff2a..b4152324bc 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -318,8 +318,8 @@ public: void scaleToFit(); - void addMaterial(graphics::MaterialPointer material, quint16 shapeID); - void removeMaterial(graphics::MaterialPointer material, quint16 shapeID); + void addMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); + void removeMaterial(graphics::MaterialPointer material, const QString& parentMaterialID); public slots: void loadURLFinished(bool success); @@ -471,6 +471,8 @@ private: float _loadingPriority { 0.0f }; void calculateTextureInfo(); + + std::vector getMeshIDsFromMaterialID(const QString& parentMaterialID); }; Q_DECLARE_METATYPE(ModelPointer) diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 25b2cec331..4dbbd190ff 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -256,6 +256,13 @@ namespace std { return result; } }; + + template <> + struct hash { + size_t operator()(const QString& a) const { + return qHash(a); + } + }; } enum ContactEventType { diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 348d93d589..5eedd1c7e4 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -780,19 +780,14 @@ -
- - -
-
-
- - +
+ +
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 3558a36c04..01ec4ae283 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -633,9 +633,8 @@ function loaded() { var elMaterialURL = document.getElementById("property-material-url"); var elMaterialMode = document.getElementById("property-material-mode"); - var elBlendFactor = document.getElementById("property-blend-factor"); var elPriority = document.getElementById("property-priority"); - var elShapeID = document.getElementById("property-shape-id"); + var elParentMaterialID = document.getElementById("property-parent-material-id"); var elMaterialPosX = document.getElementById("property-material-pos-x"); var elMaterialPosY = document.getElementById("property-material-pos-y"); var elMaterialScaleX = document.getElementById("property-material-scale-x"); @@ -1130,9 +1129,8 @@ function loaded() { elMaterialURL.value = properties.materialURL; elMaterialMode.value = properties.materialMode; setDropdownText(elMaterialMode); - elBlendFactor.value = properties.blendFactor.toFixed(2); elPriority.value = properties.priority; - elShapeID.value = properties.shapeID; + elParentMaterialID.value = properties.parentMaterialID; elMaterialPosX.value = properties.materialPos.x.toFixed(4); elMaterialPosY.value = properties.materialPos.y.toFixed(4); elMaterialScaleX.value = properties.materialScale.x.toFixed(4); @@ -1410,9 +1408,8 @@ function loaded() { elMaterialURL.addEventListener('change', createEmitTextPropertyUpdateFunction('materialURL')); elMaterialMode.addEventListener('change', createEmitTextPropertyUpdateFunction('materialMode')); - elBlendFactor.addEventListener('change', createEmitNumberPropertyUpdateFunction('blendFactor', 2)); elPriority.addEventListener('change', createEmitNumberPropertyUpdateFunction('priority', 0)); - elShapeID.addEventListener('change', createEmitNumberPropertyUpdateFunction('shapeID', 0)); + elParentMaterialID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentMaterialID')); var materialPosChangeFunction = createEmitVec2PropertyUpdateFunction('materialPos', elMaterialPosX, elMaterialPosY); elMaterialPosX.addEventListener('change', materialPosChangeFunction);