MDagPath.inclusiveMatrix() doesn't give reliable/deterministic results
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I have a problem where iterating over objects and calling MDagPath.inbclusiveMatrix() doesn't give deterministic results. Specifically, if I:
- Generate or load a scene
- Iterate over all transform objects and dump out their attributes and their world-space matrix obtained from inclusiveMatrix (script below)
- Save the scene in binary format
- Make a new empty scene (just to flush things)
- Load the scene
- Iterate and print attributes and matrices again
then comparing the output of steps 2 and 6 (i.e. before and after the save/load):
- The attributes match up perfectly (to 64 sig digits)
- Matrices returned from inclusiveMatrix differ slightly - after around 16 sig digits
This might not sound like a lot - but when these are passed to a physics solver (e.g. to initialise objects or control them), it means that a scene you've set up and tweaked will sometimes behave slightly/significantly/wildly differently after a save/load operation.
Has anybody got any ideas what might cause these differences? And even better - any idea how I might either flush the system so that inclusiveMatrix is forced to discard any out-of-date data it might be using, or get the world-space matrices a different (more reliable) way? Calling OpenMaya.MFnMatrixData on the "worldMatrix" plug results in the same data as inclusiveMatrix, unfortunately.
Tested with Maya 2018 and 2020 under Windows (though I believe it happens under Linux too)
Thanks for any ideas!
Note: I lied slightly when I said the attributes match up perfectly: "-0" tends to turn into "0". However, this doesn't appear to be related to the times that inclusiveMatrix generates different output, so I'm hoping it isn't itself a problem.
Here's my script to dump the attributes and world matrix:
from maya import cmds, OpenMaya
transforms = cmds.ls(type="transform")
for t in transforms:
slls = OpenMaya.MSelectionList()
slls.add(t)
path = OpenMaya.MDagPath()
slls.getDagPath(0, path)
mat = path.inclusiveMatrix()
for i in range(0, 4):
print(t,
"{:.64g}".format(mat(0, i)),
"{:.64g}".format(mat(1, i)),
"{:.64g}".format(mat(2, i)),
"{:.64g}".format(mat(3, i)))
for t in transforms:
x = cmds.getAttr(t + ".translateX")
y = cmds.getAttr(t + ".translateY")
z = cmds.getAttr(t + ".translateZ")
rx = cmds.getAttr(t + ".rotateX")
ry = cmds.getAttr(t + ".rotateY")
rz = cmds.getAttr(t + ".rotateZ")
print(t, "t {:.64g}".format(x), "{:.64g}".format(y), "{:.64g}".format(z))
print(t, "r {:.64g}".format(rx), "{:.64g}".format(ry), "{:.64g}".format(rz))
The most reliable test (because not all objects suffer from this) is to:
- Add the HumanIK animation example to an empty scene
- Run the script above and save the output to before.txt
- save as binary. new file. load the saved file
- Run the script again and save the output after.txt
- File compare before.txt and after.txt
It also manifests with simple objects - e.g. a few poly objects under some transforms with non-identity rotation/translation/scaling.