Batch-constraining objects (feathers to a wing)

青春壹個敷衍的年華 提交于 2020-01-03 03:14:09

问题


really not long ago I had my first dumb question answered here so... there I am again, with a hopefully less dumb and more interesting headscratcher. Keep in my mind I am still making my baby steps in scripting !

There it is : I need to rig a feathered wing, and I already have all the feathers in place. I thought of mimicking another rig I animated recently that had the feathers point-constrained to the arm and forearm, and orient-constrained to three other controllers on the arm : each and every feather was constrained to two of those controllers at a time, and the constraint's weights would shift as you went down the forearm towards the wrist, so that one feather perfectly at mid-distance between the elbow and the forearm would be equally constrained by both controllers... you get the picture.

My reasoning was as follows : let's make a loop that iterates over every feather, gets its world position, finds the distance from that feather to each of the orient controllers (through Pythagoras), normalize that and feed the values into the weight attribute of an orient constraint. I could even go the extra mile and pass the normalized distance through a sine function to get a nice easing into the feathers' silhouette.

My pseudo-code is ugly and broken, but it's a try. My issues are inlined.

Second try ! It works now, but only on active object, instead of the whole selection. What could be happening ?

import maya.cmds as cmds

# find world space position of targets
base_pos = cmds.xform('base',q=1,ws=1,rp=1)
tip_pos = cmds.xform('tip',q=1,ws=1,rp=1)

def relative_dist_from_pos(pos, ref):
# vector substract to get relative pos
    pos_from_ref = [m - n for m, n in zip(pos, ref)]
# pythagoras to get distance from vector
    dist_from_ref = (pos_from_ref[0]**2 + pos_from_ref[1]**2 + pos_from_ref[2]**2)**.5
    return dist_from_ref

def weight_from_dist(dist_from_base, dist_to_tip):
    normalize_fac = (1/(dist_from_base + dist_to_tip))
    dist_from_base *= normalize_fac
    dist_to_tip *= normalize_fac
    return dist_from_base, dist_to_tip

sel = cmds.ls(selection=True)

for obj in sel:
# find world space pos of feather
    feather_pos = cmds.xform(obj, q=1, ws=1, rp=1)

# call relative_dist_from_pos
    dist_from_base = relative_dist_from_pos(feather_pos, base_pos)
    dist_to_tip = relative_dist_from_pos(feather_pos, tip_pos)

# normalize distances
    weight_from_dist(dist_from_base, dist_to_tip)

# constrain the feather - weights are inverted
# because the smaller the distance, the stronger the constraint
    cmds.orientConstraint('base', obj, w=dist_to_tip)
    cmds.orientConstraint('tip', obj, w=dist_from_base)

There you are. Any pointers are appreciated.

Have a good night,

Hadriscus

来源:https://stackoverflow.com/questions/35833586/batch-constraining-objects-feathers-to-a-wing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!