Files
gtav-src/tools_ng/techart/dcc/motionbuilder2014/python/RS/Utils/Motion.py
T
2025-09-29 00:52:08 +02:00

91 lines
4.0 KiB
Python
Executable File

'''
Usage:
This module should only contain functionality related to importing motion.
Author:
Ross George
'''
from pyfbsdk import *
import uuid
import RS.Globals
import RS.Utils.Scene
import RS.Utils.Scene.Take
import RS.Utils.Scene.Component
'''
Imports motion from a selected file on the selected model and it's children (decendant heirarchy).
Note that it doesn't use the FileImport default method. This is for two reasons at the time of
writing there is a bug with the motion import and also it doesn't expose enough options for example
selection the take which the motion will be imported from and too.
'''
def ImportHeirarchy( MaintainTakeRange = True ):
#Deselect non model objects
for component in RS.Globals.Components:
if not issubclass( type( component ), FBModel ):
component.Selected = False
#Check we have one model selected
selectedModelList = FBModelList()
FBGetSelectedModels( selectedModelList )
if len(selectedModelList) != 1:
FBMessageBox( "Error", "In order to import motion onto a heirarchy you must have only the root model of the hierarchy that want to import onto selected. Please select a single root model and try again.", "OK" )
return
#Select the heirarchy of models
rootModel = selectedModelList[0]
targetComponentList = list()
RS.Utils.Scene.GetChildren( rootModel, targetComponentList )
targetComponentList.append( rootModel )
#Ask to choose an fbx file
filePopup = FBFilePopup()
filePopup.Caption = "Select file to import motion from..."
filePopup.Style = FBFilePopupStyle.kFBFilePopupOpen
filePopup.Filter = "*.fbx"
if filePopup.Execute():
#Merge in the file that we want copy data from
loadOptions = FBFbxOptions( True, filePopup.FileName )
if loadOptions.GetTakeCount() != 1:
FBMessageBox( "Error", "File you are trying to import has multiple takes. Can only have one.", "OK" )
return
#We are going to merge the animation into a new take and into a new namespace
loadOptions.SetAll( FBElementAction.kFBElementActionMerge, True )
loadOptions.SetTakeSelect( 0, True )
loadOptions.SetTakeDestinationName( 0, str( uuid.uuid1() ) )
tempNamespace = str( uuid.uuid1() )
loadOptions.NamespaceList = tempNamespace
loadOptions.UpdateRecentFiles = False
#Get target take before we merge
targetTake = RS.Globals.System.CurrentTake
#Preform the merge
RS.Globals.Application.FileMerge( filePopup.FileName, False, loadOptions )
#The source take will be the last that was created and merge data down to base layer
sourceTake = RS.Globals.Scene.Takes[-1]
sourceTake.MergeLayers( FBAnimationLayerMergeOptions.kFBAnimLayerMerge_AllLayers_CompleteScene, True, FBMergeLayerMode.kFBMergeLayerModeAutomatic )
#Get the components we have just merged in by namespace
sourceNamespaceComponents = FBComponentList()
RS.Globals.Scene.NamespaceGetContentList( sourceNamespaceComponents, tempNamespace )
sourceComponentList = list( sourceNamespaceComponents )
#Transfer from source take to target take on source components
RS.Utils.Scene.Take.CopyAnimationData( sourceComponentList, sourceTake, targetTake )
#Set the take and execute a copy via component match list
RS.Globals.System.CurrentTake = targetTake
componentMatchList = RS.Utils.Scene.Component.GetComponentMatchList( sourceComponentList, targetComponentList)
for componentMatch in componentMatchList:
componentMatch.CopyAnimationData()
#Delete temporary namespace and take
sourceTake.FBDelete()
RS.Globals.Scene.Evaluate()
RS.Globals.Scene.NamespaceDelete( tempNamespace )