[Maya] How to access World Matrix Input?

maya

#1

Hi,

I need to access the world translation/rotation of one object to the other.
So far:

  1. I cannot do direct connection since both objects are in different heirarchy
  2. I cannot also do parent constraint because the previous rigger mess with the scaling, so now there is shearing. (No, I’m not willing to do a scale constraint. Only translation and rotation).

I was hoping the world matrix socket would help me. There is an output but there is no input.

Is there a way around this?

You can see an illustration of the problem here:
https://www.dropbox.com/s/ogsbq1qpjs1m9xf/MYA069_world_matrix_input.png?dl=0

Thank you.

EDIT: This is still unresolved.
Based on the comments below: There is no World Matrix Input.
(1) I guess the remaining question would be is there a feature/node equivalent to the World Matrix Input?
(2) Also, be noted that both driven and driver objects are in hierarchies. The reason I’m pointing out is that the solutions below work if they are not in hierarchy.

You can check an illustration file here:
https://www.dropbox.com/s/jdgecanobdbosk6/MYA069_world_matrix_input_v1.4.ma?dl=0


#2

Connect the outTranslate and outRotate of the decomposeMatrix into your object’s translate and rotate inputs.


#3

Thanks for the response but as stated above, both objects are in hierarchy, so it won’t work.

For example
Driven’s Parent (20,30,60)
…Driven Object (0,0,0)

Supposing the driver’s world rotation is (10,20,30) if plug directly to “object’s translate and rotate inputs.”
It would result to a world rotation of (30,50,90) which is driven’s object rotation plus its parent

Back to the question, is there a world matrix input?

Thank you


#4

For your question: There is no input for the world matrix attribute.

To achieve this you will need to employ some basic matrix math.

dynamicDiffWithParent = (driver.worldMatrix * driven.parentInverseMatrix)
staticDiff = (driven.worldMatrix * driver.worldInverseMatrix)
finalMatrix = dynamicDiffWithParent * staticDiff * driven.parentWorldMatrix

The output of that can go into your driven node and you should have the proper local values.


#5

Thanks for response Ollarin.
For some reason I get an error. I reckon that what you have written is for the expression editor

You can see an illustration here:
https://www.dropbox.com/s/tcvccbwzf4qm3qz/MYA069_world_matrix_input_v1.2.png?dl=0

Thank you


#6

Insert a multMatrix between the source and the decomposeMatrix, and multiply the worldMatrix * parentInverseMatrix, connect the sum of that into the decomposeMatrix matrixIn.


#7

Hi katz

Thanks for the response but it doesn’t work as expected. For clarity, this is what I illustrated above:

"hanks for the response but as stated above, both objects are in hierarchy, so it won’t work.

For example
Driven’s Parent (20,30,60)
…Driven Object (0,0,0)

Supposing the driver’s world rotation is (10,20,30) if plug directly to “object’s translate and rotate inputs.”
It would result to a world rotation of (30,50,90) which is driven’s object rotation plus its parent

Back to the question, is there a world matrix input?

Thank you"


#8

You can also check an illustration Maya file here:
https://www.dropbox.com/s/jdgecanobdbosk6/MYA069_world_matrix_input_v1.4.ma?dl=0


#9

There is no world matrix input.

A transforms’ world matrix is composed of its local matrix, combined with the matrix of all of its parent nodes.


#10

Thanks for the response R.White.

Thanks for the confirmation.
The solutions presented above by others works but only if the driven object is NOT parented/hierarchy.
Unfortunately, my driven object is parented/hierarchy.

is there a way around this?


#11

You need to account for it being parented by using the “parent inverse matrix” of the driven object as well as that of the driver. If you’re unfamiliar with the maths I would highly recommend a crash course on maya matrices (Kimon Matara’s posts are excellent) - multiplying matrices effectively transforms matrices between ranks in a hierarchy.
Maya gives us an object’s world matrix for free - use the multMatrix node to multiply the driver’s world matrix by the driven’s parent inverse matrix. This will effectively “subtract” all transformations of the parent from the target position, leaving you with the child’s local transforms. (I’m not quite sure what the advantage is of Katz’ solution above - seems like it would just give you the local transforms of the object anyway?)


#12

Hi @EdArt

Thanks for the explanation and the reference of the Kimon’s blog.
It works as expected! Also learned some matrix theory.

(I now get what you mean by “Maya gives us an object’s world matrix for free”. Thanks Maya!)


#13

You solved it! Haha, I was just typing this up for you, maybe it’ll help someone else some day. :slight_smile:

In a nutshell, both @clesage’s and @katz approaches work, with some slight modification.

  • @clesage’s works if you untick inheritsTransform on the driven child.
  • @katz’s works if you use the driven’s parentInverseMatrix, instead of the one of the driver.

Here’s a complete example of the two.

from maya import cmds

# Setup
cmds.file(new=True, force=True)
parent = cmds.createNode("transform", name="parent")
child, _ = cmds.polyCube(name="child")
child = cmds.parent(child, parent)[0]

cmds.move(0, 1, 0, parent)
cmds.move(0, 2, 0, child)
cmds.rotate(45, 0, 0, parent)

driver, _ = cmds.polySphere(name="driver", radius=0.1)

cmds.move(5, 2, 0, driver)
cmds.rotate(-45, 0, 0, driver)

# Option A - Disable hierarchy inheritance
cmds.setAttr(child + ".inheritsTransform", False)
decompose = cmds.createNode("decomposeMatrix")

cmds.connectAttr(driver + ".worldMatrix", decompose + ".inputMatrix")
cmds.connectAttr(decompose + ".outputTranslate", child + ".translate")
cmds.connectAttr(decompose + ".outputRotate", child + ".rotate")
cmds.connectAttr(decompose + ".outputScale", child + ".scale")

# Option B - Pre-multiple inverse matrix
cmds.setAttr(child + ".inheritsTransform", True)
mult = cmds.createNode("multMatrix")
cmds.connectAttr(child + ".parentInverseMatrix[0]", mult + ".matrixIn[1]")
cmds.connectAttr(driver + ".worldMatrix[0]", mult + ".matrixIn[0]")
cmds.connectAttr(mult + ".matrixSum", decompose + ".inputMatrix", force=True)

#14

Yeah, I think I meant to connect the parentInverseMatrix of the target to the multMatrix rather than the parentInverseMatrix of the source.


#15

Heh, my answer wasn’t meant to be “an approach”. I just thought bentraje didn’t know how to get transform values out of a matrix. Some good tips in this thread, thanks!