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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-01-07 17:35:11 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-01-07 17:35:11 +0400
commit0213a43562cd60fa6e20535c5851733f47f20da4 (patch)
treed07eafc154b98f9c93345eb7e51832fd2f99249c /source/blender/editors/armature
parent2328f94e1d9291233defafae62be2d1c372be985 (diff)
Armatures Editmode: option to recalculate roll from the angle to the parent
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r--source/blender/editors/armature/armature_edit.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 8600fdc8a53..1819492c346 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -241,15 +241,22 @@ typedef enum eCalcRollTypes {
CALC_ROLL_Y = 1,
CALC_ROLL_Z = 2,
+ CALC_ROLL_TAN_X = 3,
+ CALC_ROLL_TAN_Z = 4,
+
CALC_ROLL_ACTIVE = 5,
CALC_ROLL_VIEW = 6,
- CALC_ROLL_CURSOR = 7
+ CALC_ROLL_CURSOR = 7,
} eCalcRollTypes;
static EnumPropertyItem prop_calc_roll_types[] = {
- {CALC_ROLL_X, "X", 0, "X Axis", ""},
- {CALC_ROLL_Y, "Y", 0, "Y Axis", ""},
- {CALC_ROLL_Z, "Z", 0, "Z Axis", ""},
+ {CALC_ROLL_TAN_X, "X", 0, "Local X Tangent", ""},
+ {CALC_ROLL_TAN_Z, "Z", 0, "Local Z Tangent", ""},
+
+ {CALC_ROLL_X, "X", 0, "Global X Axis", ""},
+ {CALC_ROLL_Y, "Y", 0, "Global Y Axis", ""},
+ {CALC_ROLL_Z, "Z", 0, "Global Z Axis", ""},
+
{CALC_ROLL_ACTIVE, "ACTIVE", 0, "Active Bone", ""},
{CALC_ROLL_VIEW, "VIEW", 0, "View Axis", ""},
{CALC_ROLL_CURSOR, "CURSOR", 0, "Cursor", ""},
@@ -292,6 +299,54 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op)
}
}
}
+ else if (ELEM(type, CALC_ROLL_TAN_X, CALC_ROLL_TAN_Z)) {
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (ebone->parent) {
+ bool is_edit = (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone));
+ bool is_edit_parent = (EBONE_VISIBLE(arm, ebone->parent) && EBONE_EDITABLE(ebone->parent));
+
+ if (is_edit || is_edit_parent) {
+ EditBone *ebone_other = ebone->parent;
+ float dir_a[3];
+ float dir_b[3];
+ float vec[3];
+ bool is_vec_zero;
+
+ sub_v3_v3v3(dir_a, ebone->tail, ebone->head);
+ normalize_v3(dir_a);
+
+ /* find the first bone in the chane with a different direction */
+ do {
+ sub_v3_v3v3(dir_b, ebone_other->head, ebone_other->tail);
+ normalize_v3(dir_b);
+
+ if (type == CALC_ROLL_TAN_Z) {
+ cross_v3_v3v3(vec, dir_a, dir_b);
+ }
+ else {
+ add_v3_v3v3(vec, dir_a, dir_b);
+ }
+ } while ((is_vec_zero = (normalize_v3(vec) < 0.00001f)) &&
+ (ebone_other = ebone_other->parent));
+
+ if (!is_vec_zero) {
+ if (axis_flip) negate_v3(vec);
+
+ if (is_edit) {
+ ebone->roll = ED_rollBoneToVector(ebone, vec, axis_only);
+ }
+
+ /* parentless bones use cross product with child */
+ if (is_edit_parent) {
+ if (ebone->parent->parent == NULL) {
+ ebone->parent->roll = ED_rollBoneToVector(ebone->parent, vec, axis_only);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
else {
float vec[3] = {0.0f, 0.0f, 0.0f};
if (type == CALC_ROLL_VIEW) { /* View */
@@ -365,7 +420,7 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, CALC_ROLL_TAN_X, "Type", "");
RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis");
RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align");
}