Community
Maya Programming
Welcome to Autodesk’s Maya Forums. Share your knowledge, ask questions, and explore popular Maya SDK topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Calculate offset values between two objects

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
joshua_e_mock
997 Views, 3 Replies

Calculate offset values between two objects

Does anyone know the math that Maya performs to derive the orientation offset when constraining one object to another? I'd like to be able to implement this math as Python code so that I can derive the orientation (or even translation) offset myself. 

3 REPLIES 3
Message 2 of 4
saihtam
in reply to: joshua_e_mock

Have a look at the videos in the playlist. They cover matrix math (which is what a constraint, and all transforms in Maya/CG uses) and how to do the math for an constraint and Python code.

https://www.youtube.com/watch?v=OlqzCaYSqfg&list=PLoOUA5s0du1Gq9ku-75xfFUqZrmfAgGXu&index=11

- Mathias
We'll look at how we can work with matrix math using nodes.
Message 3 of 4

In case anyone is interested, I was able to obtain the offset values by using the following code. Thanks to @saihtam for pointing me towards those videos which helped make more sense out of matrix math. 

 

import maya.api.OpenMaya as om
import pymel.core as pm

offset_node = pm.PyNode('offset_node')  # this is the node that we want offset values from
target_node = pm.PyNode('target_node')  # this is the node that we are measuring against
# get the product of the first object's world matrix and the second object's world inverse matrix
offset_matrix = offset_node.worldMatrix[0].get() * target_node.worldInverseMatrix[0].get()
# convert the matrix to an OpenMaya.MMatrix object
mm = om.MMatrix(offset_matrix)
# convert the MMatrix object to a MTransformationMatrix 
mt = om.MTransformationMatrix(mm)
# collect the offset values
rotation_offset = [om.MAngle(x).asDegrees() for x in mt.rotation()]
translation_offset = mt.translation(om.MSpace.kWorld)  
scale_offset = mt.scale(om.MSpace.kWorld)
shear_offset = mt.shear(om.MSpace.kWorld)

 

Message 4 of 4
saihtam
in reply to: joshua_e_mock

Great work figuring it out!

 

Here is some more code depending on what people want to use. Personally I'm not a huge PyMel user and don't think it's worth using just for getting a matrix here. You could instead use xform like this:

import maya.api.OpenMaya as om2

offset_node_wm = om2.MMatrix(cmds.xform('offset_node', q=True, m=True, ws=True))
target_node_wm = om2.MMatrix(cmds.xform('target_node', q=True, m=True, ws=True))

offset_matrix = offset_node_wm * target_node_wm.inverse()

mt = om2.MTransformationMatrix(offset_matrix)
# collect the offset values
rotation_offset = [om2.MAngle(x).asDegrees() for x in mt.rotation()]
translation_offset = mt.translation(om.MSpace.kWorld)  
scale_offset = mt.scale(om.MSpace.kWorld)
shear_offset = mt.shear(om.MSpace.kWorld)

 

Another thing you could do is skip the OpenMaya all together. In Maya 2019 it seems AD added a new function called "matrixUtil", which allows you to decompose a matrix. You can use it like the below code. Note that I had to include the math library as the rotation is returning radians and not degrees.

import maya.api.OpenMaya as om2
import math

offset_node_wm = om2.MMatrix(cmds.xform('offset_node', q=True, m=True, ws=True))
target_node_wm = om2.MMatrix(cmds.xform('target_node', q=True, m=True, ws=True))

offset_matrix = offset_node_wm * target_node_wm.inverse()
translation_offset = cmds.matrixUtil(*offset_matrix, q=True, t=True)
rotation_offset = [math.degrees(x) for x in cmds.matrixUtil(*offset_matrix, q=True, r=True)]
scale_offset = cmds.matrixUtil(*offset_matrix, q=True, s=True)
shear_offset = cmds.matrixUtil(*offset_matrix, q=True, sh=True) 
- Mathias

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report