## Archive for August, 2016

## understanding transformation matrices

by eks on Aug.28, 2016, under Uncategorized

After some children hiatus, I need to finish this post I’ve drafted a while ago. I’ll do another one when I get my hands on a Maya install, in the meantime copy this into the Maxscript editor and try it out:

pt = point axistripod:true size:1 name:"trMatrix" spX = sphere wirecolor:red radius:0.05 name:"xVector" spY = sphere wirecolor:green radius:0.05 name:"yVector" spZ = sphere wirecolor:blue radius:0.05 name:"zVector" ctrl = position_script() ctrl.addNode "pt" pt spX.position.controller=ctrl spX.position.controller.script ="[pt.transform[1][1], pt.transform[1][2], pt.transform[1][3]]" ctrl = position_script() ctrl.addNode "pt" pt spY.position.controller=ctrl spY.position.controller.script ="[pt.transform[2][1], pt.transform[2][2], pt.transform[2][3]]" ctrl = position_script() ctrl.addNode "pt" pt spZ.position.controller=ctrl spZ.position.controller.script ="[pt.transform[3][1], pt.transform[3][2], pt.transform[3][3]]"

This will create a point that we will call trMatrix, this is “the matrix we will be trying to understand”. Together with the point it will create three spheres, one for each axis. With a Script Controller, it will also constraint the position of each sphere to each row of the transformation matrix. So red spX will be constrained to the first row, the “x vector”, of trMatrix.transform, green spY to the second row, the “y vector”, and blue spZ to the third row, the “z vector”.

Now rotate trMatrix (don’t move it just yet, only rotate it), run this afterwards and try to understand what’s happening:

print pt.transform print "Sphere X position: " + (spX.position as string) print "Sphere Y position: " + (spX.position as string) print "Sphere Z position: " + (spX.position as string)

Due to the script controller from before, **each position in global space for each sphere is actually a row from trMatrix point’s transform matrix**. So in this case, each row of the transform matrix is actually just “an offset from zero”. In other words, it’s simply a vector in 3d space whose origin is 0, 0, 0.

Now if you move trMatrix point the spheres will stay in the same place. They are constrained to each vector in the transform matrix, but those are not affected by the point position, the last row. If you want the spheres to follow the point, you simply need to add each value from the position vector on the script controller expression, with this:

spX.position.controller.script ="[pt.transform[1].x+pt.position.x, pt.transform[1].y+pt.position.y, pt.transform[1].z+pt.position.z]"--set the expression spY.position.controller.script ="[pt.transform[2].x+pt.position.x, pt.transform[2].y+pt.position.y, pt.transform[2].z+pt.position.z]"--set the expression spZ.position.controller.script ="[pt.transform[3].x+pt.position.x, pt.transform[3].y+pt.position.y, pt.transform[3].z+pt.position.z]"--set the expression

All animators already know this intuitively but here’s the thing: **a local matrix position is simply an offset, a vector offset, from its parent, as if that parent was the origin (0,0,0)**. The global matrix is the object matrix in relation to the origin itself, but the local one is as if the origin “moved” to its parent. And so is with a hierarchical skeleton up until the root.

Lastly, here’s quickly two ways in Maxscript to get the local matrix:

$.transform * (inverse $.parent.transform) $.transform.controller.value