2021SC@SDUSC
目录
分析概括
模块功能
此模块主要用于网格蒙皮的生成以及几何体发生变换后网格蒙皮的更新,在进行位置变换后部分网格发生了数量和位置的变换,而skinnedmeshcreator的功能就在于适配这种变换使任何情况下都形成合适的蒙皮网络

网格蒙皮详解
网格是蒙皮和自由变形的基础,蒙皮的本质也就是让骨骼控制网格上的点。 如果一个点受 N 个骨骼影响,那么这些根骨骼将按百分比,分配谁控制的多,谁控制的少(权重)。在蒙皮的过程中,主要的工作就是让权重值分配的合理。蒙皮的详细过程为:
创建好骨骼和网格点
添加影响骨骼
调整权重。设置权重值:选中指定的点,再指定好它受哪个骨骼影响,然后调值
关键代码分析
SkinnedMeshCreator.h分析
class SkinnedMeshCreator
{
public:
SkinnedMeshCreator(const Object &object,
const std::map<int, RigVertexWeights> &resultWeights);//构造函数
Model *createMeshFromTransform(const std::vector<QMatrix4x4> &matricies);//在变换中创建网格
private:
Object m_object;
std::map<int, RigVertexWeights> m_resultWeights;
std::vector<std::vector<int>> m_verticesOldIndices;//旧索引顶点
std::vector<std::vector<QVector3D>> m_verticesBindPositions;//顶点绑定位置
std::vector<std::vector<QVector3D>> m_verticesBindNormals;//顶点绑定法线
std::vector<QColor> m_triangleColors;//三角面片颜色
};
SkinnedMeshCreator.cpp分析
SkinnedMeshCreator()函数
SkinnedMeshCreator()用于蒙皮网格内变量的初始化、初始属性的设置
SkinnedMeshCreator::SkinnedMeshCreator(const Object &object,const std::map<int, RigVertexWeights> &resultWeights) :m_object(object),m_resultWeights(resultWeights)
{
//对原物体的三角面片信息的size进行resize判断重载
m_verticesOldIndices.resize(m_object.triangles.size());
m_verticesBindNormals.resize(m_object.triangles.size());
m_verticesBindPositions.resize(m_object.triangles.size());
const std::vector<std::vector<QVector3D>> *triangleVertexNormals = m_object.triangleVertexNormals();
for (size_t triangleIndex = 0; triangleIndex < m_object.triangles.size(); triangleIndex++) {
//迭代每一个三角面片
for (int j = 0; j < 3; j++) {
//迭代三角面片每一个点
int oldIndex = m_object.triangles[triangleIndex][j];
m_verticesOldIndices[triangleIndex].push_back(oldIndex);//旧索引顶点后添加oldIndex
m_verticesBindPositions[triangleIndex].push_back(m_object.vertices[oldIndex]);//顶点绑定位置中添加vertices
if (nullptr != triangleVertexNormals)
m_verticesBindNormals[triangleIndex].push_back((*triangleVertexNormals)[triangleIndex][j]);
else
m_verticesBindNormals[triangleIndex].push_back(QVector3D());
}
}
std::map<std::pair<QUuid, QUuid>, QColor> sourceNodeToColorMap;
for (const auto &node: object.nodes)
sourceNodeToColorMap.insert({{node.partId, node.nodeId}, node.color});
//为面片添加颜色,初始为白色
m_triangleColors.resize(m_object.triangles.size(), Theme::white);
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes = object.triangleSourceNodes();
if (nullptr != triangleSourceNodes) {
for (size_t triangleIndex = 0; triangleIndex < m_object.triangles.size(); triangleIndex++) {
const auto &source = (*triangleSourceNodes)[triangleIndex];
m_triangleColors[triangleIndex] = sourceNodeToColorMap[source];//为每一个三角面片赋予颜色
}
}
}
createMeshFromTransform()函数
createMeshFromTransform()用于几何体变换后的网格蒙皮修改操作,通过判断变换前后的位置变换形成新的网格,将旧网格的属性信息进行变换后赋予新网格,从而进行蒙皮的匹配
Model *SkinnedMeshCreator::createMeshFromTransform(const std::vector<QMatrix4x4> &matricies)
{
std::vector<std::vector<QVector3D>> transformedPositions = m_verticesBindPositions;
std::vector<std::vector<QVector3D>> transformedPoseNormals = m_verticesBindNormals;
if (!matricies.empty()) {
//如果矩阵非空,更新变换的位置以及法线
for (size_t i = 0; i < transformedPositions.size(); ++i) {
//循环遍历变换位置信息
for (size_t j = 0; j < 3; ++j) {
const auto &weight = m_resultWeights[m_verticesOldIndices[i][j]];//赋予权重为顶点旧索引的结果权重
QMatrix4x4 mixedMatrix;创建4*4的混合矩阵
transformedPositions[i][j] = QVector3D();
transformedPoseNormals[i][j] = QVector3D();
for (int x = 0; x < MAX_WEIGHT_NUM; x++) {
float factor = weight.boneWeights[x];
if (factor > 0) {
//生成变换后的位置以及法线
transformedPositions[i][j] += matricies[weight.boneIndices[x]] * m_verticesBindPositions[i][j] * factor;
transformedPoseNormals[i][j] += matricies[weight.boneIndices[x]] * m_verticesBindNormals[i][j] * factor;
}
}
}
}
}
ShaderVertex *triangleVertices = new ShaderVertex[m_object.triangles.size() * 3];
int triangleVerticesNum = 0;
for (size_t triangleIndex = 0; triangleIndex < m_object.triangles.size(); triangleIndex++) {
for (int i = 0; i < 3; i++) {
//设置变换后的颜色、位置、顶点、法线信息
ShaderVertex ¤tVertex = triangleVertices[triangleVerticesNum++];
const auto &sourcePosition = transformedPositions[triangleIndex][i];
const auto &sourceColor = m_triangleColors[triangleIndex];
const auto &sourceNormal = transformedPoseNormals[triangleIndex][i];
currentVertex.posX = sourcePosition.x();
currentVertex.posY = sourcePosition.y();
currentVertex.posZ = sourcePosition.z();
currentVertex.texU = 0;
currentVertex.texV = 0;
currentVertex.colorR = sourceColor.redF();
currentVertex.colorG = sourceColor.greenF();
currentVertex.colorB = sourceColor.blueF();
currentVertex.normX = sourceNormal.x();
currentVertex.normY = sourceNormal.y();
currentVertex.normZ = sourceNormal.z();
currentVertex.metalness = Model::m_defaultMetalness;
currentVertex.roughness = Model::m_defaultRoughness;
}
}
return new Model(triangleVertices, triangleVerticesNum);//返回新模型
}
本文档介绍了Dust3D项目中的SkinnedMeshCreator模块,该模块专注于网格蒙皮的生成和更新,特别是在几何体变换后的适应。网格蒙皮涉及骨骼对网格点的权重控制,SkinnedMeshCreator通过createMeshFromTransform函数实现变换后的蒙皮匹配,确保在任何情况下都能得到合适的蒙皮效果。
468

被折叠的 条评论
为什么被折叠?



