From b56f755034bcd578cf4c2e6419531d6ef24a317c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 23 Feb 2018 15:10:49 -0800 Subject: [PATCH] material reflection --- interface/src/ui/overlays/ModelOverlay.cpp | 4 + .../src/avatars-renderer/Avatar.cpp | 4 + .../src/RenderableModelEntityItem.cpp | 4 + .../src/RenderableShapeEntityItem.cpp | 8 +- libraries/gpu/src/gpu/Texture.cpp | 10 -- libraries/gpu/src/gpu/Texture.h | 7 +- libraries/graphics-scripting/CMakeLists.txt | 2 +- .../src/graphics-scripting/Forward.h | 43 +++++- .../src/graphics-scripting/ScriptableMesh.cpp | 58 ++++++++ .../graphics-scripting/ScriptableModel.cpp | 124 ++++++++++++++++++ .../src/graphics-scripting/ScriptableModel.h | 7 +- libraries/graphics/src/graphics/Material.h | 1 + .../src/model-networking/MaterialCache.cpp | 7 + .../src/model-networking/TextureCache.cpp | 4 +- .../render-utils/src/CauterizedModel.cpp | 2 + libraries/render-utils/src/Model.cpp | 8 ++ 16 files changed, 272 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index ffcc18032c..47dd8f45f9 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -671,5 +671,9 @@ scriptable::ScriptableModelBase ModelOverlay::getScriptableModel() { } auto result = _model->getScriptableModel(); result.objectID = getID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 25ddfba670..db20f9144d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1801,5 +1801,9 @@ scriptable::ScriptableModelBase Avatar::getScriptableModel() { } auto result = _skeletonModel->getScriptableModel(); result.objectID = getSessionUUID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f3c99cde2d..5c95d1e556 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -970,6 +970,10 @@ scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScript auto result = _model->getScriptableModel(); result.objectID = getEntity()->getID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 22cd98b08a..e5cbfdb59d 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -169,8 +169,12 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() { auto geometryCache = DependencyManager::get(); auto geometryShape = geometryCache->getShapeForEntityShape(_shape); glm::vec3 vertexColor; - if (_materials["0"].top().material) { - vertexColor = _materials["0"].top().material->getAlbedo(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + if (_materials["0"].top().material) { + vertexColor = _materials["0"].top().material->getAlbedo(); + } } if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) { result.objectID = getEntity()->getID(); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 4a588c3c84..ed9505766b 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -868,16 +868,6 @@ void SphericalHarmonics::evalFromTexture(const Texture& texture) { // TextureSource -TextureSource::TextureSource() { -} - -TextureSource::~TextureSource() { -} - -void TextureSource::reset(const QUrl& url) { - _imageUrl = url; -} - void TextureSource::resetTexture(gpu::TexturePointer texture) { _gpuTexture = texture; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index ad3dc5fada..a03b894e0d 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -647,13 +647,11 @@ typedef std::vector TextureViews; // It provides the mechanism to create a texture using a customizable TextureLoader class TextureSource { public: - TextureSource(); - ~TextureSource(); + TextureSource(const QUrl& url, int type = 0) : _imageUrl(url), _type(type) {} const QUrl& getUrl() const { return _imageUrl; } const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; } - - void reset(const QUrl& url); + int getType() const { return _type; } void resetTexture(gpu::TexturePointer texture); @@ -662,6 +660,7 @@ public: protected: gpu::TexturePointer _gpuTexture; QUrl _imageUrl; + int _type { 0 }; }; typedef std::shared_ptr< TextureSource > TextureSourcePointer; diff --git a/libraries/graphics-scripting/CMakeLists.txt b/libraries/graphics-scripting/CMakeLists.txt index ad8055b647..0f59fb41f8 100644 --- a/libraries/graphics-scripting/CMakeLists.txt +++ b/libraries/graphics-scripting/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME graphics-scripting) setup_hifi_library() -link_hifi_libraries(shared networking graphics fbx model-networking script-engine) +link_hifi_libraries(shared networking graphics fbx image model-networking script-engine) include_hifi_library_headers(gpu) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 94a96446a0..b07c25ee02 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -6,9 +6,14 @@ #include #include #include +#include #include #include + +#include "graphics/Material.h" +#include "graphics/TextureMap.h" + namespace graphics { class Mesh; } @@ -31,6 +36,38 @@ namespace scriptable { using ModelProviderPointer = std::shared_ptr; using WeakModelProviderPointer = std::weak_ptr; + class ScriptableMaterial { + public: + ScriptableMaterial() {} + ScriptableMaterial(const graphics::MaterialLayer& materialLayer); + ScriptableMaterial(const ScriptableMaterial& material) { *this = material; } + ScriptableMaterial& operator=(const ScriptableMaterial& material); + + QString name; + QString model; + float opacity; + float roughness; + float metallic; + float scattering; + bool unlit; + glm::vec3 emissive; + glm::vec3 albedo; + QString emissiveMap; + QString albedoMap; + QString opacityMap; + QString metallicMap; + QString specularMap; + QString roughnessMap; + QString glossMap; + QString normalMap; + QString bumpMap; + QString occlusionMap; + QString lightmapMap; + QString scatteringMap; + quint16 priority; + }; + typedef QHash> MultiMaterialMap; + class ScriptableMeshBase : public QObject { Q_OBJECT public: @@ -55,6 +92,8 @@ namespace scriptable { WeakModelProviderPointer provider; QUuid objectID; // spatially nestable ID QVector meshes; + MultiMaterialMap materials; + QVector materialNames; ScriptableModelBase(QObject* parent = nullptr) : QObject(parent) {} ScriptableModelBase(const ScriptableModelBase& other) : QObject(other.parent()) { *this = other; } @@ -63,9 +102,11 @@ namespace scriptable { void append(const ScriptableMeshBase& mesh); void append(scriptable::WeakMeshPointer mesh); + void appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName); + void appendMaterials(const std::unordered_map& materialsToAppend); + void appendMaterialNames(const std::vector& names); // TODO: in future containers for these could go here // QVariantMap shapes; - // QVariantMap materials; // QVariantMap armature; }; diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp index 76741947fd..7da69fcad2 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp @@ -554,6 +554,57 @@ namespace { qScriptValueToSequence(array, result); } + QScriptValue qVectorScriptableMaterialToScriptValue(QScriptEngine* engine, const QVector& vector) { + return qScriptValueFromSequence(engine, vector); + } + + void qVectorScriptableMaterialFromScriptValue(const QScriptValue& array, QVector& result) { + qScriptValueToSequence(array, result); + } + + QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material) { + QScriptValue obj = engine->newObject(); + obj.setProperty("name", material.name); + obj.setProperty("model", material.model); + obj.setProperty("opacity", material.opacity); + obj.setProperty("roughness", material.roughness); + obj.setProperty("metallic", material.metallic); + obj.setProperty("scattering", material.scattering); + obj.setProperty("unlit", material.unlit); + obj.setProperty("emissive", vec3toScriptValue(engine, material.emissive)); + obj.setProperty("albedo", vec3toScriptValue(engine, material.albedo)); + obj.setProperty("emissiveMap", material.emissiveMap); + obj.setProperty("albedoMap", material.albedoMap); + obj.setProperty("opacityMap", material.opacityMap); + obj.setProperty("metallicMap", material.metallicMap); + obj.setProperty("specularMap", material.specularMap); + obj.setProperty("roughnessMap", material.roughnessMap); + obj.setProperty("glossMap", material.glossMap); + obj.setProperty("normalMap", material.normalMap); + obj.setProperty("bumpMap", material.bumpMap); + obj.setProperty("occlusionMap", material.occlusionMap); + obj.setProperty("lightmapMap", material.lightmapMap); + obj.setProperty("scatteringMap", material.scatteringMap); + obj.setProperty("priority", material.priority); + return obj; + } + + void scriptableMaterialFromScriptValue(const QScriptValue &object, scriptable::ScriptableMaterial& material) { + // No need to convert from QScriptValue to ScriptableMaterial + } + + QScriptValue multiMaterialMapToScriptValue(QScriptEngine* engine, const scriptable::MultiMaterialMap& map) { + QScriptValue obj = engine->newObject(); + for (auto key : map.keys()) { + obj.setProperty(key, qVectorScriptableMaterialToScriptValue(engine, map[key])); + } + return obj; + } + + void multiMaterialMapFromScriptValue(const QScriptValue& map, scriptable::MultiMaterialMap& result) { + // No need to convert from QScriptValue to MultiMaterialMap + } + QVector metaTypeIds{ qRegisterMetaType("uint32"), qRegisterMetaType("scriptable::uint32"), @@ -562,6 +613,9 @@ namespace { qRegisterMetaType(), qRegisterMetaType(), qRegisterMetaType(), + qRegisterMetaType(), + qRegisterMetaType>(), + qRegisterMetaType() }; } @@ -570,11 +624,15 @@ namespace scriptable { qScriptRegisterSequenceMetaType>(engine); qScriptRegisterSequenceMetaType>(engine); qScriptRegisterSequenceMetaType>(engine); + qScriptRegisterSequenceMetaType>(engine); qScriptRegisterMetaType(engine, qVectorUInt32ToScriptValue, qVectorUInt32FromScriptValue); qScriptRegisterMetaType(engine, modelPointerToScriptValue, modelPointerFromScriptValue); qScriptRegisterMetaType(engine, meshPointerToScriptValue, meshPointerFromScriptValue); qScriptRegisterMetaType(engine, meshPartPointerToScriptValue, meshPartPointerFromScriptValue); + qScriptRegisterMetaType(engine, scriptableMaterialToScriptValue, scriptableMaterialFromScriptValue); + qScriptRegisterMetaType(engine, qVectorScriptableMaterialToScriptValue, qVectorScriptableMaterialFromScriptValue); + qScriptRegisterMetaType(engine, multiMaterialMapToScriptValue, multiMaterialMapFromScriptValue); return metaTypeIds.size(); } diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index 8ceb7de6a2..9a4bfe60b6 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -14,14 +14,115 @@ #include +#include "graphics/Material.h" + +#include "image/Image.h" + // #define SCRIPTABLE_MESH_DEBUG 1 +scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const scriptable::ScriptableMaterial& material) { + name = material.name; + model = material.model; + opacity = material.opacity; + roughness = material.roughness; + metallic = material.metallic; + scattering = material.scattering; + unlit = material.unlit; + emissive = material.emissive; + albedo = material.albedo; + emissiveMap = material.emissiveMap; + albedoMap = material.albedoMap; + opacityMap = material.opacityMap; + metallicMap = material.metallicMap; + specularMap = material.specularMap; + roughnessMap = material.roughnessMap; + glossMap = material.glossMap; + normalMap = material.normalMap; + bumpMap = material.bumpMap; + occlusionMap = material.occlusionMap; + lightmapMap = material.lightmapMap; + scatteringMap = material.scatteringMap; + priority = material.priority; + + return *this; +} + +scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer& materialLayer) : + name(materialLayer.material->getName().c_str()), + model(materialLayer.material->getModel().c_str()), + opacity(materialLayer.material->getOpacity()), + roughness(materialLayer.material->getRoughness()), + metallic(materialLayer.material->getMetallic()), + scattering(materialLayer.material->getScattering()), + unlit(materialLayer.material->isUnlit()), + emissive(materialLayer.material->getEmissive()), + albedo(materialLayer.material->getAlbedo()), + priority(materialLayer.priority) +{ + auto map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP); + if (map && map->getTextureSource()) { + emissiveMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ALBEDO_MAP); + if (map && map->getTextureSource()) { + albedoMap = map->getTextureSource()->getUrl().toString(); + if (map->useAlphaChannel()) { + opacityMap = albedoMap; + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) { + metallicMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::SPECULAR_TEXTURE) { + specularMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) { + roughnessMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::GLOSS_TEXTURE) { + glossMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::NORMAL_TEXTURE) { + normalMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::BUMP_TEXTURE) { + bumpMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP); + if (map && map->getTextureSource()) { + occlusionMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP); + if (map && map->getTextureSource()) { + lightmapMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP); + if (map && map->getTextureSource()) { + scatteringMap = map->getTextureSource()->getUrl().toString(); + } +} + scriptable::ScriptableModelBase& scriptable::ScriptableModelBase::operator=(const scriptable::ScriptableModelBase& other) { provider = other.provider; objectID = other.objectID; for (const auto& mesh : other.meshes) { append(mesh); } + materials = other.materials; + materialNames = other.materialNames; return *this; } @@ -34,6 +135,8 @@ scriptable::ScriptableModelBase::~ScriptableModelBase() { m.strongMesh.reset(); } meshes.clear(); + materials.clear(); + materialNames.clear(); } void scriptable::ScriptableModelBase::append(scriptable::WeakMeshPointer mesh) { @@ -47,6 +150,27 @@ void scriptable::ScriptableModelBase::append(const ScriptableMeshBase& mesh) { meshes << mesh; } +void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName) { + materials[QString::number(shapeID)].push_back(ScriptableMaterial(material)); + materials["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterial(material)); +} + +void scriptable::ScriptableModelBase::appendMaterials(const std::unordered_map& materialsToAppend) { + auto materialsToAppendCopy = materialsToAppend; + for (auto& multiMaterial : materialsToAppendCopy) { + while (!multiMaterial.second.empty()) { + materials[QString(multiMaterial.first.c_str())].push_back(ScriptableMaterial(multiMaterial.second.top())); + multiMaterial.second.pop(); + } + } +} + +void scriptable::ScriptableModelBase::appendMaterialNames(const std::vector& names) { + for (auto& name : names) { + materialNames.append(QString::fromStdString(name)); + } +} + QString scriptable::ScriptableModel::toString() const { return QString("[ScriptableModel%1%2 numMeshes=%3]") .arg(objectID.isNull() ? "" : " objectID="+objectID.toString()) diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h index 4ed1cc9554..9dc4c6f1ca 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h @@ -19,6 +19,8 @@ namespace scriptable { Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT) Q_PROPERTY(uint32 numMeshes READ getNumMeshes) Q_PROPERTY(QVector meshes READ getMeshes) + Q_PROPERTY(scriptable::MultiMaterialMap materials READ getMaterials) + Q_PROPERTY(QVector materialNames READ getMaterialNames) ScriptableModel(QObject* parent = nullptr) : ScriptableModelBase(parent) {} ScriptableModel(const ScriptableModel& other) : ScriptableModelBase(other) {} @@ -28,7 +30,6 @@ namespace scriptable { Q_INVOKABLE scriptable::ScriptableModelPointer cloneModel(const QVariantMap& options = QVariantMap()); // TODO: in future accessors for these could go here // QVariantMap shapes; - // QVariantMap materials; // QVariantMap armature; QVector getMeshes(); @@ -37,6 +38,8 @@ namespace scriptable { return QPointer(qobject_cast(this)); } + scriptable::MultiMaterialMap getMaterials() { return materials; } + QVector getMaterialNames() { return materialNames; } // QScriptEngine-specific wrappers Q_INVOKABLE uint32 mapAttributeValues(QScriptValue callback); @@ -51,3 +54,5 @@ Q_DECLARE_METATYPE(scriptable::WeakMeshPointer) Q_DECLARE_METATYPE(scriptable::ScriptableModelPointer) Q_DECLARE_METATYPE(scriptable::ScriptableModelBase) Q_DECLARE_METATYPE(scriptable::ScriptableModelBasePointer) +Q_DECLARE_METATYPE(scriptable::ScriptableMaterial) +Q_DECLARE_METATYPE(scriptable::MultiMaterialMap) diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 632cf99391..f34f68c04a 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -358,6 +358,7 @@ public: const std::string& getName() { return _name; } + const std::string& getModel() { return _model; } void setModel(const std::string& model) { _model = model; } protected: diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp index 8d9d6571f8..85f2f43652 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.cpp +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -11,6 +11,8 @@ #include "QJsonDocument" #include "QJsonArray" +#include "RegisteredMetaTypes.h" + NetworkMaterialResource::NetworkMaterialResource(const QUrl& url) : Resource(url) {} @@ -39,6 +41,11 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& color = glm::vec3(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble()); return true; } + } else if (array.isObject()) { + bool toReturn; + isSRGB = true; + color = vec3FromVariant(array.toObject(), toReturn); + return toReturn; } return false; } diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 3a29139ee7..9b12c34f87 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -291,7 +291,7 @@ _type(), _sourceIsKTX(false), _maxNumPixels(100) { - _textureSource = std::make_shared(); + _textureSource = std::make_shared(url); _lowestRequestedMipLevel = 0; _loaded = true; } @@ -303,7 +303,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, image::TextureUsage::Type type, _sourceIsKTX(url.path().endsWith(".ktx")), _maxNumPixels(maxNumPixels) { - _textureSource = std::make_shared(); + _textureSource = std::make_shared(url, (int)type); _lowestRequestedMipLevel = 0; _shouldFailOnRedirect = !_sourceIsKTX; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 54dfd96a00..5685a85349 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -57,6 +57,7 @@ void CauterizedModel::createVisibleRenderItemSet() { Q_ASSERT(_modelMeshRenderItems.isEmpty()); _modelMeshRenderItems.clear(); + _modelMeshMaterialNames.clear(); _modelMeshRenderItemShapes.clear(); Transform transform; @@ -81,6 +82,7 @@ void CauterizedModel::createVisibleRenderItemSet() { for (int partIndex = 0; partIndex < numParts; partIndex++) { auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); _modelMeshRenderItems << std::static_pointer_cast(ptr); + _modelMeshMaterialNames.push_back(getGeometry()->getShapeMaterial(shapeID)->getName()); _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i }); shapeID++; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6d735497c0..f55b3c598d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -629,12 +629,20 @@ scriptable::ScriptableModelBase Model::getScriptableModel() { const FBXGeometry& geometry = getFBXGeometry(); int numberOfMeshes = geometry.meshes.size(); + int shapeID = 0; for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& fbxMesh = geometry.meshes.at(i); if (auto mesh = fbxMesh._mesh) { result.append(mesh); + + int numParts = (int)mesh->getNumParts(); + for (int partIndex = 0; partIndex < numParts; partIndex++) { + result.appendMaterial(graphics::MaterialLayer(getGeometry()->getShapeMaterial(shapeID), 0), shapeID, _modelMeshMaterialNames[shapeID]); + shapeID++; + } } } + result.appendMaterialNames(_modelMeshMaterialNames); return result; }