113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
|
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')
|