Hi!
I'm currently trying to implement Bone animation using SharpDX and Assimp (loading a COLLADA file exported from Blender).
I've gotten to a point where I can visualize the bone nodes and their animation with simple cubes (disregard the strange shading) to a certain extent. It still seems that the position and scaling of the skeleton differs from position & scaling of the actual mesh, but I think that doesn't seem to have an effect on the final vertex positions.
The animation itself seems to have some effect on the vertices as well. The strange thing is, while the cubes used to visualize the bone structure seem to rotate to a full extent, the vertices themselves barely move. You can see that some movement is occurring (probably even in the right direction) but not to the extent of what the actual animation's supposed to look like. I feel like I'm missing a simple matrix multiplication here, but for the love of god, I can't figure out where or which. If you'd kindly have a look at my code and see if you can find something wrong with the calculations, I'd be very grateful! If you need any additional pieces of code, just tell me!
This is what the mesh looks like while animating (also notice the strange rotation, I guess that's just a bug of Assimp/the COLLADA exporter of Blender):

Note that both wing bones are rotated upward. The wings' vertices though are barely rotating at all (you have to zoom in to actually see them move).
Here's the code that renders the model:
private void RenderSkinnedAnimation(ImportedMesh skeletalMesh, Transform transform)
{
skeletalMesh.ActiveAnimation.CurrentTime += 0.01;
skeletalMesh.ActiveAnimation.ComputeNodeTransforms(skeletalMesh.RootNode);
RenderDebugMeshes(skeletalMesh.RootNode, Matrix.Identity);
var boneMatrices = new Matrix[skeletalMesh.Bones.Count];
/* Calculate bone matrices */
for (int i = 0; i < skeletalMesh.Bones.Count; i++)
{
Matrix4x4 boneTransform = skeletalMesh.Bones.Definition.OffsetMatrix;
MeshNode node = skeletalMesh.RootNode.FindNode(b => b.Name == skeletalMesh.Bones.Definition.Name);
boneTransform.Transpose();
boneMatrices = Util.GraphicsHelper.ConvertAssimp2DX(boneTransform);
while (node.Parent != null)
{
boneMatrices = node.AnimTransform * boneMatrices;
node = node.Parent;
}
}
var resultPos = new Vector3[skeletalMesh.Mesh.VertexCount];
var resultNorm = new Vector3[skeletalMesh.Mesh.VertexCount];
var finalVertices = (Vertex[])skeletalMesh.Mesh.Vertices.Clone();
for(int i = 0; i < skeletalMesh.Mesh.VertexCount; i++)
{
resultPos = skeletalMesh.Mesh.Vertices.Position;
}
/* Calculate final vertex positions by vertex weight and bone matrices */
for(int i = 0; i < skeletalMesh.Bones.Count; i++)
{
for(int c = 0; c < skeletalMesh.Bones.Definition.VertexWeightCount; c++)
{
var weight = skeletalMesh.Bones.Definition.VertexWeights[c];
resultPos[weight.VertexID] += weight.Weight * Vector3.TransformCoordinate(skeletalMesh.Mesh.Vertices[weight.VertexID].Position, boneMatrices);
}
}
for(int i = 0; i < skeletalMesh.Mesh.VertexCount; i++)
{
finalVertices.Position = resultPos;
}
skeletalMesh.Mesh.UpdateVertexBuffer(finalVertices);
skeletalMesh.Mesh.Render(Matrix.Scaling(transform.Scale) * Matrix.Translation(transform.Position));
}
I'm updating my vertex array manually atm, this will be outsourced to a shader as soon as I get the animation to work on the CPU.
I've been taking inspiration from the code snippets posted over on this post in Assimp's forum.
It'd be awesome if someone could help me out!
Best Regards
Philipp
