-
Notifications
You must be signed in to change notification settings - Fork 37
Practical Examples
This section provides practical examples of integrating boneDynamicsNode into existing workflows.
The following video demonstrates how to incorporate boneDynamicsNode into an existing FK rig. The process includes baking the simulation results onto FK controllers, enabling direct editing of keyframes after simulation.
Below are the scripts used in the video demonstration.
🔽Connect boneDynamicsNode to a Selected Joint Chain (used around 00:55 in the video)
from maya import cmds
cmds.loadPlugin("boneDynamicsNode.mll", qt=True)
def create_dynamics_node(bone, end):
if not bone in cmds.listRelatives(end, p=True):
print("Exit: {} is not {}'s parent.".format(bone, end))
return
boneDynamicsNode = cmds.createNode("boneDynamicsNode")
cmds.connectAttr('time1.outTime', boneDynamicsNode + '.time', force=True)
cmds.connectAttr(bone + '.translate', boneDynamicsNode + '.boneTranslate', f=True)
cmds.connectAttr(bone + '.parentMatrix[0]', boneDynamicsNode + '.boneParentMatrix', f=True)
cmds.connectAttr(bone + '.parentInverseMatrix[0]', boneDynamicsNode + '.boneParentInverseMatrix', f=True)
cmds.connectAttr(bone + '.jointOrient', boneDynamicsNode + '.boneJointOrient', f=True)
cmds.connectAttr(end + '.translate', boneDynamicsNode + '.endTranslate', f=True)
cmds.connectAttr(boneDynamicsNode + '.outputRotate', bone + '.rotate', f=True)
# collision radius
radius_sphere = cmds.createNode("implicitSphere")
cmds.connectAttr(boneDynamicsNode + '.radius', radius_sphere + '.radius', f=True)
radius_sphere_tm = cmds.listRelatives(radius_sphere, p=True)[0]
cmds.parent(radius_sphere_tm, end, r=True)
cmds.setAttr(radius_sphere_tm + '.overrideEnabled', 1)
cmds.setAttr(radius_sphere_tm + '.overrideDisplayType', 2)
return boneDynamicsNode
if __name__ == "__main__":
# Select joints in order from root to tip of the joint chain.
joints = cmds.ls(sl=True)
set_name = "boneDynamicsNodeSet"
if not cmds.objExists(set_name):
cmds.select(cl=True)
cmds.sets(name=set_name)
for bone, end in zip(joints[:-1], joints[1:]):
boneDynamicsNode = create_dynamics_node(bone, end)
if boneDynamicsNode:
cmds.sets(boneDynamicsNode, addElement=set_name)
🔽Apply Orient Constraint with PairBlend Node (used around 01:49 in the video)
from maya import cmds
def orient_const_with_pair_blend(master, slave, switch=None):
cons = cmds.orientConstraint(master, slave, mo=True)[0]
pb = cmds.createNode('pairBlend')
if switch :
cmds.connectAttr(switch, '{}.weight'.format(pb), f=True)
for at in 'XYZ':
cmds.connectAttr('{}.constraintRotate{}'.format(cons, at), '{}.inRotate{}2'.format(pb, at), f=True)
cmds.connectAttr('{}.outRotate{}'.format(pb, at), '{}.rotate{}'.format(slave, at), f=True)
if __name__ == "__main__":
sel = cmds.ls(sl=True)
orient_const_with_pair_blend(sel[0], sel[1]) # To connect a switch simultaneously, add "nodeName.attributeName" as an argument
🔽Parent a Shape to a Joint to Create a Controller (used around 07:28 in the video)
from maya import cmds
jnt = "joint1_target" # Name of the joint
crv = "nurbsCircle1" # Name of the curve shape
crv_shapes = cmds.listRelatives(crv, c=True, f=True)
cmds.parent(crv_shapes, jnt, s=True, add=True)
cmds.setAttr(jnt + ".drawStyle", 2)
cmds.delete(crv)
💡Note: Usage in Animation Process
In the video, the group nameddynamics_grp
and the colliders are the nodes related to dynamics. After baking the simulation to keyframes, all of these nodes can be deleted to proceed with the animation process.
In this case, the switching mechanism is unnecessary, and inserting a PairBlend node into the constraint is not required.