remove path constraint and some fix

1.3.1

- added: button to remove follow path constraint
master
Pullusb 2022-04-20 17:54:49 +02:00
parent b982c1a6f0
commit cd23f50c55
8 changed files with 84 additions and 7 deletions

View File

@ -1,5 +1,10 @@
# Changelog
1.3.1
- added: button to remove follow path constraint
1.3.0
- changed: rename addon: `unfold anim cycle` >> `auto walk`

View File

@ -187,7 +187,8 @@ def anim_path_from_translate():
act = fn.get_obj_action(ob)
if not act:
return ('ERROR', f'No action active on {ob.name}')
base_act = None
# use original action as ref
if '_baked' in act.name:
base_act_name = act.name.split('_baked')[0]
@ -362,6 +363,28 @@ def anim_path_from_translate():
# for k in t_fcu.keyframe_points:
# k.interpolation = 'CONSTANT'
# speed indicator if animator wants to adapt the cycle
## Show a marker to determine cycle range if needed to reach a
''' # Does not work yet
if settings.end_frame > settings.start_frame:
all_keys_list = [k.co.x for fc in act.fcurves if 'foot' in fc.data_path for k in fc.keyframe_points]
base_start = int(min(all_keys_list))
base_end = int(max(all_keys_list))
base_range = base_end - base_start
wanted_duration = settings.end_frame - settings.start_frame # defined in "autowalk > motion" interface
range_needed_to_go_full_curve = base_range * (wanted_duration / frame_duration)
# create marker
mark_name = 'range to fill path'
speed_mark = bpy.context.scene.timeline_markers.get(mark_name)
if not speed_mark:
speed_mark = bpy.context.scene.timeline_markers.new(mark_name)
speed_mark.frame = int(base_start + range_needed_to_go_full_curve)
'''
if debug: print('end of set_follow_path_anim')
class AW_OT_animate_path(bpy.types.Operator):

View File

@ -1,7 +1,7 @@
import bpy
import numpy as np
from mathutils import Vector, Quaternion
from math import sin, cos, radians
import numpy as np
from . import fn
## all action needed to setup the walk

View File

@ -61,6 +61,9 @@ class AW_OT_create_a_b_step(bpy.types.Operator):
a = markers[0].location
b = markers[1].location - a # remove a postion to get position in curve object space
a_frame = int(markers[0].name.split('_')[-1])
b_frame = int(markers[1].name.split('_')[-1])
# Set the curve and constraint
curve = fn.generate_curve(location=a, direction=b, name='curve_path', context=context)
settings = context.scene.anim_cycle_settings
@ -72,9 +75,14 @@ class AW_OT_create_a_b_step(bpy.types.Operator):
# set offset animation ??? (but movement not in sync until action is retimed in NLA)
# remove all markers or keep for later reuse ?
## remove all markers or keep for later reuse ?
remove_spacetime_keys(context=None)
# if speed calculation is done later need to know start and end frame...
# Set frame start and end
settings.start_frame = a_frame
settings.end_frame = b_frame
return {"FINISHED"}
class AW_OT_remove_a_b_step(bpy.types.Operator):

View File

@ -63,6 +63,38 @@ class AW_OT_create_follow_path(bpy.types.Operator):
return {"CANCELLED"}
return {"FINISHED"}
class AW_OT_remove_follow_path(bpy.types.Operator):
bl_idname = "autowalk.remove_follow_path"
bl_label = "Remove Follow Path Constraint"
bl_description = "Remove follow path on target bone"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'ARMATURE'
def execute(self, context):
ob = context.object
# curve = context.scene.anim_cycle_settings.path_to_follow
tgt_bone = fn.get_addon_prefs().tgt_bone
bone = ob.pose.bones.get(tgt_bone)
if not bone:
self.report({'ERROR'}, f'No bone "{tgt_bone}" found')
return {"CANCELLED"}
const = next((c for c in bone.constraints if c.type == 'FOLLOW_PATH'), None)
if not const:
self.report({'ERROR'}, f'No follow path constraint on "{tgt_bone}" found')
return {"CANCELLED"}
bone.constraints.remove(const)
self.report({'INFO'}, f'removed follow_path constraint on bone "{tgt_bone}"')
# Also remove offset action ? myabe give the choice
return {"FINISHED"}
class AW_OT_snap_curve_to_ground(bpy.types.Operator):
bl_idname = "autowalk.snap_curve_to_ground"
bl_label = "Snap Curve"
@ -195,6 +227,7 @@ class AW_OT_object_from_curve(bpy.types.Operator):
classes=(
AW_OT_create_curve_path,
AW_OT_create_follow_path,
AW_OT_remove_follow_path,
AW_OT_snap_curve_to_ground,
AW_OT_edit_curve,
AW_OT_go_to_object,

View File

@ -4,7 +4,7 @@ bl_info = {
"name": "Auto Walk",
"description": "Develop a walk/run cycles along a curve and pin feets",
"author": "Samuel Bernou",
"version": (1, 3, 0),
"version": (1, 3, 1),
"blender": (3, 0, 0),
"location": "View3D",
"warning": "",

View File

@ -78,7 +78,9 @@ class AW_PT_walk_cycle_anim_panel(bpy.types.Panel):
if pb:
follow = pb.constraints.get('Follow Path')
if follow and follow.target:
box.label(text=f'{pb.name} -> {follow.target.name}', icon='CON_FOLLOWPATH')
row = box.row()
row.label(text=f'{pb.name} -> {follow.target.name}', icon='CON_FOLLOWPATH')
row.operator('autowalk.remove_follow_path', text='', icon='X')
constrained = True
## Put this in a setting popup or submenu
# if context.mode == 'POSE':
@ -89,8 +91,9 @@ class AW_PT_walk_cycle_anim_panel(bpy.types.Panel):
box = layout.box()
col=box.column()
col.label(text='Motion:')
col.prop(settings, "start_frame", text='Start')
# col.prop(settings, "foot_axis", text='Foot Axis')
row = col.row(align=True)
row.prop(settings, "start_frame", text='Start')
row.prop(settings, "end_frame", text='End')
col.operator('autowalk.animate_path', text='Animate Forward Motion', icon='ANIM')
row=col.row()

View File

@ -38,6 +38,11 @@ class AW_PG_settings(bpy.types.PropertyGroup) :
default=101,
min=0, max=2**31-1, soft_min=0, soft_max=2**31-1, step=1, options={'HIDDEN'})#, subtype='PIXEL'
end_frame : bpy.props.IntProperty(
name="End Frame", description="End frame, to calculate when character should reach the end of the path",
default=101,
min=0, max=2**31-1, soft_min=0, soft_max=2**31-1, step=1, options={'HIDDEN'})#, subtype='PIXEL'
forward_axis : bpy.props.EnumProperty(
name='Forward Axis',
default='FORWARD_Z', # Modifier default is FORWARD_X (should be TRACK_NEGATIVE_Y for a good rig)