Fix bone preview mesh
parent
03f1440e7d
commit
6e53452dc8
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue