remove path constraint and some fix
1.3.1 - added: button to remove follow path constraintmaster
parent
b982c1a6f0
commit
cd23f50c55
|
@ -1,5 +1,10 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
1.3.1
|
||||||
|
|
||||||
|
- added: button to remove follow path constraint
|
||||||
|
|
||||||
|
|
||||||
1.3.0
|
1.3.0
|
||||||
|
|
||||||
- changed: rename addon: `unfold anim cycle` >> `auto walk`
|
- changed: rename addon: `unfold anim cycle` >> `auto walk`
|
||||||
|
|
|
@ -187,7 +187,8 @@ def anim_path_from_translate():
|
||||||
act = fn.get_obj_action(ob)
|
act = fn.get_obj_action(ob)
|
||||||
if not act:
|
if not act:
|
||||||
return ('ERROR', f'No action active on {ob.name}')
|
return ('ERROR', f'No action active on {ob.name}')
|
||||||
|
|
||||||
|
base_act = None
|
||||||
# use original action as ref
|
# use original action as ref
|
||||||
if '_baked' in act.name:
|
if '_baked' in act.name:
|
||||||
base_act_name = act.name.split('_baked')[0]
|
base_act_name = act.name.split('_baked')[0]
|
||||||
|
@ -362,6 +363,28 @@ def anim_path_from_translate():
|
||||||
# for k in t_fcu.keyframe_points:
|
# for k in t_fcu.keyframe_points:
|
||||||
# k.interpolation = 'CONSTANT'
|
# 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')
|
if debug: print('end of set_follow_path_anim')
|
||||||
|
|
||||||
class AW_OT_animate_path(bpy.types.Operator):
|
class AW_OT_animate_path(bpy.types.Operator):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
import numpy as np
|
||||||
from mathutils import Vector, Quaternion
|
from mathutils import Vector, Quaternion
|
||||||
from math import sin, cos, radians
|
from math import sin, cos, radians
|
||||||
import numpy as np
|
|
||||||
from . import fn
|
from . import fn
|
||||||
|
|
||||||
## all action needed to setup the walk
|
## all action needed to setup the walk
|
||||||
|
|
|
@ -61,6 +61,9 @@ class AW_OT_create_a_b_step(bpy.types.Operator):
|
||||||
a = markers[0].location
|
a = markers[0].location
|
||||||
b = markers[1].location - a # remove a postion to get position in curve object space
|
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
|
# Set the curve and constraint
|
||||||
curve = fn.generate_curve(location=a, direction=b, name='curve_path', context=context)
|
curve = fn.generate_curve(location=a, direction=b, name='curve_path', context=context)
|
||||||
settings = context.scene.anim_cycle_settings
|
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)
|
# 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)
|
remove_spacetime_keys(context=None)
|
||||||
|
|
||||||
# if speed calculation is done later need to know start and end frame...
|
# 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"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
class AW_OT_remove_a_b_step(bpy.types.Operator):
|
class AW_OT_remove_a_b_step(bpy.types.Operator):
|
||||||
|
|
|
@ -63,6 +63,38 @@ class AW_OT_create_follow_path(bpy.types.Operator):
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
return {"FINISHED"}
|
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):
|
class AW_OT_snap_curve_to_ground(bpy.types.Operator):
|
||||||
bl_idname = "autowalk.snap_curve_to_ground"
|
bl_idname = "autowalk.snap_curve_to_ground"
|
||||||
bl_label = "Snap Curve"
|
bl_label = "Snap Curve"
|
||||||
|
@ -195,6 +227,7 @@ class AW_OT_object_from_curve(bpy.types.Operator):
|
||||||
classes=(
|
classes=(
|
||||||
AW_OT_create_curve_path,
|
AW_OT_create_curve_path,
|
||||||
AW_OT_create_follow_path,
|
AW_OT_create_follow_path,
|
||||||
|
AW_OT_remove_follow_path,
|
||||||
AW_OT_snap_curve_to_ground,
|
AW_OT_snap_curve_to_ground,
|
||||||
AW_OT_edit_curve,
|
AW_OT_edit_curve,
|
||||||
AW_OT_go_to_object,
|
AW_OT_go_to_object,
|
||||||
|
|
|
@ -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, 0),
|
"version": (1, 3, 1),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
|
@ -78,7 +78,9 @@ class AW_PT_walk_cycle_anim_panel(bpy.types.Panel):
|
||||||
if pb:
|
if pb:
|
||||||
follow = pb.constraints.get('Follow Path')
|
follow = pb.constraints.get('Follow Path')
|
||||||
if follow and follow.target:
|
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
|
constrained = True
|
||||||
## Put this in a setting popup or submenu
|
## Put this in a setting popup or submenu
|
||||||
# if context.mode == 'POSE':
|
# if context.mode == 'POSE':
|
||||||
|
@ -89,8 +91,9 @@ class AW_PT_walk_cycle_anim_panel(bpy.types.Panel):
|
||||||
box = layout.box()
|
box = layout.box()
|
||||||
col=box.column()
|
col=box.column()
|
||||||
col.label(text='Motion:')
|
col.label(text='Motion:')
|
||||||
col.prop(settings, "start_frame", text='Start')
|
row = col.row(align=True)
|
||||||
# col.prop(settings, "foot_axis", text='Foot Axis')
|
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')
|
col.operator('autowalk.animate_path', text='Animate Forward Motion', icon='ANIM')
|
||||||
|
|
||||||
row=col.row()
|
row=col.row()
|
||||||
|
|
|
@ -38,6 +38,11 @@ class AW_PG_settings(bpy.types.PropertyGroup) :
|
||||||
default=101,
|
default=101,
|
||||||
min=0, max=2**31-1, soft_min=0, soft_max=2**31-1, step=1, options={'HIDDEN'})#, subtype='PIXEL'
|
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(
|
forward_axis : bpy.props.EnumProperty(
|
||||||
name='Forward Axis',
|
name='Forward Axis',
|
||||||
default='FORWARD_Z', # Modifier default is FORWARD_X (should be TRACK_NEGATIVE_Y for a good rig)
|
default='FORWARD_Z', # Modifier default is FORWARD_X (should be TRACK_NEGATIVE_Y for a good rig)
|
||||||
|
|
Loading…
Reference in New Issue