MTransformationMatrix and Joint Orientation Python
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
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!