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
path: root/rigify
diff options
context:
space:
mode:
authorNathan Vegdahl <cessen@cessen.com>2010-11-30 02:24:13 +0300
committerNathan Vegdahl <cessen@cessen.com>2010-11-30 02:24:13 +0300
commitad83e136bf700f936c3d76d4e3f938e51fcc2cc5 (patch)
treea574358c42e4e8e12aa616812ebc7ffc971537fe /rigify
parent9ec6e4e5472e4dafa7297e685e9a9cc81e7318d9 (diff)
- Minor fix for the finger rig. It was accepting, and failing on,
single-bone chains. Now it refuses single-bone chains. - IK arm and leg rigs now set the pole angle offset more precisely, so that the arm/leg doesn't shift in the default pose when switching between IK/FK.
Diffstat (limited to 'rigify')
-rw-r--r--rigify/rigs/biped/arm/ik.py44
-rw-r--r--rigify/rigs/biped/leg/ik.py49
-rw-r--r--rigify/rigs/finger.py4
3 files changed, 74 insertions, 23 deletions
diff --git a/rigify/rigs/biped/arm/ik.py b/rigify/rigs/biped/arm/ik.py
index c341ede6..2b941b9e 100644
--- a/rigify/rigs/biped/arm/ik.py
+++ b/rigify/rigs/biped/arm/ik.py
@@ -18,7 +18,7 @@
import bpy
from mathutils import Vector
-from math import pi
+from math import pi, acos
from rigify.utils import MetarigError
from rigify.utils import copy_bone
from rigify.utils import connected_children_names
@@ -28,6 +28,33 @@ from rigify.utils import create_widget, create_line_widget, create_sphere_widget
from rna_prop_ui import rna_idprop_ui_prop_get
+def angle_on_plane(plane, vec1, vec2):
+ """ Return the angle between two vectors projected onto a plane.
+ """
+ plane.normalize()
+ vec1 = vec1 - (plane * (vec1.dot(plane)))
+ vec2 = vec2 - (plane * (vec2.dot(plane)))
+ vec1.normalize()
+ vec2.normalize()
+
+ # Determine the angle
+ angle = acos(max(-1.0, min(1.0, vec1.dot(vec2))))
+
+ if angle < 0.00001: # close enough to zero that sign doesn't matter
+ return angle
+
+ # Determine the sign of the angle
+ vec3 = vec2.cross(vec1)
+ vec3.normalize()
+ sign = vec3.dot(plane)
+ if sign >= 0:
+ sign = 1
+ else:
+ sign = -1
+
+ return angle * sign
+
+
class Rig:
""" An IK arm rig, with an optional ik/fk switch.
@@ -130,6 +157,12 @@ class Rig:
vishand_e.tail = vishand_e.head + Vector((0, 0, v1.length / 32))
vispole_e.tail = vispole_e.head + Vector((0, 0, v1.length / 32))
+ # Determine the pole offset value
+ plane = (farm_e.tail - uarm_e.head).normalize()
+ vec1 = uarm_e.x_axis.normalize()
+ vec2 = (pole_e.head - uarm_e.head).normalize()
+ pole_offset = angle_on_plane(plane, vec1, vec2)
+
# Object mode, get pose bones
bpy.ops.object.mode_set(mode='OBJECT')
pb = self.obj.pose.bones
@@ -172,14 +205,7 @@ class Rig:
con.subtarget = hand
con.pole_target = self.obj
con.pole_subtarget = pole
- if self.primary_rotation_axis == 'X' or self.primary_rotation_axis == 'Y':
- con.pole_angle = -pi / 2
- elif self.primary_rotation_axis == '-X' or self.primary_rotation_axis == '-Y':
- con.pole_angle = pi / 2
- elif self.primary_rotation_axis == 'Z':
- con.pole_angle = 0.0
- elif self.primary_rotation_axis == '-Z':
- con.pole_angle = pi
+ con.pole_angle = pole_offset
con.chain_count = 2
# Constrain org bones to controls
diff --git a/rigify/rigs/biped/leg/ik.py b/rigify/rigs/biped/leg/ik.py
index 5697a2b6..a04b57dc 100644
--- a/rigify/rigs/biped/leg/ik.py
+++ b/rigify/rigs/biped/leg/ik.py
@@ -36,12 +36,7 @@ def align_x_axis(obj, bone, vec):
"""
vec.normalize()
bone_e = obj.data.edit_bones[bone]
- dot = bone_e.x_axis.dot(vec)
- if dot < -1:
- dot = -1
- elif dot > 1:
- dot = 1
-
+ dot = max(-1.0, min(1.0, bone_e.x_axis.dot(vec)))
angle = acos(dot)
bone_e.roll += angle
@@ -56,6 +51,33 @@ def align_x_axis(obj, bone, vec):
bone_e.roll += angle * 2
+def angle_on_plane(plane, vec1, vec2):
+ """ Return the angle between two vectors projected onto a plane.
+ """
+ plane.normalize()
+ vec1 = vec1 - (plane * (vec1.dot(plane)))
+ vec2 = vec2 - (plane * (vec2.dot(plane)))
+ vec1.normalize()
+ vec2.normalize()
+
+ # Determine the angle
+ angle = acos(max(-1.0, min(1.0, vec1.dot(vec2))))
+
+ if angle < 0.00001: # close enough to zero that sign doesn't matter
+ return angle
+
+ # Determine the sign of the angle
+ vec3 = vec2.cross(vec1)
+ vec3.normalize()
+ sign = vec3.dot(plane)
+ if sign >= 0:
+ sign = 1
+ else:
+ sign = -1
+
+ return angle * sign
+
+
class Rig:
""" An IK leg rig, with an optional ik/fk switch.
@@ -258,6 +280,12 @@ class Rig:
foot_ik_target_e.head = Vector(org_foot_e.head)
foot_ik_target_e.tail = Vector(org_foot_e.tail)
+ # Determine the pole offset value
+ plane = (shin_e.tail - thigh_e.head).normalize()
+ vec1 = thigh_e.x_axis.normalize()
+ vec2 = (pole_e.head - thigh_e.head).normalize()
+ pole_offset = angle_on_plane(plane, vec1, vec2)
+
# Object mode, get pose bones
bpy.ops.object.mode_set(mode='OBJECT')
pb = self.obj.pose.bones
@@ -312,14 +340,7 @@ class Rig:
con.subtarget = foot_ik_target
con.pole_target = self.obj
con.pole_subtarget = pole
- if self.primary_rotation_axis == 'X' or self.primary_rotation_axis == 'Y':
- con.pole_angle = -pi / 2
- elif self.primary_rotation_axis == '-X' or self.primary_rotation_axis == '-Y':
- con.pole_angle = pi / 2
- elif self.primary_rotation_axis == 'Z':
- con.pole_angle = 0.0
- elif self.primary_rotation_axis == '-Z':
- con.pole_angle = pi
+ con.pole_angle = pole_offset
con.chain_count = 2
# toe_parent constraint
diff --git a/rigify/rigs/finger.py b/rigify/rigs/finger.py
index de028f36..f5788d02 100644
--- a/rigify/rigs/finger.py
+++ b/rigify/rigs/finger.py
@@ -39,6 +39,10 @@ class Rig:
self.org_bones = [bone] + connected_children_names(obj, bone)
self.params = params
+ if len(self.org_bones) <= 1:
+ raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones." % (strip_org(bone)))
+
+
# Get user-specified layers, if they exist
if params.separate_extra_layers:
self.ex_layers = list(params.extra_layers)