Использование сценариев Python для установки нуля временного кода анимации в motionbuilder
Все.
У меня есть файл анимации, время начала которого не равно нулю. Я пытаюсь создать сценарий, который установит нулевой временной код анимации. Например, на картинке показано, что тайм-код не отсчитывается от нуля. Большое спасибо за вашу помощь。введите описание изображения здесь
1 ответ
Я немного опоздал, но, наверное, все же интересно поделиться!
Вы можете легко установить временной интервал текущего дубля, используя экземпляр FBTimeSpan(), подобный этому, указав начальный и конечный кадры как объекты FBTime():
lStartFrame = 0
lEndFrame = 100
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
Но я думаю, что то, что вы ищете, - это способ компенсировать анимацию и заставить ее начинаться с 0, не так ли?
Вот две функции из моей собственной библиотеки, использующие режим истории для смещения текущей анимации в заданном кадре. Первый работает с текущим или всеми персонажами вашей сцены (дорожка анимации персонажей). Второй по выбранным компонентам (общая анимационная дорожка). Для каждого из них вы можете передать в качестве аргумента кадр, с которого он должен начинаться, и если вы хотите создать новый временной интервал в конце (замените старые первый / последний кадры новыми).
from pyfbsdk import *
def offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True):
''' Offset current/all(default) characters animation to a given frame, 0 by default '''
# get list of current/all characters
if all_chars:
char_list = FBSystem().Scene.Characters
else:
char_list = [FBApplication().CurrentCharacter]
# get initial timespan
lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()
# turn on Story mode
FBStory().Mute = False
# process character list
for char in char_list:
# set timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# set current character
FBApplication().CurrentCharacter = char
# insert character animation track
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackCharacter, FBStory().RootFolder)
track.Name = '{}_charAnimTrack'.format(FBApplication().CurrentCharacter.Name)
track.Details.append(FBApplication().CurrentCharacter)
# insert take in story mode
take = FBSystem().CurrentTake
inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
# move inserted clip to given frame
inserted_clip.Start = FBTime(0,0,0,frame)
# frame new timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
# defining plot options and plot to current take
PlotOptions = FBPlotOptions()
PlotOptions.ConstantKeyReducerKeepOneKey = True
PlotOptions.PlotAllTakes = False
PlotOptions.PlotOnFrame = True
PlotOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
PlotOptions.PlotTranslationOnRootOnly = True
PlotOptions.PreciseTimeDiscontinuities = True
PlotOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
PlotOptions.UseConstantKeyReducer = True
char.PlotAnimation(FBCharacterPlotWhere.kFBCharacterPlotOnSkeleton, PlotOptions)
# empty Story mode
for track in FBStory().RootFolder.Tracks:
for clip in track.Clips:
clip.FBDelete()
track.FBDelete()
# set back original timespan if specified
if not frame_anim:
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# turn off Story mode
FBStory().Mute = True
def offset_generic_animation_at_frame(frame = 0, frame_anim = True):
''' Offset selected components animation to a given frame, 0 by default '''
# get selected components
lModelList = FBModelList()
FBGetSelectedModels(lModelList)
if not lModelList:
raise ValueError("Select at least one component")
# get initial timespan
lStartFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStart().GetFrame()
lEndFrame = FBSystem().CurrentTake.LocalTimeSpan.GetStop().GetFrame()
# turn on Story mode
FBStory().Mute = False
# set timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# insert generic animation track and add selected components to it
track = FBStoryTrack(FBStoryTrackType.kFBStoryTrackAnimation, FBStory().RootFolder)
track.Name = 'genericAnimTrack'
for comp in lModelList:
track.Details.append(comp)
# insert take in story mode
take = FBSystem().CurrentTake
inserted_clip = track.CopyTakeIntoTrack(take.LocalTimeSpan, take)
# move inserted clip to given frame
inserted_clip.Start = FBTime(0,0,0,frame)
# frame new timespan
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, inserted_clip.Start.GetFrame(), 0), FBTime(0, 0, 0, inserted_clip.Stop.GetFrame(), 0))
# plot selected take
lOptions = FBPlotOptions()
lOptions.ConstantKeyReducerKeepOneKey = False
lOptions.PlotAllTakes = False
lOptions.PlotOnFrame = True
lOptions.PlotPeriod = FBTime( 0, 0, 0, 1 )
lOptions.PlotTranslationOnRootOnly = False
lOptions.PreciseTimeDiscontinuities = True
lOptions.RotationFilterToApply = FBRotationFilter.kFBRotationFilterGimbleKiller
lOptions.UseConstantKeyReducer = False
FBSystem().CurrentTake.PlotTakeOnSelected(lOptions)
# empty Story mode
for track in FBStory().RootFolder.Tracks:
for clip in track.Clips:
clip.FBDelete()
track.FBDelete()
# set back original timespan if specified
if not frame_anim:
FBSystem().CurrentTake.LocalTimeSpan = FBTimeSpan(FBTime(0, 0, 0, lStartFrame, 0), FBTime(0, 0, 0, lEndFrame, 0))
# turn off Story mode
FBStory().Mute = True
# MAIN
offset_generic_animation_at_frame(frame = 0, frame_anim = False)
offset_character_animation_at_frame(frame = 0, all_chars = True, frame_anim=True)