I’m still a beginner in the Maya API.
I’m trying to build a temporary pivot tool, and I made a very simple version just to test the core logic.
The idea is:
I compute the relative matrix and apply it to the selected object.
The problem is that while I’m working on the current frame, everything behaves correctly.
But after I close the tool and scrub or check other frames, the character gets completely broken
What could be causing this issue?
I’ve uploaded the code and a screen recording of the problem to Google Drive, since this platform doesn’t allow video uploads.
It looks like your math is behaving correctly, but if you want the new positions to reflect across time you will have to deal with setting keyframes on everything that moved.
You are using cmds.xform but that does not set any keys.
In your video I can see (barely) that you have auto-key on, but that will only key channels that have at least one existing key (hence everything looking broken. Some channels are getting keyed and some aren’t). When your selection changes I can see that at least one of the objects has no keys on ty, tz, and rx. That is probably what your issue is.
Setting the matrix with cmds.xform is going to set all the translate, rotate, and scale channels. If you set any key, you will probably need to set one on all of these channels. You will need to decide:
Whether to skip setting keys if there are no keys on any channels.
Whether auto-key being enabled should affect the result.
I did some more testing. I baked the animation on every frame, then used the script to change the pose, but the animation still breaks.
From what I noticed, the controls have custom rotate pivots. When I use cmds.xform to apply the transform, it seems like the rotate pivot of the controls is being overridden by the rotate pivot of the temporary pivot transform.
Is there a way to apply new transform values to the controls without affecting or overriding their existing rotate pivot values?
This is another test. The problem is that the translation is always wrong.
I’m doing the test on frame 7, and I uploaded the scene I’m testing on to Drive.
import maya.cmds as cmds
import maya.mel
import maya.api.OpenMaya as om
import maya.api.OpenMayaAnim as oma
import math
def get_dag_path(nodeName):
selection_list = om.MSelectionList().add(nodeName)
return selection_list.getDagPath(0)
# pivot_name_1 repesent point a
pivot_name_1 = "locator3"
pivot_1 = get_dag_path(pivot_name_1)
pivot_matrix_1 = pivot_1.inclusiveMatrix()
# pivot_name_2 repesent point b ( after locator3 moved )
pivot_name_2 = "locator4"
pivot_2 = get_dag_path(pivot_name_2)
pivot_matrix_2 = pivot_2.inclusiveMatrix()
# obj_name = "Char_Norman_A1_v011:ctrl_Root"
obj_name = "Char_Norman_A1_v011:ctrlIK_Lf_ArmIK"
obj = get_dag_path(obj_name)
obj_matrix = obj.inclusiveMatrix()
# parent_name = "Char_Norman_A1_v011:grAll_Ctrl"
parent_name = "Char_Norman_A1_v011:grCon_Lf_ArmIK"
parent = get_dag_path(parent_name)
parent_matrix = parent.inclusiveMatrix()
relative_matrix = obj_matrix * pivot_matrix_1.inverse()
new_obj_matrix = relative_matrix * pivot_matrix_2
local_matrix = new_obj_matrix * parent_matrix.inverse()
transform_matrix = om.MTransformationMatrix(new_obj_matrix)
translation = transform_matrix.translation(om.MSpace.kTransform)
rotation = transform_matrix.rotation(False)
cmds.xform(obj_name, translation=translation)
cmds.xform(obj_name,
rotation=[ math.degrees(rotation.x), math.degrees(rotation.y), math.degrees(rotation.z) ])