MTransformationMatrix and Joint Orientation Python

MTransformationMatrix and Joint Orientation Python

flexmaster
Explorer Explorer
4,574 Views
6 Replies
Message 1 of 7

MTransformationMatrix and Joint Orientation Python

flexmaster
Explorer
Explorer

Hey,

 

I'm trying to reconstruct a MTransformationMatrix from maya's MFnIkJoint in maya 2015. According to the docs the construction works as such:

 

The transformation matrix for a joint node is below.

  • matrix = [S] * [RO] * [R] * [JO] * [IS] * [T]

(where '*' denotes matrix multiplication).

These matrices are defined as follows:

  • [S] : scale
  • [RO] : rotateOrient (attribute name is rotateAxis)
  • [R] : rotate
  • [JO] : jointOrient
  • [IS] : parentScaleInverse
  • [T] : translate

 

 

So I've followed that and written the code below. The problem is that the constructed matrix I created does not seem to respect joint orientation.

If I get the MTransformationMatrix directly from the MFnIkJoint function it somehow seems to store the joint orientation. Does anyone know where the MTransformationMatrix is storing joint orientation? It seems to be a mystery to me as it isn't in MTransformationMatrix::rotationOrientation or MTransformationMatrix::rotation. 

 

 

import time
from maya import cmds
from maya import OpenMaya, OpenMayaAnim

 

# Make a joint
jnt = cmds.joint(orientation=[0, 45, 0])
jnt2 = cmds.joint(p=[2, 0, -2])

 

# get a dagPath
mSel = OpenMaya.MSelectionList()
mSel.add(jnt)

dagPath = OpenMaya.MDagPath()
mSel.getDagPath(0, dagPath)

 

# Put it in MFnIkJoint function set
startJointFn = OpenMayaAnim.MFnIkJoint(dagPath)
initMatrix = startJointFn.transformation()

 

# Make a scale pointer
util = OpenMaya.MScriptUtil()
util.createFromList([1.0, 1.0, 1.0], 3)
scalePtr = util.asDoublePtr()

 

# Get scale

startJointFn.getScale(scalePtr)
S_MTMatrix = OpenMaya.MTransformationMatrix()
S_MTMatrix.setScale(scalePtr, OpenMaya.MSpace.kTransform)
S = S_MTMatrix.asMatrix()

 

# Get rotate orientation
RO_Quat = OpenMaya.MQuaternion()
startJointFn.getScaleOrientation(RO_Quat)
RO_MTMatrix = OpenMaya.MTransformationMatrix()
RO_MTMatrix.rotateBy(RO_Quat, OpenMaya.MSpace.kTransform)
RO = RO_MTMatrix.asMatrix()

 

# Get Rotation
R_Quat = OpenMaya.MQuaternion()
startJointFn.getRotation(R_Quat)
R_MTMatrix = OpenMaya.MTransformationMatrix()
R_MTMatrix.rotateBy(R_Quat, OpenMaya.MSpace.kTransform)
R = R_MTMatrix.asMatrix()

 

# Get joint orientation

JO_Quat = OpenMaya.MQuaternion()
startJointFn.getOrientation(JO_Quat)
JO_MTMatrix = OpenMaya.MTransformationMatrix()
JO_MTMatrix.rotateBy(JO_Quat, OpenMaya.MSpace.kTransform)
JO = JO_MTMatrix.asMatrix()

 

# Get inverse scale of parent.
parentMObj = startJointFn.parent(0)
if not parentMObj.apiTypeStr() == "kWorld":
    parentFn = OpenMaya.MFnTransform(parentMObj)
    parentFn.getScale(scalePtr)

 

IS_MTMatrix = OpenMaya.MTransformationMatrix()
IS_MTMatrix.setScale(scalePtr, OpenMaya.MSpace.kTransform)
IS = IS_MTMatrix.asMatrixInverse()

 

# Get Translation
T_Vector = startJointFn.getTranslation(OpenMaya.MSpace.kTransform)
T_MTMatrix = OpenMaya.MTransformationMatrix()
T_MTMatrix.setTranslation(T_Vector, OpenMaya.MSpace.kTransform)
T = T_MTMatrix.asMatrix()

 

# Multiply like the docs say.
matrix = S * RO * R * JO * IS * T

 

# Put it into MTransformationMatrix

TMatrix = OpenMaya.MTransformationMatrix(matrix)

 

# If the two MTransformationMatrices are equal.
if TMatrix.isEquivalent(initMatrix):
   

    # Set joint to calculated matrix

    startJointFn.set(TMatrix)
    cmds.refresh()

 

    # Wait 1 second and set it back to the inital transformation matrix from the joint function

    # This is just to see the difference between the two transformation matrices.
    time.sleep(1)
    startJointFn.set(initMatrix)

 

 

Thanks for any help!

0 Likes
4,575 Views
6 Replies
Replies (6)
Message 2 of 7

Anonymous
Not applicable

You should not need to be doing this calculation

 

  • matrix = [S] * [RO] * [R] * [JO] * [IS] * [T]

 

Instead you can just do

 

ikJoint.setScale   -- To set the [s] paramater

ikJoint.setScaleOrientation -- to set the RO parameter

ikJoint.setRotation  -- to set the R parameter

ikJoint.setOrientation -- to set the JO parameter

 

etc directly

0 Likes
Message 3 of 7

Anonymous
Not applicable

That calculation you see is just done for the final rendering position of the joint

0 Likes
Message 4 of 7

flexmaster
Explorer
Explorer

That makes sense. The question is what is set in the MTransformationMatrix that you get from the MFnIkJoint function set that stores the joint orientation? If I grab that set and use the set function in MFnIkJoint it retains the joint orientation. Where is joint orientation stored in the MFnTransformationMatrix?

0 Likes
Message 5 of 7

Anonymous
Not applicable

What I was trying to say -- is that you shouldn't need to do that full calcuation your self, as you can do:

 

MFnIkJoint joint;

MTransformation transMatrix = joint.transformation();

 

 

From the TransformationMatrix -- You cannot get back the JointOrient    --- If you really need that ugly stuff -- you can directly ask MFnIkJoint. 

TransformationMatrix -- however gives you the more important thing -- the total rotation:

 

The Total Rotation =  [RO] * [R] * [JO]    =  transMatrix.getRotationQuaternion()

0 Likes
Message 6 of 7

flexmaster
Explorer
Explorer

Agreed. I shouldn't have to calculate it and I use the transformation in my code I supplied to show the differences between the two transformation matrices even though they say they are equivalent.

 

What's really odd though is that the MTransformation transMatrix = joint.transformation() part you're talking about some how retains the joint orientation in the MFnTransformationMatrix. That's shown when I grab the transformation matrix and then set it back onto the joint. Is this some weird under the hood maya thing that occurs that I can't actually reproduce because the api doesn't give you a function to add joint orientation?

0 Likes
Message 7 of 7

Anonymous
Not applicable

There is probably a way to reconstruct them from the various member functions:

 

MTransformationMatrix --> 

[Sp]x[S]x[Sh]x[Sp]x[St]x[Rp]x[Ro]x[R]x[Rp]x[Rt]x[T]

 

Looks like [Rp] x [Rt]  is related to the Joint Orient 

0 Likes