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


 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
26
27
28
29
30
import maya.OpenMaya as om
import math

transformFn = om.MFnTransform() # Create empty transform function set

mSel = om.MSelectionList()
mSel.add('pSphere1')
mSel.add('pCube1')

dagPath = om.MDagPath()

mSel.getDagPath(0, dagPath) # Get the dagPath for pSphere1
transformFn.setObject(dagPath) # Set the function set to operate on pSphere1 dagPath
transformationMatrix = transformFn.transformation() # Get a MTransformationMatrix object
matrixA = transformationMatrix.asMatrix() # Get a MMatrix object representing to local matrix of pSphere1

mSel.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 parent
worldMatrixB = matrixB * matrixA

translation = 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.z
print '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
import maya.OpenMaya as om
import math

transformFn = om.MFnTransform() # Create empty transform function set

mSel = om.MSelectionList()
mSel.add('pSphere1')
mSel.add('pCube1')

dagPath = om.MDagPath()

mSel.getDagPath(0, dagPath) # get dagPath for pSphere1
worldMatrixInverseA = dagPath.inclusiveMatrixInverse() # get the world inverse matrix for pCube1 parent (pSphere1)

mSel.getDagPath(1, dagPath)
worldMatrixB = dagPath.inclusiveMatrix() # Get the world matrix for pCube1

localMatrixB = worldMatrixB * worldMatrixInverseA # Multiply pCube1's world matrix by it's parents world inverse matrix

translation = 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.z
print 'pCube1.rotate ->', math.degrees(rotation.x), math.degrees(rotation.y), math.degrees(rotation.z)


No comments:

Post a Comment