Show body skinning mesh

master
Jeremy HU 2022-12-06 20:01:22 +11:00
parent 8b8579d02e
commit d2bc7716f2
8 changed files with 99 additions and 7 deletions

View File

@ -15,6 +15,11 @@ std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePrevi
return m_bonePreviewMeshes.release(); return m_bonePreviewMeshes.release();
} }
std::unique_ptr<ModelMesh> BoneGenerator::takeBodyPreviewMesh()
{
return std::move(m_bodyPreviewMesh);
}
void BoneGenerator::process() void BoneGenerator::process()
{ {
QElapsedTimer countTimeConsumed; QElapsedTimer countTimeConsumed;
@ -81,6 +86,37 @@ void BoneGenerator::process()
&vertexProperties); &vertexProperties);
} }
{
const auto& preview = bodyPreview();
std::vector<dust3d::Vector3> previewTriangleNormals;
previewTriangleNormals.reserve(preview.triangles.size());
for (const auto& face : preview.triangles) {
previewTriangleNormals.emplace_back(dust3d::Vector3::normal(
preview.vertices[face[0]],
preview.vertices[face[1]],
preview.vertices[face[2]]));
}
std::vector<std::vector<dust3d::Vector3>> previewTriangleVertexNormals;
dust3d::smoothNormal(preview.vertices,
preview.triangles,
previewTriangleNormals,
0,
&previewTriangleVertexNormals);
std::vector<std::tuple<dust3d::Color, float /*metalness*/, float /*roughness*/>> vertexProperties(preview.vertexColors.size());
for (size_t i = 0; i < vertexProperties.size(); ++i) {
vertexProperties[i] = std::make_tuple(preview.vertexColors[i],
(float)0.0, (float)1.0);
}
m_bodyPreviewMesh = std::make_unique<ModelMesh>(preview.vertices,
preview.triangles,
previewTriangleVertexNormals,
dust3d::Color::createWhite(),
(float)0.0,
(float)1.0,
&vertexProperties);
m_bodyPreviewMesh->setMeshId(m_object->meshId);
}
qDebug() << "The bone generation took" << countTimeConsumed.elapsed() << "milliseconds"; qDebug() << "The bone generation took" << countTimeConsumed.elapsed() << "milliseconds";
emit finished(); emit finished();

View File

@ -13,6 +13,7 @@ class BoneGenerator : public QObject, public dust3d::BoneGenerator {
public: public:
BoneGenerator(std::unique_ptr<dust3d::Object> object, std::unique_ptr<dust3d::Snapshot> snapshot); BoneGenerator(std::unique_ptr<dust3d::Object> object, std::unique_ptr<dust3d::Snapshot> snapshot);
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* takeBonePreviewMeshes(); std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* takeBonePreviewMeshes();
std::unique_ptr<ModelMesh> takeBodyPreviewMesh();
public slots: public slots:
void process(); void process();
signals: signals:
@ -22,6 +23,7 @@ private:
std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> m_bonePreviewMeshes; std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> m_bonePreviewMeshes;
std::unique_ptr<dust3d::Object> m_object; std::unique_ptr<dust3d::Object> m_object;
std::unique_ptr<dust3d::Snapshot> m_snapshot; std::unique_ptr<dust3d::Snapshot> m_snapshot;
std::unique_ptr<ModelMesh> m_bodyPreviewMesh;
}; };
#endif #endif

View File

@ -2118,6 +2118,21 @@ quint64 Document::resultTextureMeshId()
return m_resultTextureMesh->meshId(); return m_resultTextureMesh->meshId();
} }
ModelMesh* Document::takeResultBodyBonePreviewMesh()
{
if (nullptr == m_resultBodyBonePreviewMesh)
return nullptr;
ModelMesh* resultBodyBonePreviewMesh = new ModelMesh(*m_resultBodyBonePreviewMesh);
return resultBodyBonePreviewMesh;
}
quint64 Document::resultBodyBonePreviewMeshId()
{
if (nullptr == m_resultBodyBonePreviewMesh)
return 0;
return m_resultBodyBonePreviewMesh->meshId();
}
void Document::meshReady() void Document::meshReady()
{ {
ModelMesh* resultMesh = m_meshGenerator->takeResultMesh(); ModelMesh* resultMesh = m_meshGenerator->takeResultMesh();
@ -3079,6 +3094,8 @@ void Document::boneReady()
emit resultBonePreviewMeshesChanged(); emit resultBonePreviewMeshesChanged();
} }
m_resultBodyBonePreviewMesh = m_boneGenerator->takeBodyPreviewMesh();
// TODO: // TODO:
m_boneGenerator.reset(); m_boneGenerator.reset();

View File

@ -358,6 +358,8 @@ public:
bool isMeshGenerationSucceed(); bool isMeshGenerationSucceed();
ModelMesh* takeResultTextureMesh(); ModelMesh* takeResultTextureMesh();
quint64 resultTextureMeshId(); quint64 resultTextureMeshId();
ModelMesh* takeResultBodyBonePreviewMesh();
quint64 resultBodyBonePreviewMeshId();
void updateTurnaround(const QImage& image); void updateTurnaround(const QImage& image);
void clearTurnaround(); void clearTurnaround();
void updateTextureImage(QImage* image); void updateTextureImage(QImage* image);
@ -589,6 +591,7 @@ private:
std::unique_ptr<BoneGenerator> m_boneGenerator; std::unique_ptr<BoneGenerator> m_boneGenerator;
bool m_isResultBoneObsolete = false; bool m_isResultBoneObsolete = false;
std::unique_ptr<ModelMesh> m_resultBodyBonePreviewMesh;
private: private:
static unsigned long m_maxSnapshot; static unsigned long m_maxSnapshot;

View File

@ -278,6 +278,13 @@ DocumentWindow::DocumentWindow()
bonesDocker->setWidget(m_boneManageWidget); bonesDocker->setWidget(m_boneManageWidget);
bonesDocker->setAllowedAreas(Qt::RightDockWidgetArea); bonesDocker->setAllowedAreas(Qt::RightDockWidgetArea);
connect(bonesDocker, &QDockWidget::visibilityChanged, this, [this](bool visible) {
if (this->m_showBodyBonePreview == visible)
return;
this->m_showBodyBonePreview = visible;
forceUpdateRenderModel();
});
tabifyDockWidget(partsDocker, bonesDocker); tabifyDockWidget(partsDocker, bonesDocker);
partsDocker->raise(); partsDocker->raise();
@ -426,6 +433,13 @@ DocumentWindow::DocumentWindow()
}); });
m_windowMenu->addAction(m_showPartsListAction); m_windowMenu->addAction(m_showPartsListAction);
m_showBonesListAction = new QAction(tr("Bones"), this);
connect(m_showBonesListAction, &QAction::triggered, [=]() {
bonesDocker->show();
bonesDocker->raise();
});
m_windowMenu->addAction(m_showBonesListAction);
QMenu* dialogsMenu = m_windowMenu->addMenu(tr("Dialogs")); QMenu* dialogsMenu = m_windowMenu->addMenu(tr("Dialogs"));
connect(dialogsMenu, &QMenu::aboutToShow, [=]() { connect(dialogsMenu, &QMenu::aboutToShow, [=]() {
dialogsMenu->clear(); dialogsMenu->clear();
@ -1440,6 +1454,10 @@ void DocumentWindow::bonePreviewImagesReady()
void DocumentWindow::forceUpdateRenderModel() void DocumentWindow::forceUpdateRenderModel()
{ {
ModelMesh* mesh = nullptr; ModelMesh* mesh = nullptr;
if (m_showBodyBonePreview) {
mesh = m_document->takeResultBodyBonePreviewMesh();
m_currentUpdatedMeshId = m_document->resultBodyBonePreviewMeshId();
} else {
if (m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating()) { if (m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating()) {
mesh = m_document->takeResultMesh(); mesh = m_document->takeResultMesh();
m_currentUpdatedMeshId = m_document->resultMeshId(); m_currentUpdatedMeshId = m_document->resultMeshId();
@ -1449,6 +1467,7 @@ void DocumentWindow::forceUpdateRenderModel()
} }
if (m_modelRemoveColor && mesh) if (m_modelRemoveColor && mesh)
mesh->removeColor(); mesh->removeColor();
}
m_modelRenderWidget->updateMesh(mesh); m_modelRenderWidget->updateMesh(mesh);
} }

View File

@ -152,6 +152,7 @@ private:
QMenu* m_windowMenu = nullptr; QMenu* m_windowMenu = nullptr;
QAction* m_showPartsListAction = nullptr; QAction* m_showPartsListAction = nullptr;
QAction* m_showBonesListAction = nullptr;
QAction* m_showDebugDialogAction = nullptr; QAction* m_showDebugDialogAction = nullptr;
QMenu* m_helpMenu = nullptr; QMenu* m_helpMenu = nullptr;
@ -187,6 +188,8 @@ private:
SpinnableToolbarIcon* m_inprogressIndicator = nullptr; SpinnableToolbarIcon* m_inprogressIndicator = nullptr;
std::map<QKeySequence, QShortcut*> m_shortcutMap; std::map<QKeySequence, QShortcut*> m_shortcutMap;
bool m_showBodyBonePreview = false;
}; };
#endif #endif

View File

@ -160,6 +160,11 @@ std::map<Uuid, BoneGenerator::BonePreview>& BoneGenerator::bonePreviews()
return m_bonePreviews; return m_bonePreviews;
} }
BoneGenerator::BonePreview& BoneGenerator::bodyPreview()
{
return m_bodyPreview;
}
void BoneGenerator::addBonePreviewTriangle(BonePreview& bonePreview, void BoneGenerator::addBonePreviewTriangle(BonePreview& bonePreview,
std::unordered_map<size_t, size_t>& oldToNewVertexMap, std::unordered_map<size_t, size_t>& oldToNewVertexMap,
const std::vector<size_t>& triangle) const std::vector<size_t>& triangle)
@ -198,6 +203,11 @@ void BoneGenerator::generateBonePreviews()
m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview))); m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview)));
} }
std::unordered_map<size_t, size_t> bodyOldToNewVertexMap;
for (const auto& triangle : m_triangles) {
addBonePreviewTriangle(m_bodyPreview, bodyOldToNewVertexMap, triangle);
}
} }
} }

View File

@ -68,6 +68,7 @@ public:
BoneGenerator(); BoneGenerator();
void generate(); void generate();
std::map<Uuid, BonePreview>& bonePreviews(); std::map<Uuid, BonePreview>& bonePreviews();
BonePreview& bodyPreview();
protected: protected:
void setVertices(const std::vector<Vector3>& vertices); void setVertices(const std::vector<Vector3>& vertices);
@ -88,6 +89,7 @@ private:
std::vector<Uuid> m_vertexSourceNodes; std::vector<Uuid> m_vertexSourceNodes;
std::map<Uuid, std::unordered_set<size_t>> m_boneVertices; std::map<Uuid, std::unordered_set<size_t>> m_boneVertices;
std::map<Uuid, BonePreview> m_bonePreviews; std::map<Uuid, BonePreview> m_bonePreviews;
BonePreview m_bodyPreview;
void buildEdges(); void buildEdges();
void resolveVertexSources(); void resolveVertexSources();