diff --git a/characters/insurrectionist/p4-rigging.blend b/characters/insurrectionist/p4-rigging.blend index 52eb6f8..0d8a0cf 100644 Binary files a/characters/insurrectionist/p4-rigging.blend and b/characters/insurrectionist/p4-rigging.blend differ diff --git a/characters/insurrectionist/post_rig.py b/characters/insurrectionist/post_rig.py index e2e2436..ddecd8a 100644 --- a/characters/insurrectionist/post_rig.py +++ b/characters/insurrectionist/post_rig.py @@ -1,5 +1,5 @@ import bpy -from bpy.types import Constraint +from bpy.types import Constraint, PoseBone rig = bpy.data.objects["insurrectionist"] @@ -44,7 +44,10 @@ bpy.ops.object.mode_set(mode='POSE') ## Declare Functions for animation constraints -def drv_blend_1D(shape_target: str, key_target: str, bone_name: str, max_x: float, prop: str = 'LOC_Z', formula: str = ''): +def arrcopy(copyTo, copyFrom): + for i in range(min(len(copyTo), len(copyFrom))): + copyTo[i] = copyFrom[i] +def drv_blend_1D(shape_target: str, key_target: str, bone_name: str, max_x: float, prop: str = 'LOC_Y', formula: str = ''): block = bpy.data.shape_keys[shape_target].key_blocks[key_target] bmin = block.slider_min bmax = block.slider_max @@ -67,7 +70,57 @@ def drv_blend_1D(shape_target: str, key_target: str, bone_name: str, max_x: floa t.bone_target = bone_name t.transform_type = prop t.transform_space = 'LOCAL_SPACE' +def drv_constraint_1D(c: Constraint, bone_name: str, max_x: float, prop: str = 'LOC_Y', formula: str = ''): + bmin = 0.0 + bmax = 1.0 + + c.driver_remove('influence') + fcurve = c.driver_add('influence') + d = fcurve.driver + d.type = 'SCRIPTED' + + if formula == '': + d.expression = str(bmax / max_x) + '*x' + else: + d.expression = formula + + v = d.variables.new() + v.name = 'x' + v.type = 'TRANSFORMS' + t = v.targets[0] + t.id = rig + t.bone_target = bone_name + t.transform_type = prop + t.transform_space = 'LOCAL_SPACE' +def constrain_slider(b: PoseBone, minimum: float = 0, maximum: float = 0.06): + c = b.constraints.new('LIMIT_LOCATION') + c.use_min_y = True + c.use_max_y = True + c.min_y = minimum + c.max_y = maximum + c.use_transform_limit = True + c.owner_space = 'LOCAL' +# Fix widget scalings +for b in rig.pose.bones: + if b.name.startswith("menu_"): + b.use_custom_shape_bone_size = False + b.custom_shape_translation = (0.0, 0.03, 0.0) + b.custom_shape_scale_xyz = (0.06, 0.06, 0.0) + arrcopy(b.lock_scale, [False, True, False]) + elif b.name.startswith("slider1d"): + b.use_custom_shape_bone_size = False + b.custom_shape_scale_xyz = (0.02, 0.003, 0.005) + + arrcopy(b.lock_location, [True, False, True]) + arrcopy(b.lock_rotation, [True, True, True]) + arrcopy(b.lock_scale, [True, True, True]) + b.lock_rotation_w = True + +# Constrain menu sliders so they are limited to proper bounds +constrain_slider(rig.pose.bones.get('slider1d_axe_gripadjust')) +constrain_slider(rig.pose.bones.get('slider1d_axe_thrust')) +constrain_slider(rig.pose.bones.get('slider1d_axe_smear'), -0.03, 0.03) # Arm and Hand switch for Axe Base # https://blender.stackexchange.com/questions/46928/set-bone-constraints-via-python-api#46986 @@ -80,3 +133,6 @@ if axe_base is not None: axe_constraint.target_space = 'POSE' axe_constraint.owner_space = 'POSE' axe_constraint.influence = 0.0 + +## Set up driver constraint for the switch +drv_constraint_1D(axe_constraint, 'slider1d_axe_gripadjust', 0.06)