594 lines
14 KiB
Text
594 lines
14 KiB
Text
|
|
// ExportXanim.mel
|
|
//
|
|
// Notes:
|
|
//
|
|
//
|
|
// Also the start frame, end frame and the rate are set in the script in the first function. This also has to be input to the script from the export window.
|
|
//
|
|
// The OutPutNoteTracks function simply exports a blank note track for each joint in the animation. This also needs to change latter to export
|
|
// real note tracks.
|
|
//
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: OutPutNoteTracks
|
|
//
|
|
// This procedure outputs the note tracks.
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
|
|
global proc OutPutNoteTracks (string $PartsArray[], int $fileId, string $NoteTrack)
|
|
{
|
|
|
|
// To keep things compatible with 3ds max, export a blank note track for each joint (part) in the file.
|
|
// Add the real note track to part 0
|
|
|
|
// For now, simply export a note track for each object or PART in the skeleton.
|
|
// This will probably change latter.
|
|
|
|
fprint $fileId "\n";
|
|
fprint $fileId "NOTETRACKS\n";
|
|
fprint $fileId "\n";
|
|
|
|
|
|
|
|
|
|
// Add the note track to part 0
|
|
|
|
if ($NoteTrack != "NO NOTE TRACK")
|
|
{
|
|
// Calculate all the NoteTrack information
|
|
|
|
string $NoteTrack = "NoteTrack";
|
|
|
|
float $MainNoteKeys[] = `keyframe -q ($NoteTrack + ".MainNote")`;
|
|
//float $SecondNoteKeys[] = `keyframe -q ($NoteTrack + ".SecondaryNote")`;
|
|
|
|
// Add the 2 arrays together
|
|
|
|
//float $BothNoteTrackKeys[] = `AddFloatArray $MainNoteKeys $SecondNoteKeys`;
|
|
|
|
// Remove all the duplicate key frames from the array
|
|
|
|
//$BothNoteTrackKeys = `RemoveFloatDuplicate $BothNoteTrackKeys`;
|
|
|
|
// Reorder them from smallest to largest
|
|
|
|
float $MasterNoteKeyList[] = $MainNoteKeys; //`OrderFloatArray $BothNoteTrackKeys`;
|
|
|
|
|
|
print "\n\nTest:";
|
|
print ("\nNote track key frame list = \n");
|
|
print $MasterNoteKeyList;
|
|
|
|
int $NumKeys = `size $MasterNoteKeyList`;
|
|
|
|
|
|
fprint $fileId ("PART 0\n");
|
|
fprint $fileId ("NUMTRACKS 1\n");
|
|
fprint $fileId ("\n");
|
|
fprint $fileId ("NOTETRACK 0\n");
|
|
fprint $fileId ("NUMKEYS " + $NumKeys + "\n");
|
|
|
|
|
|
float $EachKey;
|
|
|
|
// Get the list of attributes from the Note track
|
|
|
|
string $MainNTListTemp = `addAttr -q -enumName ($NoteTrack + ".MainNote")`;
|
|
//string $SecondNTListTemp = `addAttr -q -enumName ($NoteTrack + ".SecondaryNote")`;
|
|
|
|
string $MainNTList[];
|
|
clear $MainNTList;
|
|
|
|
//string $SecondNTList[];
|
|
//clear $SecondNTList;
|
|
|
|
tokenize $MainNTListTemp ":" $MainNTList;
|
|
//tokenize $SecondNTListTemp ":" $SecondNTList;
|
|
|
|
|
|
for ( $EachKey in $MasterNoteKeyList )
|
|
{
|
|
fprint $fileId ("FRAME " + $EachKey + " ");
|
|
|
|
int $MainT = `getAttr -time $EachKey ($NoteTrack + ".MainNote")`;
|
|
//int $SecondT = `getAttr -time $EachKey ($NoteTrack + ".SecondaryNote")`;
|
|
|
|
// Check for the old 3ds max tag in note track 1
|
|
|
|
if ($MainNTList[$MainT] != "3dsMax")
|
|
{
|
|
// Main note track is not a 3ds max note track, so print the new format.
|
|
//fprint $fileId ("\"" + $MainNTList[$MainT]) + " = " + $SecondNTList[$SecondT] + "\" \n");
|
|
fprint $fileId ("\"" + $MainNTList[$MainT] + "\" \n");
|
|
}
|
|
//else
|
|
//{
|
|
// There is a old 3ds max note track, probably from the converter, so print it the same as 3ds max.
|
|
// fprint $fileId ("\"" + $SecondNTList[$SecondT] + "\" \n");
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
fprint $fileId ("\n");
|
|
|
|
|
|
/*
|
|
NUMTRACKS 1
|
|
|
|
NOTETRACK 0
|
|
NUMKEYS 3
|
|
*/
|
|
// Print the note track key information
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
fprint $fileId ("PART 0\n");
|
|
fprint $fileId ("NUMTRACKS 0\n");
|
|
fprint $fileId ("\n");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string $EachPart;
|
|
int $PartNumber = 0;
|
|
|
|
int $PartLoopSize = `size $PartsArray`;
|
|
|
|
for ($PartNumber = 1 ; $PartNumber < $PartLoopSize ; $PartNumber++ )
|
|
{
|
|
fprint $fileId ("PART " + $PartNumber +"\n");
|
|
fprint $fileId ("NUMTRACKS 0\n");
|
|
fprint $fileId ("\n");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: OutPutAnimation
|
|
//
|
|
// This procedure outputs all the frame data. It is the main work horse of the script.
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
global proc OutPutAnimation (int $StartFrame, int $EndFrame, string $PartsArray[], int $fileId, int $isDouble)
|
|
{
|
|
int $isDouble;
|
|
|
|
int $isDouble = `checkBox -q -v ExportDouble`;
|
|
|
|
|
|
|
|
// Set up a few vars
|
|
|
|
int $FrameLoop;
|
|
int $PartLoop;
|
|
|
|
int $roundoffLoop;
|
|
|
|
int $PartNum;
|
|
|
|
int $NumParts = `size $PartsArray`;
|
|
|
|
|
|
// 2 vars for the node name. Maya can't have spaces, while max can, so we need to have both names.
|
|
|
|
string $Part;
|
|
|
|
|
|
float $JointMatrix[];
|
|
|
|
float $JScale[];
|
|
|
|
|
|
// Thanks to a update bug in Maya, force an update by going to frame 100 and then frame 0
|
|
//Maya will not update correctly after a load, so if the exporter trys to export the same frame that it loaded on
|
|
//then the screen/animation might not be correct. By changing frames a update is forced fixing everything.
|
|
|
|
currentTime 100;
|
|
currentTime 0;
|
|
|
|
|
|
// Enter the frame loop
|
|
|
|
for ($FrameLoop = $StartFrame; $FrameLoop < ($EndFrame + 1) ; $FrameLoop++ )
|
|
{
|
|
// goto the correct time.
|
|
|
|
currentTime $FrameLoop;
|
|
|
|
//print the frame number
|
|
fprint $fileId ("FRAME " + $FrameLoop + "\n");
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
source ListCODChars;
|
|
|
|
string $AllChars[] = `ListCODChars`;
|
|
|
|
// Tokenize the list with : to get the prefix
|
|
|
|
string $EachChar;
|
|
string $CharList[];
|
|
int $CharCount = 0;
|
|
|
|
string $Tokenize[];
|
|
|
|
for ($EachChar in $AllChars)
|
|
{
|
|
|
|
tokenize $EachChar ":" $Tokenize;
|
|
|
|
// Make sure the size of $Tokenize is > 1 meaning there was a : in the original name.
|
|
|
|
if (`size $Tokenize` > 1 )
|
|
{
|
|
print "\n\n";
|
|
print $Tokenize[0];
|
|
|
|
$CharList[$CharCount] = $Tokenize[0];
|
|
$CharCount++;
|
|
}
|
|
else
|
|
{
|
|
warning ($Tokenize[0] + " is not referenced.");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if($isDouble==1)
|
|
{
|
|
|
|
string $faceArray[]={"Mouth_CTRs.A_Open","Mouth_CTRs.EE","Mouth_CTRs.OO","Mouth_CTRs.UU","Mouth_CTRs.WQ","Mouth_CTRs.BMP","Mouth_CTRs.FV","Mouth_CTRs.Smile_LE","Mouth_CTRs.Smile_RI","Mouth_CTRs.Snear_LE","Mouth_CTRs.Snear_RI",
|
|
"Mouth_CTRs.Mouth_UP","Mouth_CTRs.Mouth_Wide_LE","Mouth_CTRs.Mouth_Wide_RI","Mouth_CTRs.Mouth_Down_LE","Mouth_CTRs.Mouth_Down_RI","Mouth_CTRs.Mouth_Small_LE","Mouth_CTRs.Mouth_Small_RI",
|
|
"Mouth_CTRs.CH_SH","Mouth_CTRs.Bottom_Lip_Down","Mouth_CTRs.A_Left_Right",
|
|
|
|
|
|
|
|
"Eye_CTR.Blink_LE","Eye_CTR.Blink_RI","Eye_CTR.Squint_LE","Eye_CTR.Squint_RI","Eye_CTR.Eye_LE_Wide_T","Eye_CTR.Eye_RI_Wide_T",
|
|
"Eye_CTR.Eye_LE_Wide_B","Eye_CTR.Eye_RI_Wide_B","Eye_CTR.Eyes_Horizontal","Eye_CTR.EyesVerticle",
|
|
|
|
|
|
|
|
"Brow_Ctrs.Brow_Up_LE","Brow_Ctrs.Brow_Up_RI",
|
|
"Brow_Ctrs.Brow_Down_LE","Brow_Ctrs.Brow_Down_RI","Brow_Ctrs.Squeeze","Brow_Ctrs.Brow_Rotate_LE","Brow_Ctrs.Brow_Rotate_RI"};
|
|
|
|
|
|
int $i=0;
|
|
for($each in $faceArray)
|
|
{
|
|
float $visem = 0;
|
|
float $visem = `getAttr ($Tokenize[0] + ":DefMesh:" + $faceArray[$i])`;
|
|
setAttr ($Tokenize[0] + ":DefMesh:" + $faceArray[$i]) ($visem * 2);
|
|
//setKeyframe ($Tokenize[0] + ":DefMesh:" + $faceArray[$i]);
|
|
$i++;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Enter the part/joint loop
|
|
|
|
for ($PartLoop = 0; $PartLoop < $NumParts ; $PartLoop++)
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// Get the part name from the part list array
|
|
$Part = $PartsArray[$PartLoop];
|
|
|
|
|
|
// Collect all the joint matrix info and print it
|
|
|
|
clear $JointMatrix;
|
|
clear $JScale;
|
|
|
|
// First check the object exists.
|
|
if (`objExists $Part`)
|
|
{
|
|
|
|
$JointMatrix = `xform -q -ws -m $Part`;
|
|
|
|
$JScale = `getAttr ($Part + ".scale")`;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
$JScale[0] = 1;
|
|
$JScale[1] = 1;
|
|
$JScale[2] = 1;
|
|
|
|
}
|
|
|
|
// Maya works in cm, but the game engine works in inches.
|
|
// Because of this we need to scale the joint offset by 2.54
|
|
|
|
$JointMatrix[12] = $JointMatrix[12] /2.54;
|
|
$JointMatrix[13] = $JointMatrix[13] /2.54;
|
|
$JointMatrix[14] = $JointMatrix[14] /2.54;
|
|
|
|
|
|
// round off the results to 4 floating points
|
|
|
|
$JScale[0] = `roundoff $JScale[0] 4`;
|
|
$JScale[1] = `roundoff $JScale[0] 4`;
|
|
$JScale[2] = `roundoff $JScale[0] 4`;
|
|
|
|
for ($roundoffLoop = 0; $roundoffLoop <16 ; $roundoffLoop++ )
|
|
{
|
|
|
|
$JointMatrix[$roundoffLoop] = `roundoff $JointMatrix[$roundoffLoop] 4`;
|
|
|
|
}
|
|
|
|
|
|
// do the printing
|
|
// print part number
|
|
fprint $fileId ("PART " + $PartLoop + "\n");
|
|
|
|
|
|
fprint $fileId ("OFFSET " + $JointMatrix[12] + " " + $JointMatrix[13] + " " + $JointMatrix[14] + "\n");
|
|
|
|
fprint $fileId ("SCALE " + $JScale[0] + " " + $JScale[1] + " " + $JScale[2] + "\n");
|
|
|
|
fprint $fileId ("X " + $JointMatrix[0] + " " + $JointMatrix[1] + " " + $JointMatrix[2] + "\n");
|
|
|
|
fprint $fileId ("Y " + $JointMatrix[4] + " " + $JointMatrix[5] + " "+ $JointMatrix[6] + "\n");
|
|
|
|
fprint $fileId ("Z " + $JointMatrix[8] + " " + $JointMatrix[9] + " "+ $JointMatrix[10] + "\n");
|
|
|
|
|
|
// Add a blank line to end this loop
|
|
fprint $fileId "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: OutPutFrameInfo
|
|
//
|
|
// This procedure outputs the frame information, number, rate etc.
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
global proc OutPutFrameInfo(int $NumberOfFrames, int $FrameRate, int $fileId)
|
|
{
|
|
|
|
fprint $fileId ("FRAMERATE " + $FrameRate + "\n");
|
|
fprint $fileId ("NUMFRAMES " + $NumberOfFrames + "\n");
|
|
|
|
// Add a blank line to end this proc
|
|
fprint $fileId "\n";
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: OutputHeader
|
|
//
|
|
// This procedure outputs the header part of the file as well as the time and date.
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
global proc OutputHeader( string $exportFileName, int $fileId)
|
|
{
|
|
// Export file name
|
|
fprint $fileId "//Export filename: `";
|
|
|
|
fprint $fileId $exportFileName;
|
|
|
|
fprint $fileId "`\n";
|
|
|
|
// Source file name
|
|
string $SceneFileName = `file -q -sn`;
|
|
fprint $fileId "//Source filename: `";
|
|
fprint $fileId $SceneFileName;
|
|
fprint $fileId "`\n";
|
|
|
|
// Time and date
|
|
string $Date = `system ("date /T")`;
|
|
string $Time = `system ("time /T")`;
|
|
|
|
// strip out the return code (/n)
|
|
|
|
int $StrSize = `size $Date`;
|
|
$Date = `substring $Date 1 ($StrSize-2)` ;
|
|
|
|
int $StrSize = `size $Time`;
|
|
$Time = `substring $Time 1 ($StrSize-2)` ;
|
|
|
|
strip $Date;
|
|
strip $Time;
|
|
fprint $fileId "//Export time: ";
|
|
fprint $fileId $Date;
|
|
fprint $fileId " ";
|
|
fprint $fileId $Time;
|
|
fprint $fileId "\n";
|
|
|
|
fprint $fileId "\n";
|
|
fprint $fileId "ANIMATION\nVERSION 3\n";
|
|
fprint $fileId "\n";
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: OutputPartList
|
|
//
|
|
// This procedure outputs the list of joints and their corresponding part number.
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
global proc OutputPartList(int $fileId, string $PartsArray[])
|
|
{
|
|
|
|
int $PartSize = `size $PartsArray`;
|
|
|
|
int $PartNum = 0;
|
|
|
|
fprint $fileId ("NUMPARTS " + $PartSize + "\n");
|
|
|
|
string $Each;
|
|
string $OutPutEach;
|
|
string $TokenizeEach[];
|
|
|
|
for ($Each in $PartsArray)
|
|
{
|
|
// Remove any prefix names. There are possibily 2 in these rigs.
|
|
|
|
clear $TokenizeEach;
|
|
|
|
tokenize $Each ":" $TokenizeEach;
|
|
|
|
$OutPutEach = $TokenizeEach[(`size $TokenizeEach`) -1];
|
|
|
|
fprint $fileId ("PART " + $PartNum++ + " \"");
|
|
fprint $fileId ($OutPutEach + "\"\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
// Add a blank line to end this proc
|
|
fprint $fileId "\n";
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
// PROC: ExportXanim
|
|
//
|
|
// This is the main entry point
|
|
//
|
|
//-------------------------------------------------------------------------------------------------------------------------------------//
|
|
|
|
global proc ExportXanim(int $StartFrame, int $EndFrame, int $FrameRate, string $PartsArray[], string $FileName, string $NoteTrack, int $isDouble)
|
|
{
|
|
|
|
float $startTime;
|
|
float $totalTime;
|
|
print "did it get here again";
|
|
$startTime = `timerX`;
|
|
|
|
|
|
// Need to add a window at some point to set the options below.
|
|
|
|
// int $StartFrame = 70;
|
|
// int $EndFrame = 158;
|
|
|
|
// int $FrameRate = 30;
|
|
|
|
|
|
// string $PartsArray[];
|
|
|
|
// $PartsArray = `ls -sl`;
|
|
|
|
int $NumberOfFrames = (($EndFrame - $StartFrame) + 1);
|
|
|
|
// Check there are frames to export
|
|
|
|
if ($NumberOfFrames < 0)
|
|
{
|
|
warning "No frames to export, Not exporting";
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set the file name
|
|
// This needs to change to a file browser eventually
|
|
|
|
// $FileName = "C:/testStuff/TestMayaExport.txt";
|
|
|
|
|
|
// Check that there are parts to export
|
|
|
|
if ($PartsArray[0] == "" )
|
|
{
|
|
print ("\n\nNo Parts selected for export file : " +$FileName + "\nPlease Select the Export nodes\n");
|
|
warning "No Parts selected, Not exporting";
|
|
return;
|
|
}
|
|
|
|
|
|
// Force the file name extension to be XANIM_EXPORT
|
|
|
|
string $OldName[];
|
|
clear $OldName;
|
|
|
|
tokenize $FileName "." $OldName;
|
|
|
|
$FileName = ($OldName[0] + ".XANIM_EXPORT");
|
|
|
|
// open the file for writting
|
|
|
|
int $fileId=`fopen $FileName "w"`;
|
|
|
|
//Output the header information
|
|
|
|
OutputHeader $FileName $fileId; // Done
|
|
|
|
OutputPartList $fileId $PartsArray; //Done
|
|
|
|
OutPutFrameInfo $NumberOfFrames $FrameRate $fileId ; //Done
|
|
|
|
OutPutAnimation $StartFrame $EndFrame $PartsArray $fileId $isDouble;
|
|
|
|
OutPutNoteTracks $PartsArray $fileId $NoteTrack;
|
|
|
|
// Close the file
|
|
|
|
fclose $fileId;
|
|
|
|
$totalTime = `timerX -startTime $startTime`;
|
|
print ("ExportXanim: Total Export Time: "+$totalTime+"\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|