Retargeting Skeleton Translations [Maya Script]

Hi this is a script that retargets skeleton translations.
If community takes interest in this ill extend it further. :slight_smile:

Step:1 Create base rig skeleton (A-Pose/T-Pose) press first button.
Step:2 Import Animation (see all the translations get messed up) click button 2. :slight_smile:

-Writes the base skeleton translations to a file
-Gets current Time
-Sets time range
-Retargets the translations to imported animation
-Bakes all keys
-Sets root to 0 0 0
-Ignores Pelvis joint & IK joints
-no need to select anything button does everything
retarget.PNG.jpg



////////////////////////////////////////////////////////////////////////////
//  /$$     /$$          /$$     /$$ /$$$$$$$$                  /$$       //    
// |  $$   /$$/         | $$    |__/|__  $$__/                 | $$       //    
//  \  $$ /$$//$$$$$$  /$$$$$$   /$$   | $$  /$$$$$$   /$$$$$$$| $$$$$$$  //    
//   \  $$$$//$$__  $$|_  $$_/  | $$   | $$ /$$__  $$ /$$_____/| $$__  $$ //    
//    \  $$/| $$$$$$$$  | $$    | $$   | $$| $$$$$$$$| $$      | $$  \ $$ //    
//     | $$ | $$_____/  | $$ /$$| $$   | $$| $$_____/| $$      | $$  | $$ //    
//     | $$ |  $$$$$$$  |  $$$$/| $$   | $$|  $$$$$$$|  $$$$$$$| $$  | $$ //    
//     |__/  \_______/   \___/  |__/   |__/ \_______/ \_______/|__/  |__/ //    
//                                                                        //                                                                                                                                                      
//      /$$$$$$   /$$                     /$$ /$$                         //        
//     /$$__  $$ | $$                    | $$|__/                         //        
//    | $$  \__//$$$$$$   /$$   /$$  /$$$$$$$ /$$  /$$$$$$   /$$$$$$$     //        
//    |  $$$$$$|_  $$_/  | $$  | $$ /$$__  $$| $$ /$$__  $$ /$$_____/     //        
//     \____  $$ | $$    | $$  | $$| $$  | $$| $$| $$  \ $$|  $$$$$$      //        
//     /$$  \ $$ | $$ /$$| $$  | $$| $$  | $$| $$| $$  | $$ \____  $$     //        
//    |  $$$$$$/ |  $$$$/|  $$$$$$/|  $$$$$$$| $$|  $$$$$$/ /$$$$$$$/     //        
//     \______/   \___/   \______/  \_______/|__/ \______/ |_______/      //            
////////////////////////////////////////////////////////////////////////////  
//YetiTech $tudios                                                        //
//Retargeting Script v1.0 2016                                            //
//by Nikhil Jeewa  (â—£_â—¢)                                                 //
////////////////////////////////////////////////////////////////////////////
window -width 150;
columnLayout -adjustableColumn true;
    button -l "Write Base Joints" -c "writeTranslate";
    button -l "Retarget Translation Joints" -c "retarget";
showWindow;

//write base joints translations to file
proc writeTranslate(){
    select -cl;
    int $fileq=`file -q -ex "C:/YetiTech/Retarget.txt"`;
    if ($fileq==0){
        sysFile -makeDir "C:/YetiTech";
        fopen "C:/YetiTech/Retarget.txt";
    }        
    string $joints]=`ls -type joint`;
    select -r $joints;      
    string $filepath="C:/YetiTech/Retarget.txt";
    $baseJoints=`fopen $filepath "w"`;
    for ($xyz in $joints){
        float $pos [3] = `xform -wd -q -t $xyz`;
        fprint $baseJoints ($xyz+" "+$pos[0]+" "+$pos[1]+" "+$pos[2]+"
");
        print ($xyz+" "+$pos[0]+" "+$pos[1]+" "+$pos[2]+"
");
    }
    fclose $baseJoints;        
    print "Base Translations written to file C:\YetiTech\Retarget.txt";
}

//retarget base skeleton translations
proc retarget(){
    select -cl;
    playbackOptions -e -playbackSpeed 1;    
    int $lastFrame=0;
    int $key;
    string $jKeys]=`ls -type joint`;
    for ($j in $jKeys){
        $key=`findKeyframe -ts -w last $j`;
        if ($key>$lastFrame){
            $lastFrame=$key;
        }
    }  
    playbackOptions -min 1 -max $lastFrame;
    print ("last frame: "+$lastFrame+"
");  
    //get current time
    for ($i=1;$i<=$lastFrame;$i++){
        currentTime $i;
        print ("Current Time: "+$i+"
");
        setKeys;
    }
    print "Translations have been retargeted";
    playButtonForward;
}
//retarget keys    
proc setKeys(){
    string $filepath="C:/yetitech/Retarget.txt";
    $baseTrans=`fopen $filepath "r"`;
    string $nextLine=`fgetline $baseTrans`;
    while (size($nextLine)>0){
        string $jointXYZ=strip($nextLine);
        $nextLine=`fgetline $baseTrans`;
        print ($jointXYZ+"
");
        string $array];
        $array = stringToStringArray($jointXYZ," ");        
        string $jName=$array[0];
        float $x=$array[1];
        float $y=$array[2];
        float $z=$array[3];
        select $jName;
        if ($jName=="pelvis"||$jName=="foot_root"||$jName=="ik_foot_l"||$jName=="ik_foot_r"||$jName=="ik_hand_root"||$jName=="ik_hand_gun"||$jName=="ik_hand_l"||$jName=="ik_hand_r"){
            print ("joint skipped");            
        }else if ($jName=="root"){
            setAttr root.translateX 0;    
            setAttr root.translateY 0;    
            setAttr root.translateZ 0;
            setKeyframe;
        }else{            
            setAttr ($jName+".translateX") $x;
            setAttr ($jName+".translateY") $y;
            setAttr ($jName+".translateZ") $z;
            setKeyframe;
        }    
    }  
    fclose $baseTrans;    
}


Awesome, this will be quite useful. Thanks :D!

If you are re-targeting to Epics Rigging tool kit change this line

$keys = keyframe -q "root.translateX";

to

$keys = keyframe -q "root.translateY";

Hi !

I’m sorry, but I’m not quite understanding how this script works.
I have two skeletons, one with animation and the other one without it. The skeleton without animation has some addicional joints that don’t need animations.
How can I with this script retarget the animation from one to the other?
Thank you!

If you have animation that does not match your skeleton and you want to retarget to a your skeleton (where joint translations are different), this script will save the translations of your skeleton to file (step 1). When you import animation made from a different skeleton, the translations of the joints will change. Step 2 retargets the joints translations from the file so that your skeleton now has the animation with proper joint translations.

This script will work if the joint names are the same any extra joints will be ignored.

If you still dont understand take the ue4 mannequin make the legs and arms longer. Follow Step 1. Import animation from the marketplace, you will see the mannequin arm and leg joints shrink back to the original. Follow Step 2, now you have animation retargeted and your skeleton will have long arm/legs again.

Please Note: This script will not work with Maya LT. (I will make this script compatible with Maya LT later.)

I have updated the script to ignore IK joints & cleaned up the code to find the last key frame better. :slight_smile:

No need to do this, script has been updated with cleaner code. :slight_smile:

hi,

This looks what i need but dont really understand it. I want to remake a human ik profile in maya to the ue4 mannequin rig, does it do this and what base files do i need?