bone roation causing scaling problems

Topics: User Forum
Mar 21, 2007 at 2:43 PM
Edited Mar 21, 2007 at 2:44 PM
I created a simple robot model.
I then created an animation where it raises its right hand up to its shoulder, bending at the elbow.
To bend the arm, I rotate the bone at the elbow.

The animation executes perfectly in the 9.0c DirectX viewer.
Using the animation component, segments of the the arm mesh scale to be very long or very short, distorting the animation/mesh.

Can anyone offer some advice?

Thanks in advance,
JohnD
Coordinator
Mar 21, 2007 at 6:55 PM
Edited Mar 21, 2007 at 6:56 PM
Could be you are using more than 4 influences per bone. Or it could be something in the in the interpolation code.

Would you mind sending me the model at david_astle@hotmail.com so I can take a look?

If it displays correctly in the directx viewer and has <= 4 influences per vertex, it DEFINITELY should display correctly using the component. This is the first model I've heard of that displays properly in the viewer but not using the component.
Coordinator
Mar 21, 2007 at 8:40 PM
Edited Mar 21, 2007 at 8:45 PM
Mar 21, 2007 at 9:00 PM
Edited Mar 21, 2007 at 9:08 PM
I have the same problem.

I have a very simple model composed by two meshes: head and a body and one animation. If I use the X-File animation importer, the animation gets distorted, if I use the standard XNA X-File importer, the animation's deformations are displayed correctely (at least it looks so) but the head is in the wrong place. The model works perfectely with the DirectX SDK Viewer.

I have emailed you the model, if you would be kind enough to take a look at it.

Thank you

Joao
Coordinator
Mar 22, 2007 at 1:07 AM
Sure, thanks
Coordinator
Mar 22, 2007 at 3:07 AM
Edited Mar 22, 2007 at 3:07 AM
Thanks guys. I fixed the problem and will post a new release when Codeplex lets me. If you're curious, the problem was that I wasn't multiplying the world matrix by the absolute mesh bindpose transform for skinned meshes in ModelAnimator.
Mar 22, 2007 at 4:51 AM
Thanks Dastle! Looking forward for the new release, because I have a feeling it will solve the bone animation problem i described on the other post.

Donny
Coordinator
Mar 22, 2007 at 6:56 PM
Sorry, on further inspection, I'll have to examine the issue further. My code change did not quite solve the problem.
Coordinator
Mar 22, 2007 at 10:56 PM
Edited Mar 22, 2007 at 10:58 PM
The problem is that for some models the absolute mesh transform that was used in the modeling program for the bind pose of the mesh is different than that expressed by the bones in the model. The XNA framework forces us to use the (absolute mesh transform * inverse(absolute bone transform)) to calculate the inverse bind pose, while the directx mesh viewer uses values directly from the files (since the inverse bind pose is stored in the .X files). This will potentially take a lot of thought to solve without resorting to a hack.

Note that these models are rejected by the microsoft skinning example because their geometry is too complicated. I'll just need some time :)
Mar 23, 2007 at 1:53 AM
Thanks for all your hard work Dastle!
I'm currently using Blender to model and FragMotion to bone and animate.
Can anyone recommend a different set of tools that work?

Thanks,
JohnD
Coordinator
Mar 31, 2007 at 5:43 AM
Edited Mar 31, 2007 at 5:43 AM
Well, good news and bad news. The good news is I've found exactly what caused the problem in these cases and came up with a solution. That bad news is that for one of the two issues the solution only currently works when you use the animation library .X importer.

One issue was that I didn't allow the use of more than one skinned mesh in a model. This has been fixed for all importers.

The other issue was related to XNA not passing the processor the correct inverse bind pose. I.E., absolute mesh transform * inverse(absolute bone transform) does not give the correct inverse bind pose in all cases as was claimed on the MSDN forums! I fixed this by passing the correct value from my importer to the processor, but obviously I can't do this for the XNA importers.

I'll try to get it compatible with XNA some more, and then submit the new release.

This has without a doubt been the trickiest issue so far.
Coordinator
Mar 31, 2007 at 8:48 AM
Edited Mar 31, 2007 at 9:18 AM
Just for the hell of it I'm going to go in depth about what the problem is. Maybe somebody will be able to assist me :)

The XNA .X importer bakes the transforms for a model before passing it to a processor.

The pseudo code for that algorithm is:

for (NodeContent node)
{
if (node does not represent a skinned bone)
{
do nothing
}
else
{
node.Transform = (unbaked absolute mesh transform) * (node.AbsoluteTransform) * Invert(node.Parent.AbsoluteTransform);
}

Recurse on each child node.
}

This has the effect of moving the bones to a space relative to their mesh's parent bone. The problem, however, is that the original, unbaked absolute mesh transform is required so that the inverse bind pose of each bone can be correctly computed. Since we are not given this information in the processor, we have to calculate it. I fixed this issue in unreleased code by passing the information from my importer, and using it if it is available. This fix does not apply to the XNA importers, however.

So, the best we can do in our attempt is to try to reconstruct the original skeleton down to at least each absolute mesh transform. From there we can find the unbaked absolute mesh transforms. I'm going to skip the steps for brevity, and show the formula I came up with. If the skeleton above the mesh is transformed to the origin, then:

(unbaked absolute mesh transform)^2 = (baked absolute mesh transform)

And here we arrive at the core of the problem! Finding the square root of a matrix is not a simple problem and I need to do a bit of research to find the solution :) Almost always, a matrix with have multiple square roots. So, it's possible that their isn't a good solution.

I posted this on the XNA forums. I'm very tempted to think this is a rather significant bug in XNA, but I'll just wait till a response.
Coordinator
Apr 1, 2007 at 10:55 PM
No responses. The best solution I could come up with to find the square root is to attempt to decompose the matrix into rotation/scale/translate, and interpolate halfway from the identity matrix/quaternion in each case. This should work in most, but not all, cases. I'll implement this fix, display a warning whenever this case occurs, and then make the next release.
Coordinator
Apr 2, 2007 at 6:00 AM
I've made a new release. The models you emailed to me work if you use the "X File - Animation Library" importer.
Sep 15, 2007 at 8:45 PM
I may be experiencing a similar problem with a model that I did not create. I have the '.x' file, but not the original model. How can I determine if there are more than 4 influences per vertex?

Thanx in advance.