Retargeting in maya

Hi @yann.b, did you finally to manage this? Which was the issue? Many thanks

Hi @eyechol
I did not. :sweat_smile:
Iā€™m still working on it though (in my free time)

I think I have a better understanding of matrix but it still not working.

Our rigging team dealt with retargeting legacy rigs onto new rigs (with new joint orients & rotations ).
We didnā€™t have to retarget scale, but maybe our approach will be helpful.
We basically built a 3rd rig just for transfer purposes, and used locators to store orient offsets.
This is similar @tfox_TD suggestion.

assuming you are transferring skeletons only:

1.) put the source (old) skeleton and the target (new) skeleton in the same pose
Their joints line up, even though the orients differ.

2.) duplicate the source rig to make a transfer rig
3.) create locators at each joint of the transfer rig
4.) point constrain (no offset) the locators to the transfer rig joints
5.) orient constrain (no offset) the locators to the target rig joints.
6.) Delete all the locator point and orient constraints

now the locators match position of the source but orientation of the target.
They basically store the matrix transforms @Munkybutt mentions (without scale)

7.) parent constrain (keep offset) locators to the joints of the transfer rig
8.) parent constrain (no offset) the transfer rig joints to the source rig joints
9.) parent constrain (no offset) the target rig joints to the transfer rig locators

now the target rig joints will follow the source rig, but have the orientation of the locators.
after that you just bake the target rig keys.

This will only partly account for squash and stretch achieved by no-uniform joint scaling.
However, I did a quick and dirty test that indicates a similar scale constraint relationship from source ā†’ transfer ā†’ target Will work.

Hope that helps

4 Likes

Hello :slight_smile:
I finaly succeed in making it work! :partying_face:
It took a while but now everything works fine.
I think the way I did it is not exactly the way I was told in this topic, but it works welll. So I am happy :smiley:
Thanks everyone !

But now I have another problem.
I would like to interpolate a matrix to another one.
How can I do that?
Is there a function in python/cmds/maya api that can do that ?

1 Like

You canā€™t do that directly with a matrix. At least not in the way you probably want.
I mean, you technically can, but itā€™s equivalent to interpolating an angle by pointing at an object moving in a straight line. It may work well for small angles, but as you get closer to 180 you no longer get consistent motion.
So the way to do it is to decompose the matrices into scale vectors, translation vectors, and rotation quaternions. Then you can interpolate the scales and translations as normal, and use SLERP for the quaternions.

1 Like

I find out that Pymel has a ā€œblendā€ you can use on a matrix.

import pymel.core as pm

obj = pm.ls(selection=True)[0]
obj2 = pm.ls(selection = True)[1]

matrix_obj2 = obj2.getMatrix()
matrix_obj = obj.getMatrix()

new_matrix = matrix_obj.blend(matrix_obj2, .5)

obj.setMatrix(new_matrix)

From what I can see it works.
But like you said, it might just work on small angle.

To do it the way you told me, I have to learn how to decompose a Matrix. I will look into it!

Thank you

Hello again! :sweat_smile:
Sooo, I have been busy and I tried to do something a bit specidic but it does not work.
Iā€™ll explain:
I have 2 characters. A version with facial blendshape and another version with a facial skeleton.
They are the same character. Same height, same build but they do not share the same topology.
I am trying to retarget the animations of the older version (the one with the blendshape) onto the newer version (the one with the skeleton rig)
As I said in a previous reply, the retargeting works great! With the scale and everything!

Now I am trying to retarget the facial blendshape on the facial skeleton.
Here is what I did:

  1. create a file that contains the matrix of all the bones for each corresponding blendshape (If the blendshape is like this :open_mouth: , I create the same pose on the facial skeleton and create a file with all the matrix)
  2. create a ā€œmappingā€ so the script know which file to use for each blendshape
  3. And with this I try to retarget everything

As @tfox_TD suggested I decomposed the matrix and made a lerp and a slerp.
It works great. I can retarget a blendshape to a facial rig.

My problem is when I try to to the same thing with multiple blendshape at the same time. The result is really bad.

For each morpher I interpolate from the neutral to the target using the weight of the blendshape:

new_matrix_f_target_a = interpolateMatrix(matrix_f_neutral, matrix_f_target_a, weight)

Then I calculate the offset :

offset_a = new_matrix_f_target_a * matrix_f_neutral.inverse()

Then I multiply everything :

new_offset = offset_a * offset_b * [ā€¦]
new_matrix = new_offset * matrix_f_neutral

As I said, it works if I only use 1 blendshape (and depending on the blendshape, it can works up to 3 or 4)
I think it canā€™t work because matrix are not commutative.
Is there a way to resolve this?

Thank you and sorry for the long post :sweat_smile:

Blending matrices is technically undefined, but it is possible to get stable and repeatable blends if you make some assumptions. And the matrices should probably be decomposed before combining. That way you only have to deal with one non-commutative property (the rotations).

And while I know thereā€™s a lot to be said about doing this stuff by hand, I would suggest messing with Mayaā€™s built-in blendMatrix node, because itā€™s purpose built to ā€¦ well ā€¦ blend between multiple matrices :wink:

Or if nothing else, itā€™ll give you a known target that you can work toward matching with your own code so you can see how it works.

1 Like

Unfortunately, I canā€™t use the blendMatrix node.
I am using maya 2018 and I can only find it in maya 2020.
But from what I can read in the documentation, I think I can achieve the same result using lerp and slerp.
I already tried that and it was not good.

I made new tests and from what I can see, I can have good result overall. The only time it looks weird is when I activate all the blendshape at once. I think it will not happen often :slight_smile:

Thank you again