Created
May 3, 2022 13:43
-
-
Save Muream/32dcdf95163728efbd77a41ccb958624 to your computer and use it in GitHub Desktop.
Ensure Planar Orientation Maya
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import maya.api.OpenMaya as om2 | |
from maya import cmds | |
def ensure_planar_orientation(transform_a, transform_b, transform_c): | |
"""Orients the three given transform based on the plane they form. | |
X axis aims at the next transform. | |
Z axis is the normal axis to the plane. | |
Y axis is the tertiary axis, computed based on the 2 previous ones. | |
""" | |
a = om2.MVector( | |
cmds.xform(transform_a, query=True, translation=True, worldSpace=True) | |
) | |
b = om2.MVector( | |
cmds.xform(transform_b, query=True, translation=True, worldSpace=True) | |
) | |
c = om2.MVector( | |
cmds.xform(transform_c, query=True, translation=True, worldSpace=True) | |
) | |
# get the aim vectors for transforms a and b. | |
# this will be the X axis of our transforms. | |
ab_vec = (b - a).normal() | |
bc_vec = (c - b).normal() | |
# The normal vector is the cross product of the two vectors defining our plane | |
# This will be the Z Axis of our transforms. | |
# It is the same for all the joints. | |
plane_normal_vec = (ab_vec ^ bc_vec).normal() | |
# the tertiary vector is simply a cross product of the aim and normal vectors | |
# This will be the Y Axis of our transforms. | |
a_tertiary_vec = (plane_normal_vec ^ ab_vec).normal() | |
b_tertiary_vec = (plane_normal_vec ^ bc_vec).normal() | |
# fmt: off | |
# We construct the matrix of each transform based on the computed vectors | |
transform_a_matrix = om2.MMatrix([ | |
ab_vec.x, ab_vec.y, ab_vec.z, 0, | |
a_tertiary_vec.x, a_tertiary_vec.y, a_tertiary_vec.z, 0, | |
plane_normal_vec.x, plane_normal_vec.y, plane_normal_vec.z, 0, | |
a.x, a.y, a.z, 1, | |
]) | |
transform_b_matrix = om2.MMatrix([ | |
bc_vec.x, bc_vec.y, bc_vec.z, 0, | |
b_tertiary_vec.x, b_tertiary_vec.y, b_tertiary_vec.z, 0, | |
plane_normal_vec.x, plane_normal_vec.y, plane_normal_vec.z, 0, | |
b.x, b.y, b.z, 1, | |
]) | |
# Transform `c` has the same orientation as `b` but uses its own translation | |
transform_c_matrix = om2.MMatrix([ | |
bc_vec.x, bc_vec.y, bc_vec.z, 0, | |
b_tertiary_vec.x, b_tertiary_vec.y, b_tertiary_vec.z, 0, | |
plane_normal_vec.x, plane_normal_vec.y, plane_normal_vec.z, 0, | |
c.x, c.y, c.z, 1, | |
]) | |
# fmt: on | |
# Finally we apply those matrices onto the actual transforms | |
cmds.xform(transform_a, matrix=transform_a_matrix, worldSpace=True) | |
cmds.xform(transform_b, matrix=transform_b_matrix, worldSpace=True) | |
cmds.xform(transform_c, matrix=transform_c_matrix, worldSpace=True) | |
if __name__ == "__main__": | |
ensure_planar_orientation(*cmds.ls(sl=True)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment