Tag: animation
exporting mirrored animations from Motionbuilder
by eks on Mar.06, 2011, under MotionBuilder, pipeline
It’s quite easy. Basically you need to:
- plot to the skeleton;
- save one animation;
- turn on Mirror Animation for the character;
- plot back to the control rig, which then mirrors the animation;
- rotate the Character Reference model 180 degrees;
- plot back to the skeleton;
- save mirrored animation.
The tricky part is just number 5 where you need to do some matrix rotation. Python for this would be something like:
from pyfbsdk import * app = FBApplication() char = app.CurrentCharacter savePath = r"C:\" filename = app.FBXFileName skeleton = FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton ctrlrig = FBCharacterPlotWhere.kFBCharacterPlotOnControlRig # plot to skeleton, see bellow plotAnim(char, skeleton) # save left animation sOptions = FBFbxOptions(False) # false = save options sOptions.SaveCharacter = True sOptions.SaveControlSet = False sOptions.SaveCharacterExtension = False sOptions.ShowFileDialog = False sOptions.ShowOptionsDialog = False app.SaveCharacterRigAndAnimation(savePath + "\\" + filename + "_L", char, sOptions) # activate mirror and plot char.MirrorMode = True plotAnim(char, ctrlrig) # get reference model refModel = FBFindModelByName("Character_Ctrl:Reference") # rotating 180, the tricky part # http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q28 rotateY180 = FBMatrix() rotateY180[0] = math.cos((180*0.017453292519943295769236907684886)) rotateY180[2] = math.sin((180*0.017453292519943295769236907684886)) rotateY180[8] = -math.sin((180*0.017453292519943295769236907684886)) rotateY180[10] = math.cos((180*0.017453292519943295769236907684886)) refMT = FBMatrix() refModel.GetMatrix(refMT) refModel.SetMatrix( MatrixMult(rotateY180, refMT) ) scene.Evaluate() # plot back to skeleton plotAnim(char, skeleton) # save again app.SaveCharacterRigAndAnimation(savePath + "\\" + filename + "_R", char, sOptions)
The plot and multiplication functions are:
# This is from Neil3d: http://neill3d.com/mobi-skript-raschet-additivnoj-animacii?langswitch_lang=en def MatrixMult(Ma, Mb): res = FBMatrix() for i in range(0,4): for j in range(0,4): sum=0 for k in range(0,4): sum += Ma[i*4+k] * Mb[k*4+j] res[i*4+j] = sum return res def plotAnim(char, where): if char.GetCharacterize: switchOn = char.SetCharacterizeOn(True) plotoBla = FBPlotOptions() plotoBla.ConstantKeyReducerKeepOneKey = True plotoBla.PlotAllTakes = True plotoBla.PlotOnFrame = True plotoBla.PlotPeriod = FBTime( 0, 0, 0, 1 ) #plotoBla.PlotTranslationOnRootOnly = True plotoBla.PreciseTimeDiscontinuities = True #plotoBla.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller plotoBla.UseConstantKeyReducer = False plotoBla.ConstantKeyReducerKeepOneKey = True if (not char.PlotAnimation(where, plotoBla)): FBMessageBox( "Something went wrong", "Plot animation returned false, cannot continue", "OK", None, None ) return False return char
If you are exporting the character to a game, pay attention to the root node rotation. If you used it in the characterization, chances are it might also be rotated, and you might not want that to happen. You can also establish a convention on the name of the files, and easily detect if the animation currently open ends with _L or _R, and adapt the filename correctly.
FBApplication().SaveCharacterRigAndAnimation() is the equivalent of the Save Character Animation on the Character Controls window, which saves only the animation, without mesh. I prefer to use this when exporting only the animation from Motionbuilder to some other software, since it’s cleaner, faster and file sizes are smaller, but you could use any other function also.