Version 2 of my shockAssembly. This time written in python so no need for pymel
Made for constraining two objects together in the form of a shock absorber. Objects can be groupnodes or single geometry. Two required.
Locators will be created at the pivot of each object so be sure to move the pivot to where ever you want your shock to pivot from.
Locators can be parentconstrained to external objects in order to attach them. If you don’t want to use the locators there is a group and bone system in place to be used in existing rigs
Demo:
## ## Shockassembly ## ------------- ## 27 maj 2009 ## Jan-Erik "Jonne" Östman (jonne@jonne.net) ## ## www.jonne.net ## ## ## Instructions: ## ------------- ## Made for constraining two obejects together in the form of a shock absorber. ## Objects kan be groupnodes or single geometry. Two required. ## Locators will be created at the pivot of each object so be sure to move the ## pivot to where ever you want your shock to pivot from. ## Locators can be parentconstrained to external objects in order to attach them ## ## -------------------------------------------------------------------------------- import maya.cmds as cmds def createShockAssembly(start=None, end=None): sel = cmds.ls(sl=1) ## ## Create locators at object pivots to drive the setup ## # Find the world location of the selected object's pivot. firstPivot = cmds.xform(sel[0], q=1, ws=1, rp=1) secondPivot = cmds.xform(sel[1], q=1, ws=1, rp=1) # Create and move locators to pivot of selected object sFirstLoc = cmds.move(firstPivot[0],firstPivot[1],firstPivot[2], cmds.spaceLocator( n=(sel[0]+"_LOC" )) , absolute=True) sSecondLoc = cmds.move(secondPivot[0],secondPivot[1],secondPivot[2], cmds.spaceLocator( n=(sel[1]+"_LOC" )), absolute=True) ## ## Get start and end info ## if not start: if len(sel)>0: start = sel[0]+"_LOC" else: return 0 if not end: if len(sel)>1: end = sel[1]+"_LOC" else: return 0 ## ## Take userinput as a custom shockname ## result = cmds.promptDialog( title='Shock Name', message='Enter Name:', button=['OK', 'Cancel'], defaultButton='OK', cancelButton='Cancel', dismissString='Cancel') if result == 'OK': shockName = cmds.promptDialog(query=True, text=True) else: shockName = "shock_" ## ## Build the heirarchy ## locs = ["%s_GRP" % shockName, "%s_startPos_NUL" % shockName , "%s_StartGeo_GRP" % shockName, "%s_endPos_NUL" % shockName, "%s_EndGeo_GRP" % shockName] for c, cur in enumerate(locs): grp = cmds.group(n = cur, em = 1) locs[c] = grp #replace old list entry with new one # Parent groups to create heirarchy if c == 1: cmds.parent(grp, locs[0]) if c == 2: cmds.parent(grp, locs[1]) if c == 3: cmds.parent(grp, locs[0]) if c == 4: cmds.parent(grp, locs[1]) ## ## Build joints and IK ## startP = cmds.xform(start, q=1, ws=1, t=1) endP = cmds.xform(end, q=1, ws=1, t=1) cmds.xform(locs[1],ws = 1, t = (startP[0], startP[1], startP[2])) cmds.xform(locs[3],ws = 1, t = (endP[0], endP[1], endP[2])) # Clear selection cmds.select(cl=1) # Create joints jnt1 = cmds.joint(p = (startP[0], startP[1], startP[2]), r = 1) jnt2 = cmds.joint(p = (endP[0], endP[1], endP[2]), a=1, r = 1) cmds.joint(jnt1, e = True, zso = True, oj = "xyz") cmds.joint(jnt2 , e=True, zso = True, oj = 'xyz') # Create IKHandle ikh = cmds.ikHandle(sj = jnt1, ee = jnt2, sol = "ikRPsolver") # Hide joints and IKhandle cmds.setAttr(jnt1 + '.visibility', 0) cmds.setAttr(jnt2 + '.visibility', 0) cmds.setAttr(ikh[0] + '.visibility', 0) # Parent joints and IK under the main groupnode cmds.parent(jnt1, locs[0]) cmds.parent(ikh[0], locs[0]) ## ## Constraints ## # Create a polevector pvNul = cmds.group(n = "%s_shockJointCahinPoleVector_NUL" % shockName , em=1) cmds.parent(pvNul, jnt1) cmds.xform(pvNul, t = (0, 0, 5)) cmds.parent(pvNul, locs[0]) cmds.pointConstraint(locs[3], locs[4], n = locs[4] + "_PCN") cmds.poleVectorConstraint(pvNul, ikh[0], n = ikh[0] + "_PVC") # Orient and point constraints cmds.pointConstraint(locs[3], ikh[0], n = ikh[0] + "_PCN") cmds.pointConstraint(start,locs[0],mo=True,n="start_PCN") cmds.pointConstraint(end,locs[3],mo=True,n="end_PCN") cmds.orientConstraint(jnt2,locs[4],mo=True,n=locs[4]+"_OCN") cmds.orientConstraint(jnt1,locs[2],mo=True,n=locs[2]+"_OCN") # Create a new maingroup and parent everything under it mainGroup = cmds.group(n = "%s_GRP" % shockName, em=1) cmds.parent(sel[0],locs[2]) cmds.parent(sel[1], locs[4]) cmds.parent(start, mainGroup) cmds.parent(end, mainGroup) cmds.parent(locs[0], mainGroup) # end createShockAssembly() # Run the function createShockAssembly()