fix bake keys cycle iteration
1.3.4 - fixed: bake keys with better cycle compatibilitymaster
parent
d4ba199b63
commit
cd17ccf708
|
@ -1,5 +1,9 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
1.3.4
|
||||||
|
|
||||||
|
- fixed: bake keys with better cycle compatibility
|
||||||
|
|
||||||
1.3.3
|
1.3.3
|
||||||
|
|
||||||
- changed: `Set Time Keys` in NLA do not remove keys if exists but offset to match start of strip (if has moved) to resync
|
- changed: `Set Time Keys` in NLA do not remove keys if exists but offset to match start of strip (if has moved) to resync
|
||||||
|
|
|
@ -10,6 +10,8 @@ from time import time
|
||||||
def bake_cycle(on_selection=True, end=None):
|
def bake_cycle(on_selection=True, end=None):
|
||||||
print(fn.helper())
|
print(fn.helper())
|
||||||
end = end or bpy.context.scene.frame_end
|
end = end or bpy.context.scene.frame_end
|
||||||
|
end += 20 # add an hardcoded margin !
|
||||||
|
print('end: ', end)
|
||||||
debug = fn.get_addon_prefs().debug
|
debug = fn.get_addon_prefs().debug
|
||||||
obj = bpy.context.object
|
obj = bpy.context.object
|
||||||
if obj.type != 'ARMATURE':
|
if obj.type != 'ARMATURE':
|
||||||
|
@ -28,6 +30,12 @@ def bake_cycle(on_selection=True, end=None):
|
||||||
ct = 0
|
ct = 0
|
||||||
ct_no_cycle = 0
|
ct_no_cycle = 0
|
||||||
|
|
||||||
|
## TODO calculate offset only once to avoid errors !
|
||||||
|
all_keys = [k.co.x for fc in act.fcurves if not '.offset' in fc.data_path for k in fc.keyframe_points]
|
||||||
|
first = int(min(all_keys))
|
||||||
|
last = int(max(all_keys))
|
||||||
|
offset = last - first
|
||||||
|
|
||||||
for fcu in act.fcurves:
|
for fcu in act.fcurves:
|
||||||
|
|
||||||
## if a curve is not cycled don't touch
|
## if a curve is not cycled don't touch
|
||||||
|
@ -69,13 +77,17 @@ def bake_cycle(on_selection=True, end=None):
|
||||||
k_dic['type'] = k.type
|
k_dic['type'] = k.type
|
||||||
fcu_kfs.append(k_dic)
|
fcu_kfs.append(k_dic)
|
||||||
|
|
||||||
first = fcu_kfs[0]['co'][0]
|
## not used
|
||||||
# second = fcu_kfs[1]['co'][0]
|
# second = fcu_kfs[1]['co'][0]
|
||||||
# before_last= fcu_kfs[-2]['co'][0]
|
# before_last= fcu_kfs[-2]['co'][0]
|
||||||
last = fcu_kfs[-1]['co'][0]
|
|
||||||
# first_offset = second - first
|
# first_offset = second - first
|
||||||
|
|
||||||
current_offset = offset = last - first
|
## old
|
||||||
|
# first = fcu_kfs[0]['co'][0]
|
||||||
|
# last = fcu_kfs[-1]['co'][0]
|
||||||
|
# current_offset = offset = last - first
|
||||||
|
|
||||||
|
current_offset = offset
|
||||||
|
|
||||||
keys_num = len(fcu_kfs)
|
keys_num = len(fcu_kfs)
|
||||||
if debug >= 2: print(keys_num)
|
if debug >= 2: print(keys_num)
|
||||||
|
@ -84,8 +96,12 @@ def bake_cycle(on_selection=True, end=None):
|
||||||
if debug >= 2: print(b_name, f'{keys_num} key')
|
if debug >= 2: print(b_name, f'{keys_num} key')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
## ! important: delete last after computing offset IF cycle have first frame repeatead as last !
|
## delete last after computing offset IF cycle have first frame repeatead as last !
|
||||||
fcu_kfs.pop()
|
|
||||||
|
# fcu_kfs_without_last = fcu_kfs.copy()
|
||||||
|
# fcu_kfs_without_last.pop()
|
||||||
|
|
||||||
|
# last_kf = fcu_kfs.pop() (or just iterate with slicing [:-1])
|
||||||
# print('offset: ', offset)
|
# print('offset: ', offset)
|
||||||
|
|
||||||
if debug >= 2: print('keys', len(fcu_kfs))
|
if debug >= 2: print('keys', len(fcu_kfs))
|
||||||
|
@ -93,11 +109,21 @@ def bake_cycle(on_selection=True, end=None):
|
||||||
|
|
||||||
# maybe add possibility define target manually ?
|
# maybe add possibility define target manually ?
|
||||||
|
|
||||||
end += 20 # add an hardcoded margin !
|
iterations = int( ((end - last) // offset) + 1 )
|
||||||
iterations = ((end - last) // offset) + 1
|
|
||||||
if debug >= 2: print('iterations: ', iterations)
|
if debug >= 2: print('iterations: ', iterations)
|
||||||
for _i in range(int(iterations)):
|
|
||||||
for kf in fcu_kfs:
|
for i in range(iterations):
|
||||||
|
# if i == iterations - 1: # last
|
||||||
|
# kfs = fcu_kfs
|
||||||
|
# else:
|
||||||
|
# kfs = fcu_kfs_without_last
|
||||||
|
# for kf in kfs:
|
||||||
|
|
||||||
|
for count, kf in enumerate(fcu_kfs):
|
||||||
|
if count == keys_num and i < iterations - 1:
|
||||||
|
# last key of fcurves, to use only if on last iteration
|
||||||
|
continue
|
||||||
|
|
||||||
# create a new key, adding offset to keys
|
# create a new key, adding offset to keys
|
||||||
fcu.keyframe_points.add(1)
|
fcu.keyframe_points.add(1)
|
||||||
new = fcu.keyframe_points[-1]
|
new = fcu.keyframe_points[-1]
|
||||||
|
@ -107,6 +133,9 @@ def bake_cycle(on_selection=True, end=None):
|
||||||
else:
|
else:
|
||||||
setattr(new, att, val)
|
setattr(new, att, val)
|
||||||
current_offset += offset
|
current_offset += offset
|
||||||
|
|
||||||
|
# FIXME on last cycle - re-add last keyframe to "close" the cycle
|
||||||
|
|
||||||
|
|
||||||
ct += 1
|
ct += 1
|
||||||
|
|
||||||
|
@ -268,7 +297,7 @@ class AW_OT_bake_cycle_and_step(bpy.types.Operator):
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
|
||||||
err = bake_cycle(context.scene.anim_cycle_settings.expand_on_selected_bones, end=self.endframe)
|
err = bake_cycle(context.scene.anim_cycle_settings.expand_on_selected_bones, end=self.end_frame)
|
||||||
if err:
|
if err:
|
||||||
self.report({err[0]}, err[1])
|
self.report({err[0]}, err[1])
|
||||||
if err[0] == 'ERROR':
|
if err[0] == 'ERROR':
|
||||||
|
|
|
@ -4,7 +4,7 @@ bl_info = {
|
||||||
"name": "Auto Walk",
|
"name": "Auto Walk",
|
||||||
"description": "Develop a walk/run cycles along a curve and pin feets",
|
"description": "Develop a walk/run cycles along a curve and pin feets",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (1, 3, 2),
|
"version": (1, 3, 4),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
Loading…
Reference in New Issue