Armature bone feature:

New Bone option: "Relative Parenting". 

This makes Child-Objects of Bones transform similar to how deformations 
of bones are calculated. Allows to move bones in editmode to set pivot.

The option is in Bone Panel, with clear label. 
It is ON now by default when you add new bones

Requested by Kjartan, our famous robot designer :) For "hard body rigs" it's
very useful.
This commit is contained in:
Ton Roosendaal 2012-12-21 12:07:28 +00:00
parent b5054896c3
commit 915f78af92
5 changed files with 21 additions and 8 deletions

@ -170,6 +170,8 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
if ob and pchan: if ob and pchan:
col.label(text="Bone Group:") col.label(text="Bone Group:")
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="") col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
col.label(text="Object Children:")
col.prop(bone, "use_relative_parenting")
col = split.column() col = split.column()
col.label(text="Parent:") col.label(text="Parent:")
@ -181,11 +183,11 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
sub = col.column() sub = col.column()
sub.active = (bone.parent is not None) sub.active = (bone.parent is not None)
sub.prop(bone, "use_connect") sub.prop(bone, "use_connect")
sub.prop(bone, "use_inherit_rotation", text="Inherit Rotation") sub.prop(bone, "use_inherit_rotation")
sub.prop(bone, "use_inherit_scale", text="Inherit Scale") sub.prop(bone, "use_inherit_scale")
sub = col.column() sub = col.column()
sub.active = (not bone.parent or not bone.use_connect) sub.active = (not bone.parent or not bone.use_connect)
sub.prop(bone, "use_local_location", text="Local Location") sub.prop(bone, "use_local_location")
class BONE_PT_display(BoneButtonsPanel, Panel): class BONE_PT_display(BoneButtonsPanel, Panel):

@ -1839,7 +1839,10 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
} }
/* get bone transform */ /* get bone transform */
copy_m4_m4(mat, pchan->pose_mat); if (pchan->bone->flag & BONE_RELATIVE_PARENTING)
copy_m4_m4(mat, pchan->chan_mat);
else
copy_m4_m4(mat, pchan->pose_mat);
/* but for backwards compatibility, the child has to move to the tail */ /* but for backwards compatibility, the child has to move to the tail */
copy_v3_v3(vec, mat[1]); copy_v3_v3(vec, mat[1]);

@ -2256,6 +2256,7 @@ void undo_push_armature(bContext *C, const char *name)
/* *************** Adding stuff in editmode *************** */ /* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */ /* default bone add, returns it selected, but without tail set */
/* XXX should be used everywhere, now it mallocs bones still locally in functions */
EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name) EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
{ {
EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone"); EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone");
@ -2265,7 +2266,7 @@ EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
BLI_addtail(arm->edbo, bone); BLI_addtail(arm->edbo, bone);
bone->flag |= BONE_TIPSEL; bone->flag |= BONE_TIPSEL | BONE_RELATIVE_PARENTING;
bone->weight = 1.0f; bone->weight = 1.0f;
bone->dist = 0.25f; bone->dist = 0.25f;
bone->xwidth = 0.1f; bone->xwidth = 0.1f;
@ -3410,7 +3411,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
copy_v3_v3(newbone->tail, newbone->head); copy_v3_v3(newbone->tail, newbone->head);
newbone->parent = ebone; newbone->parent = ebone;
newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone newbone->flag = ebone->flag & (BONE_TIPSEL | BONE_RELATIVE_PARENTING); // copies it, in case mirrored bone
if (newbone->parent) newbone->flag |= BONE_CONNECTED; if (newbone->parent) newbone->flag |= BONE_CONNECTED;
} }
@ -3419,7 +3420,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
copy_v3_v3(newbone->tail, ebone->head); copy_v3_v3(newbone->tail, ebone->head);
newbone->parent = ebone->parent; newbone->parent = ebone->parent;
newbone->flag = BONE_TIPSEL; newbone->flag = BONE_TIPSEL | BONE_RELATIVE_PARENTING;
if (newbone->parent && (ebone->flag & BONE_CONNECTED)) { if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
newbone->flag |= BONE_CONNECTED; newbone->flag |= BONE_CONNECTED;

@ -198,7 +198,9 @@ typedef enum eBone_Flag {
BONE_EDITMODE_LOCKED = (1 << 19), /* bone transforms are locked in EditMode */ BONE_EDITMODE_LOCKED = (1 << 19), /* bone transforms are locked in EditMode */
BONE_TRANSFORM_CHILD = (1 << 20), /* Indicates that a parent is also being transformed */ BONE_TRANSFORM_CHILD = (1 << 20), /* Indicates that a parent is also being transformed */
BONE_UNSELECTABLE = (1 << 21), /* bone cannot be selected */ BONE_UNSELECTABLE = (1 << 21), /* bone cannot be selected */
BONE_NO_LOCAL_LOCATION = (1 << 22) /* bone location is in armature space */ BONE_NO_LOCAL_LOCATION = (1 << 22), /* bone location is in armature space */
BONE_RELATIVE_PARENTING = (1 << 23) /* object child will use relative transform (like deform) */
} eBone_Flag; } eBone_Flag;
#define MAXBONENAME 64 #define MAXBONENAME 64

@ -529,6 +529,11 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_LOCAL_LOCATION);
RNA_def_property_update(prop, 0, "rna_Armature_update_data"); RNA_def_property_update(prop, 0, "rna_Armature_update_data");
prop = RNA_def_property(srna, "use_relative_parenting", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Relative Parenting", "Object children will use relative transform, like deform");
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_RELATIVE_PARENTING);
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE); prop = RNA_def_property(srna, "show_wire", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_DRAWWIRE);
RNA_def_property_ui_text(prop, "Draw Wire", RNA_def_property_ui_text(prop, "Draw Wire",