def orient( self, _orientchildless=True, _rotateOrder=None ) : # get the rotation order we're after if( not _rotateOrder ) : _rotateOrder = settings.rotationorder # check we have a child to aim to and decide of aim vectors aimvector = utils.aim_axis_to_vectors( _rotateOrder )[0] upvector = utils.aim_axis_to_vectors( _rotateOrder )[1] aim = aimvector children = self.getChildren() parent = self.getParent() if( not parent ) : parent = self if( len( children ) < 1 ) : if( not _orientchildless ) : utils.wrn( '%s has no children. Skipping orient...' % ( self.name() ) ) return False else : aim = [ a * b for a, b in zip( aimvector, [-1] * 3 ) ] pm.select( None ) # create children average aim locator childrenlocator = pm.spaceLocator() if( len( children ) ) : pm.delete( pm.pointConstraint( children + [ childrenlocator ], mo=False ) ) else : childrenlocator.setTranslation( parent.getTranslation( space='world' ), space='world' ) # create up aim locator and aim self to it uplocator = pm.spaceLocator() pm.delete( pm.pointConstraint( [ parent, self, childrenlocator, uplocator ], mo=False ) ) pm.delete( pm.aimConstraint( [ self, uplocator ], mo=False, wut='object', wuo=parent ) ) uplocator.translateBy( ( 0, 0, 0.5 ) ) # unparent children, aim the joint to the average of it's children, then reparent children for joint in children : joint.setParent( None ) pm.delete( pm.aimConstraint( [ childrenlocator, self ], mo=False, wut='object', wuo=uplocator, upVector=upvector, aim=aim ) ) pm.makeIdentity( self, a=True, r=True ) for joint in children : joint.setParent( self ) # tidy up pm.delete( childrenlocator ) pm.delete( uplocator ) pm.select( self ) return True
def connect_rigs( self, _blendcontrol=None ) : # get the object the blend attr should be added to blendcontrol = _blendcontrol if( not blendcontrol ) : blendcontrolname = utils.name_from_tags( settings.staticcontrols[ 'ikfkblend' ], 'control' ) blendcontrol = pm.PyNode( blendcontrolname ) try : # create the blend attr blendattrname = utils.name_from_tags( self.tree_root().name, 'blend' ) self.blendattr = utils.add_set_attr( blendcontrol, blendattrname, 0.0 ) except : utils.err( 'Could not create blend attribute on %s' % ( blendcontrol ) ) return False # blend between rigs onto blendjointchain jointchains = self.tree_children( 'jointchain' ) if( len( jointchains ) != 1 ) : utils.err( '%s does not have ONE jointchain in it\'s children. Not sure which to use as the blend chain.' % ( self ) ) return False blendjoints = jointchains[0].all_joints() rigs = self.tree_children( '.*Rig' ) multdivdict = {} # set min/max values for blendattr self.blendattr.setMin( 0 ) self.blendattr.setMax( len( self.tree_children( '.*Rig' ) ) - 1 ) for i, rig in enumerate( rigs ) : for jointchain in rig.tree_children( 'jointchain' ) : rigjoints = jointchain.all_joints() if( len( rigjoints ) != len( blendjoints ) ) : utils.wrn( '%s has a different number of joints to %s. Skipping...' % ( jointchain, jointchains[0] ) ) continue # create a triangle curve with float time offset by j # by overlapping each triangle, n number of rigs can be blended # _/\____ # __/\___ this is how 3 rigs would blend together # ___/\__ animcurve = pm.nodetypes.AnimCurveUL() animcurve.rename( utils.name_from_tags( self.tree_root().name, 'blend', rig.PARTNAME, 'animcurveUL' ) ) offset = i pm.setKeyframe( animcurve, f=-1 + offset, v=0 ) pm.setKeyframe( animcurve, f=0 + offset, v=1 ) pm.setKeyframe( animcurve, f=1 + offset, v=0 ) self.blendattr >> animcurve.input multdivdict[ rig ] = [] for rigjoint in rigjoints : # vary input of joints rotation by animcurve output multdiv = pm.nodetypes.MultiplyDivide() multdiv.rename( utils.name_from_tags( rigjoint, 'blend', rig.PARTNAME, 'multiplydivide' ) ) multdivdict[ rig ].append( multdiv ) # connect animcurev and rotate to multdiv animcurve.output >> multdiv.input1X animcurve.output >> multdiv.input1Y animcurve.output >> multdiv.input1Z rigjoint.rotate >> multdiv.input2 for j, blendjoint in enumerate( blendjoints ) : # use a PMA node to blend between the rigs pma = pm.nodetypes.PlusMinusAverage() pma.rename( utils.name_from_tags( blendjoint, 'blend', rig.PARTNAME, 'plusminusaverage' ) ) pma.operation.set( 1 ) # connect everything up k = 0 for rig, multdivlist in multdivdict.iteritems() : multdivlist[j].output >> pma.input3D[k] k += 1 pma.output3D >> blendjoint.rotate