Finding the local Z vector in maya/python

Hi there,

I’m trying to find a good way to find the direction an objects Z axis is pointing in Maya.

Not knowing any better way, i’m finding the objects matrix using the xform command, then multiplying that by the world z vector.

This produces a result that has the x and y axes inverted - if I multiply the result by -1 for x and -1 for y i get something I can use.

This all works, albeit shakily, until the object I’m finding the z vector on has been rotated because it’s parented to something else that’s rotated.

I’m sure some of you have done this before, I would like to know your take on this problem.

(using cgkit.cgtypes mat and vec classes for multiplication. The transpose() function is because maya uses row major matrices and cgtypes column major - or the other way around…)

—snip

import maya
from cgkit.cgtypes import *

def FindSnapTypeAndOrientation(obj):
#get the orientation of the obj
matrix = mat4( maya.cmds.xform(obj, query=True, worldSpace=True, matrix=True) ).transpose()
zVec = vec3([0,0,1])
zOrientation = (zVec * matrix).normalize()
return zOrientation

—snip

Thanks

Jon

I think that the world orientation is what you are looking to determine. You can query or change the world up axis with the upAxis() command (MEL or Python). It will return a string giving whether “y” or “z” is up (the only two current options).

EDIT: On second reading, that doesn’t appear to be what you are looking for. I think the answer will include multiplying your local matrix by the inverse parent matrix, continuing until you have a world-parented object.

Mathwise the matrix you take probably contains translation aswell, and directions doesn’t contain translations so you should get a rotation matrix and multiply by the forward vector for the world!
If the object is a child of an object, that means it’s inheriting the transformations of the parent. So what you’ll need to do math wise is to multiply the parents inverted matrix (so you are back in worldspace and not parent space) with the childs matrix and then multiply with the forward vector.

Maya probably has a tool for this? I don’t know. But what you also could do if transformations aren’t frozen is to place something offseted in the objects Z axis. Then point contrain two null objects; one to the original object and another to the offseted object. This way the null objects are in worldspace, skip this step though if there are no parent child relationships. So all you do is normalize(pos B - pos A) to get the direction in worldspace. Now how you apply the offset in the objects Z axis is all up to you, should be doable with script in objectspace or something I believe.
Something like move -r -os -wd 0 0 1.0 for objectspace.

Better to wait for someone else to answer this thread though, as there probably is an easier way around this problem :slight_smile:

Yep, that’s my nasty little workaround, offsetting a duplicate then getting the difference in translation in worldspace normalised.

I imagined i could get it through the matrices but it’s not working how i thought it would.

Jon

[QUOTE=jonthorsen1000;7227]I’m trying to find a good way to find the direction an objects Z axis is pointing in Maya.[/QUOTE]

What do you mean by ‘Z Axis’? The ‘Z axis’ you would see if the gizmo were in local space?

That is just the object’s world space transform’s row3.

If you get the object’s transform, do you know if that is in world or parent space?

Yes that’s what I mean by z axis.

matix = xform(object, matrix=True, worldSpace=True) will get the correct matrix right?

Jon

Now that Rob mentions Row3. I just remembered about this drawing I made. With parent/child objects just concatenate the worldmatrix with inverted matrix from the parent and pick the row3 vector for your direction. If I’m thinking right now this should work :slight_smile: Remember that AB != BA, and if I think right you should do parent matrix * object matrix to go back and not the other way around!

The other guys have got you covered.

That said, I wouldn’t mess with the multiply. As referenced in LoneWolf’s image, one row/column will just be the local Up-Vector. I would just grab those entries directly. If there is scale, you will need to renormalize.

Also, if you are doing your multiply, remember, W should be 0 for normals and 1 for positions. This will properly handle translation in the matrix.