Advertisement

Skinning question

Started by May 10, 2023 06:34 PM
4 comments, last by RobM 1 year, 5 months ago

I'm just trying to import some Mixamo animations into my engine. They seems to use right-handedness which means, for me, scaling in the z axis by -1 as my engine is left-handed. I can actually get this to work, skeleton renders fine and the inverse bind matrices seem to be okay, but I seem to have to scale the animation matrices after I linearly interpolate them in order for it all to render correctly.

What I'd like to do is get everything scaled at the import stage so the mesh and animation just appears correctly without having to mess about with scaling further down the line. The problem I have is with my matrix interpolation code. If I take in two almost identical animation matrices (representing frame 1 and 2 for example), when I decompose them into scale, translation and quaternion (using XMMatrixDecompose), the quaternions look vastly different and slerping and converting them to matrices just doesn't work at all.

Has anyone tried to decompose non-uniformly scaled matrices in this way before? I can't fathom why just because they're scaled Z -1 that the resulting quaternions would be so different. Like different values and signs.

Is there a better way of doing this, i.e. converting handedness?

AFAIK you shouldn't be decomposing or interpolating matrices directly, you should interpolate each component separately (position, rotation, scale), then build the final matrix once using those interpolated values. Then you should be able to negate position.z and scale.z to change to left handed. This would correspond to negating the 3rd row of the final matrix (could also be 3rd column, depending on conventions).

I know you're probably already committed to left handedness, but why? All of math and physics uses the right-hand rule. In math class, X points right, Y points up, and Z points out of the page. By using left handedness you are saying Z points into the page instead, which makes it at odds with how the majority of the world handles coordinate systems. Due to this, left handedness and conversions between handedness are a huge source of headache (as you have experienced). I think we can blame DirectX for poisoning the waters here long ago.

Advertisement

Thanks for the post. I'm decomposing the animation matrix in order to interpolate each component separately. This does work fine, I mean if I negate the 3rd row after I've done all my matrix blending, but I just didn't want to ‘muddy the waters' in the engine by having to check per object whether it needs to be scaled by -1 in Z just because of handedness differences.

I hadn't thought of that to be honest, when I were a young lad, tinkering about with software renderers (a lonnnnng time ago), I just always envisaged x right, y up and z away from me. It makes more sense to me that z gets higher into the screen, mostly due to the fact that it's literally the directly you're looking in (if your head had its own orientation). undoing 30+ years of thinking that might be tricky.

So are you saying most game engines and games use right-handed (z+ out of the screen)? I haven't checked, but when I've seen tutorials of people importing Mixamo characters and animations into Unreal, they don't have to faff about with z-reversing.

Here is what I do. Given an transformation T to import some model (geometry, skeleton, animation clips)

  1. I transform the vertex positions with T
  2. I transform the vertex normals with T.Rotation
  3. I transform the the matrices M by T * M * inverse( T )

Let v' be the original vertex and v be the transformed one (after import). Hence v = T v'. So during skinning you apply conceptually these transformations T * M * inverse( T ) * T * v'. Try to understand what the transformation sequence does. You basically undo the import transformation, Then you apply the original transform and finally you transform into you desired space. This is what you want to happen.

HTH,

-Dirk

@Aressera I just noticed that Blender is X+ right, Z+ up and Y+ into the screen (away from the viewer). One thing that I'm really confused about is that the mesh and animation I downloaded from Mixamo is X+ right, Y+ up and Z- into the screen, so essentially right-handed. When I load it into Blender, it appears to be facing the viewer, i.e. the model is facing in the negative, what would be Z, direction (it's actually Y in this case).

So somehow, Blender knows how to orient this model but the only orientation-like metadata in the Collada file is “Y_UP”! Actually, all I think it's done is rotate it around the X axis by 90 degrees. if you undo that it puts it back in Mixamo space.

This topic is closed to new replies.

Advertisement