Show body skinning mesh
parent
8b8579d02e
commit
d2bc7716f2
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue