Untitled

 avatar
unknown
plain_text
10 days ago
2.0 kB
4
Indexable
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 chris@rigmarolestudio.com
'''

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
    
poleControl = pm.PyNode('L_hand_ik_pv_ctrl_grp')
swag = cmds.ls(sl=True)
p1 = pm.PyNode(swag[0])
p2 = pm.PyNode(swag[1])
p3 = pm.PyNode(swag[2])

polePosition = calculate_pole_vector(p1, p2, p3, poleDistance=0.5)
poleControl.setTranslation(polePosition, space='world')
Editor is loading...
Leave a Comment