2018-10-09 02:19:12 +00:00
|
|
|
#include <QGuiApplication>
|
|
|
|
#include <QElapsedTimer>
|
|
|
|
#include "materialpreviewsgenerator.h"
|
|
|
|
#include "meshgenerator.h"
|
2018-10-25 00:19:38 +00:00
|
|
|
#include "snapshotxml.h"
|
2018-10-09 02:19:12 +00:00
|
|
|
#include "ds3file.h"
|
|
|
|
#include "texturegenerator.h"
|
|
|
|
#include "imageforever.h"
|
2018-10-26 23:04:45 +00:00
|
|
|
#include "meshresultpostprocessor.h"
|
2018-10-09 02:19:12 +00:00
|
|
|
|
|
|
|
MaterialPreviewsGenerator::MaterialPreviewsGenerator()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
MaterialPreviewsGenerator::~MaterialPreviewsGenerator()
|
|
|
|
{
|
|
|
|
for (auto &item: m_previews) {
|
|
|
|
delete item.second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-25 00:19:38 +00:00
|
|
|
void MaterialPreviewsGenerator::addMaterial(QUuid materialId, const std::vector<MaterialLayer> &layers)
|
2018-10-09 02:19:12 +00:00
|
|
|
{
|
|
|
|
m_materials.push_back({materialId, layers});
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::set<QUuid> &MaterialPreviewsGenerator::generatedPreviewMaterialIds()
|
|
|
|
{
|
|
|
|
return m_generatedMaterialIds;
|
|
|
|
}
|
|
|
|
|
2020-04-07 23:15:20 +00:00
|
|
|
Model *MaterialPreviewsGenerator::takePreview(QUuid materialId)
|
2018-10-09 02:19:12 +00:00
|
|
|
{
|
2020-04-07 23:15:20 +00:00
|
|
|
Model *resultMesh = m_previews[materialId];
|
2018-10-09 02:19:12 +00:00
|
|
|
m_previews[materialId] = nullptr;
|
|
|
|
return resultMesh;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MaterialPreviewsGenerator::generate()
|
|
|
|
{
|
2018-10-25 00:19:38 +00:00
|
|
|
Snapshot *snapshot = new Snapshot;
|
2018-10-09 02:19:12 +00:00
|
|
|
|
|
|
|
std::vector<QUuid> partIds;
|
|
|
|
Ds3FileReader ds3Reader(":/resources/material-demo-model.ds3");
|
|
|
|
for (int i = 0; i < ds3Reader.items().size(); ++i) {
|
|
|
|
Ds3ReaderItem item = ds3Reader.items().at(i);
|
|
|
|
if (item.type == "model") {
|
|
|
|
QByteArray data;
|
|
|
|
ds3Reader.loadItem(item.name, &data);
|
|
|
|
QXmlStreamReader stream(data);
|
|
|
|
loadSkeletonFromXmlStream(snapshot, stream);
|
|
|
|
for (const auto &item: snapshot->parts) {
|
|
|
|
partIds.push_back(QUuid(item.first));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GeneratedCacheContext *cacheContext = new GeneratedCacheContext();
|
|
|
|
MeshGenerator *meshGenerator = new MeshGenerator(snapshot);
|
|
|
|
meshGenerator->setGeneratedCacheContext(cacheContext);
|
|
|
|
|
|
|
|
meshGenerator->generate();
|
|
|
|
for (const auto &mirror: cacheContext->partMirrorIdMap) {
|
|
|
|
partIds.push_back(QUuid(mirror.first));
|
|
|
|
}
|
|
|
|
|
2020-11-17 14:31:51 +00:00
|
|
|
Object *object = meshGenerator->takeObject();
|
|
|
|
if (nullptr != object) {
|
|
|
|
MeshResultPostProcessor *poseProcessor = new MeshResultPostProcessor(*object);
|
2018-10-26 23:04:45 +00:00
|
|
|
poseProcessor->poseProcess();
|
2020-11-17 14:31:51 +00:00
|
|
|
delete object;
|
|
|
|
object = poseProcessor->takePostProcessedObject();
|
2018-10-26 23:04:45 +00:00
|
|
|
delete poseProcessor;
|
|
|
|
}
|
2018-10-09 02:19:12 +00:00
|
|
|
|
2020-11-17 14:31:51 +00:00
|
|
|
if (nullptr != object) {
|
2019-12-24 23:24:49 +00:00
|
|
|
for (const auto &material: m_materials) {
|
2020-11-17 14:31:51 +00:00
|
|
|
TextureGenerator *textureGenerator = new TextureGenerator(*object);
|
2019-12-24 23:24:49 +00:00
|
|
|
for (const auto &layer: material.second) {
|
|
|
|
for (const auto &mapItem: layer.maps) {
|
|
|
|
const QImage *image = ImageForever::get(mapItem.imageId);
|
|
|
|
if (nullptr == image)
|
|
|
|
continue;
|
|
|
|
for (const auto &partId: partIds) {
|
|
|
|
if (TextureType::BaseColor == mapItem.forWhat)
|
|
|
|
textureGenerator->addPartColorMap(partId, image, layer.tileScale);
|
|
|
|
else if (TextureType::Normal == mapItem.forWhat)
|
|
|
|
textureGenerator->addPartNormalMap(partId, image, layer.tileScale);
|
|
|
|
else if (TextureType::Metalness == mapItem.forWhat)
|
|
|
|
textureGenerator->addPartMetalnessMap(partId, image, layer.tileScale);
|
|
|
|
else if (TextureType::Roughness == mapItem.forWhat)
|
|
|
|
textureGenerator->addPartRoughnessMap(partId, image, layer.tileScale);
|
|
|
|
else if (TextureType::AmbientOcclusion == mapItem.forWhat)
|
|
|
|
textureGenerator->addPartAmbientOcclusionMap(partId, image, layer.tileScale);
|
|
|
|
}
|
2018-10-09 02:19:12 +00:00
|
|
|
}
|
|
|
|
}
|
2019-12-24 23:24:49 +00:00
|
|
|
textureGenerator->generate();
|
2020-04-07 23:15:20 +00:00
|
|
|
Model *texturedResultMesh = textureGenerator->takeResultMesh();
|
2019-12-24 23:24:49 +00:00
|
|
|
if (nullptr != texturedResultMesh) {
|
2020-04-07 23:15:20 +00:00
|
|
|
m_previews[material.first] = new Model(*texturedResultMesh);
|
2019-12-24 23:24:49 +00:00
|
|
|
m_generatedMaterialIds.insert(material.first);
|
|
|
|
delete texturedResultMesh;
|
|
|
|
}
|
|
|
|
delete textureGenerator;
|
2018-10-09 02:19:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-17 14:31:51 +00:00
|
|
|
delete object;
|
2018-10-09 02:19:12 +00:00
|
|
|
|
|
|
|
delete meshGenerator;
|
|
|
|
delete cacheContext;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MaterialPreviewsGenerator::process()
|
|
|
|
{
|
|
|
|
QElapsedTimer countTimeConsumed;
|
|
|
|
countTimeConsumed.start();
|
|
|
|
|
|
|
|
generate();
|
|
|
|
|
|
|
|
qDebug() << "The material previews generation took" << countTimeConsumed.elapsed() << "milliseconds";
|
|
|
|
|
|
|
|
emit finished();
|
|
|
|
}
|