【发布时间】:2019-12-06 21:00:15
【问题描述】:
我正在导出使用旧动画方法的模型。骨架网格物体中的每个骨骼都有一个局部的平移和旋转值。在 Unity 中,我可以设置每个子网格的本地位置,并且模型在每一帧看起来都是正确的。
我现在尝试使用 glmsharp 从我的 C# 程序中导出这些网格,并且得到了奇怪的视觉导出。我在其他地方使用模型导出代码,它可以工作,所以我们假设问题出在子网格顶点的平移和旋转中。
这是我的方法:
public void ShiftSkeletonValues(List<SkeletonNode> skeleton, List<BoneTrack> boneTracks,
mat4 parentMatrix, int index, int frame, ILogger logger)
{
mat4 translationMatrix = mat4.Translate(boneTracks[index]._frames[frame].Translation);
mat4 rotationMatrix = glm.ToMat4(boneTracks[index]._frames[frame].Rotation);
mat4 modelMatrix = translationMatrix * rotationMatrix;
mat4 combinedMatrix = modelMatrix * parentMatrix;
ShiftAndRotateVertices(combinedMatrix, index, logger);
foreach (var pieces in skeleton[index].Children)
{
ShiftSkeletonValues(skeleton, boneTracks, combinedMatrix, pieces, frame, logger);
}
}
这个函数递归地迭代骨架。调用此方法时,我传入了一个标识 mat4。该函数计算出平移矩阵,然后计算出旋转矩阵(Rotation 是一个四元数)。然后我将它们组合到模型矩阵中,再次将其与父矩阵组合,然后在每个子网格中移动和旋转顶点。然后对于任何连接的部分(孩子),我用组合矩阵递归地调用这个函数。
我用来实际修改顶点值的代码非常简单:
private void ShiftAndRotateVertices(mat4 combineModelMatrix, int index, ILogger logger)
{
MobVertexPiece mobPiece = MobPieces[index];
for (int i = 0; i < mobPiece.Count; ++i)
{
var position = Vertices[mobPiece.Start + i];
vec4 newPosition = new vec4(position, 1.0f);
vec4 shiftedPosition = combineModelMatrix * newPosition;
Vertices[mobPiece.Start + i] = shiftedPosition.xyz;
}
}
我将顶点转换为 vec4,并将其乘以组合模型矩阵。同样,这个逻辑应该模仿 Unity 处理局部旋转的方式。不知道我哪里出错了。我认为这与旋转矩阵有关。
【问题讨论】:
-
您是否检查过矩阵是否以正确的顺序相乘?我不记得我脑海中的正确顺序是什么,但请记住,对于矩阵乘法,
A * B不与B * A相同。 -
@Andrea 就是这样。
标签: c# unity3d opengl glm-math