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

347 lines
14 KiB
Python
Executable File

from pyfbsdk import *
from pyfbsdk_additions import *
from xml.dom import minidom
import RS.Globals as glo
import RS.Config
import RS.Perforce
import RS.Core.Reference.Lib
import RS.Core.Reference.Manager
import RS.Core.Expression.RelationConstraintUtils
reload (RS.Core.Expression.RelationConstraintUtils)
reload (RS.Core.Reference.Lib)
def FindAnimationNode(pParent, pName):
lResult = None
for lNode in pParent.Nodes:
if lNode.Name == pName:
lResult = lNode
break
return lResult
# Copy Model's TR animation data
def copyAnimation(pSrc, pDst ):
for pName in [ 'Translation/X','Translation/Y','Translation/Z', 'Rotation/X','Rotation/Y','Rotation/Z']:
lSrcNode = findAnimationNode( pName, pSrc.AnimationNode )
lDstNode = findAnimationNode( pName, pDst.AnimationNode )
if lSrcNode and lSrcNode.FCurve and lDstNode:
lDstNode.FCurve.KeyReplaceBy(lSrcNode.FCurve)
class MBCharacterSkeleton:
def __init__(self):
self.name = ""
self.nameSpace = ""
self.character = None
self.skelRoot = None
self.allJoints = []
def __GetChildJoints(self, joint):
allChildren = []
for child in joint.Children:
allChildren.append(child)
allChildren += self.__GetChildJoints(child)
return allChildren
def GetSkeleton(self):
self.allJoints.append(self.skelRoot)
self.allJoints += self.__GetChildJoints(self.skelRoot)
self.allJoints.append(self.skelRoot.Parent)
def PlotSkeleton(self, take=None):
#Plot all takes if none are supplied
if take == None:
for joint in self.allJoints:
joint.Selected = True
def loadIKConstraint(recCharacterNamespace, giverCharacterNamespace):
myXMLPATH = "{0}/etc/config/general/ConvertAnimSkelToSkelIKJoints.xml".format(RS.Config.Tool.Path.Root)
FBSystem().Scene.Evaluate()
#rManager = cRelationManager("", "")
rManager = RS.Core.Expression.RelationConstraintUtils.cRelationManager((recCharacterNamespace +"_IK_REL"), "")
rManager.pluginName = "temp"
rManager.characterName = recCharacterNamespace
rManager.entities.append(recCharacterNamespace)
rManager.entities.append(giverCharacterNamespace)
rManager.loadConstraintXML(myXMLPATH)
rManager.constructConstraint()
#print rManager.allControllers
#rManager.debugPrintConstraint(1)
def getCharacterFromModel( skelModelNode ):
scene = FBSystem().Scene
#print "-{0}".format(skelModelNode.LongName)
for fbChar in scene.Characters:
#print "-{0}".format(fbChar.LongName)
for fbCharProp in fbChar.PropertyList:
if "link" in fbCharProp.Name.lower():
for obj in fbCharProp:
#print "-{0}, {1}".format(skelModelNode.LongName, obj.LongName)
if skelModelNode.LongName.lower() == obj.LongName.lower():
return fbChar
return None
def ConnectJointToJoint(sourceJointBox, destJointBox):
propsToConnect = ["Rotation", "Translation", "Scaling"]
for prop in propsToConnect:
sourceAnimNode = FindAnimationNode(sourceJointBox.AnimationNodeOutGet(), prop )
destAnimNode = FindAnimationNode(destJointBox.AnimationNodeInGet(), prop)
if sourceAnimNode and destAnimNode:
FBConnect (sourceAnimNode, destAnimNode)
else:
print "Could not connect! {0}, {1}".format(sourceAnimNode, destAnimNode)
def SkeletonToSkeletonTransfer( sourceCharacter, destCharacter ):
relationInst = FBConstraintRelation("Mid_To_Final")
relationInst.Active = True
y = 0
for srcJoint in sourceCharacter.allJoints:
for dstJoint in destCharacter.allJoints:
if srcJoint.Name.lower() == dstJoint.Name.lower():
sourceBox = relationInst.SetAsSource(srcJoint)
relationInst.SetBoxPosition(sourceBox, 0, y)
destBox = relationInst.ConstrainObject(dstJoint)
relationInst.SetBoxPosition(destBox, 200, y)
ConnectJointToJoint(sourceBox, destBox)
y += 75
return relationInst
def LoadSettingsFile( settingsFilePath ):
if settingsFilePath:
charMap = {}
xmldoc = minidom.parse( settingsFilePath )
charNodes = xmldoc.getElementsByTagName( 'character' )
for charNode in charNodes:
fbxPath = str( charNode.attributes[ 'fbx' ].value )
charName = str( charNode.attributes[ 'namecomp' ].value )
stage = str( charNode.attributes[ 'stage' ].value )
if stage == "final":
charName += "F"
charMap[charName] = fbxPath
return charMap
else:
print "Couldn't load settings file:{0}".format(settingsFilePath)
return {}
def ProcessFile( sourceFile, outputFile):
settingsFilePath = '{0}/etc/config/general/ConvertAnimSkeletonSettings.xml'.format(RS.Config.Tool.Path.Root)
transModelPaths = LoadSettingsFile(settingsFilePath)
'''
{'player':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Player_Zero_Transfer_MID.fbx",
'playerF':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Player_Zero_Final.fbx",
'male':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Male_Skeleton_MID.fbx",
'maleF':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Male_Skeleton_Final.fbx",
'female':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Female_Skeleton_MID.fbx",
'femaleF':r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Female_Skeleton_Final.fbx"
}
'''
try:
FBApplication().FileNew()
bOpen = FBApplication().FileOpen(sourceFile, 0)
except:
return 0
scene = FBSystem().Scene
refManager = RS.Core.Reference.Manager.RsReferenceManager()
refManager.collectSceneReferences()
origSceneChars = refManager.characters
lOptions = FBPlotOptions()
lOptions.ConstantKeyReducerKeepOneKey = False
lOptions.UseConstantKeyReducer = False
lOptions.PlotAllTakes = True
lOptions.PlotOnFrame = True
lOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
lOptions.PlotTranslationOnRootOnly = False
lOptions.PreciseTimeDiscontinuities = True
lOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
for char in origSceneChars:
charNamespace = char.namespace
charName = char.name
print "{0}:{1}".format(charNamespace,charName)
charModel = FBFindModelByLabelName("{0}:{1}".format(charNamespace,"SKEL_ROOT"))
if charModel != None:
charCharacter = getCharacterFromModel(charModel)
#charCharacter.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, lOptions)
print "Found Giver Character:{0}".format(charCharacter)
characterName = "Player_Zero"
charPath = None
for key in transModelPaths.keys():
if key in charNamespace.lower():
charPath = transModelPaths[key]
finalCharPath = transModelPaths[key + "F"]
if charPath == None:
charPath = r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Player_Zero_Transfer_MID.fbx"
finalCharPath = r"X:\rdr3\art\animation\resources\characters\Models\ingame\NewSkel\Player_Zero_Final.fbx"
#Ref in both versions of the character for processing...
newChar = RS.Core.Reference.Lib.rs_CreateReference(charPath, characterName, quiet=True, returnReferenceNull=True )
newCharFinal = RS.Core.Reference.Lib.rs_CreateReference(finalCharPath, characterName, quiet=True, returnReferenceNull=True )
print "MID CHAR:{0}".format(newChar)
print "FINAL CHAR:{0}".format(newCharFinal)
if newChar != False and len(newChar) > 0:
#Get the reference null object for the character
newChar = newChar[0]
#Get the Skel root if possible
newCharModel = FBFindModelByLabelName("{0}:{1}".format(newChar.Name,"SKEL_ROOT"))
#Get the fbcharacter associated with the model
newCharCharacter = getCharacterFromModel(newCharModel)
if newCharCharacter:
newCharCharacter.CreateControlRig(True)
print "Still Have it {0}".format(charCharacter)
newCharCharacter.InputCharacter = charCharacter
newCharCharacter.InputType = FBCharacterInputType.kFBCharacterInputCharacter
newCharCharacter.ActiveInput = True
#newCharCharacter.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, lOptions)
newCharCharacter.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, lOptions)
FBSystem().Scene.Evaluate()
loadIKConstraint(newChar.Name, charNamespace)
charMidInst = MBCharacterSkeleton()
charMidInst.skelRoot = newCharModel
charMidInst.GetSkeleton()
#Lets handle the final skeleton now
if newCharFinal != False and len(newCharFinal) > 0:
#Get the reference null object for the character
newFinalChar = newCharFinal[0]
#Get the Skel root if possible
newFinalCharModel = FBFindModelByLabelName("{0}:{1}".format(newFinalChar.Name,"SKEL_ROOT"))
if newFinalCharModel:
#Lets make a new skeleton class for organizational purposes
charInstFinal = MBCharacterSkeleton()
charInstFinal.skelRoot = newFinalCharModel
charInstFinal.GetSkeleton()
#Now lets create the relation constraint to do skel to skel
midToFinRel = SkeletonToSkeletonTransfer( charMidInst, charInstFinal)
#Get the fbcharacter associated with the model
newFinalCharCharacter = getCharacterFromModel(newFinalCharModel)
#Create a rig
newFinalCharCharacter.CreateControlRig(True)
#Plot to the rig
newFinalCharCharacter.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, lOptions)
#Turn off the relation constraint
midToFinRel.Active = False
else:
print "Could not FIND CHAR".format(finalCharPath, newFinalChar)
else:
print "Could not ref in: {0}, {1}".format(finalCharPath, newFinalChar)
else:
print "Could not ref in: {0}, {1}".format(charPath, newChar)
else:
print "ERROR: Could not find character for {0}!".format(charNamespace)
bSave = FBApplication().FileSave(outputFile)
'''
scene = FBSystem().Scene
refManager = RS.Core.Reference.Manager.RsReferenceManager()
refManager.collectSceneReferences()
origSceneChars = refManager.characters
lOptions = FBPlotOptions()
lOptions.ConstantKeyReducerKeepOneKey = False
lOptions.UseConstantKeyReducer = False
lOptions.PlotAllTakes = True
lOptions.PlotOnFrame = True
lOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
lOptions.PlotTranslationOnRootOnly = False
lOptions.PreciseTimeDiscontinuities = True
lOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
MBChars = []
for char in origSceneChars:
print char.name
charNamespace = char.namespace
charName = char.name
charModel = FBFindModelByLabelName("{0}:{1}".format(charNamespace,"SKEL_ROOT"))
if charModel:
charCharacter = getCharacterFromModel(charModel)
if charCharacter:
#charCharacter.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnControlRig, lOptions)
charInst = MBCharacterSkeleton()
charInst.name = charName
charInst.nameSpace = charNamespace
charInst.skelRoot = charModel
charInst.GetSkeleton()
MBChars.append(charInst)
print MBChars[1].name
SkeletonToSkeletonTransfer( MBChars[0], MBChars[1])
'''