Implement bone vertex weights calculation
parent
b906409ab9
commit
f70dbc47ae
|
@ -37,6 +37,14 @@ void BoneGenerator::process()
|
||||||
|
|
||||||
for (const auto& it : m_snapshot->boneIdList) {
|
for (const auto& it : m_snapshot->boneIdList) {
|
||||||
Bone bone;
|
Bone bone;
|
||||||
|
auto findBone = m_snapshot->bones.find(it);
|
||||||
|
if (findBone == m_snapshot->bones.end())
|
||||||
|
continue;
|
||||||
|
for (const auto& nodeIdString : dust3d::String::split(dust3d::String::valueOrEmpty(findBone->second, "jointNodeIdList"), ',')) {
|
||||||
|
if (nodeIdString.empty())
|
||||||
|
continue;
|
||||||
|
bone.joints.push_back(dust3d::Uuid(nodeIdString));
|
||||||
|
}
|
||||||
addBone(dust3d::Uuid(it), bone);
|
addBone(dust3d::Uuid(it), bone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,11 +127,6 @@ void BoneGenerator::buildBoneJoints()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoneGenerator::assignVerticesToBoneJoints()
|
|
||||||
{
|
|
||||||
// TODO:
|
|
||||||
}
|
|
||||||
|
|
||||||
void BoneGenerator::groupBoneVertices()
|
void BoneGenerator::groupBoneVertices()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
|
for (size_t i = 0; i < m_vertexSourceNodes.size(); ++i) {
|
||||||
|
@ -147,13 +142,53 @@ void BoneGenerator::groupBoneVertices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BoneGenerator::calculateBoneVertexWeights(const Uuid& boneId, Bone& bone)
|
||||||
|
{
|
||||||
|
auto findBoneVertices = m_boneVertices.find(boneId);
|
||||||
|
if (findBoneVertices == m_boneVertices.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::unordered_set<size_t>> segments(bone.startPositions.size());
|
||||||
|
|
||||||
|
// Split bone vertices by joint position and forward direction
|
||||||
|
for (size_t jointIndex = 0; jointIndex + 1 < bone.startPositions.size(); ++jointIndex) {
|
||||||
|
const auto& nextJointPosition = bone.startPositions[jointIndex + 1];
|
||||||
|
auto forwardDirection = bone.forwardVectors[jointIndex].normalized();
|
||||||
|
for (const auto& vertex : findBoneVertices->second) {
|
||||||
|
const auto& vertexPosition = m_vertices[vertex];
|
||||||
|
if (Vector3::dotProduct(forwardDirection, (vertexPosition - nextJointPosition).normalized()) <= 0.0) {
|
||||||
|
segments[jointIndex].insert(vertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bone.vertexWeights.resize(bone.startPositions.size());
|
||||||
|
for (size_t jointIndex = 0; jointIndex < bone.startPositions.size(); ++jointIndex) {
|
||||||
|
for (const auto& it : segments[jointIndex])
|
||||||
|
bone.vertexWeights[jointIndex].push_back(VertexWeight { it, 1.0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate joint radius based on group all the boundary vertices,
|
||||||
|
// and use these vertices as points of sphere,
|
||||||
|
// boundary vertices means the edge connected these vertices in different bone vertex split
|
||||||
|
// Use m_triangles which contains all triangles to find the edges of vertices
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
// Weight vertex as normal when not in joint radius range
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
// Weight vertex as joint radius considered
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
void BoneGenerator::generate()
|
void BoneGenerator::generate()
|
||||||
{
|
{
|
||||||
buildEdges();
|
buildEdges();
|
||||||
resolveVertexSources();
|
resolveVertexSources();
|
||||||
groupBoneVertices();
|
groupBoneVertices();
|
||||||
buildBoneJoints();
|
buildBoneJoints();
|
||||||
assignVerticesToBoneJoints();
|
for (auto& boneIt : m_boneMap)
|
||||||
|
calculateBoneVertexWeights(boneIt.first, boneIt.second);
|
||||||
generateBonePreviews();
|
generateBonePreviews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +263,14 @@ void BoneGenerator::generateBonePreviews()
|
||||||
auto findBone = m_boneMap.find(it.first);
|
auto findBone = m_boneMap.find(it.first);
|
||||||
if (findBone == m_boneMap.end())
|
if (findBone == m_boneMap.end())
|
||||||
continue;
|
continue;
|
||||||
const auto& color = s_colors[findBone->second.index % s_colors.size()];
|
const auto& color = s_colors[(findBone->second.index) % s_colors.size()];
|
||||||
for (const auto& vertexIndex : it.second)
|
const auto& alternativeColor = s_colors[(findBone->second.index + s_colors.size() / 2) % s_colors.size()];
|
||||||
vertexSkinColors[vertexIndex].push_back(color);
|
for (size_t jointIndex = 0; jointIndex < findBone->second.vertexWeights.size(); ++jointIndex) {
|
||||||
|
const auto& useColor = 0 == jointIndex % 2 ? color : alternativeColor;
|
||||||
|
for (const auto& vertexWeight : findBone->second.vertexWeights[jointIndex]) {
|
||||||
|
vertexSkinColors[vertexWeight.vertex].push_back(useColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::vector<Color> bodyVertexColors(m_vertices.size());
|
std::vector<Color> bodyVertexColors(m_vertices.size());
|
||||||
for (const auto& it : vertexSkinColors) {
|
for (const auto& it : vertexSkinColors) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
std::vector<Uuid> joints;
|
std::vector<Uuid> joints;
|
||||||
std::vector<Vector3> startPositions;
|
std::vector<Vector3> startPositions;
|
||||||
std::vector<Vector3> forwardVectors;
|
std::vector<Vector3> forwardVectors;
|
||||||
std::vector<VertexWeight> vertexWeights;
|
std::vector<std::vector<VertexWeight>> vertexWeights;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Node {
|
struct Node {
|
||||||
|
@ -97,12 +97,12 @@ private:
|
||||||
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 assignVerticesToBoneJoints();
|
|
||||||
void generateBonePreviews();
|
void generateBonePreviews();
|
||||||
void addBonePreviewTriangle(BonePreview& bonePreview,
|
void 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,
|
||||||
const Color& color);
|
const Color& color);
|
||||||
|
void calculateBoneVertexWeights(const Uuid& boneId, Bone& bone);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue