[python] query joint aim axis?

Hello Devs ‘n’ riggers !

I would like to know if someone knows how to get the aim vector of a joint with python ( preferred 2.7)??

Can’t find clear python solution and i’m getting stuck here.

Can someone help? Or have an idea?

Cheers!

Hi @ssky,

You could get the dot product of each axis of the joints transform and compare it against the direction - there should only be a single axis that returns a value not zero.


import maya.cmds as cmds
import maya.api.OpenMaya as apiOM

# Jnt is your joint, target is what your aim is looking at.

m0 = apiOM.MMatrix(
  cmds.xform(jnt, q=True, ws=True, matrix=true))

p0 = apiOM.MVector(
  cmds.xform(target, q=True, ws=True, translation=True))

p0 = (p0 - m0).normal()

aim_axis = None

for i, axis in enumerate("xyz"):

  p1 = apiOM.MVector(map(
      lambda n: m0.getElement(i, n), range(3)))

  if (p1 * p0) > 0.0:

     aim_axis = axis
     break

*note if theres scale on the joint, you may have to make the transform orthogonalized. I’m also assuming that theres not an offset of the joint - you have to use the preTransform if thats the case.

-c

2 Likes

Hello! Thank you so much for the help! It make sense.

I have another question, in a particular case, when for exemple you select the root joint, or a joint that doesn’t have any child? How can you determine the target to return the good axis?

Does your joint have a good rotation axis? You can measure the local space of one axis + 1.0 and use that as a target.

@ssky, if you know the axis you’re wanting to use you could do the same thing but use the angle of the dot product. I’m assuming you have a joint and number of target objects I.e.

  1. Define a target variable (None), and minima ~ 10000.
  2. Get the normal of the axis you want to use.
  3. For a list of targets get there normal direction (joint -> target)
  4. For each dot product between them that returns a value > 0.0:
    b. Get the angle of the dot product - math.acos(value)
    c. If the angle is below an initial minima.
    d. Set the minima to the angle and assign the target
    e. Loop through all the targets with step 4b - 4d
  5. Return the target and if need be the angle.

The angle is basically your error, it’s the residual of how close the target is to the axis in direction. If you don’t know what axis it gets a little trickier because you have 3 axes with n-number of targets - I guess you’d loop through each target for each axis and compare the angles - but you may get false positives.

-c

Hello Guys! Thank you a lot for the answers. This is ok, this solution seems to be the way to go for joint aim axis. For the root, i choose Chris solution, as it should be always well oriented, if it’s not i just kick a warning telling that you need to properly align your joints first, witch i think make sense, you don’t want different orients on a single hierarchy right?

Thx a lot for the help!