auto_walk/animate_path.py

113 lines
3.6 KiB
Python
Raw Normal View History

2021-04-05 01:35:12 +02:00
import bpy
from . import fn
def anim_path_from_y_translate():
print(fn.helper())
obj = bpy.context.object
if obj.type != 'ARMATURE':
return ('ERROR', 'active is not an armature type')
# found curve through constraint
b = bpy.context.active_pose_bone
if not 'shoe' in b.bone.name:
return ('ERROR', 'no "shoe" in active bone name')
curve = None
if bpy.context.scene.anim_cycle_settings.path_to_follow:
curve = bpy.context.scene.anim_cycle_settings.path_to_follow
# if curve is not defined try to track it from constraints on armature
if not curve:
curve, _const = fn.get_follow_curve_from_armature(obj)
if isinstance(curve, str):
return curve, _const
act = fn.get_obj_action(obj)
if not act:
return ('ERROR', f'No action active on {obj.name}')
# CHANGE - retiré le int de la frame
# keyframes = [int(k.co[0]) for fcu in act.fcurves for k in fcu.keyframe_points]
## calculate offset from bones
locy_fcu = None
for fcu in act.fcurves:
if fcu.data_path.split('"')[1] != b.bone.name:
continue
if fcu.data_path.split('.')[-1] == 'location' and fcu.array_index == 1:
locy_fcu = fcu
if not locy_fcu:
return ('ERROR', 'Current bone, location.y animation not found')
start = None
end = None
## based on extreme
for k in locy_fcu.keyframe_points:
# if k.select_control_point: # based on selection
if k.type == 'EXTREME': # using extreme keys.
if not start:
start = k
end = k
else:
if start is not None:
## means back to other frame type after passed breaskdown we stop
break
if not start:
return ('ERROR', f"No extreme marked frame was found on bone {b.bone.name}.{['x','y','z'][locy_fcu.array_index]}")
if start == end:
return ('ERROR', 'Seems like only one key was marked as extreme ! Need at least two chained')
start_frame = start.co.x
start_val = start.co.y
end_frame = end.co.x
end_val = end.co.y
move_frame = end_frame - start_frame
# Y positive value (forward) ->
move_val = abs(start_val - end_val)
print('move_val: ', move_val)
length = fn.get_curve_length(curve)
steps = length / move_val
frame_duration = steps * move_frame
### Clear keyframe before creating new ones
# curve.data.animation_data_clear() # too much.. delete only eval_time
if curve.data.animation_data and curve.data.animation_data.action:
for fcu in curve.data.animation_data.action.fcurves:
if fcu.data_path == 'eval_time':
curve.data.animation_data.action.fcurves.remove(fcu)
break
# TODO check if need to start at 100 or at current frame...
anim_frame = 100 # C.scene.frame_current
curve.data.path_duration = frame_duration
curve.data.eval_time = 0
curve.data.keyframe_insert('eval_time', frame=anim_frame)# , options={'INSERTKEY_AVAILABLE'}
curve.data.eval_time = frame_duration
curve.data.keyframe_insert('eval_time', frame=anim_frame + frame_duration)
## all to linear (will be set to CONSTANT at the moment of sampling)
for fcu in curve.data.animation_data.action.fcurves:
if fcu.data_path == 'eval_time':
for k in fcu.keyframe_points:
k.interpolation = 'LINEAR'
## set all to constant
# for k in t_fcu.keyframe_points:
# k.interpolation = 'CONSTANT'
print('end of set_follow_path_anim')