Custom Character and Animation - Chapter 24: Character Animation

I’m trying to debug an issue I have for a skinned mesh that plays its animation perfectly fine in Reality Converter, but in the simulator the mesh gets stretched out. Below is an image of Skelly working fine, but not the Ninja. Is it because Skelly is using less bones? The code looks generic to me, like it should be able to handle a different type of skeleton. (Is there a reason Skelly is waving with its right arm in the simulator but waving with its left arm in Reality Converter?)


@nekohno - hi and welcome to the forums!

I tried the code out with quite a few models, but there are very likely models with certain configurations that don’t work. Is it a model you can share so that I can look at it?

As to the left to right, that’s mentioned in Chapter 16, GPU Compute Programming:

… due to both math and file formats. In Chapter 6, “Coordinate Spaces”, you learned that this book uses a left-handed coordinate system. This USD file expects a right-handed coordinate system.

2 Likes

Hi @caroline, the model is from Synty Studios. Their assets are quite popular. They have some free packs with characters such as POLYGON Santa Pack and POLYGON Starter Pack Synty Store Free Assets. They have files for Unity, Unreal, and SourceFiles. What I did was upload the character FBX from SourceFiles to Mixamo, then download the FBX with animation, then use the Reality Converter.

Thanks for those details. I’ve downloaded a cat-walking Santa, and that’s quite a problem we have! It’s tough code, so it’ll probably take me a while to correct it, but I’m very grateful that you pointed it out.

Blender and Cheetah 3D don’t like the .fbx file, and I’m surprised that Reality Converter does so well with it.

1 Like

I see, thank you. I appreciate that you took the time to reproduce the problem!

1 Like

@nekohno - So many matrices :sweat_smile:!

Synty’s Santa with a Mixamo catwalk went from this:

To this:

So I think this is working, if you’d like to give it a try.

Animation.zip (3.8 MB)

The problem is that I’m not implementing USD fully. That would take a lot of code. So there will always be models that don’t work. But this is a better implementation and will take into account more models.

Here are the code changes:

  1. Add scaling to key values (AnimationClip, Animation).
  2. Change Skin to take into account the geometry bind transform.
  3. Add a new set of transforms to Skin that multiply Skeleton’s inverse bind pose with the geometry bind pose.
  4. In Skeleton, remove applying the inverse bind pose.
  5. In Skin, when updating the joint matrix palette, update the skeleton world pose with the new geometry bind transform.

Notes:

  1. Scaling isn’t as usual in animations as rotations and translations, but these models scale the root right down.
  2. geomBindTransform in the USD format is “an optional property to define the space for skinning” (OpenUSD). In my converted Santa model, this scaled the space by 0.01. (Btw, somewhere in the USD spec, it recommends all scalings to be linear (ie all 3 axes are scaled the same).)
  3. Scale down the skeleton’s inverse bind pose into the skinned space.
  4. You’ll multiply the current pose by the bind pose when updating the joint matrix palette in Skin, so remove that part from Skeleton.
  5. In Skin, multiply the skeleton’s current pose by the newly scaled inverse bind pose.

I hope this helps and the Ninja can wield his weapons instead of turning into a crumpled heap.

If you’re interested in taking this further and exploring the USD skeleton schema, here’s the link:

https://openusd.org/dev/api/usd_skel_page_front.html

1 Like

@caroline Can confirm it works! Thank you!

1 Like