Creating a master controller based off average values from multiple controllers

29 views
Skip to first unread message

yann19

unread,
Oct 3, 2019, 8:07:42 PM10/3/19
to Python Programming for Autodesk Maya
Hi everyone,

I have created a 'bounding box' as a master controller that controls the rotation and translation of multiple controllers.
Currently I have been able to create the said master, by taking into account of the bounding box of the child controllers.

However I am having 2 issues.

1. Getting the master controller to move along together with the child controllers.
Initially I tried to rectify it by getting the averaging position/ rotation of the children controllers, keyed it into the master controller followed by parenting in the child controllers thereafter. While it seems right on the first frame, as soon as I go to the next frame, the children controllers went out of control.

I have attached a scene file for better clarity.

This is the script that I am using to create the master controller:
cmds.select('ctrl_A', add=True)
cmds.select('ctrl_B', add=True)
selections = cmds.ls(sl=True)

master_helper = cmds.curve(
        name="masterParent", degree = 1,
        point = [(-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (0.5, 0.5, -0.5),
             (-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5), (-0.5, -0.5, 0.5),
             (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5),
             (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5),
             (0.5, 0.5, -0.5), (0.5, -0.5, -0.5), (-0.5, -0.5, -0.5),
             (-0.5, 0.5, -0.5)]
    )

boundingBox = cmds.exactWorldBoundingBox(selections)
scaleX = abs(boundingBox[0] - boundingBox[3])
scaleY = abs(boundingBox[1] - boundingBox[4])
scaleZ = abs(boundingBox[2] - boundingBox[5])

cmds.xform(master_helper, scale=[scaleX, scaleY, scaleZ])

count = len(selections)
sums = [0,0,0]
for item in selections:
    pos = cmds.xform(item, q=True, rp=True, ws=True)
    sums[0] += pos[0]
    sums[1] += pos[1]
    sums[2] += pos[2]
center = [sums[0]/count, sums[1]/count, sums[2]/count]

cmds.move(center[0], center[1], center[2], master_helper)
cmds.makeIdentity(master_helper, apply=True, translate=True, rotate=True, scale=True)

cmds.parent('ctrl_A', master_helper)
cmds.parent('ctrl_B', master_helper)

And this is the averaging that I was trying to use but failing badly:
# This code portion is inserted before the parenting

trans_sum = [0,0,0]
rots_sum = [0,0,0]
for i in selections:
    trans = cmds.xform(i, query=True, translation=True)
    rots = cmds.xform(i, query=True, rotation=True)
    
    trans_sum[0] += trans[0]
    trans_sum[1] += trans[1]
    trans_sum[2] += trans[2]
    rots_sum[0] += rots[0]
    rots_sum[1] += rots[2]
    rots_sum[2] += rots[2]

trans_avg = [trans_sum[0]/count, trans_sum[1]/count, trans_sum[2]/count]
rots_avg = [rots_sum[0]/count, rots_sum[1]/count, rots_sum[2]/count]

cmds.xform(master_helper, ws=True, translation=trans_avg, rotation=rots_avg)
cmds.move(center[0], center[1], center[2], master_helper)

cmds.setKeyframe(master_helper)


2. I am wondering if it will also be possible to modify the master controller shape (the bounding box) where it will be located at the center of the child controllers?


animation_test.mb
Reply all
Reply to author
Forward
Message has been deleted
0 new messages