Fix bone preview mesh

master
Jeremy HU 2022-12-04 03:58:33 +11:00
parent 03f1440e7d
commit 6e53452dc8
8 changed files with 76 additions and 47 deletions

View File

@ -1,7 +1,15 @@
#include "bone_generator.h" #include "bone_generator.h"
#include <QDebug>
#include <QElapsedTimer>
#include <dust3d/mesh/smooth_normal.h> #include <dust3d/mesh/smooth_normal.h>
#include <dust3d/mesh/trim_vertices.h> #include <dust3d/mesh/trim_vertices.h>
BoneGenerator::BoneGenerator(std::unique_ptr<dust3d::Object> object, std::unique_ptr<dust3d::Snapshot> snapshot)
: m_object(std::move(object))
, m_snapshot(std::move(snapshot))
{
}
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePreviewMeshes() std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePreviewMeshes()
{ {
return m_bonePreviewMeshes.release(); return m_bonePreviewMeshes.release();
@ -9,6 +17,34 @@ std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* BoneGenerator::takeBonePrevi
void BoneGenerator::process() void BoneGenerator::process()
{ {
QElapsedTimer countTimeConsumed;
countTimeConsumed.start();
setVertices(m_object->vertices);
setTriangles(m_object->triangles);
setPositionToNodeMap(m_object->positionToNodeIdMap);
for (const auto& it : m_object->nodeMap) {
Node node;
node.position = it.second.origin;
addNode(it.first, node);
}
for (const auto& it : m_snapshot->boneIdList) {
Bone bone;
addBone(dust3d::Uuid(it), bone);
}
for (const auto& it : m_snapshot->nodes) {
NodeBinding nodeBinding;
for (const auto& boneIdString : dust3d::String::split(dust3d::String::valueOrEmpty(it.second, "boneIdList"), ',')) {
if (boneIdString.empty())
continue;
nodeBinding.boneIds.insert(dust3d::Uuid(boneIdString));
}
addNodeBinding(dust3d::Uuid(it.first), nodeBinding);
}
generate(); generate();
m_bonePreviewMeshes = std::make_unique<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>>(); m_bonePreviewMeshes = std::make_unique<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>>();
@ -36,5 +72,7 @@ void BoneGenerator::process()
previewTriangleVertexNormals); previewTriangleVertexNormals);
} }
qDebug() << "The bone generation took" << countTimeConsumed.elapsed() << "milliseconds";
emit finished(); emit finished();
} }

View File

@ -3,6 +3,7 @@
#include "model_mesh.h" #include "model_mesh.h"
#include <QObject> #include <QObject>
#include <dust3d/base/snapshot.h>
#include <dust3d/rig/bone_generator.h> #include <dust3d/rig/bone_generator.h>
#include <map> #include <map>
#include <memory> #include <memory>
@ -10,6 +11,7 @@
class BoneGenerator : public QObject, public dust3d::BoneGenerator { class BoneGenerator : public QObject, public dust3d::BoneGenerator {
Q_OBJECT Q_OBJECT
public: public:
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();
public slots: public slots:
void process(); void process();
@ -18,6 +20,8 @@ signals:
private: 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::Snapshot> m_snapshot;
}; };
#endif #endif

View File

@ -3036,10 +3036,13 @@ void Document::generateBone()
emit boneGenerating(); emit boneGenerating();
// TODO: auto object = std::make_unique<dust3d::Object>(*m_uvMappedObject);
auto snapshot = std::make_unique<dust3d::Snapshot>();
toSnapshot(snapshot.get());
QThread* thread = new QThread; QThread* thread = new QThread;
m_boneGenerator = std::make_unique<BoneGenerator>(); m_boneGenerator = std::make_unique<BoneGenerator>(std::move(object), std::move(snapshot));
m_boneGenerator->moveToThread(thread); m_boneGenerator->moveToThread(thread);
connect(thread, &QThread::started, m_boneGenerator.get(), &BoneGenerator::process); connect(thread, &QThread::started, m_boneGenerator.get(), &BoneGenerator::process);
connect(m_boneGenerator.get(), &BoneGenerator::finished, this, &Document::boneReady); connect(m_boneGenerator.get(), &BoneGenerator::finished, this, &Document::boneReady);

View File

@ -40,7 +40,7 @@ namespace dust3d {
struct ObjectNode { struct ObjectNode {
//Uuid partId; //Uuid partId;
//Uuid nodeId; //Uuid nodeId;
//Vector3 origin; Vector3 origin;
//float radius = 0.0; //float radius = 0.0;
Color color; Color color;
//float colorSolubility = 0.0; //float colorSolubility = 0.0;

View File

@ -641,7 +641,7 @@ std::unique_ptr<MeshState> MeshGenerator::combinePartMesh(const std::string& par
partCache.nodeMap.clear(); partCache.nodeMap.clear();
for (const auto& meshNode : meshNodes) { for (const auto& meshNode : meshNodes) {
partCache.nodeMap.emplace(std::make_pair(meshNode.sourceId, partCache.nodeMap.emplace(std::make_pair(meshNode.sourceId,
ObjectNode { partColor })); ObjectNode { meshNode.origin, partColor }));
} }
if (PartTarget::Model == target) { if (PartTarget::Model == target) {
@ -767,30 +767,6 @@ CombineMode MeshGenerator::componentCombineMode(const std::map<std::string, std:
return combineMode; return combineMode;
} }
std::string MeshGenerator::componentColorName(const std::map<std::string, std::string>* component)
{
if (nullptr == component)
return std::string();
std::string linkDataType = String::valueOrEmpty(*component, "linkDataType");
if ("partId" == linkDataType) {
std::string partIdString = String::valueOrEmpty(*component, "linkData");
auto findPart = m_snapshot->parts.find(partIdString);
if (findPart == m_snapshot->parts.end()) {
return std::string();
}
auto& part = findPart->second;
std::string colorSolubility = String::valueOrEmpty(part, "colorSolubility");
if (!colorSolubility.empty()) {
return std::string("+");
}
std::string colorName = String::valueOrEmpty(part, "color");
if (colorName.empty())
return std::string("-");
return colorName;
}
return std::string();
}
std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode) std::unique_ptr<MeshState> MeshGenerator::combineComponentMesh(const std::string& componentIdString, CombineMode* combineMode)
{ {
std::unique_ptr<MeshState> mesh; std::unique_ptr<MeshState> mesh;

View File

@ -163,7 +163,6 @@ private:
std::unique_ptr<MeshState> combineStitchingMesh(const std::vector<std::string>& partIdStrings, std::unique_ptr<MeshState> combineStitchingMesh(const std::vector<std::string>& partIdStrings,
const std::vector<std::string>& componentIdStrings, const std::vector<std::string>& componentIdStrings,
GeneratedComponent& componentCache); GeneratedComponent& componentCache);
std::string componentColorName(const std::map<std::string, std::string>* component);
void collectUncombinedComponent(const std::string& componentIdString); void collectUncombinedComponent(const std::string& componentIdString);
void cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector<Vector2>& cutTemplate); void cutFaceStringToCutTemplate(const std::string& cutFaceString, std::vector<Vector2>& cutTemplate);
void postprocessObject(Object* object); void postprocessObject(Object* object);

View File

@ -21,7 +21,6 @@
*/ */
#include <dust3d/rig/bone_generator.h> #include <dust3d/rig/bone_generator.h>
#include <unordered_map>
namespace dust3d { namespace dust3d {
@ -161,25 +160,29 @@ std::map<Uuid, BoneGenerator::BonePreview>& BoneGenerator::bonePreviews()
return m_bonePreviews; return m_bonePreviews;
} }
void BoneGenerator::addBonePreviewTriangle(BonePreview& bonePreview,
std::unordered_map<size_t, size_t>& oldToNewVertexMap,
const std::vector<size_t>& triangle)
{
std::vector<size_t> newTriangle(3);
for (size_t i = 0; i < 3; ++i) {
auto findVertex = oldToNewVertexMap.find(triangle[i]);
if (findVertex == oldToNewVertexMap.end()) {
oldToNewVertexMap.insert(std::make_pair(triangle[i], bonePreview.vertices.size()));
newTriangle[i] = bonePreview.vertices.size();
bonePreview.vertices.push_back(m_vertices[triangle[i]]);
} else {
newTriangle[i] = findVertex->second;
}
}
bonePreview.triangles.emplace_back(newTriangle);
}
void BoneGenerator::generateBonePreviews() void BoneGenerator::generateBonePreviews()
{ {
for (const auto& it : m_boneVertices) { for (const auto& it : m_boneVertices) {
BonePreview bonePreview; BonePreview bonePreview;
std::unordered_map<size_t, size_t> oldToNewVertexMap; std::unordered_map<size_t, size_t> oldToNewVertexMap;
auto addTriangleAsLocal = [&](const std::vector<size_t>& globalTriangle) {
std::vector<size_t> newTriangle(3);
for (size_t i = 0; i < 3; ++i) {
auto findVertex = oldToNewVertexMap.find(globalTriangle[i]);
if (findVertex == oldToNewVertexMap.end()) {
oldToNewVertexMap.insert(std::make_pair(globalTriangle[i], bonePreview.vertices.size()));
newTriangle[i] = bonePreview.vertices.size();
bonePreview.vertices.push_back(m_vertices[globalTriangle[i]]);
} else {
newTriangle[i] = findVertex->first;
}
}
bonePreview.triangles.emplace_back(newTriangle);
};
for (const auto& triangle : m_triangles) { for (const auto& triangle : m_triangles) {
size_t countedPoints = 0; size_t countedPoints = 0;
@ -189,7 +192,7 @@ void BoneGenerator::generateBonePreviews()
} }
if (0 == countedPoints) if (0 == countedPoints)
continue; continue;
addTriangleAsLocal(triangle); addBonePreviewTriangle(bonePreview, oldToNewVertexMap, triangle);
} }
m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview))); m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview)));

View File

@ -30,6 +30,7 @@
#include <dust3d/base/vector3.h> #include <dust3d/base/vector3.h>
#include <map> #include <map>
#include <set> #include <set>
#include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@ -64,14 +65,16 @@ public:
}; };
BoneGenerator(); BoneGenerator();
void generate();
std::map<Uuid, BonePreview>& bonePreviews();
protected:
void setVertices(const std::vector<Vector3>& vertices); void setVertices(const std::vector<Vector3>& vertices);
void setTriangles(const std::vector<std::vector<size_t>>& triangles); void setTriangles(const std::vector<std::vector<size_t>>& triangles);
void setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap); void setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap);
void addBone(const Uuid& boneId, const Bone& bone); void addBone(const Uuid& boneId, const Bone& bone);
void addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBidning); void addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBidning);
void addNode(const Uuid& nodeId, const Node& node); void addNode(const Uuid& nodeId, const Node& node);
void generate();
std::map<Uuid, BonePreview>& bonePreviews();
private: private:
std::vector<Vector3> m_vertices; std::vector<Vector3> m_vertices;
@ -92,6 +95,9 @@ private:
void buildBoneJoints(); void buildBoneJoints();
void assignVerticesToBoneJoints(); void assignVerticesToBoneJoints();
void generateBonePreviews(); void generateBonePreviews();
void addBonePreviewTriangle(BonePreview& bonePreview,
std::unordered_map<size_t, size_t>& oldToNewVertexMap,
const std::vector<size_t>& triangle);
}; };
} }