mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 17:41:12 +02:00
working on fst material mapping
This commit is contained in:
parent
f7a487a020
commit
4f03157f39
13 changed files with 146 additions and 79 deletions
|
@ -1,5 +1,5 @@
|
||||||
set(TARGET_NAME material-networking)
|
set(TARGET_NAME material-networking)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl)
|
link_hifi_libraries(shared shaders networking graphics ktx image gl)
|
||||||
include_hifi_library_headers(gpu)
|
include_hifi_library_headers(gpu)
|
||||||
include_hifi_library_headers(hfm)
|
include_hifi_library_headers(hfm)
|
|
@ -71,6 +71,7 @@ private:
|
||||||
|
|
||||||
class NetworkMaterialResource : public Resource {
|
class NetworkMaterialResource : public Resource {
|
||||||
public:
|
public:
|
||||||
|
NetworkMaterialResource() : Resource() {}
|
||||||
NetworkMaterialResource(const QUrl& url);
|
NetworkMaterialResource(const QUrl& url);
|
||||||
|
|
||||||
QString getType() const override { return "NetworkMaterial"; }
|
QString getType() const override { return "NetworkMaterial"; }
|
||||||
|
@ -100,6 +101,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
using NetworkMaterialResourcePointer = QSharedPointer<NetworkMaterialResource>;
|
using NetworkMaterialResourcePointer = QSharedPointer<NetworkMaterialResource>;
|
||||||
|
using MaterialMapping = std::vector<std::pair<std::string, NetworkMaterialResourcePointer>>;
|
||||||
|
|
||||||
class MaterialCache : public ResourceCache {
|
class MaterialCache : public ResourceCache {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Sam Gondelman on 2/7/2019
|
|
||||||
// Copyright 2019 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 "ApplyMaterialMappingTask.h"
|
|
||||||
|
|
||||||
#include "ModelBakerLogging.h"
|
|
||||||
|
|
||||||
#include <material-networking/MaterialCache.h>
|
|
||||||
|
|
||||||
void ApplyMaterialMappingTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
|
||||||
const auto& materialsIn = input.get0();
|
|
||||||
const auto& mapping = input.get1();
|
|
||||||
|
|
||||||
auto materialsOut = materialsIn;
|
|
||||||
|
|
||||||
auto mappingIter = mapping.find("materialMap");
|
|
||||||
if (mappingIter != mapping.end()) {
|
|
||||||
QByteArray materialMapValue = mappingIter.value().toByteArray();
|
|
||||||
QJsonObject materialMap = QJsonDocument::fromJson(materialMapValue).object();
|
|
||||||
if (materialMap.isEmpty()) {
|
|
||||||
qCDebug(model_baker) << "Material Map found but did not produce valid JSON:" << materialMapValue;
|
|
||||||
} else {
|
|
||||||
for (auto& material : materialsOut) {
|
|
||||||
auto materialMapIter = materialMap.find(material.name);
|
|
||||||
if (materialMapIter != materialMap.end()) {
|
|
||||||
QJsonObject materialOptions = materialMapIter.value().toObject();
|
|
||||||
qCDebug(model_baker) << "Mapping material:" << material.name << " with HFMaterial: " << materialOptions;
|
|
||||||
|
|
||||||
{
|
|
||||||
auto scatteringIter = materialOptions.find("scattering");
|
|
||||||
if (scatteringIter != materialOptions.end()) {
|
|
||||||
float scattering = (float)scatteringIter.value().toDouble();
|
|
||||||
material._material->setScattering(scattering);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto scatteringMapIter = materialOptions.find("scatteringMap");
|
|
||||||
if (scatteringMapIter != materialOptions.end()) {
|
|
||||||
QByteArray scatteringMap = scatteringMapIter.value().toVariant().toByteArray();
|
|
||||||
material.scatteringTexture = HFMTexture();
|
|
||||||
material.scatteringTexture.name = material.name + ".scatteringMap";
|
|
||||||
material.scatteringTexture.filename = scatteringMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output = materialsOut;
|
|
||||||
}
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "CalculateBlendshapeNormalsTask.h"
|
#include "CalculateBlendshapeNormalsTask.h"
|
||||||
#include "CalculateBlendshapeTangentsTask.h"
|
#include "CalculateBlendshapeTangentsTask.h"
|
||||||
#include "PrepareJointsTask.h"
|
#include "PrepareJointsTask.h"
|
||||||
#include "ApplyMaterialMappingTask.h"
|
|
||||||
|
|
||||||
namespace baker {
|
namespace baker {
|
||||||
|
|
||||||
|
@ -102,7 +101,7 @@ namespace baker {
|
||||||
|
|
||||||
class BuildModelTask {
|
class BuildModelTask {
|
||||||
public:
|
public:
|
||||||
using Input = VaryingSet6<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>, QHash<QString, hfm::Material>>;
|
using Input = VaryingSet5<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>>;
|
||||||
using Output = hfm::Model::Pointer;
|
using Output = hfm::Model::Pointer;
|
||||||
using JobModel = Job::ModelIO<BuildModelTask, Input, Output>;
|
using JobModel = Job::ModelIO<BuildModelTask, Input, Output>;
|
||||||
|
|
||||||
|
@ -112,7 +111,6 @@ namespace baker {
|
||||||
hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
|
hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
|
||||||
hfmModelOut->jointRotationOffsets = input.get3();
|
hfmModelOut->jointRotationOffsets = input.get3();
|
||||||
hfmModelOut->jointIndices = input.get4();
|
hfmModelOut->jointIndices = input.get4();
|
||||||
hfmModelOut->materials = input.get5();
|
|
||||||
output = hfmModelOut;
|
output = hfmModelOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -120,9 +118,9 @@ namespace baker {
|
||||||
class BakerEngineBuilder {
|
class BakerEngineBuilder {
|
||||||
public:
|
public:
|
||||||
using Input = VaryingSet2<hfm::Model::Pointer, QVariantHash>;
|
using Input = VaryingSet2<hfm::Model::Pointer, QVariantHash>;
|
||||||
using Output = hfm::Model::Pointer;
|
using Output = VaryingSet2<hfm::Model::Pointer, MaterialMapping>;
|
||||||
using JobModel = Task::ModelIO<BakerEngineBuilder, Input, Output>;
|
using JobModel = Task::ModelIO<BakerEngineBuilder, Input, Output>;
|
||||||
void build(JobModel& model, const Varying& input, Varying& hfmModelOut) {
|
void build(JobModel& model, const Varying& input, Varying& output) {
|
||||||
const auto& hfmModelIn = input.getN<Input>(0);
|
const auto& hfmModelIn = input.getN<Input>(0);
|
||||||
const auto& mapping = input.getN<Input>(1);
|
const auto& mapping = input.getN<Input>(1);
|
||||||
|
|
||||||
|
@ -156,17 +154,19 @@ namespace baker {
|
||||||
const auto jointRotationOffsets = jointInfoOut.getN<PrepareJointsTask::Output>(1);
|
const auto jointRotationOffsets = jointInfoOut.getN<PrepareJointsTask::Output>(1);
|
||||||
const auto jointIndices = jointInfoOut.getN<PrepareJointsTask::Output>(2);
|
const auto jointIndices = jointInfoOut.getN<PrepareJointsTask::Output>(2);
|
||||||
|
|
||||||
// Apply material mapping
|
// Parse material mapping
|
||||||
const auto materialMappingInputs = ApplyMaterialMappingTask::Input(materials, mapping).asVarying();
|
const auto materialMappingInputs = ParseMaterialMappingTask::Input(materials, mapping).asVarying();
|
||||||
const auto materialsOut = model.addJob<ApplyMaterialMappingTask>("ApplyMaterialMapping", materialMappingInputs);
|
const auto materialMapping = model.addJob<ParseMaterialMappingTask>("ParseMaterialMapping", materialMappingInputs);
|
||||||
|
|
||||||
// Combine the outputs into a new hfm::Model
|
// Combine the outputs into a new hfm::Model
|
||||||
const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying();
|
const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying();
|
||||||
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
|
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
|
||||||
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
|
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
|
||||||
const auto meshesOut = model.addJob<BuildMeshesTask>("BuildMeshes", buildMeshesInputs);
|
const auto meshesOut = model.addJob<BuildMeshesTask>("BuildMeshes", buildMeshesInputs);
|
||||||
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, materialsOut).asVarying();
|
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices).asVarying();
|
||||||
hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
|
const auto hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
|
||||||
|
|
||||||
|
output = Output(hfmModelOut, materialMapping);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,7 +178,8 @@ namespace baker {
|
||||||
|
|
||||||
void Baker::run() {
|
void Baker::run() {
|
||||||
_engine->run();
|
_engine->run();
|
||||||
hfmModel = _engine->getOutput().get<BakerEngineBuilder::Output>();
|
hfmModel = _engine->getOutput().get<BakerEngineBuilder::Output>().get0();
|
||||||
|
materialMapping = _engine->getOutput().get<BakerEngineBuilder::Output>().get1();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
|
|
||||||
|
#include "ParseMaterialMappingTask.h"
|
||||||
|
|
||||||
namespace baker {
|
namespace baker {
|
||||||
class Baker {
|
class Baker {
|
||||||
public:
|
public:
|
||||||
|
@ -27,6 +29,7 @@ namespace baker {
|
||||||
|
|
||||||
// Outputs, available after run() is called
|
// Outputs, available after run() is called
|
||||||
hfm::Model::Pointer hfmModel;
|
hfm::Model::Pointer hfmModel;
|
||||||
|
MaterialMapping materialMapping;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EnginePointer _engine;
|
EnginePointer _engine;
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// Created by Sam Gondelman on 2/7/2019
|
||||||
|
// Copyright 2019 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 "ParseMaterialMappingTask.h"
|
||||||
|
|
||||||
|
#include "ModelBakerLogging.h"
|
||||||
|
|
||||||
|
void ParseMaterialMappingTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) {
|
||||||
|
const auto& materialsIn = input.get0();
|
||||||
|
const auto& mapping = input.get1();
|
||||||
|
|
||||||
|
MaterialMapping materialMapping;
|
||||||
|
|
||||||
|
auto mappingIter = mapping.find("materialMap");
|
||||||
|
if (mappingIter != mapping.end()) {
|
||||||
|
QByteArray materialMapValue = mappingIter.value().toByteArray();
|
||||||
|
QJsonObject materialMap = QJsonDocument::fromJson(materialMapValue).object();
|
||||||
|
if (materialMap.isEmpty()) {
|
||||||
|
qCDebug(model_baker) << "Material Map found but did not produce valid JSON:" << materialMapValue;
|
||||||
|
} else {
|
||||||
|
auto mappingKeys = materialMap.keys();
|
||||||
|
for (auto mapping : mappingKeys) {
|
||||||
|
auto mappingValue = materialMap[mapping].toObject();
|
||||||
|
|
||||||
|
// Old subsurface scattering mapping
|
||||||
|
{
|
||||||
|
auto scatteringIter = mappingValue.find("scattering");
|
||||||
|
auto scatteringMapIter = mappingValue.find("scatteringMap");
|
||||||
|
if (scatteringIter != mappingValue.end() || scatteringMapIter != mappingValue.end()) {
|
||||||
|
std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
|
||||||
|
|
||||||
|
if (scatteringIter != mappingValue.end()) {
|
||||||
|
float scattering = (float)scatteringIter.value().toDouble();
|
||||||
|
material->setScattering(scattering);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scatteringMapIter != mappingValue.end()) {
|
||||||
|
QString scatteringMap = scatteringMapIter.value().toString();
|
||||||
|
material->setScatteringMap(scatteringMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
material->setDefaultFallthrough(true);
|
||||||
|
|
||||||
|
NetworkMaterialResourcePointer materialResource = NetworkMaterialResourcePointer(new NetworkMaterialResource(), [](NetworkMaterialResource* ptr) { ptr->deleteLater(); });
|
||||||
|
materialResource->moveToThread(qApp->thread());
|
||||||
|
materialResource->parsedMaterials.names.push_back("scattering");
|
||||||
|
materialResource->parsedMaterials.networkMaterials["scattering"] = material;
|
||||||
|
|
||||||
|
materialMapping.push_back(std::pair<std::string, NetworkMaterialResourcePointer>("mat::" + mapping.toStdString(), materialResource));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output = materialMapping;
|
||||||
|
}
|
|
@ -6,8 +6,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_ApplyMaterialMappingTask_h
|
#ifndef hifi_ParseMaterialMappingTask_h
|
||||||
#define hifi_ApplyMaterialMappingTask_h
|
#define hifi_ParseMaterialMappingTask_h
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
|
@ -15,13 +15,15 @@
|
||||||
|
|
||||||
#include "Engine.h"
|
#include "Engine.h"
|
||||||
|
|
||||||
class ApplyMaterialMappingTask {
|
#include <material-networking/MaterialCache.h>
|
||||||
|
|
||||||
|
class ParseMaterialMappingTask {
|
||||||
public:
|
public:
|
||||||
using Input = baker::VaryingSet2<QHash<QString, hfm::Material>, QVariantHash>;
|
using Input = baker::VaryingSet2<QHash<QString, hfm::Material>, QVariantHash>;
|
||||||
using Output = QHash<QString, hfm::Material>;
|
using Output = MaterialMapping;
|
||||||
using JobModel = baker::Job::ModelIO<ApplyMaterialMappingTask, Input, Output>;
|
using JobModel = baker::Job::ModelIO<ParseMaterialMappingTask, Input, Output>;
|
||||||
|
|
||||||
void run(const baker::BakeContextPointer& context, const Input& input, Output& output);
|
void run(const baker::BakeContextPointer& context, const Input& input, Output& output);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ApplyMaterialMappingTask_h
|
#endif // hifi_ParseMaterialMappingTask_h
|
|
@ -174,6 +174,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) {
|
||||||
void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
|
void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
|
||||||
if (success && _geometryResource) {
|
if (success && _geometryResource) {
|
||||||
_hfmModel = _geometryResource->_hfmModel;
|
_hfmModel = _geometryResource->_hfmModel;
|
||||||
|
_materialMapping = _geometryResource->_materialMapping;
|
||||||
_meshParts = _geometryResource->_meshParts;
|
_meshParts = _geometryResource->_meshParts;
|
||||||
_meshes = _geometryResource->_meshes;
|
_meshes = _geometryResource->_meshes;
|
||||||
_materials = _geometryResource->_materials;
|
_materials = _geometryResource->_materials;
|
||||||
|
@ -341,6 +342,7 @@ void GeometryDefinitionResource::setGeometryDefinition(HFMModel::Pointer hfmMode
|
||||||
|
|
||||||
// Assume ownership of the processed HFMModel
|
// Assume ownership of the processed HFMModel
|
||||||
_hfmModel = modelBaker.hfmModel;
|
_hfmModel = modelBaker.hfmModel;
|
||||||
|
_materialMapping = modelBaker.materialMapping;
|
||||||
|
|
||||||
// Copy materials
|
// Copy materials
|
||||||
QHash<QString, size_t> materialIDAtlas;
|
QHash<QString, size_t> materialIDAtlas;
|
||||||
|
@ -437,6 +439,7 @@ const QVariantMap Geometry::getTextures() const {
|
||||||
// FIXME: The materials should only be copied when modified, but the Model currently caches the original
|
// FIXME: The materials should only be copied when modified, but the Model currently caches the original
|
||||||
Geometry::Geometry(const Geometry& geometry) {
|
Geometry::Geometry(const Geometry& geometry) {
|
||||||
_hfmModel = geometry._hfmModel;
|
_hfmModel = geometry._hfmModel;
|
||||||
|
_materialMapping = geometry._materialMapping;
|
||||||
_meshes = geometry._meshes;
|
_meshes = geometry._meshes;
|
||||||
_meshParts = geometry._meshParts;
|
_meshParts = geometry._meshParts;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ public:
|
||||||
bool isHFMModelLoaded() const { return (bool)_hfmModel; }
|
bool isHFMModelLoaded() const { return (bool)_hfmModel; }
|
||||||
|
|
||||||
const HFMModel& getHFMModel() const { return *_hfmModel; }
|
const HFMModel& getHFMModel() const { return *_hfmModel; }
|
||||||
|
const MaterialMapping& getMaterialMapping() const { return _materialMapping; }
|
||||||
const GeometryMeshes& getMeshes() const { return *_meshes; }
|
const GeometryMeshes& getMeshes() const { return *_meshes; }
|
||||||
const std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const;
|
const std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const;
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ protected:
|
||||||
|
|
||||||
// Shared across all geometries, constant throughout lifetime
|
// Shared across all geometries, constant throughout lifetime
|
||||||
std::shared_ptr<const HFMModel> _hfmModel;
|
std::shared_ptr<const HFMModel> _hfmModel;
|
||||||
|
MaterialMapping _materialMapping;
|
||||||
std::shared_ptr<const GeometryMeshes> _meshes;
|
std::shared_ptr<const GeometryMeshes> _meshes;
|
||||||
std::shared_ptr<const GeometryMeshParts> _meshParts;
|
std::shared_ptr<const GeometryMeshParts> _meshParts;
|
||||||
|
|
||||||
|
|
|
@ -359,7 +359,7 @@ class Resource : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Resource() : QObject(), _loaded(true) {}
|
||||||
Resource(const Resource& other);
|
Resource(const Resource& other);
|
||||||
Resource(const QUrl& url);
|
Resource(const QUrl& url);
|
||||||
virtual ~Resource();
|
virtual ~Resource();
|
||||||
|
|
|
@ -97,6 +97,7 @@ void CauterizedModel::createRenderItemSet() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_blendshapeOffsetsInitialized = true;
|
_blendshapeOffsetsInitialized = true;
|
||||||
|
applyMaterialMapping();
|
||||||
} else {
|
} else {
|
||||||
Model::createRenderItemSet();
|
Model::createRenderItemSet();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1465,6 +1465,7 @@ void Model::createRenderItemSet() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_blendshapeOffsetsInitialized = true;
|
_blendshapeOffsetsInitialized = true;
|
||||||
|
applyMaterialMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::isRenderable() const {
|
bool Model::isRenderable() const {
|
||||||
|
@ -1519,17 +1520,60 @@ std::set<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialNam
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Model::applyMaterialMapping() {
|
||||||
|
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||||
|
PrimitiveMode primitiveMode = getPrimitiveMode();
|
||||||
|
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
|
||||||
|
|
||||||
|
render::Transaction transaction;
|
||||||
|
std::unordered_map<unsigned int, quint16> priorityMap;
|
||||||
|
auto& materialMapping = getMaterialMapping();
|
||||||
|
qDebug() << "boop" << materialMapping.size();
|
||||||
|
for (auto& mapping : materialMapping) {
|
||||||
|
std::set<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(mapping.first.c_str()));
|
||||||
|
|
||||||
|
qDebug() << "boop2" << mapping.first.c_str() << shapeIDs.size();
|
||||||
|
if (shapeIDs.size() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto networkMaterialResource = mapping.second;
|
||||||
|
qDebug() << (bool)networkMaterialResource;
|
||||||
|
if (networkMaterialResource && networkMaterialResource->isLoaded() && networkMaterialResource->parsedMaterials.names.size() > 0) {
|
||||||
|
auto 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;
|
||||||
|
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
|
graphics::MaterialLayer material = graphics::MaterialLayer(networkMaterial, ++priorityMap[shapeID]);
|
||||||
|
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
|
||||||
|
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||||
|
data.addMaterial(material);
|
||||||
|
// if the material changed, we might need to update our item key or shape key
|
||||||
|
data.updateKey(renderItemsKey);
|
||||||
|
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
void Model::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
void Model::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||||
std::set<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
std::set<unsigned int> shapeIDs = getMeshIDsFromMaterialID(QString(parentMaterialName.c_str()));
|
||||||
|
|
||||||
|
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
||||||
|
PrimitiveMode primitiveMode = getPrimitiveMode();
|
||||||
|
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
|
||||||
|
|
||||||
render::Transaction transaction;
|
render::Transaction transaction;
|
||||||
for (auto shapeID : shapeIDs) {
|
for (auto shapeID : shapeIDs) {
|
||||||
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
if (shapeID < _modelMeshRenderItemIDs.size()) {
|
||||||
auto itemID = _modelMeshRenderItemIDs[shapeID];
|
auto itemID = _modelMeshRenderItemIDs[shapeID];
|
||||||
auto renderItemsKey = _renderItemKeyGlobalFlags;
|
|
||||||
PrimitiveMode primitiveMode = getPrimitiveMode();
|
|
||||||
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex;
|
||||||
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex);
|
||||||
bool useDualQuaternionSkinning = _useDualQuaternionSkinning;
|
|
||||||
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
|
transaction.updateItem<ModelMeshPartPayload>(itemID, [material, renderItemsKey,
|
||||||
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) {
|
||||||
data.addMaterial(material);
|
data.addMaterial(material);
|
||||||
|
|
|
@ -183,6 +183,7 @@ public:
|
||||||
/// Provided as a convenience, will crash if !isLoaded()
|
/// Provided as a convenience, will crash if !isLoaded()
|
||||||
// And so that getHFMModel() isn't chained everywhere
|
// And so that getHFMModel() isn't chained everywhere
|
||||||
const HFMModel& getHFMModel() const { assert(isLoaded()); return _renderGeometry->getHFMModel(); }
|
const HFMModel& getHFMModel() const { assert(isLoaded()); return _renderGeometry->getHFMModel(); }
|
||||||
|
const MaterialMapping& getMaterialMapping() const { assert(isLoaded()); return _renderGeometry->getMaterialMapping(); }
|
||||||
|
|
||||||
bool isActive() const { return isLoaded(); }
|
bool isActive() const { return isLoaded(); }
|
||||||
|
|
||||||
|
@ -373,6 +374,8 @@ signals:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
void applyMaterialMapping();
|
||||||
|
|
||||||
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }
|
void setBlendshapeCoefficients(const QVector<float>& coefficients) { _blendshapeCoefficients = coefficients; }
|
||||||
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue