【发布时间】:2016-04-18 14:19:09
【问题描述】:
我正在从事一个具有以下目标的项目:
- 使用 Assimp.NET 加载装配好的 3D 网格(例如人体骨骼)
- 处理网格骨骼,使其适合您自己的身体(使用 Microsoft Kinect v2)
- 执行顶点蒙皮
加载绑定网格和提取骨骼信息(希望)没有任何问题(基于本教程:http://www.richardssoftware.net/2013/10/skinned-models-in-directx-11-with.html)。每个骨骼(“ModelBone”类)包含以下信息:
Assimp.Matrix4x4 LocalTransform
Assimp.Matrix4x4 GlobalTransform
Assimp.Matrix4x4 Offset
LocalTransform是直接从assimp节点(node.Transform)中提取出来的。
GlobalTransform 包括自己的LocalTransform 和所有父母的LocalTransform(见代码截断calculateGlobalTransformation())。
Offset 直接从 assimp bone (bone.OffsetMatrix) 中提取。
目前我没有实现 GPU 顶点蒙皮,但我遍历每个顶点并操纵它的位置和法线向量。
foreach (Vertex vertex in this.Vertices)
{
Vector3D newPosition = new Vector3D();
Vector3D newNormal = new Vector3D();
for (int i=0; i < vertex.boneIndices.Length; i++)
{
int boneIndex = vertex.boneIndices[i];
float boneWeight = vertex.boneWeights[i];
ModelBone bone = this.BoneHierarchy.Bones[boneIndex];
Matrix4x4 finalTransform = bone.GlobalTransform * bone.Offset;
// Calculate new vertex position and normal
newPosition += boneWeight * (finalTransform * vertex.originalPosition);
newNormal += boneWeight * (finalTransform * vertex.originalNormal);
}
// Apply new vertex position and normal
vertex.position = newPosition;
vertex.normal = newNormal;
}
就像我已经说过的,我想使用 Kinect v2 传感器来操作骨骼,所以我不必使用动画(例如,插入关键帧,...)!但一开始我希望能够手动操作骨骼(例如将网格的躯干旋转 90 度)。因此,我通过调用Assimp.Matrix4x4.FromRotationX(1.5708f); 创建了一个 4x4 旋转矩阵(围绕 x 轴 90 度)。然后我用这个旋转矩阵替换骨骼的LocalTransform:
Assimp.Matrix4x4 rotation = Assimp.Matrix4x4.FromRotationX(1.5708f);
bone.LocalTransform = rotation;
UpdateTransformations(bone);
骨骼操作后,我使用以下代码计算骨骼的新 GlobalTransform 及其子骨骼:
public void UpdateTransformations(ModelBone bone)
{
this.calculateGlobalTransformation(bone);
foreach (var child in bone.Children)
{
UpdateTransformations(child);
}
}
private void calculateGlobalTransformation(ModelBone bone)
{
// Global transformation includes own local transformation ...
bone.GlobalTransform = bone.LocalTransform;
ModelBone parent = bone.Parent;
while (parent != null)
{
// ... and all local transformations of the parent bones (recursively)
bone.GlobalTransform = parent.LocalTransform * bone.GlobalTransform;
parent = parent.Parent;
}
}
这种方法会产生这个image。转换似乎正确地应用于所有子骨骼,但被操纵的骨骼围绕世界空间原点而不是围绕其自己的局部空间旋转:(我已经尝试将GlobalTransform 翻译(GlobalTransform 的最后一行)包含到之前的旋转矩阵设置为LocalTransform,但是没有成功...
希望有人能帮我解决这个问题!
提前致谢!
【问题讨论】: