DigitalEro Offline

James IK Rig

Sat, 10 Aug 2013 20:05:57

luythen

I'm stuck on rigging the James nude model in source filmmaker. I based the rig .py on Aardvak's IK rigs for Mass Effect but for some reason the knee and foot positioning doesn't work. The rig gets initialized, other bones and IK handles work, the toe handle is attached but the knees and foot don't cause any transformation. Spent quite some time now trying to find a typo or difference in how the skeleton is set up but fail to see the error. Anybody any ideas?
# standard stuff here
...
    
# bone and ik definitions
#==============================================================================================
    # Find the dag nodes for all of the bones in the model which will be used by the script
    #==============================================================================================
    boneRoot      = sfmUtils.FindFirstDag( [ "ValveBiped.God" ], True )
    bonePelvis    = sfmUtils.FindFirstDag( [ "ValveBiped.Pelvis",		"Bip01_Pelvis",		"bip_pelvis" ], True )
    boneSpine0    = sfmUtils.FindFirstDag( [ "ValveBiped.LowerBack",		"Bip01_Spine",		"bip_spine_0" ], True )
    boneSpine1    = sfmUtils.FindFirstDag( [ "ValveBiped.Chest",		"Bip01_Spine1",		"bip_spine_1" ], True )
    boneSpine2    = sfmUtils.FindFirstDag( [ "ValveBiped.Chest1",		"Bip01_Spine2",		"bip_spine_2" ], True ) 
    boneSpine3    = sfmUtils.FindFirstDag( [ "ValveBiped.Chest2",		"Bip01_Spine3",		"bip_spine_3" ], True )
    boneNeck      = sfmUtils.FindFirstDag( [ "ValveBiped.Neck",		"Bip01_Neck",		"bip_neck_0",	  ], True )
    boneHead      = sfmUtils.FindFirstDag( [ "ValveBiped.Neck1",	"Bip01_Neck1",		"bip_head",	 ], True )
    
    boneUpperLegR = sfmUtils.FindFirstDag( [ "ValveBiped.RightHip",    "Bip01_R_Thigh",    "bip_hip_R" ], True )
    boneLowerLegR = sfmUtils.FindFirstDag( [ "ValveBiped.RightKnee1",     "Bip01_R_Calf",     "bip_knee_R" ], True )
    boneFootR     = sfmUtils.FindFirstDag( [ "ValveBiped.RightAnkle",     "Bip01_R_Foot",     "bip_foot_R" ], True )
    boneToeR      = sfmUtils.FindFirstDag( [ "ValveBiped.RightToe",     "Bip01_R_Toe0",     "bip_toe_R" ], True ) 
    boneCollarR   = sfmUtils.FindFirstDag( [ "ValveBiped.RightCollar", "Bip01_R_Clavicle", "bip_collar_R" ], True )   
    boneUpperArmR = sfmUtils.FindFirstDag( [ "ValveBiped.RightShoulder", "Bip01_R_UpperArm", "bip_upperArm_R" ], True ) 
    boneLowerArmR = sfmUtils.FindFirstDag( [ "ValveBiped.RightElbow",  "Bip01_R_Forearm",  "bip_lowerArm_R" ], True )
    boneHandR     = sfmUtils.FindFirstDag( [ "ValveBiped.Bip01_R_Hand",     "Bip01_R_Hand",     "bip_hand_R" ], True )
   
    boneUpperLegL = sfmUtils.FindFirstDag( [ "ValveBiped.LeftHip",    "Bip01_L_Thigh",    "bip_hip_L" ], True )
    boneLowerLegL = sfmUtils.FindFirstDag( [ "ValveBiped.LeftKnee1",     "Bip01_L_Calf",     "bip_knee_L" ], True )
    boneFootL     = sfmUtils.FindFirstDag( [ "ValveBiped.LeftAnkle",     "Bip01_L_Foot",     "bip_foot_L" ], True )
    boneToeL      = sfmUtils.FindFirstDag( [ "ValveBiped.LeftToe",     "Bip01_L_Toe0",     "bip_toe_L" ], True ) 
    boneCollarL   = sfmUtils.FindFirstDag( [ "ValveBiped.LeftCollar", "Bip01_L_Clavicle", "bip_collar_L" ], True )        
    boneUpperArmL = sfmUtils.FindFirstDag( [ "ValveBiped.LeftShoulder", "Bip01_L_UpperArm", "bip_upperArm_L" ], True ) 
    boneLowerArmL = sfmUtils.FindFirstDag( [ "ValveBiped.LeftElbow",  "Bip01_L_Forearm",  "bip_lowerArm_L" ], True ) 
    boneHandL     = sfmUtils.FindFirstDag( [ "ValveBiped.Bip01_L_Hand",     "Bip01_L_Hand",     "bip_hand_L" ], True )
    

    #==============================================================================================
    # Create the rig handles and constrain them to existing bones
    #==============================================================================================
    rigRoot    = sfmUtils.CreateConstrainedHandle( "rig_root",     boneRoot,    bCreateControls=False )
    rigPelvis  = sfmUtils.CreateConstrainedHandle( "rig_pelvis",   bonePelvis,  bCreateControls=False )
    rigSpine0  = sfmUtils.CreateConstrainedHandle( "rig_spine_0",  boneSpine0,  bCreateControls=False )
    rigSpine1  = sfmUtils.CreateConstrainedHandle( "rig_spine_1",  boneSpine1,  bCreateControls=False )
    rigSpine2  = sfmUtils.CreateConstrainedHandle( "rig_spine_2",  boneSpine2,  bCreateControls=False )
    rigChest   = sfmUtils.CreateConstrainedHandle( "rig_chest",    boneSpine3,  bCreateControls=False )
    rigNeck    = sfmUtils.CreateConstrainedHandle( "rig_neck",     boneNeck,    bCreateControls=False )
    rigHead    = sfmUtils.CreateConstrainedHandle( "rig_Head",     boneHead,    bCreateControls=False )
    
    rigFootR   = sfmUtils.CreateConstrainedHandle( "rig_foot_R",   boneFootR,   bCreateControls=False )
    rigToeR    = sfmUtils.CreateConstrainedHandle( "rig_toe_R",    boneToeR,    bCreateControls=False )
    rigCollarR = sfmUtils.CreateConstrainedHandle( "rig_collar_R", boneCollarR, bCreateControls=False )
    rigHandR   = sfmUtils.CreateConstrainedHandle( "rig_hand_R",   boneHandR,   bCreateControls=False )
    rigFootL   = sfmUtils.CreateConstrainedHandle( "rig_foot_L",   boneFootL,   bCreateControls=False )
    rigToeL    = sfmUtils.CreateConstrainedHandle( "rig_toe_L",    boneToeL,    bCreateControls=False )
    rigCollarL = sfmUtils.CreateConstrainedHandle( "rig_collar_L", boneCollarL, bCreateControls=False )
    rigHandL   = sfmUtils.CreateConstrainedHandle( "rig_hand_L",   boneHandL,   bCreateControls=False )
        
    
    # Use the direction from the heel to the toe to compute the knee offsets, 
    # this makes the knee offset indpendent of the inital orientation of the model.
    vKneeOffsetR = ComputeVectorBetweenBones( boneFootR, boneToeR, 10 )
    vKneeOffsetL = ComputeVectorBetweenBones( boneFootL, boneToeL, 10 )
    
    
    rigKneeR   = sfmUtils.CreateOffsetHandle( "rig_knee_R",  boneLowerLegR, vKneeOffsetR,  bCreateControls=False )   
    rigKneeL   = sfmUtils.CreateOffsetHandle( "rig_knee_L",  boneLowerLegL, vKneeOffsetL,  bCreateControls=False )
    rigElbowR  = sfmUtils.CreateOffsetHandle( "rig_elbow_R", boneLowerArmR, -vKneeOffsetR,  bCreateControls=False )
    rigElbowL  = sfmUtils.CreateOffsetHandle( "rig_elbow_L", boneLowerArmL, -vKneeOffsetL,  bCreateControls=False )
    
    # Create a helper handle which will remain constrained to the each foot position that can be used for parenting.
    rigFootHelperR = sfmUtils.CreateConstrainedHandle( "rig_footHelper_R", boneFootR, bCreateControls=False )
    rigFootHelperL = sfmUtils.CreateConstrainedHandle( "rig_footHelper_L", boneFootL, bCreateControls=False )
    
    # Create a list of all of the rig dags
    allRigHandles = [ rigRoot, rigPelvis, rigSpine0, rigSpine1, rigSpine2, rigChest, rigNeck, rigHead,
                      rigCollarR, rigElbowR, rigHandR, rigKneeR, rigFootR, rigToeR,
                      rigCollarL, rigElbowL, rigHandL, rigKneeL, rigFootL, rigToeL ];
    
    
    #==============================================================================================
    # Generate the world space logs for the rig handles and remove the constraints
    #==============================================================================================
    sfm.ClearSelection()
    sfmUtils.SelectDagList( allRigHandles )
    sfm.GenerateSamples()
    sfm.RemoveConstraints()    
    
    
    #==============================================================================================
    # Build the rig handle hierarchy
    #==============================================================================================
    sfmUtils.ParentMaintainWorld( rigPelvis,        rigRoot )
    sfmUtils.ParentMaintainWorld( rigSpine0,        rigPelvis )
    sfmUtils.ParentMaintainWorld( rigSpine1,        rigSpine0 )
    sfmUtils.ParentMaintainWorld( rigSpine2,        rigSpine1 )
    sfmUtils.ParentMaintainWorld( rigChest,         rigSpine2 )
    sfmUtils.ParentMaintainWorld( rigNeck,          rigChest )
    sfmUtils.ParentMaintainWorld( rigHead,          rigNeck )
    
    sfmUtils.ParentMaintainWorld( rigFootHelperR,   rigRoot )
    sfmUtils.ParentMaintainWorld( rigFootHelperL,   rigRoot )
    sfmUtils.ParentMaintainWorld( rigFootR,         rigRoot )
    sfmUtils.ParentMaintainWorld( rigFootL,         rigRoot )
    sfmUtils.ParentMaintainWorld( rigKneeR,         rigFootHelperR )
    sfmUtils.ParentMaintainWorld( rigKneeL,         rigFootHelperL )
    sfmUtils.ParentMaintainWorld( rigToeR,          rigFootHelperR )
    sfmUtils.ParentMaintainWorld( rigToeL,          rigFootHelperL )
    
    sfmUtils.ParentMaintainWorld( rigCollarR,       rigChest )
    sfmUtils.ParentMaintainWorld( rigElbowR,        rigCollarR )
    sfmUtils.ParentMaintainWorld( rigHandR,	    rigRoot )
    sfmUtils.ParentMaintainWorld( rigCollarL,       rigChest )
    sfmUtils.ParentMaintainWorld( rigElbowL,        rigCollarL )
    sfmUtils.ParentMaintainWorld( rigHandL,	    rigRoot )
    
    # Create the hips control, this allows a pelvis rotation that does not effect the spine,
    # it is only used for rotation so a position control is not created. Additionally add the
    # new control to the selection so the that set default call operates on it too.
    rigHips = sfmUtils.CreateHandleAt( "rig_hips", rigPelvis, False, True )
    sfmUtils.Parent( rigHips, rigPelvis, vs.REPARENT_LOGS_OVERWRITE )
    sfm.SelectDag( rigHips )

    # Set the defaults of the rig transforms to the current locations. Defaults are stored in local
    # space, so while the parent operation tries to preserve default values it is cleaner to just
    # set them once the final hierarchy is constructed.
    sfm.SetDefault()
    
    
    #==============================================================================================
    # Create the reverse foot controls for both the left and right foot
    #==============================================================================================
    rigLegsGroup = rootGroup.CreateControlGroup( "RigLegs" )
    rigHelpersGroup = rootGroup.CreateControlGroup( "RigHelpers" )
    rigHelpersGroup.SetVisible( False )
    rigHelpersGroup.SetSnappable( False )
    
    footIKTargetR = rigFootR
    footIkTargetL = rigFootL
    
    if ( gameModel != None ) :
        footRollIkTargetR = CreateReverseFoot( "rig_footRoll", "R", gameModel, animSet, shot, rigHelpersGroup, rigLegsGroup )
        footRollIkTargetL = CreateReverseFoot( "rig_footRoll", "L", gameModel, animSet, shot, rigHelpersGroup, rigLegsGroup )
        if ( footRollIkTargetR != None ) :
            footIKTargetR = footRollIkTargetR
        if ( footRollIkTargetL != None ) :
            footIkTargetL = footRollIkTargetL
    
    
    #==============================================================================================
    # Create constraints to drive the bone transforms using the rig handles
    #==============================================================================================
    
    # The following bones are simply constrained directly to a rig handle
    sfmUtils.CreatePointOrientConstraint( rigRoot,      boneRoot        )
    sfmUtils.CreatePointOrientConstraint( rigHips,      bonePelvis      )
    sfmUtils.CreatePointOrientConstraint( rigSpine0,    boneSpine0      )
    sfmUtils.CreatePointOrientConstraint( rigSpine1,    boneSpine1      )
    sfmUtils.CreatePointOrientConstraint( rigSpine2,    boneSpine2      )
    sfmUtils.CreatePointOrientConstraint( rigChest,     boneSpine3      )
    sfmUtils.CreatePointOrientConstraint( rigNeck,      boneNeck        )
    sfmUtils.CreatePointOrientConstraint( rigHead,      boneHead        )
    sfmUtils.CreatePointOrientConstraint( rigCollarR,   boneCollarR     )
    sfmUtils.CreatePointOrientConstraint( rigCollarL,   boneCollarL     )
    sfmUtils.CreatePointOrientConstraint( rigToeR,      boneToeR        )
    sfmUtils.CreatePointOrientConstraint( rigToeL,      boneToeL        )
    
    # Create ik constraints for the arms and legs that will control the rotation of the hip / knee and 
    # upper arm / elbow joints based on the position of the foot and hand respectively.
    sfmUtils.BuildArmLeg( rigKneeR,  footIKTargetR, boneUpperLegR,  boneFootR, True )
    sfmUtils.BuildArmLeg( rigKneeL,  footIkTargetL, boneUpperLegL,  boneFootL, True )
    sfmUtils.BuildArmLeg( rigElbowR, rigHandR,      boneUpperArmR,  boneHandR, True )
    sfmUtils.BuildArmLeg( rigElbowL, rigHandL,      boneUpperArmL,  boneHandL, True )
    
    
    #==============================================================================================
    # Create handles for the important attachment points 
    #==============================================================================================    
    attachmentGroup = rootGroup.CreateControlGroup( "Attachments" )  
    attachmentGroup.SetVisible( False )
    
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_heel_R",       attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_toe_R",        attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_outerFoot_R",  attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_innerFoot_R",  attachmentGroup )
    
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_heel_L",       attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_toe_L",        attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_outerFoot_L",  attachmentGroup )
    sfmUtils.CreateAttachmentHandleInGroup( "pvt_innerFoot_L",  attachmentGroup )
    
    
    
    #==============================================================================================
    # Re-organize the selection groups
    #==============================================================================================  
    rigBodyGroup = rootGroup.CreateControlGroup( "RigBody" )
    rigArmsGroup = rootGroup.CreateControlGroup( "RigArms" )
    
    RightArmGroup = rootGroup.CreateControlGroup( "RightArm" )
    LeftArmGroup = rootGroup.CreateControlGroup( "LeftArm" )
    RightLegGroup = rootGroup.CreateControlGroup( "RightLeg" )
    LeftLegGroup = rootGroup.CreateControlGroup( "LeftLeg" )   
    
    sfmUtils.AddDagControlsToGroup( rigBodyGroup, rigRoot, rigPelvis, rigHips, rigSpine0, rigSpine1, rigSpine2, rigChest, rigNeck, rigHead )  
      
    rigArmsGroup.AddChild( RightArmGroup )
    rigArmsGroup.AddChild( LeftArmGroup )
    sfmUtils.AddDagControlsToGroup( RightArmGroup,  rigHandR, rigElbowR, rigCollarR )
    sfmUtils.AddDagControlsToGroup( LeftArmGroup, rigHandL, rigElbowL, rigCollarL )
    
    rigLegsGroup.AddChild( RightLegGroup )
    rigLegsGroup.AddChild( LeftLegGroup )
    sfmUtils.AddDagControlsToGroup( RightLegGroup, rigKneeR, rigFootR, rigToeR )
    sfmUtils.AddDagControlsToGroup( LeftLegGroup, rigKneeL, rigFootL, rigToeL )
    
    sfmUtils.MoveControlGroup( "rig_footRoll_L", rigLegsGroup, LeftLegGroup )
    sfmUtils.MoveControlGroup( "rig_footRoll_R", rigLegsGroup, RightLegGroup )
    

 
    sfmUtils.AddDagControlsToGroup( rigHelpersGroup, rigFootHelperR, rigFootHelperL )

    # Set the control group visiblity, this is done through the rig so it can track which
    # groups it hid, so they can be set back to being visible when the rig is detached.
    HideControlGroups( rig, rootGroup, "Body", "Arms", "Legs", "Unknown", "Other", "Root" )      
        
    #Re-order the groups
    fingersGroup = rootGroup.FindChildByName( "Fingers", False ) 
    rootGroup.MoveChildToBottom( rigBodyGroup )
    rootGroup.MoveChildToBottom( rigLegsGroup )    
    rootGroup.MoveChildToBottom( rigArmsGroup )      
    rootGroup.MoveChildToBottom( fingersGroup )  
       
    rightFingersGroup = rootGroup.FindChildByName( "RightFingers", True ) 
    if ( rightFingersGroup != None ):
        RightArmGroup.AddChild( rightFingersGroup )
        rightFingersGroup.SetSelectable( False )
                                
    leftFingersGroup = rootGroup.FindChildByName( "LeftFingers", True ) 
    if ( leftFingersGroup != None ):
        LeftArmGroup.AddChild( leftFingersGroup )
        leftFingersGroup.SetSelectable( False )
        

    #==============================================================================================
    # Set the selection groups colors
    #==============================================================================================
    topLevelColor = vs.Color( 0, 128, 255, 255 )
    RightColor = vs.Color( 255, 0, 0, 255 )
    LeftColor = vs.Color( 0, 255, 0, 255 )
    
    rigBodyGroup.SetGroupColor( topLevelColor, False )
    rigArmsGroup.SetGroupColor( topLevelColor, False )
    rigLegsGroup.SetGroupColor( topLevelColor, False )
    attachmentGroup.SetGroupColor( topLevelColor, False )
    rigHelpersGroup.SetGroupColor( topLevelColor, False )
    
    RightArmGroup.SetGroupColor( RightColor, False )
    LeftArmGroup.SetGroupColor( LeftColor, False )
    RightLegGroup.SetGroupColor( RightColor, False )
    LeftLegGroup.SetGroupColor( LeftColor, False )
    
    
    # End the rig definition
    sfm.EndRig()
    return
    
#==================================================================================================
# Script entry
#==================================================================================================

# Construct the rig for the selected animation set
BuildRig();


    
    




Sun, 11 Aug 2013 22:43:07

luythen

Hey, small update. It's really an arcande problem. The IK rigs initialize and the foot handles to transfer their rotation information but for some reason the position info doesn't get transferred the same way. That kind of indicates that at least in theory the bones and rigs are somehow attached to some extent. I adjusted the standard IK rig from Aarkvard and the biped_simple for quite a selection of other models now but the James model has some different issue, that seems to shoot the way the foot handles work. I checked the other handles (in a raw scene without anything else) but things like the spine, hands and head work as expected. It somehow can't transfer the positioning.
Mon, 12 Aug 2013 06:03:36

Pipedude

you can look at mine and compare - http://pastebin.com/W4keybzE
Mon, 12 Aug 2013 23:45:42

luythen

thx, I will check yours out and see what might be going wrong with mine.
Tue, 13 Aug 2013 18:31:24

luythen

Your rig doesn't work either. I'll download the James model again and see if maybe I have some kind of resource conflict. Do you use this one by Ex Nihilo from the GMod forum as well? <!-- l --><a class="postlink-local" href="https://digitalero.org/phpbb/viewtopic.php?f=22&t=84">viewtopic.php?f=22&t=84</a><!-- l -->
Tue, 13 Aug 2013 23:36:28

Pipedude

I use the newer one LordAardvark fixed up for SFM, since I don't see it anywhere i'd ask him directly and if I remember correctly that old model was impossible to rig. So your best bet is to ask LordAardvark.
Wed, 14 Aug 2013 18:15:00

luythen

"Pipedude" said ...
I use the newer one LordAardvark fixed up for SFM, since I don't see it anywhere i'd ask him directly and if I remember correctly that old model was impossible to rig. So your best bet is to ask LordAardvark.
Well, that would explain a lot. Thanks for your heads up. Much appreciated, was already seriously doubting myself.