From b482c4a8a9cdb02cedc233767e72888da2befb26 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Sun, 3 Nov 2024 15:37:58 -0800 Subject: [PATCH] fix material inspector not grabbing correct material sometimes --- .../src/avatars-renderer/Avatar.cpp | 15 +++++- .../src/RenderableModelEntityItem.cpp | 15 +++++- .../graphics-scripting/ScriptableModel.cpp | 5 +- libraries/render-utils/src/Model.cpp | 50 ++++++++++--------- libraries/render-utils/src/Model.h | 4 +- 5 files changed, 59 insertions(+), 30 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index fb22db3ce0..ab28dba7a1 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1957,10 +1957,23 @@ scriptable::ScriptableModelBase Avatar::getScriptableModel() { } auto result = _skeletonModel->getScriptableModel(); result.objectID = getSessionUUID().isNull() ? AVATAR_SELF_ID : getSessionUUID(); + + std::unordered_map materials; { std::lock_guard lock(_materialsLock); - result.appendMaterials(_materials); + materials = _materials; } + + for (auto& multiMaterial : materials) { + while (!multiMaterial.second.empty()) { + auto shapeIDs = _skeletonModel->getMeshIDsAndMaterialNamesFromMaterialID(multiMaterial.first.c_str()); + for (const auto& shapeID : shapeIDs) { + result.appendMaterial(multiMaterial.second.top(), shapeID.first, shapeID.second); + } + multiMaterial.second.pop(); + } + } + return result; } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index eeb7945660..d6e7f77b7b 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -987,10 +987,23 @@ scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScript auto result = model->getScriptableModel(); result.objectID = getEntity()->getID(); + + std::unordered_map materials; { std::lock_guard lock(_materialsLock); - result.appendMaterials(_materials); + materials = _materials; } + + for (auto& multiMaterial : materials) { + while (!multiMaterial.second.empty()) { + auto shapeIDs = model->getMeshIDsAndMaterialNamesFromMaterialID(multiMaterial.first.c_str()); + for (const auto& shapeID : shapeIDs) { + result.appendMaterial(multiMaterial.second.top(), shapeID.first, shapeID.second); + } + multiMaterial.second.pop(); + } + } + return result; } diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index 3cf70915c3..a515b29826 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -257,8 +257,9 @@ void scriptable::ScriptableModelBase::append(const ScriptableMeshBase& mesh) { } void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& materialLayer, int shapeID, std::string materialName) { - materialLayers[QString::number(shapeID)].push_back(ScriptableMaterialLayer(materialLayer)); - materialLayers["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterialLayer(materialLayer)); + ScriptableMaterialLayer layer = ScriptableMaterialLayer(materialLayer); + materialLayers[QString::number(shapeID)].push_back(layer); + materialLayers["mat::" + QString::fromStdString(materialName)].push_back(layer); } void scriptable::ScriptableModelBase::appendMaterials(const std::unordered_map& materialsToAppend) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 69a593ed09..409275e3db 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1653,13 +1653,13 @@ bool Model::isRenderable() const { return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); } -std::set Model::getMeshIDsFromMaterialID(QString parentMaterialName) { - std::set toReturn; +std::set> Model::getMeshIDsAndMaterialNamesFromMaterialID(QString parentMaterialName) { + std::set> toReturn; const QString all("all"); if (parentMaterialName == all) { for (unsigned int i = 0; i < (unsigned int)_modelMeshRenderItemIDs.size(); i++) { - toReturn.insert(i); + toReturn.insert({ i, i < _modelMeshMaterialNames.size() ? _modelMeshMaterialNames[i] : "" }); } } else if (!parentMaterialName.isEmpty()) { auto parseFunc = [this, &toReturn] (QString& target) { @@ -1673,12 +1673,14 @@ std::set Model::getMeshIDsFromMaterialID(QString parentMaterialNam std::string targetStdString = target.replace(0, MATERIAL_NAME_PREFIX.size(), "").toStdString(); for (unsigned int i = 0; i < (unsigned int)_modelMeshMaterialNames.size(); i++) { if (_modelMeshMaterialNames[i] == targetStdString) { - toReturn.insert(i); + toReturn.insert({ i, _modelMeshMaterialNames[i] }); } } return; } - toReturn.insert(target.toUInt()); + + uint result = target.toUInt(); + toReturn.insert({ result, result < _modelMeshMaterialNames.size() ? _modelMeshMaterialNames[result] : "" }); }; if (parentMaterialName.length() > 2 && parentMaterialName.startsWith("[") && parentMaterialName.endsWith("]")) { @@ -1720,15 +1722,15 @@ void Model::applyMaterialMapping() { continue; } - std::set shapeIDs = getMeshIDsFromMaterialID(QString(mapping.first.c_str())); + auto shapeIDs = getMeshIDsAndMaterialNamesFromMaterialID(QString(mapping.first.c_str())); if (shapeIDs.size() == 0) { continue; } // This needs to be precomputed before the lambda, since the lambdas could be called out of order std::unordered_map priorityMapPerResource; - for (auto shapeID : shapeIDs) { - priorityMapPerResource[shapeID] = ++_priorityMap[shapeID]; + for (const auto& shapeID : shapeIDs) { + priorityMapPerResource[shapeID.first] = ++_priorityMap[shapeID.first]; } std::weak_ptr weakSelf = shared_from_this(); @@ -1756,15 +1758,15 @@ void Model::applyMaterialMapping() { networkMaterial = networkMaterialResource->parsedMaterials.networkMaterials[networkMaterialResource->parsedMaterials.names[0]]; } } - for (auto shapeID : shapeIDs) { - if (shapeID < modelMeshRenderItemIDs.size()) { - auto itemID = modelMeshRenderItemIDs[shapeID]; - auto meshIndex = modelMeshRenderItemShapes[shapeID].meshIndex; + for (const auto& shapeID : shapeIDs) { + if (shapeID.first < modelMeshRenderItemIDs.size()) { + auto itemID = modelMeshRenderItemIDs[shapeID.first]; + auto meshIndex = modelMeshRenderItemShapes[shapeID.first].meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKeyMap.at(meshIndex); - graphics::MaterialLayer material = graphics::MaterialLayer(networkMaterial, priorityMapPerResource.at(shapeID)); + graphics::MaterialLayer material = graphics::MaterialLayer(networkMaterial, priorityMapPerResource.at(shapeID.first)); { std::unique_lock lock(self->_materialMappingMutex); - self->_materialMapping[shapeID].push_back(material); + self->_materialMapping[shapeID.first].push_back(material); } transaction.updateItem(itemID, [material, renderItemsKey, invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) { @@ -1787,17 +1789,17 @@ void Model::applyMaterialMapping() { } void Model::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { - std::set shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str())); + auto shapeIDs = getMeshIDsAndMaterialNamesFromMaterialID(QString(parentMaterialName.c_str())); auto renderItemsKey = _renderItemKeyGlobalFlags; PrimitiveMode primitiveMode = getPrimitiveMode(); bool useDualQuaternionSkinning = _useDualQuaternionSkinning; render::Transaction transaction; - for (auto shapeID : shapeIDs) { - if (shapeID < _modelMeshRenderItemIDs.size()) { - auto itemID = _modelMeshRenderItemIDs[shapeID]; - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + for (const auto& shapeID : shapeIDs) { + if (shapeID.first < _modelMeshRenderItemIDs.size()) { + auto itemID = _modelMeshRenderItemIDs[shapeID.first]; + auto meshIndex = _modelMeshRenderItemShapes[shapeID.first].meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); transaction.updateItem(itemID, [material, renderItemsKey, invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) { @@ -1812,14 +1814,14 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par } void Model::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { - std::set shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str())); + auto shapeIDs = getMeshIDsAndMaterialNamesFromMaterialID(QString(parentMaterialName.c_str())); render::Transaction transaction; - for (auto shapeID : shapeIDs) { - if (shapeID < _modelMeshRenderItemIDs.size()) { - auto itemID = _modelMeshRenderItemIDs[shapeID]; + for (const auto& shapeID : shapeIDs) { + if (shapeID.first < _modelMeshRenderItemIDs.size()) { + auto itemID = _modelMeshRenderItemIDs[shapeID.first]; auto renderItemsKey = _renderItemKeyGlobalFlags; PrimitiveMode primitiveMode = getPrimitiveMode(); - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + auto meshIndex = _modelMeshRenderItemShapes[shapeID.first].meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = _useDualQuaternionSkinning; transaction.updateItem(itemID, [material, renderItemsKey, diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index bc9b8fcfff..6b641df002 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -371,6 +371,8 @@ public: void setBlendshapeCoefficients(const QVector& coefficients) { _blendshapeCoefficients = coefficients; } + std::set> getMeshIDsAndMaterialNamesFromMaterialID(QString parentMaterialName); + public slots: void loadURLFinished(bool success); @@ -521,8 +523,6 @@ private: std::function _loadingPriorityOperator { []() { return 0.0f; } }; void calculateTextureInfo(); - - std::set getMeshIDsFromMaterialID(QString parentMaterialName); }; Q_DECLARE_METATYPE(ModelPointer)