Wednesday, 21 December 2016

Matrix fun!

Here's a few snippets I wrote when learning how to interact with matrices via Maya's Python API.

Note: You can get the local and world matrices directly from attributes on a dag node. You can also use the xform command.

In the example image, pCube1 is a child of pSphere1. If the position of both objects in the scene are random, we can find the local and world matrices for pCube1 and the world-space and local-space positions (translate, rotate, scale) of pCube1 with the example bits of code below. The channel box will only give us local or relative values to the objects parent.

Finding a world matrix from a local matrix

importmaya.OpenMayaasomimportmathtransformFn=om.MFnTransform()# Create empty transform function setmSel=om.MSelectionList()mSel.add('pSphere1')mSel.add('pCube1')dagPath=om.MDagPath()mSel.getDagPath(0,dagPath)# Get the dagPath for pSphere1transformFn.setObject(dagPath)# Set the function set to operate on pSphere1 dagPathtransformationMatrix=transformFn.transformation()# Get a MTransformationMatrix objectmatrixA=transformationMatrix.asMatrix()# Get a MMatrix object representing to local matrix of pSphere1mSel.getDagPath(1,dagPath)transformFn.setObject(dagPath)transformationMatrix=transformFn.transformation()matrixB=transformationMatrix.asMatrix()# Get a MMatrix object representing to local matrix of pCube1# Multiply local matrices up from child to parentworldMatrixB=matrixB*matrixAtranslation=om.MTransformationMatrix(worldMatrixB).getTranslation(om.MSpace.kWorld)# <-- Not sure on this parameter. All I care about is the 4th row in the matrix.rotation=om.MTransformationMatrix(worldMatrixB).eulerRotation()print'\n'print'pCube1.translate ->',translation.x,translation.y,translation.zprint'pCube1.rotate ->',math.degrees(rotation.x),math.degrees(rotation.y),math.degrees(rotation.z)

We could just call the inclusiveMatrix() method on a dagPath object to retrieve the world matrix (as is done below) but lets just say that for umm...some unknown reason you only had the local matrix to work with.

Finding a local matrix from a world matrix

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

importmaya.OpenMayaasomimportmathtransformFn=om.MFnTransform()# Create empty transform function setmSel=om.MSelectionList()mSel.add('pSphere1')mSel.add('pCube1')dagPath=om.MDagPath()mSel.getDagPath(0,dagPath)# get dagPath for pSphere1worldMatrixInverseA=dagPath.inclusiveMatrixInverse()# get the world inverse matrix for pCube1 parent (pSphere1)mSel.getDagPath(1,dagPath)worldMatrixB=dagPath.inclusiveMatrix()# Get the world matrix for pCube1localMatrixB=worldMatrixB*worldMatrixInverseA# Multiply pCube1's world matrix by it's parents world inverse matrixtranslation=om.MTransformationMatrix(localMatrixB).getTranslation(om.MSpace.kWorld)# <-- Not sure on this parameter. All I care about is the 4th row in the matrix.rotation=om.MTransformationMatrix(localMatrixB).eulerRotation()print'\n'print'pCube1.translate ->',translation.x,translation.y,translation.zprint'pCube1.rotate ->',math.degrees(rotation.x),math.degrees(rotation.y),math.degrees(rotation.z)