Maya: Accessing matrix components with DG nodes?

I want to access individual components of a matrix, and looking at the matrix dg nodes, I can’t find one that allows or that. Compose has component in, as does fourByFourMatrix, but most things pass out a matrix, not anything that I can grab components from. I would like to grab the x axis vector from a worldMatrix.

When doing things like this, do people write mel expressions? For ‘live’ rigging that uses vector math, the only options are dg nodes, api plugin that makes dg nodes, or mel expressions, correct?

I am just asking because someone wanted me to show some python code live in the DG and I’m having issues. Anyone know if someone has released some math utility DG nodes? Like holdMatrix says it caches and holds an initial matrix input, but it updates in certain circumstances (when even set to not evaluate), which makes it’s usefulness a bit dubious for that.

For most things you can use the VectorProduct node: for example, you can connect the worldMatrix of a node to matrix input of a VectorProduct and set it’s operation to VectorMatrixProduct. You can extract the X, Y or Z vectors of the matrix by setting the input 1 to (1,0,0), (0,1,0) etc. This is equivalent to a standard vector-matrix multiply, so it will give you orientation but not translations. or scales. There’s a flag to normalize the output or not. It sounds like what you want is worldMatrix > VectorProduct with VectorMatrixProduct operation, input 1 = (1,0,0) and normalize on (unless you need shear).

If you set the operation to PointMatrixProduct, you’ll get the point-matrix multiply with scale and translation (but you have to watch out for unitConversion nodes sneaking in and screwing with your numbers). Using PointMatrixProduct and setting the input to (0,0,0) gives your the translation component of the matrix.

The only things you can’t get this way are the homogenous coordinates: the 4th column of the matrix. You probably don’t need them if you’re not doing perspective matrices.

Extra credit:

You can also select a column or row of a matrix by multiplying a ‘selection matrix’ of all 1s and 0s against your matrix:


1   1   1  1            X1,  X2, X3,  W1
0   0   0  0     *     Y1,  Y2, Y3 ,  W2
0   0   0  0            Z1,  Z2, Z3,  W3
0   0   0  0            T1,  T2,  T3,  W4

produces

 X1,  X2, X3,  W1
   0,    0,   0,  0      
   0,    0,   0,  0      
   0,    0,   0,  0      

So you can do that with a selection matrix and a multMatrix

I’m not sure about that selection matrix technique, surely


1   1   1  1            X1, X2, X3, W1            (X1 + Y1 + Z1 + T1), (X2 + Y2 + Z2 + T2), (X3 + Y3 + Z3 + T3), (W1 + W2 + W3 + W4)
0   0   0  0     *      Y1, Y2, Y3, W2     =                   0,               0,             0,                            0
0   0   0  0            Z1, Z2, Z3, W3                         0,               0,             0,                            0
0   0   0  0            T1, T2, T3, W4                         0,               0,             0,                            0

whereas


                        X1, X2, X3, W1            
1   0   0  0     *      Y1, Y2, Y3, W2     =      X1, X2, X3, W1
                        Z1, Z2, Z3, W3                       
                        T1, T2, T3, W4                        

and


1   0   0  0            X1, X2, X3, W1             X1, X2, X3, W1
0   0   0  0     *      Y1, Y2, Y3, W2     =       0,  0,  0,  0
0   0   0  0            Z1, Z2, Z3, W3             0,  0,  0,  0
0   0   0  0            T1, T2, T3, W4             0,  0,  0,  0

and switch it round to select a column

-Harry

That’s a good catch. I was looking at some older code which apparently depends on a bug in pymel:

 
import pymel.core.datatypes as dt
import pymel.core as pm

m1 = dt.Matrix(  [1,1,1,1], [0,0,0,0], [0,0,0,0], [0,0,0,0])
m2 = dt.Matrix()
print m1 * m2
# [[1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]

m3 = pm.xform('pCube1', m=True, q=True)
print m1 * m3
#[[0.608262950917, -0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [-0.0, -0.0, 0.0, 0.0], [0.0, 0.0, -0.0, 0.0]]

m_col = dt.Matrix(  [1,0,0,0] * 4)   # all 1s in col 1
print m_col * m3
#[[0.608262950917, -0.0, 0.0, 0.0], [0.422546137936, 0.0, 0.0, 0.0], [-0.67191587558, -0.0, 0.0, 0.0], [148.972906249, 0.0, -0.0, 0.0]]


That’s worrisome…

Thanks guys, I didn’t get this notification, or I would have replied sooner.