mirror of
https://github.com/lubosz/overte.git
synced 2025-04-09 06:04:42 +02:00
Merge pull request #15427 from SamGondelman/materialMap
Case 22079: Bake existing materialMap in FST
This commit is contained in:
commit
0768cd58dc
4 changed files with 80 additions and 23 deletions
|
@ -276,4 +276,8 @@ void MaterialBaker::setMaterials(const QHash<QString, hfm::Material>& materials,
|
|||
addTexture(material.name, image::TextureUsage::SCATTERING_TEXTURE, material.scatteringTexture);
|
||||
addTexture(material.name, image::TextureUsage::LIGHTMAP_TEXTURE, material.lightmapTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBaker::setMaterials(const NetworkMaterialResourcePointer& materialResource) {
|
||||
_materialResource = materialResource;
|
||||
}
|
|
@ -31,6 +31,9 @@ public:
|
|||
QString getBakedMaterialData() const { return _bakedMaterialData; }
|
||||
|
||||
void setMaterials(const QHash<QString, hfm::Material>& materials, const QString& baseURL);
|
||||
void setMaterials(const NetworkMaterialResourcePointer& materialResource);
|
||||
|
||||
NetworkMaterialResourcePointer getNetworkMaterialResource() const { return _materialResource; }
|
||||
|
||||
static void setNextOvenWorkerThreadOperator(std::function<QThread*()> getNextOvenWorkerThreadOperator) { _getNextOvenWorkerThreadOperator = getNextOvenWorkerThreadOperator; }
|
||||
|
||||
|
|
|
@ -241,14 +241,12 @@ void ModelBaker::bakeSourceCopy() {
|
|||
config->getJobConfig("BuildDracoMesh")->setEnabled(true);
|
||||
// Do not permit potentially lossy modification of joint data meant for runtime
|
||||
((PrepareJointsConfig*)config->getJobConfig("PrepareJoints"))->passthrough = true;
|
||||
// The resources parsed from this job will not be used for now
|
||||
// TODO: Proper full baking of all materials for a model
|
||||
config->getJobConfig("ParseMaterialMapping")->setEnabled(false);
|
||||
|
||||
// Begin hfm baking
|
||||
baker.run();
|
||||
|
||||
_hfmModel = baker.getHFMModel();
|
||||
_materialMapping = baker.getMaterialMapping();
|
||||
dracoMeshes = baker.getDracoMeshes();
|
||||
dracoMaterialLists = baker.getDracoMaterialLists();
|
||||
}
|
||||
|
@ -260,7 +258,7 @@ void ModelBaker::bakeSourceCopy() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (_hfmModel->materials.size() > 0) {
|
||||
if (!_hfmModel->materials.isEmpty()) {
|
||||
_materialBaker = QSharedPointer<MaterialBaker>(
|
||||
new MaterialBaker(_modelURL.fileName(), true, _bakedOutputDir),
|
||||
&MaterialBaker::deleteLater
|
||||
|
@ -269,7 +267,7 @@ void ModelBaker::bakeSourceCopy() {
|
|||
connect(_materialBaker.data(), &MaterialBaker::finished, this, &ModelBaker::handleFinishedMaterialBaker);
|
||||
_materialBaker->bake();
|
||||
} else {
|
||||
outputBakedFST();
|
||||
bakeMaterialMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,26 +283,14 @@ void ModelBaker::handleFinishedMaterialBaker() {
|
|||
auto baseName = relativeBakedMaterialURL.left(relativeBakedMaterialURL.lastIndexOf('.'));
|
||||
relativeBakedMaterialURL = baseName + BAKED_MATERIAL_EXTENSION;
|
||||
|
||||
// First we add the materials in the model
|
||||
QJsonArray materialMapping;
|
||||
for (auto material : _hfmModel->materials) {
|
||||
QJsonObject json;
|
||||
json["mat::" + material.name] = relativeBakedMaterialURL + "#" + material.name;
|
||||
materialMapping.push_back(json);
|
||||
}
|
||||
|
||||
// The we add any existing mappings from the mapping
|
||||
if (_mapping.contains(MATERIAL_MAPPING_FIELD)) {
|
||||
QByteArray materialMapValue = _mapping[MATERIAL_MAPPING_FIELD].toByteArray();
|
||||
QJsonObject oldMaterialMapping = QJsonDocument::fromJson(materialMapValue).object();
|
||||
for (auto key : oldMaterialMapping.keys()) {
|
||||
auto materialResource = baker->getNetworkMaterialResource();
|
||||
if (materialResource) {
|
||||
for (auto materialName : materialResource->parsedMaterials.names) {
|
||||
QJsonObject json;
|
||||
json[key] = oldMaterialMapping[key];
|
||||
materialMapping.push_back(json);
|
||||
json[QString("mat::" + QString(materialName.c_str()))] = relativeBakedMaterialURL + "#" + materialName.c_str();
|
||||
_materialMappingJSON.push_back(json);
|
||||
}
|
||||
}
|
||||
|
||||
_mapping[MATERIAL_MAPPING_FIELD] = QJsonDocument(materialMapping).toJson(QJsonDocument::Compact);
|
||||
} else {
|
||||
// this material failed to bake - this doesn't fail the entire bake but we need to add the errors from
|
||||
// the material to our warnings
|
||||
|
@ -314,7 +300,62 @@ void ModelBaker::handleFinishedMaterialBaker() {
|
|||
handleWarning("Failed to bake the materials for model with URL " + _modelURL.toString());
|
||||
}
|
||||
|
||||
outputBakedFST();
|
||||
bakeMaterialMap();
|
||||
}
|
||||
|
||||
void ModelBaker::bakeMaterialMap() {
|
||||
if (!_materialMapping.empty()) {
|
||||
// TODO: The existing material map must be baked in order, so we do it all on this thread to preserve the order.
|
||||
// It could be spread over multiple threads if we had a good way of preserving the order once all of the bakers are done
|
||||
_materialBaker = QSharedPointer<MaterialBaker>(
|
||||
new MaterialBaker("materialMap" + QString::number(_materialMapIndex++), true, _bakedOutputDir),
|
||||
&MaterialBaker::deleteLater
|
||||
);
|
||||
_materialBaker->setMaterials(_materialMapping.front().second);
|
||||
connect(_materialBaker.data(), &MaterialBaker::finished, this, &ModelBaker::handleFinishedMaterialMapBaker);
|
||||
_materialBaker->bake();
|
||||
} else {
|
||||
outputBakedFST();
|
||||
}
|
||||
}
|
||||
|
||||
void ModelBaker::handleFinishedMaterialMapBaker() {
|
||||
auto baker = qobject_cast<MaterialBaker*>(sender());
|
||||
|
||||
if (baker) {
|
||||
if (!baker->hasErrors()) {
|
||||
// this MaterialBaker is done and everything went according to plan
|
||||
qCDebug(model_baking) << "Adding baked material to FST mapping " << baker->getBakedMaterialData();
|
||||
|
||||
QString materialName;
|
||||
{
|
||||
auto materialResource = baker->getNetworkMaterialResource();
|
||||
if (materialResource) {
|
||||
auto url = materialResource->getURL();
|
||||
if (!url.isEmpty()) {
|
||||
QString urlString = url.toDisplayString();
|
||||
auto index = urlString.lastIndexOf("#");
|
||||
if (index != -1) {
|
||||
materialName = urlString.right(urlString.length() - index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject json;
|
||||
json[QString(_materialMapping.front().first.c_str())] = baker->getMaterialData() + BAKED_MATERIAL_EXTENSION + materialName;
|
||||
_materialMappingJSON.push_back(json);
|
||||
} else {
|
||||
// this material failed to bake - this doesn't fail the entire bake but we need to add the errors from
|
||||
// the material to our warnings
|
||||
_warningList << baker->getWarnings();
|
||||
}
|
||||
} else {
|
||||
handleWarning("Failed to bake the materialMap for model with URL " + _modelURL.toString() + " and mapping target " + _materialMapping.front().first.c_str());
|
||||
}
|
||||
|
||||
_materialMapping.erase(_materialMapping.begin());
|
||||
bakeMaterialMap();
|
||||
}
|
||||
|
||||
void ModelBaker::outputUnbakedFST() {
|
||||
|
@ -363,6 +404,9 @@ void ModelBaker::outputBakedFST() {
|
|||
outputMapping[FILENAME_FIELD] = _bakedModelURL.fileName();
|
||||
outputMapping.remove(TEXDIR_FIELD);
|
||||
outputMapping.remove(COMMENT_FIELD);
|
||||
if (!_materialMappingJSON.isEmpty()) {
|
||||
outputMapping[MATERIAL_MAPPING_FIELD] = QJsonDocument(_materialMappingJSON).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
hifi::ByteArray fstOut = FSTReader::writeMapping(outputMapping);
|
||||
|
||||
QFile fstOutputFile { outputFSTURL };
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QtCore/QDir>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "Baker.h"
|
||||
#include "MaterialBaker.h"
|
||||
|
@ -80,14 +81,19 @@ protected slots:
|
|||
void handleModelNetworkReply();
|
||||
virtual void bakeSourceCopy();
|
||||
void handleFinishedMaterialBaker();
|
||||
void handleFinishedMaterialMapBaker();
|
||||
|
||||
private:
|
||||
void outputUnbakedFST();
|
||||
void outputBakedFST();
|
||||
void bakeMaterialMap();
|
||||
|
||||
bool _hasBeenBaked { false };
|
||||
|
||||
hfm::Model::Pointer _hfmModel;
|
||||
MaterialMapping _materialMapping;
|
||||
int _materialMapIndex { 0 };
|
||||
QJsonArray _materialMappingJSON;
|
||||
QSharedPointer<MaterialBaker> _materialBaker;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue