834 lines
29 KiB
Plaintext
Executable File
834 lines
29 KiB
Plaintext
Executable File
//------------------------------------------------------------------------------
|
|
// FaceFX for Maya.
|
|
//
|
|
// Owner: Jamie Redmond
|
|
//
|
|
// Copyright (c) 2002-2011 OC3 Entertainment, Inc. All Rights Reserved.
|
|
//------------------------------------------------------------------------------
|
|
//
|
|
// Commercial use prohibited without a valid FaceFX license from
|
|
// OC3 Entertainment.
|
|
|
|
global int $__FaceFXIsLoaded;
|
|
|
|
global string $__FaceFXGroupSelection = "";
|
|
global string $__FaceFXAnimationSelection = "";
|
|
|
|
// Called when the new menu item is selected.
|
|
global proc FaceFxNew()
|
|
{
|
|
string $result = `promptDialog
|
|
-title "Create New Actor"
|
|
-message "Enter Name:"
|
|
-button "OK" -button "Cancel"
|
|
-defaultButton "OK" -cancelButton "Cancel"
|
|
-dismissString "Cancel"`;
|
|
if( $result == "OK" )
|
|
{
|
|
string $name = `promptDialog -query -text`;
|
|
fxcreateactor -name $name;
|
|
}
|
|
}
|
|
|
|
// Called when the open menu item is selected.
|
|
global proc FaceFxOpen()
|
|
{
|
|
string $actorFile = `fileDialog -dm "*.facefx;*.xml"`;
|
|
if( $actorFile != "" )
|
|
{
|
|
fxloadactor -file $actorFile;
|
|
}
|
|
}
|
|
|
|
// Called when the change analysis actor menu item is selected.
|
|
global proc FaceFxChangeAnalysisActor()
|
|
{
|
|
string $actorFile = `fileDialog -dm "*.facefx"`;
|
|
if( $actorFile != "" )
|
|
{
|
|
fxchangeanalysisactor -file $actorFile;
|
|
}
|
|
}
|
|
|
|
// Called when the user saves the actor from the save as dialog.
|
|
global proc FaceFxOnSaveAs( string $actorFile, string $type )
|
|
{
|
|
// See if the file extension was provided and if not append
|
|
// it.
|
|
string $ext = `match "\.facefx" $actorFile`;
|
|
if( $ext == "" )
|
|
{
|
|
$ext = `match "\.xml" $actorFile`;
|
|
}
|
|
if( $ext == "" )
|
|
{
|
|
$actorFile += ".facefx";
|
|
}
|
|
fxsaveactor -file $actorFile;
|
|
}
|
|
|
|
// Called when the save menu item is selected.
|
|
global proc FaceFxSave()
|
|
{
|
|
// Maya 2011 has a new interface still
|
|
if( getApplicationVersionAsFloat() > 2010.9 )
|
|
{
|
|
string $result[] = `fileDialog2 -fm 0
|
|
-fileFilter "FaceFX Actor Files (*.facefx);;FaceFX XML Actor Files (*.xml)"
|
|
-caption "Save"
|
|
-okCaption "Save"
|
|
-dialogStyle 2`;
|
|
|
|
if(size( $result[0] ) > 0 )
|
|
{
|
|
FaceFxOnSaveAs($result[0], "");
|
|
}
|
|
}
|
|
// Maya 2010 appears to have broken the filtering feature.
|
|
else if( getApplicationVersionAsFloat() > 2009.9 )
|
|
{
|
|
fileBrowserDialog -mode 2
|
|
-fileCommand "FaceFxOnSaveAs"
|
|
-actionName "Save"
|
|
-operationMode "SaveAs";
|
|
}
|
|
else
|
|
{
|
|
fileBrowserDialog -mode 2
|
|
-fileCommand "FaceFxOnSaveAs"
|
|
-actionName "Save"
|
|
-operationMode "SaveAs"
|
|
-dialogStyle 1
|
|
-filterList "FaceFX,*.facefx;XML,*.xml"
|
|
-fileType "FaceFX,XML";
|
|
|
|
}
|
|
}
|
|
|
|
// Quit the FaceFx script. Called when the script first starts.
|
|
global proc FaceFxQuit()
|
|
{
|
|
// If the main FaceFx window is up, delete it first.
|
|
if( `window -exists __FaceFxMainWindow` )
|
|
{
|
|
deleteUI -window __FaceFxMainWindow;
|
|
}
|
|
}
|
|
|
|
// Called when the about menu item is selected.
|
|
global proc FaceFxAbout()
|
|
{
|
|
// Destroy any previous about window.
|
|
if(`window -exists __FaceFxAboutWindow`)
|
|
{
|
|
deleteUI -window __FaceFxAboutWindow;
|
|
}
|
|
|
|
// Display the about window.
|
|
window -titleBarMenu false -sizeable false -title "About FaceFX" -resizeToFitChildren true __FaceFxAboutWindow;
|
|
columnLayout;
|
|
string $pluginPath = `pluginInfo -query -path FaceFx`;
|
|
string $pluginName = "FaceFx.mll";
|
|
string $logoImage = "FaceFX_Logo_Small.bmp";
|
|
string $logoPath = `substitute $pluginName $pluginPath $logoImage`;
|
|
image -width 142 -height 50 -image $logoPath;
|
|
text -label "FaceFX for Maya";
|
|
text -label "Copyright (c) 2002-2010";
|
|
text -label "OC3 Entertainment, Inc.";
|
|
button -w 50 -h 20 -label "OK" -command ("deleteUI -window __FaceFxAboutWindow") -annotation "Dismiss this window.";
|
|
setParent ..;
|
|
|
|
showWindow __FaceFxAboutWindow;
|
|
}
|
|
|
|
// Called when the import reference pose button is pressed.
|
|
global proc FaceFxOnImportRefPose()
|
|
{
|
|
int $frame = `currentTime -q`;
|
|
fximportrefpose -frame $frame;
|
|
}
|
|
|
|
// Called when the user clicks "Export Reference Pose" from the export reference pose outliner window.
|
|
global proc FaceFxExportRefPose()
|
|
{
|
|
// Delete outliner.
|
|
if (`window -exists __FaceFxRefBoneSelectionWindow`)
|
|
{
|
|
deleteUI -window __FaceFxRefBoneSelectionWindow;
|
|
}
|
|
|
|
// The Current selection should be all of the bones.
|
|
string $currentSelection[] = `ls -sl`;
|
|
|
|
// Take the string array and concatenate a space-deliminated string.
|
|
string $refBoneList = "";
|
|
int $i = 0;
|
|
for( $i=0; $i < size($currentSelection); $i++ )
|
|
{
|
|
if( $i == size($currentSelection)-1 )
|
|
{
|
|
$refBoneList += $currentSelection[$i];
|
|
}
|
|
else
|
|
{
|
|
$refBoneList += $currentSelection[$i] + " ";
|
|
}
|
|
}
|
|
int $frame = `currentTime -q`;
|
|
fxexportrefpose -frame $frame -bones $refBoneList;
|
|
}
|
|
|
|
// Called when the export reference pose button is pressed.
|
|
global proc FaceFxOnExportRefPose()
|
|
{
|
|
// Delete outliner.
|
|
if (`window -exists __FaceFxRefBoneSelectionWindow`)
|
|
{
|
|
deleteUI -window __FaceFxRefBoneSelectionWindow;
|
|
}
|
|
|
|
// Maya 2011 has a new interface still
|
|
if( getApplicationVersionAsFloat() > 2010.9 )
|
|
{
|
|
|
|
window -title "Select all of the bones that FaceFX should control." -widthHeight 425 550 -menuBar true __FaceFxRefBoneSelectionWindow;
|
|
frameLayout -label "Select all of the bones that FaceFX should control.";
|
|
string $facefxoutlinerpanel = `outlinerPanel`;
|
|
string $facefxoutliner = `outlinerPanel -query -outlinerEditor $facefxoutlinerpanel`;
|
|
outlinerEditor -edit
|
|
-mainListConnection "worldList"
|
|
-selectionConnection "modelList"
|
|
-showShapes false
|
|
-showAttributes false
|
|
-showConnected false
|
|
-showAnimCurvesOnly false
|
|
-autoExpand false
|
|
-showDagOnly true
|
|
-ignoreDagHierarchy false
|
|
-expandConnections false
|
|
-showCompounds true
|
|
-showNumericAttrsOnly false
|
|
-highlightActive true
|
|
-autoSelectNewObjects false
|
|
-doNotSelectNewObjects false
|
|
-transmitFilters false
|
|
-showSetMembers true
|
|
-setFilter defaultSetFilter
|
|
$facefxoutliner;
|
|
button -label "Export Reference Pose" -command "FaceFxExportRefPose()" -annotation "Exports the reference pose.";
|
|
showWindow;
|
|
}
|
|
else
|
|
{
|
|
// Create outliner window for choosing the bones.
|
|
window -title "Select all of the bones that FaceFX should control." -widthHeight 425 550 -menuBar true __FaceFxRefBoneSelectionWindow;
|
|
paneLayout -cn "horizontal2" -ps 1 100 90;
|
|
frameLayout -label "Select all of the bones that FaceFX should control.";
|
|
outlinerEditor
|
|
-mainListConnection "worldList"
|
|
-selectionConnection "modelList"
|
|
-showShapes false
|
|
-showAttributes false
|
|
-showConnected false
|
|
-showAnimCurvesOnly false
|
|
-autoExpand false
|
|
-showDagOnly true
|
|
-ignoreDagHierarchy false
|
|
-expandConnections false
|
|
-showCompounds true
|
|
-showNumericAttrsOnly false
|
|
-highlightActive true
|
|
-autoSelectNewObjects false
|
|
-doNotSelectNewObjects false
|
|
-transmitFilters false
|
|
-showSetMembers true
|
|
-setFilter defaultSetFilter
|
|
__FaceFxOutlinerWindow;
|
|
setParent ..;
|
|
setParent ..;
|
|
button -label "Export Reference Pose" -command "FaceFxExportRefPose()" -annotation "Exports the reference pose.";
|
|
showWindow;
|
|
}
|
|
}
|
|
|
|
// Called when the import node button is pressed.
|
|
global proc FaceFxOnImportNode()
|
|
{
|
|
int $frame = `currentTime -q`;
|
|
string $name[] = `textScrollList -query -selectItem __FaceFxNodesListBox`;
|
|
// The node list box only supports single selection.
|
|
fximportbonepose -frame $frame -name $name[0];
|
|
}
|
|
|
|
// Called when the export node button is pressed.
|
|
global proc FaceFxOnExportNode()
|
|
{
|
|
string $selectedName[] = `textScrollList -query -selectItem __FaceFxNodesListBox`;
|
|
if( size($selectedName) == 0 ) $selectedName[0] = "NewNode";
|
|
// The node list box only supports single selection.
|
|
string $result = `promptDialog
|
|
-title "Export Bone Pose"
|
|
-message "Enter Name:"
|
|
-text $selectedName[0]
|
|
-button "OK" -button "Cancel"
|
|
-defaultButton "OK" -cancelButton "Cancel"
|
|
-dismissString "Cancel"`;
|
|
if( $result == "OK" )
|
|
{
|
|
string $name = `promptDialog -query -text`;
|
|
string $nodetype = `optionMenu -query -value __FaceFxNodeTypeDropdown`;
|
|
if( $nodetype == "FxBonePoseNode" )
|
|
{
|
|
int $frame = `currentTime -q`;
|
|
fxexportbonepose -frame $frame -name $name;
|
|
// Select the newly exported pose.
|
|
textScrollList -edit -selectItem $name __FaceFxNodesListBox;
|
|
}
|
|
else if ( $nodetype == "FxCombinerNode" )
|
|
{
|
|
fxcreatenode -n $name -t $nodetype -nodemin -1 -nodemax 1;
|
|
}
|
|
else if ( $nodetype == "FxMorphTargetNode" )
|
|
{
|
|
fxcreatenode -n $name -t $nodetype -nodemin 0 -nodemax 1;
|
|
}
|
|
else
|
|
{
|
|
print "Error: Unrecognized node type";
|
|
}
|
|
}
|
|
__FaceFxOnNodesChanged();
|
|
}
|
|
|
|
// Called when the batch import nodes button is pressed.
|
|
global proc FaceFxOnBatchImportNodes()
|
|
{
|
|
string $batchFile = `fileDialog -dm "*.txt"`;
|
|
if( $batchFile != "" )
|
|
{
|
|
fxbatchimportboneposes -file $batchFile;
|
|
}
|
|
}
|
|
|
|
// Called when the batch export nodes button is pressed.
|
|
global proc FaceFxOnBatchExportNodes()
|
|
{
|
|
string $nodetype = `optionMenu -query -value __FaceFxNodeTypeDropdown`;
|
|
if( $nodetype == "FxBonePoseNode" )
|
|
{
|
|
string $batchFile = `fileDialog -dm "*.txt"`;
|
|
if( $batchFile != "" )
|
|
{
|
|
fxbatchexportboneposes -file $batchFile;
|
|
}
|
|
}
|
|
if ( $nodetype == "FxMorphTargetNode" )
|
|
{
|
|
string $blendshape_object_array[] = `ls -type blendShape`;
|
|
for($blendshape in $blendshape_object_array)
|
|
{
|
|
string $blendshape_target_array[] = `listAttr -m ($blendshape + ".w")`;
|
|
for($blendshape_target in $blendshape_target_array)
|
|
{
|
|
string $fullTargetName = $blendshape + "." + $blendshape_target;
|
|
fxcreatenode -n $fullTargetName -t "FxMorphTargetNode" -nodemin 0 -nodemax 1;
|
|
}
|
|
}
|
|
__FaceFxOnNodesChanged();
|
|
}
|
|
}
|
|
|
|
// Called when the animation group selection changes.
|
|
global proc FaceFxOnAnimGroupSelChanged()
|
|
{
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
global string $__FaceFXGroupSelection;
|
|
$__FaceFXGroupSelection = $group;
|
|
string $anims[] = `fxgetanims -group $group`;
|
|
textScrollList -e -removeAll __FaceFxAnimationsListBox;
|
|
int $i;
|
|
for( $i = 0; $i < size($anims); $i++ )
|
|
{
|
|
textScrollList -e -append $anims[$i] __FaceFxAnimationsListBox;
|
|
}
|
|
}
|
|
|
|
// Called when the user presses the Import button on the animations pane.
|
|
global proc FaceFxOnImportAnimation()
|
|
{
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
string $anim[] = `textScrollList -query -selectItem __FaceFxAnimationsListBox`;
|
|
float $framerate = 60.0;
|
|
string $timeUnit = `currentUnit -q -time`;
|
|
switch ($timeUnit)
|
|
{
|
|
case "game":
|
|
$framerate = 15.0;
|
|
break;
|
|
case "film":
|
|
$framerate = 24.0;
|
|
break;
|
|
case "pal":
|
|
$framerate = 25.0;
|
|
break;
|
|
case "ntsc":
|
|
$framerate = 30.0;
|
|
break;
|
|
case "show":
|
|
$framerate = 48.0;
|
|
break;
|
|
case "palf":
|
|
$framerate = 50.0;
|
|
break;
|
|
case "ntscf":
|
|
$framerate = 60.0;
|
|
break;
|
|
default:
|
|
warning "You're using a non-standard frame rate. Defaulting to 60 fps.";
|
|
}
|
|
int $curFrame = `currentTime -q`;
|
|
float $curTime = (float)$curFrame / (float)$framerate;
|
|
// The animation list box only supports single selection.
|
|
fximportanim -group $group -anim $anim[0] -framerate $framerate -audioStartTime $curTime;
|
|
}
|
|
// Called when the user presses the Clean button on the animations pane.
|
|
global proc FaceFxOnCleanAnimation()
|
|
{
|
|
progressWindow
|
|
-title "Please Wait"
|
|
-progress 0
|
|
-status "Cleaning animation timeline"
|
|
-isInterruptable false;
|
|
|
|
fxclean;
|
|
progressWindow -endProgress;
|
|
}
|
|
|
|
// Called when the user presses the Rename button on the animations pane.
|
|
global proc FaceFxOnRenameAnimation()
|
|
{
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
string $anim[] = `textScrollList -query -selectItem __FaceFxAnimationsListBox`;
|
|
string $result = `promptDialog
|
|
-title "Rename Animation"
|
|
-message "Enter Name:"
|
|
-text $anim[0]
|
|
-button "OK" -button "Cancel"
|
|
-defaultButton "OK" -cancelButton "Cancel"
|
|
-dismissString "Cancel"`;
|
|
if( $result == "OK" )
|
|
{
|
|
string $name = `promptDialog -query -text`;
|
|
fxrenameanim -group $group -anim $anim[0] -name $name;
|
|
__FaceFxOnActorChanged();
|
|
}
|
|
}
|
|
// Called when the user presses the Delete button on the animations pane.
|
|
global proc FaceFxOnDeleteAnimation()
|
|
{
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
string $anim[] = `textScrollList -query -selectItem __FaceFxAnimationsListBox`;
|
|
fxdeleteanim -group $group -anim $anim[0];
|
|
__FaceFxOnActorChanged();
|
|
}
|
|
// Called when the user presses the Delete button on the animations pane.
|
|
global proc FaceFxOnGenerateAnimation()
|
|
{
|
|
progressWindow
|
|
-title "Please Wait"
|
|
-progress 0
|
|
-status "Generating animation..."
|
|
-isInterruptable false;
|
|
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
fxgenerateanim -group $group;
|
|
__FaceFxOnActorChanged();
|
|
progressWindow -endProgress;
|
|
}
|
|
global proc FaceFxOnNewTake()
|
|
{
|
|
string $group = `optionMenu -query -value __FaceFxAnimationGroupsDropdown`;
|
|
string $anim[] = `textScrollList -query -selectItem __FaceFxAnimationsListBox`;
|
|
fxnewtake -group $group -anim $anim[0];
|
|
}
|
|
global proc FaceFxOnAddGroup()
|
|
{
|
|
string $result = `promptDialog
|
|
-title "Add Animation Group"
|
|
-message "Enter Name:"
|
|
-text ""
|
|
-button "OK" -button "Cancel"
|
|
-defaultButton "OK" -cancelButton "Cancel"
|
|
-dismissString "Cancel"`;
|
|
if( $result == "OK" )
|
|
{
|
|
string $group = `promptDialog -query -text`;
|
|
global string $__FaceFXGroupSelection;
|
|
$__FaceFXGroupSelection = $group;
|
|
fxinsertanimgroup -group $group;
|
|
__FaceFxOnActorChanged();
|
|
}
|
|
}
|
|
|
|
// Initialize the main FaceFx window.
|
|
global proc FaceFxPanelAdd( string $panelLayout )
|
|
{
|
|
global int $__FaceFXIsLoaded;
|
|
$__FaceFXIsLoaded = 1;
|
|
|
|
// Set up the menu bar.
|
|
menu -label "File";
|
|
menuItem -label "New" -command "FaceFxNew()";
|
|
menuItem -label "Open..." - command "FaceFxOpen()";
|
|
menuItem -label "Save..." - command "FaceFxSave()";
|
|
menuItem -divider true;
|
|
menuItem -label "Change Analysis Actor..." - command "FaceFxChangeAnalysisActor()";
|
|
menuItem -divider true;
|
|
menuItem -label "About..." - command "FaceFxAbout()";
|
|
|
|
// The main layout.
|
|
tabLayout __FaceFxMainTabLayout;
|
|
scrollLayout -hst 0 __FaceFxMainScrollLayout;
|
|
// The tab gets the actor name.
|
|
string $actorName = `fxgetactorname`;
|
|
tabLayout -edit -tabLabel __FaceFxMainScrollLayout $actorName __FaceFxMainTabLayout;
|
|
columnLayout __FaceFxMainColumnLayout;
|
|
|
|
// Set up the reference pose controls.
|
|
frameLayout -borderStyle "etchedIn" -labelVisible true -label "Reference Pose" -cll true -marginWidth 10 -marginHeight 5 __FaceFxRefPoseLayout;
|
|
columnLayout __FaceFxRefPoseColumnLayout;
|
|
text -label "Reference Bones";
|
|
textScrollList -numberOfRows 12 -allowMultiSelection false -w 300 __FaceFxRefBonesListBox;
|
|
rowLayout -numberOfColumns 2 -adjustableColumn 2 -cw2 78 78 __FaceFxRefPoseRowLayout;
|
|
button -w 78 -h 20 -annotation "Imports the reference pose." -label "Import" -command "FaceFxOnImportRefPose()" -align "center" __FaceFxImportRefPoseButton;
|
|
button -w 78 -h 20 -annotation "Exports the reference pose." -label "Export..." -command "FaceFxOnExportRefPose()" -align "center" __FaceFxExportRefPoseButton;
|
|
setParent ..;
|
|
setParent ..;
|
|
setParent ..;
|
|
|
|
// Set up the node controls.
|
|
frameLayout -borderStyle "etchedIn" -labelVisible true -label "Nodes" -cll true -marginWidth 10 -marginHeight 5 __FaceFxNodesLayout;
|
|
columnLayout __FaceFxNodesColumnLayout;
|
|
//text -label "Nodes";
|
|
optionMenu -w 230 -h 20 -label "Node Type" -changeCommand "__FaceFxOnNodesChanged()" __FaceFxNodeTypeDropdown;
|
|
menuItem -label "FxBonePoseNode" -parent __FaceFxNodeTypeDropdown;
|
|
menuItem -label "FxMorphTargetNode" -parent __FaceFxNodeTypeDropdown;
|
|
menuItem -label "FxCombinerNode" -parent __FaceFxNodeTypeDropdown;
|
|
|
|
textScrollList -numberOfRows 16 -allowMultiSelection false -w 300 -selectCommand "__FaceFxOnNodeSelChanged()" __FaceFxNodesListBox;
|
|
rowLayout -numberOfColumns 4 -adjustableColumn 4 -cw4 72 72 78 78 __FaceFxNodesRowLayout;
|
|
button -w 72 -h 20 -annotation "Imports a node." -label "Import" -command "FaceFxOnImportNode()" -align "center" __FaceFxImportNodeButton;
|
|
button -w 72 -h 20 -annotation "Exports a node." -label "Export..." -command "FaceFxOnExportNode()" -align "center" __FaceFxExportNodeButton;
|
|
button -w 78 -h 20 -annotation "Batch imports nodes." -label "Batch Import..." -command "FaceFxOnBatchImportNodes()" -align "center" __FaceFxBatchImportNodesButton;
|
|
button -w 78 -h 20 -annotation "Batch exports nodes." -label "Batch Export..." -command "FaceFxOnBatchExportNodes()" -align "center" __FaceFxBatchExportNodesButton;
|
|
setParent ..;
|
|
setParent ..;
|
|
setParent..;
|
|
|
|
|
|
// Set up the animation controls.
|
|
frameLayout -borderStyle "etchedIn" -labelVisible true -label "Animations" -cll true -marginWidth 10 -marginHeight 5 __FaceFxAnimationsLayout;
|
|
columnLayout __FaceFxAnimationsColumnLayout;
|
|
rowLayout -numberOfColumns 2 -adjustableColumn 2 -cw2 230 70 __FaceFxAnimationGroupsRowLayout;
|
|
optionMenu -w 230 -h 20 -label "Animation Group" -changeCommand "FaceFxOnAnimGroupSelChanged()" __FaceFxAnimationGroupsDropdown;
|
|
button -w 70 -h 20 -annotation "Adds an animation group." -label "Add Group" -command "FaceFxOnAddGroup()" -align "center" __FaceFxAddAnimGroupButton;
|
|
setParent ..;
|
|
textScrollList -numberOfRows 12 -allowMultiSelection false -w 300 -selectCommand "__FaceFxOnAnimSelectionChanged()" __FaceFxAnimationsListBox;
|
|
rowLayout -numberOfColumns 4 -adjustableColumn 4 -cw4 72 72 78 78 __FaceFxAnimationsRowLayout;
|
|
button -w 72 -h 20 -annotation "Imports an animation." -label "Import" -command "FaceFxOnImportAnimation()" -align "center" __FaceFxImportAnimationButton;
|
|
button -w 73 -h 20 -annotation "Cleans animation timeline." -label "Clean" -command "FaceFxOnCleanAnimation()" -align "center" __FaceFxCleanAnimationButton;
|
|
button -w 78 -h 20 -annotation "Renames an animation." -label "Rename" -command "FaceFxOnRenameAnimation()" -align "center" __FaceFxRenameAnimationButton;
|
|
button -w 78 -h 20 -annotation "Deletes an animation." -label "Delete" -command "FaceFxOnDeleteAnimation()" -align "center" __FaceFxDeleteAnimationButton;
|
|
setParent ..;
|
|
rowLayout -numberOfColumns 2 -adjustableColumn 2 -cw2 150 150 __FaceFxAnimationsRowLayout2;
|
|
if(`fxisanalysistool`)
|
|
{
|
|
button -w 150 -h 20 -annotation "Generates an animation." -label "Generate Animation" -command "FaceFxOnGenerateAnimation()" -align "center" __FaceFxGenerateAnimationButton;
|
|
button -w 150 -h 20 -annotation "Generates a new take." -label "New Take" -command "FaceFxOnNewTake()" -align "center" __FaceFxNewTakeButton;
|
|
}
|
|
else
|
|
{
|
|
button -w 150 -h 20 -annotation "Generates an animation." -visible false -label "Generate Animation" -command "FaceFxOnGenerateAnimation()" -align "center" __FaceFxGenerateAnimationButton;
|
|
button -w 150 -h 20 -annotation "Generates a new take." -visible false -label "New Take" -command "FaceFxOnNewTake()" -align "center" __FaceFxNewTakeButton;
|
|
}
|
|
setParent ..;
|
|
setParent ..;
|
|
__FaceFxOnAnimSelectionChanged();
|
|
if(`fxismoddeveloper`)
|
|
{
|
|
disable __FaceFxImportAnimationButton;
|
|
}
|
|
// If there was already a FaceFx actor loaded, make sure the UI reflects the actor's data.
|
|
__FaceFxOnActorChanged();
|
|
}
|
|
|
|
// Called from the plug-in when the actor has changed.
|
|
global proc __FaceFxOnActorChanged()
|
|
{
|
|
global int $__FaceFXIsLoaded;
|
|
if ( $__FaceFXIsLoaded == 1 )
|
|
{
|
|
// Update the actor name.
|
|
string $actorName = `fxgetactorname`;
|
|
tabLayout -edit -tabLabel __FaceFxMainScrollLayout $actorName __FaceFxMainTabLayout;
|
|
// Update the reference bones display.
|
|
__FaceFxOnRefBonesChanged();
|
|
// Update the nodes display.
|
|
__FaceFxOnNodesChanged();
|
|
// Update the animations display. This requires a recreation of the entire animations panel
|
|
// because MEL's optionMenu does not allow removing items, only appending them.
|
|
deleteUI __FaceFxAnimationGroupsRowLayout;
|
|
deleteUI __FaceFxAnimationsListBox;
|
|
deleteUI __FaceFxAnimationsRowLayout;
|
|
deleteUI __FaceFxAnimationsRowLayout2;
|
|
|
|
|
|
rowLayout -numberOfColumns 2 -adjustableColumn 2 -cw2 230 70 -parent __FaceFxAnimationsColumnLayout __FaceFxAnimationGroupsRowLayout;
|
|
optionMenu -w 230 -h 20 -label "Animation Group" -changeCommand "FaceFxOnAnimGroupSelChanged()" __FaceFxAnimationGroupsDropdown;
|
|
button -w 70 -h 20 -annotation "Adds an animation group." -label "Add Group" -command "FaceFxOnAddGroup()" -align "center" __FaceFxAddAnimGroupButton;
|
|
textScrollList -numberOfRows 10 -allowMultiSelection false -w 300 -selectCommand "__FaceFxOnAnimSelectionChanged()" -parent __FaceFxAnimationsColumnLayout __FaceFxAnimationsListBox;
|
|
rowLayout -numberOfColumns 4 -adjustableColumn 4 -cw4 72 72 78 78 -parent __FaceFxAnimationsColumnLayout __FaceFxAnimationsRowLayout;
|
|
button -w 72 -h 20 -annotation "Imports an animation." -label "Import" -command "FaceFxOnImportAnimation()" -align "center" __FaceFxImportAnimationButton;
|
|
button -w 72 -h 20 -annotation "Cleans animation timeline." -label "Clean" -command "FaceFxOnCleanAnimation()" -align "center" __FaceFxCleanAnimationButton;
|
|
button -w 78 -h 20 -annotation "Renames selected animation." -label "Rename" -command "FaceFxOnRenameAnimation()" -align "center" __FaceFxRenameAnimationButton;
|
|
button -w 78 -h 20 -annotation "Deletes selected animation." -label "Delete" -command "FaceFxOnDeleteAnimation()" -align "center" __FaceFxDeleteAnimationButton;
|
|
setParent ..;
|
|
rowLayout -numberOfColumns 2 -adjustableColumn 2 -cw2 150 150 -parent __FaceFxAnimationsColumnLayout __FaceFxAnimationsRowLayout2;
|
|
if(`fxisanalysistool`)
|
|
{
|
|
button -w 150 -h 20 -annotation "Generates an animation." -label "Generate Animation" -command "FaceFxOnGenerateAnimation()" -align "center" __FaceFxGenerateAnimationButton;
|
|
button -w 150 -h 20 -annotation "Generates a new take." -label "New Take" -command "FaceFxOnNewTake()" -align "center" __FaceFxNewTakeButton;
|
|
}
|
|
else
|
|
{
|
|
button -w 150 -h 20 -annotation "Generates an animation." -visible false -label "Generate Animation" -command "FaceFxOnGenerateAnimation()" -align "center" __FaceFxGenerateAnimationButton;
|
|
button -w 150 -h 20 -annotation "Generates a new take." -visible false -label "New Take" -command "FaceFxOnNewTake()" -align "center" __FaceFxNewTakeButton;
|
|
}
|
|
setParent ..;
|
|
if(`fxismoddeveloper`)
|
|
{
|
|
disable __FaceFxImportAnimationButton;
|
|
}
|
|
__FaceFxOnAnimSelectionChanged();
|
|
// Add the animation groups to the group dropdown.
|
|
string $groups[] = `fxgetanimgroups`;
|
|
int $i;
|
|
global string $__FaceFXGroupSelection;
|
|
for( $i = 0; $i < size($groups); $i++ )
|
|
{
|
|
menuItem -label $groups[$i] -parent __FaceFxAnimationGroupsDropdown;
|
|
if( $groups[$i] == $__FaceFXGroupSelection )
|
|
{
|
|
optionMenu -edit -value $__FaceFXGroupSelection __FaceFxAnimationGroupsDropdown;
|
|
}
|
|
}
|
|
FaceFxOnAnimGroupSelChanged();
|
|
}
|
|
}
|
|
|
|
// Called from the plug-in when the reference bones have changed.
|
|
global proc __FaceFxOnRefBonesChanged()
|
|
{
|
|
int $hasValidRefPose = 0;
|
|
string $refBones[] = `fxgetrefbones`;
|
|
if ( size($refBones) > 0 )
|
|
{
|
|
$hasValidRefPose = 1;
|
|
}
|
|
button -edit -enable $hasValidRefPose __FaceFxImportRefPoseButton;
|
|
textScrollList -e -removeAll __FaceFxRefBonesListBox;
|
|
string $refBones[] = `fxgetrefbones`;
|
|
int $i;
|
|
for( $i = 0; $i < size($refBones); $i++ )
|
|
{
|
|
textScrollList -e -append $refBones[$i] __FaceFxRefBonesListBox;
|
|
}
|
|
// Need to call this so that we know if bone poses can be exported.
|
|
__FaceFxOnNodeSelChanged();
|
|
}
|
|
|
|
// Called when the node selection changes.
|
|
global proc __FaceFxOnNodeSelChanged()
|
|
{
|
|
string $nodetype = `optionMenu -query -value __FaceFxNodeTypeDropdown`;
|
|
int $hasValidSelection = 0;
|
|
string $selectedName[] = `textScrollList -query -selectItem __FaceFxNodesListBox`;
|
|
if( size($selectedName) > 0 )
|
|
{
|
|
$hasValidSelection = 1;
|
|
}
|
|
int $hasValidRefPose = 0;
|
|
string $refBones[] = `fxgetrefbones`;
|
|
if ( size($refBones) > 0 )
|
|
{
|
|
$hasValidRefPose = 1;
|
|
}
|
|
|
|
button -edit -enable false __FaceFxImportNodeButton;
|
|
button -edit -enable false __FaceFxExportNodeButton;
|
|
button -edit -enable false __FaceFxBatchImportNodesButton;
|
|
button -edit -enable false __FaceFxBatchExportNodesButton;
|
|
if( $nodetype == "FxBonePoseNode" )
|
|
{
|
|
if ( $hasValidRefPose )
|
|
{
|
|
if( $hasValidSelection )
|
|
{
|
|
button -edit -enable true __FaceFxImportNodeButton;
|
|
}
|
|
button -edit -enable true __FaceFxExportNodeButton;
|
|
button -edit -enable true __FaceFxBatchImportNodesButton;
|
|
button -edit -enable true __FaceFxBatchExportNodesButton;
|
|
}
|
|
}
|
|
else if ( $nodetype == "FxMorphTargetNode" )
|
|
{
|
|
button -edit -enable true __FaceFxExportNodeButton;
|
|
button -edit -enable true __FaceFxBatchExportNodesButton;
|
|
}
|
|
else
|
|
{
|
|
button -edit -enable true __FaceFxExportNodeButton;
|
|
}
|
|
|
|
}
|
|
|
|
// Called from the plug-in when the nodes have changed.
|
|
global proc __FaceFxOnNodesChanged()
|
|
{
|
|
string $selectedName[] = `textScrollList -query -selectItem __FaceFxNodesListBox`;
|
|
|
|
string $nodetype = `optionMenu -query -value __FaceFxNodeTypeDropdown`;
|
|
textScrollList -e -removeAll __FaceFxNodesListBox;
|
|
string $nodes[] = `fxgetnodes -type $nodetype`;
|
|
int $hasValidSelection = 0;
|
|
|
|
int $i;
|
|
for( $i = 0; $i < size($nodes); $i++ )
|
|
{
|
|
textScrollList -e -append $nodes[$i] __FaceFxNodesListBox;
|
|
if( $nodes[$i] == $selectedName[0])
|
|
{
|
|
$hasValidSelection = 1;
|
|
}
|
|
}
|
|
if( $hasValidSelection )
|
|
{
|
|
textScrollList -e -selectItem $selectedName[0] __FaceFxNodesListBox;
|
|
}
|
|
__FaceFxOnNodeSelChanged();
|
|
}
|
|
// Called from the plug-in when the nodes have changed.
|
|
global proc __FaceFxOnAnimSelectionChanged()
|
|
{
|
|
string $selectedName[] = `textScrollList -query -selectItem __FaceFxAnimationsListBox`;
|
|
int $hasValidSelection = 0;
|
|
if( size($selectedName) > 0 )
|
|
{
|
|
$hasValidSelection = 1;
|
|
//global string $__FaceFXAnimationSelection;
|
|
//$__FaceFXAnimationSelection = $selectedName[0];
|
|
}
|
|
button -edit -enable $hasValidSelection __FaceFxImportAnimationButton;
|
|
button -edit -enable $hasValidSelection __FaceFxRenameAnimationButton;
|
|
button -edit -enable $hasValidSelection __FaceFxDeleteAnimationButton;
|
|
if(`fxisanalysistool`)
|
|
{
|
|
button -edit -enable $hasValidSelection __FaceFxNewTakeButton;
|
|
}
|
|
|
|
string $morphnodes[] = `fxgetnodes -type "FxMorphTargetNodes"`;
|
|
int $hasSomethingToClean = 0;
|
|
string $refBones[] = `fxgetrefbones`;
|
|
if ( size($refBones) > 0 || size($morphnodes) > 0 )
|
|
{
|
|
$hasSomethingToClean = 1;
|
|
}
|
|
button -edit -enable $hasSomethingToClean __FaceFxCleanAnimationButton;
|
|
}
|
|
|
|
global proc string FaceFxPanelSave( string $panel)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
global proc FaceFxPanelCreate( string $panel )
|
|
{
|
|
}
|
|
|
|
global proc FaceFxPanelRemove( string $panel )
|
|
{
|
|
global int $__FaceFXIsLoaded;
|
|
$__FaceFXIsLoaded = 0;
|
|
}
|
|
|
|
global proc FaceFxPanelDelete( string $panel )
|
|
{
|
|
FaceFxQuit();
|
|
}
|
|
|
|
// Main script procedure.
|
|
global proc FaceFxMain()
|
|
{
|
|
// Quit any previous FaceFx window.
|
|
FaceFxQuit();
|
|
|
|
// Only register the FaceFx scripted panel type once.
|
|
if( !`scriptedPanelType -q -exists FaceFxScriptedPanel` )
|
|
{
|
|
scriptedPanelType
|
|
// Callbacks Maya will use for scriptedPanels of this type.
|
|
-acb FaceFxPanelAdd
|
|
-ccb FaceFxPanelCreate
|
|
-rcb FaceFxPanelRemove
|
|
-dcb FaceFxPanelDelete
|
|
-scb FaceFxPanelSave
|
|
-unique true
|
|
FaceFxScriptedPanel;
|
|
}
|
|
|
|
// Find any existing FaceFX panels.
|
|
string $facefxPanels[] = `getPanel -scriptType FaceFxScriptedPanel`;
|
|
|
|
if ( size( $facefxPanels ) )
|
|
{
|
|
// Unparent the scriptedPanel from where it is currently docked
|
|
scriptedPanel -e -unParent $facefxPanels[0];
|
|
// Fill the 'hole' left in the UI from removing the scriptedPanel.
|
|
fillEmptyPanes;
|
|
}
|
|
else
|
|
{
|
|
// Create an unparented scriptedPanel.
|
|
scriptedPanel -unParent -type FaceFxScriptedPanel
|
|
-menuBarVisible true
|
|
-label "FaceFX"
|
|
__FaceFxScriptedPanel;
|
|
|
|
// Refresh the $facefxPanels variable
|
|
$facefxPanels = `getPanel -scriptType FaceFxScriptedPanel`;
|
|
}
|
|
|
|
// Create the window and its layout
|
|
window -title "FaceFX" -iconName "FaceFx" -menuBar true -menuBarVisible true -resizeToFitChildren true __FaceFxMainWindow;
|
|
|
|
// Just create the layout for now and leave it empty.
|
|
string $layout = `paneLayout -configuration "single"`;
|
|
setParent ..;
|
|
|
|
// Now dock the scriptedPanel into the layout.
|
|
scriptedPanel -e -parent $layout $facefxPanels[0];
|
|
|
|
showWindow __FaceFxMainWindow;
|
|
__FaceFxOnActorChanged();
|
|
}
|
|
|
|
// scriptJobs for File -> New and File -> Open.
|
|
//int $fileNewJob = `scriptJob -event "NewSceneOpened" FaceFxMain`;
|
|
//int $fileOpenJob = `scriptJob -event "SceneOpened" FaceFxMain`;
|
|
|
|
// Load the plugin
|
|
loadPlugin -quiet "FaceFx.mll";
|
|
|
|
// Call the main procedure.
|
|
FaceFxMain(); |