Reputation: 559
I am exporting models that use an old method of animation. Every bone in the skeletal mesh has a translation and rotation value which are local. In Unity, I can set the local position of each submesh and the model looks correct at every frame.
I am now trying to export these meshes from my C# program using glmsharp and am getting strange visual exports. I use the model export code elsewhere and it works so we will assume the issue is in the translation and rotation of the submesh vertices.
This is my approach:
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);
}
}
This function iterates the skeleton recursively. When invoking this method, I pass in an identity mat4. This function figures out the translation matrix and then the rotation matrix (Rotation is a quaternion). I then combine them into the model matrix, combine it again with the parent matrix and then shift and rotate vertices in each submesh. Then for any connected pieces (children), I recursively call this function with the combine matrix.
The code I use to actual modify the vertex values is pretty straightforward:
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;
}
}
I convert the vertex to a vec4, and multiply it by the combined model matrix. Again, this logic should mimic the way Unity handles local rotations. Not sure where I went wrong. I think it has something to do with the rotation matrix.
Upvotes: 1
Views: 516
Reputation: 559
Played around a bit more with it and realized I had everything right except the final operation. It should have been parentMatrix * modelMatrix
when combining them. Andrea also suggested this in a comment. Thank you!
Upvotes: 1