Rigify: support uniform scaling of limbs via the master control.
Existing IK & FK controls only allowed squash and stretch scaling.
This commit is contained in:
parent
7f4c2d5e48
commit
2f1c38fd50
|
@ -181,31 +181,35 @@ class BaseLimbRig(BaseRig):
|
|||
@stage.generate_bones
|
||||
def make_master_control(self):
|
||||
org = self.bones.org.main[0]
|
||||
self.bones.mch.master = name = self.copy_bone(org, make_derived_name(org, 'mch', '_parent_socket'), scale=1/12)
|
||||
self.bones.mch.master = name = self.copy_bone(org, make_derived_name(org, 'mch', '_parent_widget'), scale=1/12)
|
||||
self.bones.ctrl.master = name = self.copy_bone(org, make_derived_name(org, 'ctrl', '_parent'), scale=1/4)
|
||||
self.get_bone(name).roll = 0
|
||||
self.prop_bone = self.bones.ctrl.master
|
||||
|
||||
@stage.parent_bones
|
||||
def parent_master_control(self):
|
||||
self.set_bone_parent(self.bones.ctrl.master, self.bones.mch.master)
|
||||
self.set_bone_parent(self.bones.mch.master, self.bones.mch.follow)
|
||||
self.set_bone_parent(self.bones.ctrl.master, self.rig_parent_bone, inherit_scale='NONE')
|
||||
self.set_bone_parent(self.bones.mch.master, self.bones.org.main[0], inherit_scale='NONE')
|
||||
|
||||
@stage.configure_bones
|
||||
def configure_master_control(self):
|
||||
bone = self.get_bone(self.bones.ctrl.master)
|
||||
bone.lock_location = (True, True, True)
|
||||
bone.lock_rotation = (True, True, True)
|
||||
bone.lock_scale = (True, True, True)
|
||||
bone.lock_scale = (False, False, False)
|
||||
bone.lock_rotation_w = True
|
||||
|
||||
@stage.rig_bones
|
||||
def rig_master_control(self):
|
||||
self.make_constraint(self.bones.mch.master, 'COPY_ROTATION', self.bones.org.main[0])
|
||||
mch = self.bones.mch
|
||||
self.make_constraint(mch.master, 'COPY_SCALE', 'root', use_make_uniform=True)
|
||||
self.make_constraint(mch.master, 'COPY_SCALE', self.bones.ctrl.master, use_offset=True, space='LOCAL')
|
||||
|
||||
@stage.generate_widgets
|
||||
def make_master_control_widget(self):
|
||||
create_gear_widget(self.obj, self.bones.ctrl.master, radius=1)
|
||||
master = self.bones.ctrl.master
|
||||
set_bone_widget_transform(self.obj, master, self.bones.mch.master)
|
||||
create_gear_widget(self.obj, master, radius=1)
|
||||
|
||||
|
||||
####################################################
|
||||
|
@ -235,6 +239,10 @@ class BaseLimbRig(BaseRig):
|
|||
mch = self.bones.mch.follow
|
||||
|
||||
self.make_constraint(mch, 'COPY_SCALE', 'root', use_make_uniform=True)
|
||||
self.make_constraint(
|
||||
mch, 'COPY_SCALE', self.bones.ctrl.master,
|
||||
use_make_uniform=True, use_offset=True, space='LOCAL'
|
||||
)
|
||||
|
||||
con = self.make_constraint(mch, 'COPY_ROTATION', 'root')
|
||||
|
||||
|
@ -325,7 +333,9 @@ class BaseLimbRig(BaseRig):
|
|||
|
||||
def rig_fk_parent_bone(self, i, parent_mch, org):
|
||||
if i >= 2:
|
||||
self.make_constraint(parent_mch, 'COPY_SCALE', 'root', use_make_uniform=True)
|
||||
self.make_constraint(
|
||||
parent_mch, 'COPY_SCALE', self.bones.mch.follow, use_make_uniform=True
|
||||
)
|
||||
|
||||
|
||||
####################################################
|
||||
|
@ -435,6 +445,13 @@ class BaseLimbRig(BaseRig):
|
|||
@stage.rig_bones
|
||||
def rig_ik_controls(self):
|
||||
self.rig_hide_pole_control(self.bones.ctrl.ik_pole)
|
||||
self.rig_ik_control_scale(self.bones.ctrl.ik)
|
||||
|
||||
def rig_ik_control_scale(self, ctrl):
|
||||
self.make_constraint(
|
||||
ctrl, 'COPY_SCALE', self.bones.ctrl.master,
|
||||
use_make_uniform=True, use_offset=True, space='LOCAL',
|
||||
)
|
||||
|
||||
@stage.generate_widgets
|
||||
def make_ik_control_widgets(self):
|
||||
|
@ -801,7 +818,7 @@ class BaseLimbRig(BaseRig):
|
|||
self.make_constraint(tweak, 'DAMPED_TRACK', next_tweak)
|
||||
|
||||
elif entry.seg_idx is not None:
|
||||
self.make_constraint(tweak, 'COPY_SCALE', 'root', use_make_uniform=True)
|
||||
self.make_constraint(tweak, 'COPY_SCALE', self.bones.mch.follow, use_make_uniform=True)
|
||||
|
||||
if i == 0:
|
||||
self.make_constraint(tweak, 'COPY_LOCATION', entry.org)
|
||||
|
@ -1007,7 +1024,8 @@ class RigifyLimbIk2FkBase:
|
|||
endmat = convert_pose_matrix_via_rest_delta(matrices[-1], ik_bones[-1], ctrl_bones[-1])
|
||||
|
||||
set_transform_from_matrix(
|
||||
obj, self.ctrl_bone_list[-1], endmat, keyflags=self.keyflags
|
||||
obj, self.ctrl_bone_list[-1], endmat, keyflags=self.keyflags,
|
||||
undo_copy_scale=True,
|
||||
)
|
||||
|
||||
# Remove foot heel transform, if present
|
||||
|
|
|
@ -182,18 +182,33 @@ def undo_copy_scale_with_offset(obj, bone, con, old_matrix):
|
|||
"Undo the effects of Copy Scale with Offset constraint on a bone matrix."
|
||||
inf = con.influence
|
||||
|
||||
if con.mute or inf == 0 or not con.is_valid or not con.use_offset or con.use_add or con.use_make_uniform:
|
||||
if con.mute or inf == 0 or not con.is_valid or not con.use_offset or con.use_add:
|
||||
return old_matrix
|
||||
|
||||
tgt_matrix = get_constraint_target_matrix(con)
|
||||
tgt_scale = tgt_matrix.to_scale()
|
||||
use = [con.use_x, con.use_y, con.use_z]
|
||||
|
||||
if con.use_make_uniform:
|
||||
if con.use_x and con.use_y and con.use_z:
|
||||
total = tgt_matrix.determinant()
|
||||
else:
|
||||
total = 1
|
||||
for i, use in enumerate(use):
|
||||
if use:
|
||||
total *= tgt_scale[i]
|
||||
|
||||
tgt_scale = [abs(total)**(1./3.)]*3
|
||||
else:
|
||||
for i, use in enumerate(use):
|
||||
if not use:
|
||||
tgt_scale[i] = 1
|
||||
|
||||
scale_delta = [
|
||||
1 / (1 + (math.pow(x, con.power) - 1) * inf)
|
||||
for x in get_constraint_target_matrix(con).to_scale()
|
||||
for x in tgt_scale
|
||||
]
|
||||
|
||||
for i, use in enumerate([con.use_x, con.use_y, con.use_z]):
|
||||
if not use:
|
||||
scale_delta[i] = 1
|
||||
|
||||
return old_matrix @ Matrix.Diagonal([*scale_delta, 1])
|
||||
|
||||
def undo_copy_scale_constraints(obj, bone, matrix):
|
||||
|
|
Loading…
Reference in New Issue