Last active
April 20, 2024 14:07
-
-
Save chris-lesage/0fcc9a344f2096cf6c82a353cb735b3e to your computer and use it in GitHub Desktop.
Autodesk Maya script to calculate pole vector position based on 3 input objects
This file contains 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 pymel.core as pm | |
''' | |
An Autodesk Maya PyMEL script that calculates a pole vector position | |
based on 3 input PyNode objects. example: leg, knee, ankle bones. | |
Chris Lesage [email protected] | |
''' | |
def calculate_pole_vector(p1, p2, p3, poleDistance=1): | |
""" | |
This function takes 3 PyMEL PyNodes as inputs. | |
Creates a pole vector position at a "nice" distance away from a triangle of positions. | |
Normalizes the bone lengths relative to the knee to calculate straight ahead | |
without shifting up and down if the bone lengths are different. | |
Returns a pymel.core.datatypes.Vector | |
""" | |
vec1 = p1.getTranslation(space='world') # "hips" | |
vec2 = p2.getTranslation(space='world') # "knee" | |
vec3 = p3.getTranslation(space='world') # "ankle" | |
# 1. Calculate a "nice distance" based on average of the two bone lengths. | |
legLength = (vec2-vec1).length() | |
kneeLength = (vec3-vec2).length() | |
distance = (legLength + kneeLength) * 0.5 * poleDistance | |
# 2. Normalize the length of leg and ankle, relative to the knee. | |
# This will ensure that the pole vector goes STRAIGHT ahead of the knee | |
# Avoids up-down offset if there is a length difference between the two bones. | |
vec1norm = ((vec1 - vec2).normal() * distance) + vec2 | |
vec3norm = ((vec3 - vec2).normal() * distance) + vec2 | |
# 3. given 3 points, calculate a pole vector position | |
mid = vec1norm + (vec2-vec1norm).projectionOnto(vec3norm-vec1norm) | |
# 4. Move the pole vector in front of the knee by the "nice distance". | |
midPointer = vec2 - mid | |
poleVector = (midPointer.normal() * distance) + vec2 | |
return poleVector |
This file contains 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 pymel.core as pm | |
# EXAMPLE script | |
poleControl = pm.PyNode('poleVector_ctrl') | |
p1 = pm.PyNode('leg_bone') | |
p2 = pm.PyNode('knee_bone') | |
p3 = pm.PyNode('ankle_bone') | |
polePosition = calculate_pole_vector(p1, p2, p3, poleDistance=1) | |
poleControl.setTranslation(polePosition, space='world') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment