コード例 #1
0
ファイル: fgshooter.py プロジェクト: Bumpybox/Tapp
def fixedCamera(render_cam, frame):
    '''
    Create an fgshooter camera fixed at the render camera's position for a spcified frame.
    '''
    # Not the best way to get the world position and rotation values out of the render_camera... but it works.
    # Pymel's matrix.rotate and matrix.getRotation() seem to be broken.
    tmp_node = pm.createNode("decomposeMatrix")
    render_cam.worldMatrix >> tmp_node.inputMatrix
    frame_position = [tmp_node.outputTranslateX.get(time = frame),
                      tmp_node.outputTranslateY.get(time = frame),
                      tmp_node.outputTranslateZ.get(time = frame)]
    frame_rotation = [tmp_node.outputRotateX.get(time = frame),
                      tmp_node.outputRotateY.get(time = frame),
                      tmp_node.outputRotateZ.get(time = frame)]
    pm.delete(tmp_node)

    # Create the fixed camera. Change it's wireframe color.
    fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera", position=frame_position, rotation=frame_rotation)
    pm.color(fg_cam, ud=2)

    # Adjust the fgshooter camera's scale to pass aperture, aspect, and focal length information.
    aperture = render_cam.horizontalFilmAperture.get(time = frame)
    aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get(time = frame)
    focal = 0.03937 * render_cam.focalLength.get(time = frame)

    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)
    fg_cam.scaleZ.set(focal)

    return fg_cam_shape
コード例 #2
0
ファイル: fgshooter.py プロジェクト: Bumpybox/Tapp
def currentCamera(render_cam):
    '''
    Create an fgshooter camera at same location as the render camera.
    '''
    # Duplicate the render camera and make sure the duplicate is not renderable.
    fg_cam = pm.duplicate(render_cam, rr=True, name="fgshooterCamera")[0]
    fg_cam_shape = fg_cam.getShape()
    fg_cam_shape.renderable.set(False)
    # Change the fgshooter camera's wireframe color.
    pm.color(fg_cam, ud=2)

    # Find the render camera's transfrom and parent the fgshooter to it.
    render_cam_transform = render_cam.listRelatives(p=True, type="transform")[0]
    pm.parent(fg_cam, render_cam_transform)

    # Pass aperture and aspect information with the fgshooter camera's scale.
    aperture = render_cam.horizontalFilmAperture.get()
    aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get()
    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)

    # Connect the render camera's focal length to the fgshooter since it could be animated.
    multiply_divide = pm.createNode("multiplyDivide")
    multiply_divide.input2X.set(0.03937)
    render_cam.focalLength >> multiply_divide.input1X
    multiply_divide.outputX >> fg_cam.scaleZ

    return fg_cam_shape
コード例 #3
0
def currentCamera(render_cam):
    '''
    Create an fgshooter camera at same location as the render camera.
    '''
    # Duplicate the render camera and make sure the duplicate is not renderable.
    fg_cam = pm.duplicate(render_cam, rr=True, name="fgshooterCamera")[0]
    fg_cam_shape = fg_cam.getShape()
    fg_cam_shape.renderable.set(False)
    # Change the fgshooter camera's wireframe color.
    pm.color(fg_cam, ud=2)

    # Find the render camera's transfrom and parent the fgshooter to it.
    render_cam_transform = render_cam.listRelatives(p=True,
                                                    type="transform")[0]
    pm.parent(fg_cam, render_cam_transform)

    # Pass aperture and aspect information with the fgshooter camera's scale.
    aperture = render_cam.horizontalFilmAperture.get()
    aspect = aperture / pm.Attribute(
        "defaultResolution.deviceAspectRatio").get()
    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)

    # Connect the render camera's focal length to the fgshooter since it could be animated.
    multiply_divide = pm.createNode("multiplyDivide")
    multiply_divide.input2X.set(0.03937)
    render_cam.focalLength >> multiply_divide.input1X
    multiply_divide.outputX >> fg_cam.scaleZ

    return fg_cam_shape
コード例 #4
0
ファイル: joint.py プロジェクト: Aiacos/DevPyLib
    def maketwistJoints(self, parentJnt, nTwistJoint, rotAxis):
        prefix = name.removeSuffix(parentJnt)
        parentJntChild = pm.listRelatives(parentJnt, c=1, type='joint')[0]

        # make twist joints
        twistJntGrp = pm.group(n=prefix + 'TwistJoint_GRP',
                               p=self.twistJointsMainGrp,
                               em=1)

        twistParentJnt = pm.duplicate(parentJnt,
                                      n=prefix + 'TwistStart_JNT',
                                      parentOnly=True)[0]
        twistChildJnt = pm.duplicate(parentJntChild,
                                     n=prefix + 'TwistEnd_JNT',
                                     parentOnly=True)[0]

        # adjust twist joints
        origJntRadius = pm.getAttr(parentJnt + '.radius')

        for j in [twistParentJnt, twistChildJnt]:
            pm.setAttr(j + '.radius', origJntRadius * 2)
            pm.color(j, ud=1)

        pm.parent(twistChildJnt, twistParentJnt)
        pm.parent(twistParentJnt, twistJntGrp)

        # attach twist joints
        pm.pointConstraint(parentJnt, twistParentJnt)

        # make IK handle
        twistIk = pm.ikHandle(n=prefix + 'TwistJoint_IKH',
                              sol='ikSCsolver',
                              sj=twistParentJnt,
                              ee=twistChildJnt)[0]
        pm.hide(twistIk)
        pm.parent(twistIk, twistJntGrp)
        pm.parentConstraint(parentJntChild, twistIk)

        pm.hide(twistParentJnt)

        innerJointList = self.makeInnerTwistJoints(prefix, twistParentJnt,
                                                   twistChildJnt, nTwistJoint,
                                                   rotAxis)
        pm.parent(innerJointList, twistJntGrp)

        # Constriant twistJoint group to main Joint
        pm.parentConstraint(parentJnt, twistJntGrp, mo=True)
コード例 #5
0
ファイル: curve.py プロジェクト: kyuhoChoi/mayaTools
def createLinkedCrv( *curves ):
    '''
    update : 2015-04-24
    '''
    if curves:
        pm.select( curves )
    curves = pm.selected()
    if not curves:
        raise

    #curves = pm.filterExpand( sm=9 )
    #curves = [ pm.PyNode(curve) for curve in curves ]

    linkedCrvs = []

    for curve in curves:       
        # 입력된 커브의 트랜스폼 노드의 히아라키 위치를 맞춰줌
        linkedCrv = pm.group(em=True)
        parent = curve.getParent()
        if parent:
            linkedCrv.setParent(space, r=True)
        linkedCrv.setMatrix( curve.getMatrix( ws=True ), ws=True )

        # 피봇 위치 맞춤
        rotatePiv = curve.getRotatePivot( space='world' )
        scalePiv  = curve.getScalePivot(  space='world' )    
        linkedCrv.setRotatePivot( rotatePiv, ws=True )
        linkedCrv.setScalePivot(  scalePiv,  ws=True )

        # 커브 쉐입 생성
        linkedCrvShape = pm.createNode('nurbsCurve', p=linkedCrv )

        # 연결 : 핵심 !
        curve.getShape().worldSpace[0] >> linkedCrvShape.create

        # 컬러 변경
        pm.color( linkedCrvShape, ud=1 )

        # 이름 변경 
        linkedCrv.rename( curve+'_linkedCrv#')

        linkedCrvs.append( linkedCrv )

    pm.select(linkedCrvs)
    return linkedCrvs
コード例 #6
0
def fixedCamera(render_cam, frame):
    '''
    Create an fgshooter camera fixed at the render camera's position for a spcified frame.
    '''
    # Not the best way to get the world position and rotation values out of the render_camera... but it works.
    # Pymel's matrix.rotate and matrix.getRotation() seem to be broken.
    tmp_node = pm.createNode("decomposeMatrix")
    render_cam.worldMatrix >> tmp_node.inputMatrix
    frame_position = [
        tmp_node.outputTranslateX.get(time=frame),
        tmp_node.outputTranslateY.get(time=frame),
        tmp_node.outputTranslateZ.get(time=frame)
    ]
    frame_rotation = [
        tmp_node.outputRotateX.get(time=frame),
        tmp_node.outputRotateY.get(time=frame),
        tmp_node.outputRotateZ.get(time=frame)
    ]
    pm.delete(tmp_node)

    # Create the fixed camera. Change it's wireframe color.
    fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera",
                                     position=frame_position,
                                     rotation=frame_rotation)
    pm.color(fg_cam, ud=2)

    # Adjust the fgshooter camera's scale to pass aperture, aspect, and focal length information.
    aperture = render_cam.horizontalFilmAperture.get(time=frame)
    aspect = aperture / pm.Attribute(
        "defaultResolution.deviceAspectRatio").get(time=frame)
    focal = 0.03937 * render_cam.focalLength.get(time=frame)

    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)
    fg_cam.scaleZ.set(focal)

    return fg_cam_shape
コード例 #7
0
ファイル: controls.py プロジェクト: kinetifex/maya-kinetifex
def rigLimbCmd( prefix='leg_', suffix=None, side=LEFT_SIDE, hasStretch=False, hasFootRoll=False, footRollMode=FOOTROLL_AUTO ):

    suffix = suffix or ('_l','_r')[side]
    exp_template = ""

    labels = {
        'control'      : prefix + 'control' + suffix,
        'aimControl'   : prefix + 'aim'  + suffix,
        'ik'           : prefix + 'ik' + suffix,
        'ikEnd'        : prefix + 'ik_end' + suffix,
        'expression'   : prefix + 'control' + suffix + '_EXP',

        'guideJointIk' : prefix + 'ik_guide_',
        'guideJoint'   : prefix + 'guide_',
        'ikStretch'    : prefix + 'ik_stretch' + suffix,
        'locStart'     : prefix + 'loc_start' + suffix,
        'locMid'       : prefix + 'loc_mid' + suffix,
        'locEnd'       : prefix + 'loc_end' + suffix,
        'locGuide'     : prefix + 'loc_guide' + suffix,
        'ikGuide'      : prefix + 'ik_guide' + suffix,
    }


    try:
        start_joint, end_joint = pm.ls(sl=1,type="joint")
    except ValueError:
        raise ValueError, "Select the start and end joints to setup."

    mid_joint = end_joint.getParent()
    parent_joint = start_joint.getParent()

    unit_scale = start_joint.getRotatePivot(ws=1)[-1]

    # -- positions and length

    start_point = start_joint.getRotatePivot(ws=1) * unit_scale
    end_point =   end_joint.getRotatePivot(ws=1) * unit_scale
    mid_point =   mid_joint.getRotatePivot(ws=1) * unit_scale
    length =      start_point.distanceTo( end_point )

    # -- Create Control

    control = createNurbsShape( labels['control'], 'sphere', size=length*.2 )
    control2 = createNurbsShape( labels['control'], 'locator', size=length*.3 )
    pm.parent( control2.getShape(), control, r=1, s=1 )
    pm.delete( control2 )
    control.translate.set( end_point )

    pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 )

    control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 )
    control.addAttr( "orientBlend", at='double', k=1, dv=0, min=0, max=1 )

    # -- Create Aim Control

    v1 = end_point - start_point
    v2 = mid_point - start_point
    v3 = v1.cross( v2 )
    v4 = v3.cross( v1 )
    aim_point = start_point + ( v4.normal() * length * 1.5 )

    aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/5 )
    pm.xform( aim_control, t=aim_point )
    pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 )

    pm.aimConstraint(  mid_joint, aim_control, weight=1, aimVector=(0, 0, 1) )

    # -- Create Aim Line

    aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] )

    line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 )
    line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 )

    pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 )
    pm.pointConstraint( mid_joint, line_handle1, offset=(0,0,0), weight=1 )

    line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" )
    line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" )

    pm.parent( [aim_line,
                line_group0,
                line_group1,
                aim_control] )

    line_group0.v.set(0)
    line_group1.v.set(0)
    setAttrs( line_group0, ['t','r','s','v'], lock=1 )
    setAttrs( line_group1, ['t','r','s','v'], lock=1 )

    setAttrs( aim_line, ['t','r','s','v'], lock=1 )

    aim_line.overrideEnabled.set(1)
    aim_line.overrideDisplayType.set(1)


    if hasStretch:
        guide_ik_start = pm.duplicate( start_joint, rc=1 )[0]
        guide_ik_mid, guide_ik_end = pm.ls( guide_ik_start, dag=1 )[1:3]

        for n in pm.ls( guide_ik_start, dag=1 ):
            pm.rename( n, labels['guideJointIk'] + n[:-1] )

        guide_start = pm.duplicate( start_joint, rc=1 )[0]
        guide_mid, guide_end = pm.ls( guide_start, dag=1 )[1:3]

        for n in pm.ls( guide_start, dag=1 ):
            pm.rename( n, labels['guideJoint'] + n[:-1] )


        parent_group = pm.group( name=labels['ikStretch'], em=1 )

        if parent_joint is not None:
            parent_group.setRotatePivot( parent_joint.getRotatePivot(ws=1) * unit_scale, ws=1 )
            pm.parentConstraint( parent_joint, parent_group, weight=1 )

        pm.parent( guide_ik_start, guide_start, parent_group )

        # -- build a temp joint chain to get loc_mid position

        loc_start = pm.group( n=labels['locStart'], em=1 )

        pm.parent( loc_start, parent_group )


        loc_start.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 )

        pm.aimConstraint( control, loc_start, weight=1, aimVector=(1,0,0) )

        loc_end = pm.group( n=labels['locEnd'], em=1, parent=loc_start )
        loc_end.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 )

        pm.pointConstraint( control, loc_end, offset=(0,0,0), skip=('y','z'), weight=1 )


        pm.select(cl=1)
        temp_start = pm.joint( p=start_point )
        temp_end = pm.joint( p=end_point )
        pm.joint( temp_start, edit=1, oj='xyz', secondaryAxisOrient='yup', ch=1 )
        pm.pointConstraint( mid_joint, temp_end, offset=(0,0,0), skip=('y','z'), weight=1 )

        loc_mid_point =   temp_end.getRotatePivot(ws=1) * unit_scale
        pm.delete( temp_start )

        # -- create the mid locator

        loc_mid = pm.group( n=labels['locMid'], em=1)#spaceLocator()
        loc_mid.translate.set( loc_mid_point )
        pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 )

        pm.pointConstraint( loc_start, loc_mid, mo=1, weight=1 )
        pm.pointConstraint( loc_end,   loc_mid, mo=1, weight=1 )

        # -- create the guide locator

        loc_guide = pm.group( n=labels['locGuide'], em=1)

        guide_constraint = pm.pointConstraint( loc_mid, loc_guide, offset=(0,0,0), weight=1 )
        pm.pointConstraint( guide_ik_mid, loc_guide, offset=(0,0,0), weight=1 )

        pm.parent( loc_mid, loc_guide, parent_group )

        guide_ik, guide_ee = pm.ikHandle( sj=guide_ik_start, ee=guide_ik_end, solver="ikRPsolver", dh=1 )
        pm.poleVectorConstraint( aim_control, guide_ik, weight=1 )
        pm.delete( guide_ik_end )

        pm.rename( guide_ik, labels['ikGuide'] )

        # -- SET STRETCH BLEND START

        guide_ik.addAttr( "stretchStart", at='double', k=1 )
        guide_ik.stretchStart.set( loc_end.tx.get() )

        # -- SET STRETCH BLEND END

        guide_ik.addAttr( "stretchEnd", at='double', k=1 )
        guide_ik.stretchEnd.set( loc_end.tx.get()*1.1 )

        # -- SET STRETCH BLEND END

        guide_ik.addAttr( "stretchFactor", at='double', k=1 )
        guide_ik.stretchFactor.set( 0.22 )


        # -- setup guide joints

        pm.aimConstraint( loc_guide, guide_start, weight=1, aimVector=(1,0,0) )
        pm.aimConstraint( loc_end, guide_mid, weight=1, aimVector=(1,0,0) )

        pm.pointConstraint( loc_guide, guide_mid, offset=(0,0,0), skip=('y','z'), weight=1 )
        pm.pointConstraint( loc_end, guide_end, offset=(0,0,0), skip=('y','z'), weight=1 )

        pm.parent( guide_ik, loc_end )
        pm.parent( guide_ik, control )

        # -- add stretch addtributes

        start_joint.addAttr( "stretch", at='double', k=1, dv=0 )
        mid_joint.addAttr( "stretch", at='double', k=1, dv=0 )


        control.addAttr( "stretchBlend", at='double', k=1, dv=0, min=0, max=1 )

        # -- build the expression

        exp_template += EXP_STRETCH \
        % { 'guide_ik'     : guide_ik,
            'loc_end'      : loc_end,
            'constraint'   : guide_constraint,

            # -- we only need these names for the constraint attribute names

            'guide_ik_mid' : guide_ik_mid.split('|')[-1],
            'loc_mid'      : loc_mid.split('|')[-1],

            'control'      : control,
            'start_joint'  : start_joint,
            'mid_joint'    : mid_joint,
            'end_joint'    : end_joint,
            'guide_mid'    : guide_mid,
            'guide_end'    : guide_end,
            }

        # -- make things look pretty

        for n in pm.ls( [ parent_group, guide_ik ], dag=1 ):
            n.visibility.set(0)

        for obj in guide_end.getChildren( type='joint' ):
            try:
                pm.delete( obj )
            except:
                pass


    # -- hook up the original joints

    main_ik, main_ee = pm.ikHandle( sj=start_joint, ee=end_joint, solver="ikRPsolver", dh=1 )
    pm.poleVectorConstraint( aim_control, main_ik, weight=1 )
    pm.rename( main_ik, labels['ik'] )

    end_ik, end_ee = pm.ikHandle( sj=end_joint, ee=end_joint.getChildren(type='joint')[0], solver="ikRPsolver", dh=1 )
    pm.rename( end_ik, labels['ikEnd'] )

    pm.parent( main_ik, end_ik, control )

    # -- fill out the expression template
    exp_template += EXP_IKFK + EXP_VIS

    exp_str = exp_template \
    % {
        #'guide_ik'     : guide_ik,
        #'loc_end'      : loc_end,
        #'constraint'   : guide_constraint,

        #we only need these names for the constraint attribute names
        #'guide_ik_mid' : guide_ik_mid.split('|')[-1],
        #'loc_mid'      : loc_mid.split('|')[-1],

        'control'      : control,
        'start_joint'  : start_joint,
        'mid_joint'    : mid_joint,
        'end_joint'    : end_joint,
        #'guide_mid'    : guide_mid,
        #'guide_end'    : guide_end,
        'main_ik'      : main_ik,
        'end_ik'       : end_ik,

        'shape1'       : control.getChildren(type="nurbsCurve")[0],
        'shape2'       : control.getChildren(type="nurbsCurve")[1],
        }

    pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' )

    if hasFootRoll:
        rigFootRoll( end_joint, control, prefix, suffix, side=side, footRollMode=footRollMode )

    resetIkSetupCmd(end_joint, control)
    resetIkSetupCmd(start_joint, aim_control)

    # -- make things look pretty

    for n in pm.ls( control, dag=1, type="transform" )[1:]:
        if n.type() != "transform":
            n.visibility.set(0)

    setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )
    pm.setAttr(aim_control.v, keyable=0 )

    addToSet( [control, aim_control], 'controlsSet' )

    pm.select( [control, aim_control], r=1 )
    pm.color( ud=(CntlColors.left, CntlColors.right)[side] )

    control.displayHandle.set(1)
    pm.select( control, r=1 )

    pm.reorder( control.getShape(), back=1 )

    return [ control, aim_control ]
コード例 #8
0
ファイル: controls.py プロジェクト: kinetifex/maya-kinetifex
def rigHeadCmd( prefix='head_', suffix='', hasStretch=True ):

    exp_template = EXP_HEAD

    labels = {
        'control'     : prefix + 'control' + suffix,
        'aimControl'  : prefix + 'aim' + suffix,
        'ik'          : prefix + 'ik' + suffix,
        'ikEnd'       : prefix + 'ik_end' + suffix,
        'parent'      : prefix + 'parent' + suffix,
        'expression'  : prefix + 'control' + suffix + '_EXP',
        'parent'      : prefix + 'parent' + suffix,
        'pivot'       : prefix + 'pivot' + suffix,
    }

    try:
        start_joint = pm.ls(sl=1,type="joint")[0]
    except ValueError:
        raise ValueError, "Select the root joint to setup."

    end_joint = start_joint.getChildren(type='joint')[0]
    neck_joint = start_joint.getParent()
    parent_joint = neck_joint.getParent()

    if neck_joint is None:
        raise ValueError, "Start joint must have a parent joint (neck)."
    if parent_joint is None:
        raise ValueError, "Start joint parent must have a parent transform (spine)."


    unit_scale = start_joint.getRotatePivot(ws=1)[-1]
    start_point = start_joint.getRotatePivot(ws=1) * unit_scale
    end_point = end_joint.getRotatePivot(ws=1) * unit_scale

    mid_point = ( start_point + end_point ) / 2
    length = start_point.distanceTo( end_point )

    aim_point = Vector( start_point[0], start_point[1], start_point[1])*100

    # -- build controls

    control = createNurbsShape( labels['control'], width=length, height=length*1.2, depth=length*1.1 )
    control.translate.set( mid_point )
    pm.makeIdentity( control, apply=True, t=1 )
    control.rotatePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale )
    control.scalePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale )
    control.selectHandle.set( start_joint.getRotatePivot(ws=1) * unit_scale )

    control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 )
    control.addAttr( "aimBlend", at='double', k=1, dv=0, min=0, max=1 )

    # -- build aim control

    aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/1.5 )
    aim_control.translate.set( aim_point )
    pm.makeIdentity( aim_control, apply=True, t=1 )

    pm.aimConstraint(  start_joint, aim_control, weight=1, aimVector=(0, 0, 1) )

    # -- Create Aim Line

    aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] )

    line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 )
    line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 )

    pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 )
    pm.pointConstraint( start_joint, line_handle1, offset=(0,0,0), weight=1 )

    line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" )
    line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" )

    pm.parent( [aim_line,
                line_group0,
                line_group1,
                aim_control] )

    line_group0.v.set(0)
    line_group1.v.set(0)
    setAttrs( line_group0, ['t','r','s','v'], lock=1 )
    setAttrs( line_group1, ['t','r','s','v'], lock=1 )

    setAttrs( aim_line, ['t','r','s','v'], lock=1 )

    aim_line.overrideEnabled.set(1)
    aim_line.overrideDisplayType.set(1)

    # -- build helper groups

    pivot_grp = pm.group( n=labels['pivot'], em=1 )
    parent_grp = pm.group( pivot_grp, n=labels['parent'] )
    parent_grp.translate.set( control.getRotatePivot(ws=1) * unit_scale )
    pm.makeIdentity( parent_grp, apply=True, t=1 )

    pivot_grp.rotateOrder.set(2)

    # -- create ik handles

    main_ik, main_ee = pm.ikHandle( n=labels['ik'],  sj=neck_joint, ee=end_joint, sol='ikRPsolver', dh=1 )
    #main_ik, main_ee = pm.ikHandle( n=labels['ik'],  sj=neck_joint, ee=start_joint, sol='ikRPsolver', dh=1 )
    #end_ik, end_ee = pm.ikHandle( n=labels['ikEnd'], sj=start_joint, ee=end_joint, sol='ikSCsolver', dh=1 )

    pm.parent( main_ik, control )
    pm.parent( control, pivot_grp )

    # -- set up constraints

    #pm.aimConstraint( control, aim_control, weight=1, aimVector=(0, 0, -1), mo=1 )
    pm.aimConstraint( aim_control, pivot_grp, weight=1, aimVector=(0, 0, 1), mo=1 )
    pm.setKeyframe( pivot_grp.r )

    pm.parentConstraint( parent_joint, parent_grp, weight=1, mo=1 )


    resetIkSetupCmd(start_joint, control)
    resetIkSetupCmd(start_joint, aim_control)


    exp_str = exp_template \
    % { 'control'      : control,
        'start_joint'  : start_joint,
        'end_joint'    : end_joint,
        'parent_joint' : parent_joint,
        'main_ik'      : main_ik,
        #'end_ik'       : end_ik,

        'pivot'        : pivot_grp,
        'shape'        : control.getShape(),
        }

    pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' )

    # -- make things look pretty

    for n in pm.ls( [main_ik], dag=1, type="transform" ):
        n.visibility.set(0)

    control.displayHandle.set(1)
    addToSet( [control, aim_control], 'controlsSet' )

    setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )
    pm.setAttr(aim_control.v, keyable=0 )

    pm.select( [control,aim_control], r=1 )

    pm.color( ud=CntlColors.head )


    return [ control, aim_control ]
コード例 #9
0
ファイル: controls.py プロジェクト: kinetifex/maya-kinetifex
def rigSpineCmd( prefix='spine_', suffix='', hasStretch=False, worldSpace=False ):

    exp_template = ''

    labels = {
        'end_control' : prefix + 'control_end' + suffix,
        'mid_control' : prefix + 'control_mid' + suffix,
        'ik'          : prefix + 'ik' + suffix,
        'curve'       : prefix + 'curve' + suffix,
        'cluster'     : prefix + 'cluster' + suffix,
        'clusters'    : prefix + 'clusters' + suffix,
        'parent'      : prefix + 'parent' + suffix,
        'expression'  : prefix + 'controls' + suffix + '_EXP',
    }

    try:
        start_joint, end_joint = pm.ls(sl=1,type="joint")
    except ValueError:
        raise ValueError, "Select the start and end joints to setup."

    parent_joint = start_joint.getParent()
    mid_joint = start_joint.getChildren(type='joint')[0]

    if parent_joint is None:
        raise ValueError, "Start joint must have a parent transform."

    main_ik, main_ee, main_curve = pm.ikHandle( n=labels['ik'],
                                             sj=start_joint,
                                             ee=end_joint,
                                             sol='ikSplineSolver',
                                             pcv=True,
                                             numSpans=1,
                                             dh=1
                                             )

    main_curve.rename( labels['curve'] )

    cluster0, handle0 = pm.cluster( main_curve+'.cv[0]', main_curve+'.cv[1]',
                                 n=labels['cluster']+'0', en=1, rel=1
                                 )
    cluster1, handle1 = pm.cluster( main_curve+'.cv[1]', main_curve+'.cv[2]',
                                 n=labels['cluster']+'1', en=1, rel=1
                                 )
    cluster2, handle2 = pm.cluster( main_curve+'.cv[4]',
                                 n=labels['cluster']+'2', en=1, rel=1
                                 )


    start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1]
    end_point = end_joint.getRotatePivot(ws=1) * end_joint.getRotatePivot(ws=1)[-1]
    handle1_point = handle1.getRotatePivot(ws=1) * handle1.getRotatePivot(ws=1)[-1]
    length = start_point.distanceTo( end_point )

    # -- build controls

    control = pm.circle( n=labels['end_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0]
    control.translate.set( end_point )
    control.rotateOrder.set(1)

    mid_control = pm.circle( n=labels['mid_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0]
    mid_control.translate.set( handle1_point )

    pm.makeIdentity( [ control, mid_control ], apply=True, s=0, r=0, t=1, n=0 )

    # -- add control attributes

    control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 )


    # -- constrain controls

    pm.pointConstraint( control, handle2, offset=(0,0,0), weight=1 )
    pm.aimConstraint( handle1, control, weight=1, aimVector=(0,-1,0), skip='y' )

    pm.pointConstraint( mid_control, handle1, offset=(0,0,0), weight=1 )
    pm.aimConstraint( handle0, mid_control, weight=1, aimVector=(0,1,0) )

    if worldSpace:
        pm.pointConstraint( parent_joint, handle0, maintainOffset=1, weight=1 )


    # -- group and parent nodes

    cluster_group = pm.group( handle0, handle1, handle2, name=labels['clusters'] )

    parent_group = pm.group( name=labels['parent'], em=1 )
    parent_group.rotatePivot.set( parent_joint.getRotatePivot(ws=1) )

    pm.parent( control, mid_control, main_ik, main_curve, cluster_group, parent_group )
    if not worldSpace:
        pm.parentConstraint( parent_joint, parent_group, w=1, mo=1 )


    if hasStretch:
        control.addAttr( "stretch", at='double', k=1, dv=0, min=-1, max=1 )
        exp_template += EXP_SPINE_STRETCH


    exp_template += EXP_SPINE

    exp_str = exp_template \
    % { 'control'      : control,
        'start_joint'  : start_joint,
        'end_joint'    : end_joint,
        'mid_joint'    : mid_joint,
        'parent_joint' : parent_joint,
        'main_ik'      : main_ik,

        'shape'        : control.getShape(),
        'mid_shape'    : mid_control.getShape(),
        }

    pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' )

    resetIkSetupCmd(end_joint, control)

    # -- make things look pretty

    for n in pm.ls( [main_ik, main_curve, cluster_group], dag=1, type="transform" ):
        n.visibility.set(0)

    addToSet( [control, mid_control], 'controlsSet' )
    control.displayHandle.set(1)

    setAttrs( control, ['rx','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    setAttrs( mid_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )
    pm.setAttr(mid_control.v, keyable=0 )

    pm.color( ud=CntlColors.center )

    pm.select( control, r=1 )

    return [ control, mid_control ]
コード例 #10
0
ファイル: controls.py プロジェクト: kinetifex/maya-kinetifex
def rigRootCmd( prefix='root_', seperate_rotation=False, rotate_prefix='pelvis_' ):

    labels = {
        'control' : prefix + 'control',
        'rotateControl' : rotate_prefix + 'control'
    }

    try:
        start_joint = pm.ls(sl=1,type="joint")[0]
    except ValueError:
        raise ValueError, "Select the root joint to setup."


    start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1]

    control = pm.circle( n=labels['control'], radius=(start_point[1] / .035), normal=(0,1,0), ch=0 )[0]
    control2 =  createNurbsShape( labels['rotateControl'],
                                  width=( start_point[1] / .025),
                                  height=(start_point[1] / .045),
                                  depth=( start_point[1] / .035),
                                  )

    control.translate.set( start_point )
    control2.translate.set( start_point )

    if not seperate_rotation:
        pm.parent( control2.getShape(), control, r=1, s=1 )
        pm.delete( control2 )
    else:
        pm.parent( control2, control )
        pm.makeIdentity( control2, apply=True, s=0, r=0, t=1, n=0 )

    pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 )


    pm.pointConstraint(  control, start_joint, offset=(0,0,0), weight=1 )

    if not seperate_rotation:
        pm.orientConstraint( control, start_joint, weight=1, mo=1 )
    else:
        pm.orientConstraint( control2, start_joint, weight=1, mo=1 )


    control.displayHandle.set(1)
    addToSet( [control], 'controlsSet' )

    setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 )
    pm.setAttr(control.v, keyable=0 )

    pm.select( control, r=1 )
    pm.color( ud=CntlColors.center )

    pm.reorder( control.getShape(), back=1 )

    if seperate_rotation:
        addToSet( [control2], 'controlsSet' )

        setAttrs( control2, ['t','s'], channelBox=0, keyable=0, lock=1 )
        pm.setAttr(control2.v, keyable=0 )

        pm.select( control2, add=1 )
        pm.color( ud=CntlColors.center )


    return pm.ls(sl=1)
コード例 #11
0
ファイル: controls.py プロジェクト: kinetifex/maya-kinetifex
def rigFootRoll( foot_joint, control, prefix, suffix=None, side=LEFT_SIDE, footRollMode=FOOTROLL_AUTO ):

    suffix = suffix or ('_l','_r')[side]
    exp_template = ""

    labels = {
        'expression'   : prefix + 'control' + suffix + '_EXP',
        'ikToe'        : prefix + 'ik_toe' + suffix,
        'pivotBall'    : prefix + 'pivot_ball' + suffix,
        'pivotToe'     : prefix + 'pivot_toe' + suffix,
        'rotateToe'    : prefix + 'rotate_toe' + suffix,
        'pivotHeel'    : prefix + 'pivot_heel' + suffix,
    }

    handles = control.getChildren(type='ikHandle')
    if len(handles) == 3:
        guide_ik, main_ik, end_ik = handles
    else:
        main_ik, end_ik = handles
        guide_ik = None

    toe_joint, heel_joint = foot_joint.getChildren( type='joint' )[:2]
    end_joint = toe_joint.getChildren( type='joint' )[0]

    toe_length = toe_joint.translate.get().length()
    heel_length = heel_joint.translate.get().length()


    pm.select( toe_joint, end_joint, r=1 )
    toe_ik, toe_ee = pm.ikHandle( name=labels['ikToe'], sol='ikRPsolver', dh=1 )

    # -- add pivot groups

    pivot_ball = createNurbsShape( labels['pivotBall'], shape='U', size=toe_length )
    pivot_ball.translate.set( toe_joint.getRotatePivot(ws=1)/100 )
    pivot_ball.ty.set( pivot_ball.ty.get() + toe_length/2 )
    pivot_ball.rotate.set(-90,90,0)
    pm.makeIdentity(pivot_ball, apply=True, translate=True, rotate=True, scale=True)
    pivot_ball.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 )

    if guide_ik:
        pm.parent( main_ik, guide_ik, pivot_ball )
    else:
        pm.parent( main_ik, pivot_ball )


    pivot_toe = createNurbsShape( labels['pivotToe'], shape='U', size=toe_length  )
    pivot_toe.translate.set( end_joint.getRotatePivot(ws=1)/100 )
    pm.makeIdentity(pivot_toe, apply=True, translate=True, rotate=True, scale=True)

    pm.parent( pivot_ball, end_ik, pivot_toe )

    rotate_toe = pm.group( toe_ik, n=labels['rotateToe'] )
    rotate_toe.setRotatePivot( toe_joint.getRotatePivot(ws=1), ws=1 )

    pivot_heel = createNurbsShape( labels['pivotHeel'], shape='U', size=heel_length  )
    pivot_heel.translate.set( heel_joint.getRotatePivot(ws=1)/100 )
    pivot_heel.ry.set(180)
    pm.makeIdentity(pivot_heel, apply=True, translate=True, rotate=True, scale=True)

    pm.parent( pivot_toe, rotate_toe, pivot_heel )

    pm.parent( pivot_heel, control )


    exp_str = pm.expression( labels['expression'], query=1, s=1 )

    # -- fill out the expression template

    exp_template += EXP_FOOT_IKFK

    exp_str += exp_template \
    % {
        'toe_ik'      : toe_ik,
        'end_ik'       : end_ik
        }


    if footRollMode == FOOTROLL_AUTO:

        control.addAttr( "footRoll",  sn="fr", at='double', k=1, dv=0, min=-10, max=20 )
        control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 )

        control.tr >> rotate_toe.rx

        # -- Set Driven Keys

        pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr,  dv=10,  v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_toe.rx, cd=control.fr,  dv=20,  v=60, itt='linear' )

        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=0,   v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=10,  v=60, itt='linear' )
        pm.setDrivenKeyframe( pivot_ball.rx, cd=control.fr, dv=20,  v=0, itt='linear' )

        pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=0,   v=0,   ott='linear' )
        pm.setDrivenKeyframe( pivot_heel.rx, cd=control.fr, dv=-10, v=-40,  itt='linear' )


    elif footRollMode == FOOTROLL_CONTROLS:

        for obj in pm.ls( control, dag=1, type="nurbsCurve" ):
            addToSet( [obj.getParent()], 'controlsSet' )

        exp_template += EXP_FOOT_IKFK

        exp_str += EXP_FOOT_IKFK_CONTROLS \
        % {
            'heel_pivot_shape'  : pivot_heel.getShape(),
            'ball_pivot_shape'  : pivot_ball.getShape(),
            'toe_pivot_shape'   : pivot_toe.getShape(),
            'end_ik'            : end_ik
            }

    else: #footRollMode == FOOTROLL_ATTRIBUTES

        control.addAttr( "heelPivot", sn="hp", at='double', k=1, dv=0 )
        control.addAttr( "ballPivot", sn="bp", at='double', k=1, dv=0 )
        control.addAttr( "toePivot",  sn="tp", at='double', k=1, dv=0 )
        control.addAttr( "toeRotate", sn="tr", at='double', k=1, dv=0 )

        control.hp >> pivot_heel.rx
        control.bp >> pivot_ball.rx
        control.tp >> pivot_toe.rx
        control.tr >> rotate_toe.rx


    for obj in pm.ls( control, dag=1, type="transform" ):
        shape = obj.getShape()

        if shape is not None:
            pm.reorder(shape, back=1)

        if obj != control:
            setAttrs( obj, ['t','s'], channelBox=0, keyable=0, lock=1 )
            if footRollMode != FOOTROLL_CONTROLS:
                setAttrs( obj, ['r'], channelBox=1, keyable=0, lock=0 )
                obj.visibility.set(0)

        obj.v.set( channelBox=0, keyable=0 )
        pm.select( obj, r=1 )
        pm.color( ud=(CntlColors.left, CntlColors.right)[side] )


    pm.expression( labels['expression'], edit=1, s=exp_str )
コード例 #12
0
def calcMidPoint(planeLoc, geo):

    originalSelect = pm.ls(sl=True)
    sel = om.MSelectionList()
    sel.add(planeLoc)
    dag = sel.getDagPath(0)
    planeTransform = om.MFnTransform(dag)
    planePoint = om.MVector(planeTransform.translation(om.MSpace.kWorld))
    planeNormal = om.MVector.kZaxisVector * planeTransform.transformation(
    ).asMatrix()

    sel = om.MSelectionList()
    sel.add(geo)
    dag = sel.getDagPath(0)

    mesh = om.MFnMesh(dag)
    edgeIt = om.MItMeshEdge(dag)
    polygonIt = om.MItMeshPolygon(dag)

    intesectList = {}
    while not edgeIt.isDone():
        vtxA = mesh.getPoint(edgeIt.vertexId(0), om.MSpace.kWorld)
        vtxB = mesh.getPoint(edgeIt.vertexId(1), om.MSpace.kWorld)
        A = om.MVector(vtxA)
        B = om.MVector(vtxB)

        result = intersectEdgePlane(planePoint, planeNormal, A, B)
        onBoudary = edgeIt.onBoundary()

        if result:
            #doLoc ('center1', result)
            intesectList[edgeIt.index()] = [result, onBoudary]

        edgeIt.next()

    if intesectList == {}:
        return

    allSortedEdges = []
    sortedEdges = []
    edgeIt.reset()
    remainedEdges = intesectList.keys()
    count = len(remainedEdges)
    boundary = [x for x in remainedEdges if intesectList[x][1] == True]
    if boundary:
        i = boundary[0]
        isClosed = False
    else:
        i = remainedEdges[0]
        isClosed = True

    while not count == 0:
        sortedEdges.append(i)
        remainedEdges.remove(i)
        edgeIt.setIndex(i)
        connectedFaces = edgeIt.getConnectedFaces()
        nextEdge = []
        for f in connectedFaces:
            polygonIt.setIndex(f)
            connectedEdges = polygonIt.getEdges()
            a = [x for x in connectedEdges if x in remainedEdges]
            if a:
                i = a[0]
                nextEdge.append(i)

        if nextEdge:
            i = nextEdge[0]
        else:
            allSortedEdges.append([sortedEdges, isClosed])
            if remainedEdges:
                boundary = [
                    x for x in remainedEdges if intesectList[x][1] == True
                ]
                if boundary:
                    i = boundary[0]
                    isClosed = False
                else:
                    i = remainedEdges[0]
                    isClosed = True
            sortedEdges = []
        count -= 1

    for loop in allSortedEdges:
        maxD = -100000.0
        minD = 100000.0
        minIndex = 0
        maxIndex = 0
        for vtx in loop[0]:
            vtxPoint = om.MVector(intesectList[vtx][0])
            if maxD < vtxPoint.length():
                maxD = vtxPoint.length()
                maxIndex = vtx

            if minD > vtxPoint.length():
                minD = vtxPoint.length()
                minIndex = vtx

        p1 = om.MVector(intesectList[maxIndex][0])
        p2 = om.MVector(intesectList[minIndex][0])
        c = (p1 + p2) / 2

        d = om.MVector(planePoint - c)

        distTreshold = .5

        if d.length() < distTreshold:
            v1 = om.MVector(p1 - c)
            v2 = v1 ^ planeNormal
            p3 = c + v2.normal() * v2.length()
            p4 = c - v2.normal() * v2.length()
            crv = pm.curve(n='clipCurve',
                           d=1,
                           p=(p1, p3, p2, p4, p1),
                           k=(0, 1, 2, 3, 4))
            loc = doLoc('center1', c)
            pm.color(crv, rgb=(1, 0, 0))
            pm.color(loc, rgb=(0, 1, 0))
            pm.select(originalSelect)
コード例 #13
0
ファイル: fgshooter.py プロジェクト: Bumpybox/Tapp
def offsetCamera(render_cam, offset):
    '''
    Create an fgshooter camera offset from the render camera by a few frames.
    '''
    # Create camera and change wireframe color.
    fg_cam, fg_cam_shape = pm.camera(name = "fgshooterCamera")
    pm.color(fg_cam, ud=2)

    # Create all the connection nodes we are going to need.
    decompose_matrix = pm.createNode("decomposeMatrix")
    multiply_divide = pm.createNode("multiplyDivide")
    frame_cache_tx = pm.createNode("frameCache")
    frame_cache_ty = pm.createNode("frameCache")
    frame_cache_tz = pm.createNode("frameCache")
    frame_cache_rx = pm.createNode("frameCache")
    frame_cache_ry = pm.createNode("frameCache")
    frame_cache_rz = pm.createNode("frameCache")
    frame_cache_fl = pm.createNode("frameCache")

    # Connect all of those nodes to the render camera.
    render_cam.worldMatrix >> decompose_matrix.inputMatrix
    decompose_matrix.outputTranslateX >> frame_cache_tx.stream
    decompose_matrix.outputTranslateY >> frame_cache_ty.stream
    decompose_matrix.outputTranslateZ >> frame_cache_tz.stream
    decompose_matrix.outputRotateX >> frame_cache_rx.stream
    decompose_matrix.outputRotateY >> frame_cache_ry.stream
    decompose_matrix.outputRotateZ >> frame_cache_rz.stream
    render_cam.focalLength >> frame_cache_fl.stream

    # If the offset is positive, use the future attribute.
    if offset > 0:
        # Workaround for a pymel bug
        offset = ".future[" + str(offset) +"]"
        pm.Attribute(frame_cache_tx + offset) >> fg_cam.translateX
        pm.Attribute(frame_cache_ty + offset) >> fg_cam.translateY
        pm.Attribute(frame_cache_tz + offset) >> fg_cam.translateZ
        pm.Attribute(frame_cache_rx + offset) >> fg_cam.rotateX
        pm.Attribute(frame_cache_ry + offset) >> fg_cam.rotateY
        pm.Attribute(frame_cache_rz + offset) >> fg_cam.rotateZ
        pm.Attribute(frame_cache_fl + offset) >> multiply_divide.input1X

    # If the offset is negative, use the past attribute.
    else:
        offset = -offset
        frame_cache_tx.past[offset] >> fg_cam.translateX
        frame_cache_ty.past[offset] >> fg_cam.translateY
        frame_cache_tz.past[offset] >> fg_cam.translateZ
        frame_cache_rx.past[offset] >> fg_cam.rotateX
        frame_cache_ry.past[offset] >> fg_cam.rotateY
        frame_cache_rz.past[offset] >> fg_cam.rotateZ
        frame_cache_fl.past[offset] >> multiply_divide.input1X

    # Pass aperture, aspect, and focal length infromation with the fgshooter camera's scale.
    # Focal length is connected because it could be animated.
    aperture = render_cam.horizontalFilmAperture.get()
    aspect = aperture / pm.Attribute("defaultResolution.deviceAspectRatio").get()
    multiply_divide.input2X.set(0.03937)

    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)
    multiply_divide.outputX >> fg_cam.scaleZ

    return fg_cam_shape
コード例 #14
0
def offsetCamera(render_cam, offset):
    '''
    Create an fgshooter camera offset from the render camera by a few frames.
    '''
    # Create camera and change wireframe color.
    fg_cam, fg_cam_shape = pm.camera(name="fgshooterCamera")
    pm.color(fg_cam, ud=2)

    # Create all the connection nodes we are going to need.
    decompose_matrix = pm.createNode("decomposeMatrix")
    multiply_divide = pm.createNode("multiplyDivide")
    frame_cache_tx = pm.createNode("frameCache")
    frame_cache_ty = pm.createNode("frameCache")
    frame_cache_tz = pm.createNode("frameCache")
    frame_cache_rx = pm.createNode("frameCache")
    frame_cache_ry = pm.createNode("frameCache")
    frame_cache_rz = pm.createNode("frameCache")
    frame_cache_fl = pm.createNode("frameCache")

    # Connect all of those nodes to the render camera.
    render_cam.worldMatrix >> decompose_matrix.inputMatrix
    decompose_matrix.outputTranslateX >> frame_cache_tx.stream
    decompose_matrix.outputTranslateY >> frame_cache_ty.stream
    decompose_matrix.outputTranslateZ >> frame_cache_tz.stream
    decompose_matrix.outputRotateX >> frame_cache_rx.stream
    decompose_matrix.outputRotateY >> frame_cache_ry.stream
    decompose_matrix.outputRotateZ >> frame_cache_rz.stream
    render_cam.focalLength >> frame_cache_fl.stream

    # If the offset is positive, use the future attribute.
    if offset > 0:
        # Workaround for a pymel bug
        offset = ".future[" + str(offset) + "]"
        pm.Attribute(frame_cache_tx + offset) >> fg_cam.translateX
        pm.Attribute(frame_cache_ty + offset) >> fg_cam.translateY
        pm.Attribute(frame_cache_tz + offset) >> fg_cam.translateZ
        pm.Attribute(frame_cache_rx + offset) >> fg_cam.rotateX
        pm.Attribute(frame_cache_ry + offset) >> fg_cam.rotateY
        pm.Attribute(frame_cache_rz + offset) >> fg_cam.rotateZ
        pm.Attribute(frame_cache_fl + offset) >> multiply_divide.input1X

    # If the offset is negative, use the past attribute.
    else:
        offset = -offset
        frame_cache_tx.past[offset] >> fg_cam.translateX
        frame_cache_ty.past[offset] >> fg_cam.translateY
        frame_cache_tz.past[offset] >> fg_cam.translateZ
        frame_cache_rx.past[offset] >> fg_cam.rotateX
        frame_cache_ry.past[offset] >> fg_cam.rotateY
        frame_cache_rz.past[offset] >> fg_cam.rotateZ
        frame_cache_fl.past[offset] >> multiply_divide.input1X

    # Pass aperture, aspect, and focal length infromation with the fgshooter camera's scale.
    # Focal length is connected because it could be animated.
    aperture = render_cam.horizontalFilmAperture.get()
    aspect = aperture / pm.Attribute(
        "defaultResolution.deviceAspectRatio").get()
    multiply_divide.input2X.set(0.03937)

    fg_cam.scaleX.set(aperture)
    fg_cam.scaleY.set(aspect)
    multiply_divide.outputX >> fg_cam.scaleZ

    return fg_cam_shape