Generate bone previews
parent
995230db59
commit
374f16038d
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dust3d/rig/skeleton_generator.h>
|
#include <dust3d/rig/skeleton_generator.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace dust3d {
|
namespace dust3d {
|
||||||
|
|
||||||
|
@ -33,9 +34,9 @@ void SkeletonGenerator::setVertices(const std::vector<Vector3>& vertices)
|
||||||
m_vertices = vertices;
|
m_vertices = vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::setFaces(const std::vector<std::vector<size_t>>& faces)
|
void SkeletonGenerator::setTriangles(const std::vector<std::vector<size_t>>& triangles)
|
||||||
{
|
{
|
||||||
m_faces = faces;
|
m_triangles = triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap)
|
void SkeletonGenerator::setPositionToNodeMap(const std::map<PositionKey, Uuid>& positionToNodeMap)
|
||||||
|
@ -48,6 +49,11 @@ void SkeletonGenerator::addBone(const Uuid& boneId, const Bone& bone)
|
||||||
m_boneMap.emplace(std::make_pair(boneId, bone));
|
m_boneMap.emplace(std::make_pair(boneId, bone));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkeletonGenerator::addNode(const Uuid& nodeId, const Node& node)
|
||||||
|
{
|
||||||
|
m_nodeMap.emplace(std::make_pair(nodeId, node));
|
||||||
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBinding)
|
void SkeletonGenerator::addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBinding)
|
||||||
{
|
{
|
||||||
m_nodeBindingMap.emplace(std::make_pair(nodeId, nodeBinding));
|
m_nodeBindingMap.emplace(std::make_pair(nodeId, nodeBinding));
|
||||||
|
@ -55,11 +61,11 @@ void SkeletonGenerator::addNodeBinding(const Uuid& nodeId, const NodeBinding& no
|
||||||
|
|
||||||
void SkeletonGenerator::buildEdges()
|
void SkeletonGenerator::buildEdges()
|
||||||
{
|
{
|
||||||
for (const auto& face : m_faces) {
|
for (const auto& triangle : m_triangles) {
|
||||||
for (size_t i = 0; i < face.size(); ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
size_t j = (i + 1) % face.size();
|
size_t j = (i + 1) % 3;
|
||||||
m_edges[face[i]].insert(face[j]);
|
m_edges[triangle[i]].insert(triangle[j]);
|
||||||
m_edges[face[j]].insert(face[i]);
|
m_edges[triangle[j]].insert(triangle[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,17 +110,29 @@ void SkeletonGenerator::resolveVertexSources()
|
||||||
|
|
||||||
void SkeletonGenerator::buildBoneJoints()
|
void SkeletonGenerator::buildBoneJoints()
|
||||||
{
|
{
|
||||||
// TODO:
|
for (auto& boneIt : m_boneMap) {
|
||||||
|
boneIt.second.startPositions.resize(boneIt.second.joints.size());
|
||||||
|
for (size_t i = 0; i < boneIt.second.joints.size(); ++i) {
|
||||||
|
const auto& nodeId = boneIt.second.joints[i];
|
||||||
|
auto nodeIt = m_nodeMap.find(nodeId);
|
||||||
|
if (nodeIt == m_nodeMap.end())
|
||||||
|
continue;
|
||||||
|
boneIt.second.startPositions[i] = nodeIt->second.position;
|
||||||
|
}
|
||||||
|
boneIt.second.forwardVectors.resize(boneIt.second.startPositions.size());
|
||||||
|
for (size_t i = 0; i + 1 < boneIt.second.startPositions.size(); ++i) {
|
||||||
|
boneIt.second.forwardVectors[i] = boneIt.second.startPositions[i + 1] - boneIt.second.startPositions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::assignBoneJointToVertices()
|
void SkeletonGenerator::assignVerticesToBoneJoints()
|
||||||
{
|
{
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::groupBoneVertices()
|
void SkeletonGenerator::groupBoneVertices()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
|
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
|
||||||
const Uuid& sourceNodeId = m_vertexSourceNodes[i];
|
const Uuid& sourceNodeId = m_vertexSourceNodes[i];
|
||||||
if (sourceNodeId.isNull())
|
if (sourceNodeId.isNull())
|
||||||
|
@ -122,19 +140,55 @@ void SkeletonGenerator::groupBoneVertices()
|
||||||
auto findBinding = m_nodeBindingMap.find(sourceNodeId);
|
auto findBinding = m_nodeBindingMap.find(sourceNodeId);
|
||||||
if (findBinding == m_nodeBindingMap.end())
|
if (findBinding == m_nodeBindingMap.end())
|
||||||
continue;
|
continue;
|
||||||
// TODO:
|
for (const auto& boneId : findBinding->second.boneIds) {
|
||||||
|
m_boneVertices[boneId].insert(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// TODO:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonGenerator::bind()
|
void SkeletonGenerator::generate()
|
||||||
{
|
{
|
||||||
buildEdges();
|
buildEdges();
|
||||||
resolveVertexSources();
|
resolveVertexSources();
|
||||||
groupBoneVertices();
|
groupBoneVertices();
|
||||||
buildBoneJoints();
|
buildBoneJoints();
|
||||||
assignBoneJointToVertices();
|
assignVerticesToBoneJoints();
|
||||||
|
generateBonePreviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkeletonGenerator::generateBonePreviews()
|
||||||
|
{
|
||||||
|
for (const auto& it : m_boneVertices) {
|
||||||
|
BonePreview bonePreview;
|
||||||
|
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) {
|
||||||
|
size_t countedPoints = 0;
|
||||||
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
|
if (it.second.end() != it.second.find(triangle[i]))
|
||||||
|
++countedPoints;
|
||||||
|
}
|
||||||
|
if (0 == countedPoints)
|
||||||
|
continue;
|
||||||
|
addTriangleAsLocal(triangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bonePreviews.emplace(std::make_pair(it.first, std::move(bonePreview)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#ifndef DUST3D_RIG_SKELETON_GENERATOR_H_
|
#ifndef DUST3D_RIG_SKELETON_GENERATOR_H_
|
||||||
#define DUST3D_RIG_SKELETON_GENERATOR_H_
|
#define DUST3D_RIG_SKELETON_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <dust3d/base/color.h>
|
||||||
#include <dust3d/base/position_key.h>
|
#include <dust3d/base/position_key.h>
|
||||||
#include <dust3d/base/uuid.h>
|
#include <dust3d/base/uuid.h>
|
||||||
#include <dust3d/base/vector3.h>
|
#include <dust3d/base/vector3.h>
|
||||||
|
@ -36,37 +38,59 @@ namespace dust3d {
|
||||||
class SkeletonGenerator {
|
class SkeletonGenerator {
|
||||||
public:
|
public:
|
||||||
struct NodeBinding {
|
struct NodeBinding {
|
||||||
std::vector<Uuid> boneIds;
|
std::set<Uuid> boneIds;
|
||||||
bool bontJoint = false;
|
};
|
||||||
|
|
||||||
|
struct VertexWeight {
|
||||||
|
size_t vertex;
|
||||||
|
double weight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Bone {
|
struct Bone {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::vector<Uuid> joints;
|
||||||
|
std::vector<Vector3> startPositions;
|
||||||
|
std::vector<Vector3> forwardVectors;
|
||||||
|
std::vector<VertexWeight> vertexWeights;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
Vector3 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BonePreview {
|
||||||
|
std::vector<Vector3> vertices;
|
||||||
|
std::vector<std::vector<size_t>> triangles;
|
||||||
};
|
};
|
||||||
|
|
||||||
SkeletonGenerator();
|
SkeletonGenerator();
|
||||||
void setVertices(const std::vector<Vector3>& vertices);
|
void setVertices(const std::vector<Vector3>& vertices);
|
||||||
void setFaces(const std::vector<std::vector<size_t>>& faces);
|
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& nodeBinding);
|
void addNodeBinding(const Uuid& nodeId, const NodeBinding& nodeBidning);
|
||||||
void bind();
|
void addNode(const Uuid& nodeId, const Node& node);
|
||||||
|
void generate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Vector3> m_vertices;
|
std::vector<Vector3> m_vertices;
|
||||||
std::vector<std::vector<size_t>> m_faces;
|
std::vector<std::vector<size_t>> m_triangles;
|
||||||
std::map<PositionKey, Uuid> m_positionToNodeMap;
|
std::map<PositionKey, Uuid> m_positionToNodeMap;
|
||||||
std::map<Uuid, NodeBinding> m_nodeBindingMap;
|
std::map<Uuid, NodeBinding> m_nodeBindingMap;
|
||||||
std::map<Uuid, Bone> m_boneMap;
|
std::map<Uuid, Bone> m_boneMap;
|
||||||
|
std::map<Uuid, Node> m_nodeMap;
|
||||||
std::map<size_t, std::set<size_t>> m_edges;
|
std::map<size_t, std::set<size_t>> m_edges;
|
||||||
std::vector<Uuid> m_vertexSourceNodes;
|
std::vector<Uuid> m_vertexSourceNodes;
|
||||||
|
std::map<Uuid, std::unordered_set<size_t>> m_boneVertices;
|
||||||
|
std::map<Uuid, BonePreview> m_bonePreviews;
|
||||||
|
|
||||||
void buildEdges();
|
void buildEdges();
|
||||||
void resolveVertexSources();
|
void resolveVertexSources();
|
||||||
Uuid resolveVertexSourceByBreadthFirstSearch(size_t vertexIndex, std::unordered_set<size_t>& visited);
|
Uuid resolveVertexSourceByBreadthFirstSearch(size_t vertexIndex, std::unordered_set<size_t>& visited);
|
||||||
void groupBoneVertices();
|
void groupBoneVertices();
|
||||||
void buildBoneJoints();
|
void buildBoneJoints();
|
||||||
void assignBoneJointToVertices();
|
void assignVerticesToBoneJoints();
|
||||||
|
void generateBonePreviews();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue