Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemeter Dzadik <Mets>2020-11-07 17:32:29 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2020-11-24 17:23:54 +0300
commit46590bb7800eea5aa1826f6e9305d7e0320829be (patch)
tree23e19892343abcc9ab1ffcf5f1b5a4e072c997bd /rigify/rig_ui_template.py
parent3bbcfa7c2d5ca564804c30f0b19c219e00dc4892 (diff)
Rigify: Fix T78463: better support unguligrade animals (horse) setup.
Add support for 5 bone chains to the limbs.paw rig. Implement a new limbs.rear_paw rig, which provides a three bone IK mechanism designed to keep the first and third bones nearly parallel by default (based on a YouTube video by @Pieriko as suggested by @icappiello). Implement a limbs.front_paw rig with automation that aims to keep the angle between second and third bones mostly stable by default (has influence option), as suitable for front paws. The horse and wolf metarigs are updated to use these new rig types, with the horse rig further overhauled by @icappiello. Maniphest Tasks: T78463 Differential Revision: https://developer.blender.org/D8496
Diffstat (limited to 'rigify/rig_ui_template.py')
-rw-r--r--rigify/rig_ui_template.py39
1 files changed, 23 insertions, 16 deletions
diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py
index 642b5110..c83dd02b 100644
--- a/rigify/rig_ui_template.py
+++ b/rigify/rig_ui_template.py
@@ -125,6 +125,11 @@ def get_pose_matrix_in_other_space(mat, pose_bone):
return pose_bone.id_data.convert_space(matrix=mat, pose_bone=pose_bone, from_space='POSE', to_space='LOCAL')
+def convert_pose_matrix_via_rest_delta(mat, from_bone, to_bone):
+ """Convert pose of one bone to another bone, preserving the rest pose difference between them."""
+ return mat @ from_bone.bone.matrix_local.inverted() @ to_bone.bone.matrix_local
+
+
def get_local_pose_matrix(pose_bone):
""" Returns the local transform matrix of the given pose bone.
"""
@@ -193,39 +198,41 @@ def match_pose_scale(pose_bone, target_bone):
## IK/FK snapping functions ##
##############################
-def correct_rotation(view_layer, bone_ik, target_matrix):
+def correct_rotation(view_layer, bone_ik, target_matrix, *, ctrl_ik=None):
""" Corrects the ik rotation in ik2fk snapping functions
"""
axis = target_matrix.to_3x3().col[1].normalized()
+ ctrl_ik = ctrl_ik or bone_ik
def distance(angle):
# Rotate the bone and return the actual angle between bones
- bone_ik.rotation_euler[1] = angle
+ ctrl_ik.rotation_euler[1] = angle
view_layer.update()
return -(bone_ik.vector.normalized().dot(axis))
- if bone_ik.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
- bone_ik.rotation_mode = 'ZXY'
+ if ctrl_ik.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
+ ctrl_ik.rotation_mode = 'ZXY'
- start_angle = bone_ik.rotation_euler[1]
+ start_angle = ctrl_ik.rotation_euler[1]
alfarange = find_min_range(distance, start_angle)
alfamin = ternarySearch(distance, alfarange[0], alfarange[1], pi / 180)
- bone_ik.rotation_euler[1] = alfamin
+ ctrl_ik.rotation_euler[1] = alfamin
view_layer.update()
-def correct_scale(view_layer, bone_ik, target_matrix):
+def correct_scale(view_layer, bone_ik, target_matrix, *, ctrl_ik=None):
""" Correct the scale of the base IK bone. """
input_scale = target_matrix.to_scale()
+ ctrl_ik = ctrl_ik or bone_ik
for i in range(3):
cur_scale = bone_ik.matrix.to_scale()
- bone_ik.scale = [
+ ctrl_ik.scale = [
v * i / c for v, i, c in zip(bone_ik.scale, input_scale, cur_scale)
]
@@ -456,8 +463,8 @@ def fk2ik_leg(obj, fk, ik):
view_layer.update()
# Foot position
- mat = mfoot.bone.matrix_local.inverted() @ foot.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) @ mat
+ footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot)
+ footmat = convert_pose_matrix_via_rest_delta(footmat, mfoot, foot)
set_pose_rotation(foot, footmat)
set_pose_scale(foot, footmat)
view_layer.update()
@@ -475,8 +482,8 @@ def fk2ik_leg(obj, fk, ik):
view_layer.update()
# Foot position
- mat = mfoot.bone.matrix_local.inverted() @ foot.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) @ mat
+ footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot)
+ footmat = convert_pose_matrix_via_rest_delta(footmat, mfoot, foot)
set_pose_rotation(foot, footmat)
set_pose_scale(foot, footmat)
view_layer.update()
@@ -516,8 +523,8 @@ def ik2fk_leg(obj, fk, ik):
view_layer.update()
# Foot position
- mat = mfooti.bone.matrix_local.inverted() @ footi.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(foot.matrix, footi) @ mat
+ footmat = get_pose_matrix_in_other_space(foot.matrix, footi)
+ footmat = convert_pose_matrix_via_rest_delta(footmat, mfooti, footi)
set_pose_translation(footi, footmat)
set_pose_rotation(footi, footmat)
set_pose_scale(footi, footmat)
@@ -544,8 +551,8 @@ def ik2fk_leg(obj, fk, ik):
view_layer.update()
# Foot position
- mat = mfooti.bone.matrix_local.inverted() @ footi.bone.matrix_local
- footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) @ mat
+ footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi)
+ footmat = convert_pose_matrix_via_rest_delta(footmat, mfooti, footi)
set_pose_translation(footi, footmat)
set_pose_rotation(footi, footmat)
set_pose_scale(footi, footmat)