大家
我有一些动画文件,其开始时间不为零。我正在尝试创建一个脚本,将动画时间码设置为零。例如,图中显示的时间码不是从零开始的。非常感谢您的帮助。 在此输入图片描述
我有点晚了,但分享这可能仍然很有趣!
您可以使用像这样的 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)
我知道已经很晚了。不过对于以后来这里的人来说,如果还担心这个问题的话,可以直接抵消Take。下面是一个例子,重点关注函数OffsetAnimation
from pyfbsdk import *
localTake = FBSystem().CurrentTake
start_frame = localTake.LocalTimeSpan.GetStart().GetFrame()
end_frame = localTake.LocalTimeSpan.GetStop().GetFrame()
## setup new time span
compensate_frames = FBTime(0,0,0,-start_frame)
p_start = FBTime(0,0,0,0)
p_end = FBTime(0,0,0,end_frame-start_frame+1)
## offset anim and setup playbar
localTake.OffsetAnimation(compensate_frames)
localTake.LocalTimeSpan = FBTimeSpan(p_start, p_end)
FBPlayerControl().GotoStart()