From 821828e8126898867fbc35f525c73164df2ef792 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Tue, 17 May 2016 01:08:47 +1200 Subject: Bendy Bones: Option to treat disconnected bbone start/end reference locations as relative This is an experimental option for use with the previous commit. It's an attempt at making these bone references more useful when there's a big gap between the reference bone being used, and the bone it's controlling. --- .../scripts/startup/bl_ui/properties_data_bone.py | 5 +++ source/blender/blenkernel/intern/armature.c | 50 ++++++++++++++++++---- source/blender/makesdna/DNA_action_types.h | 4 ++ source/blender/makesrna/intern/rna_pose.c | 18 +++++++- 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 2c22259d518..4ac10f2050b 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -212,6 +212,11 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): row.prop_search(pchan, "bbone_custom_handle_start", ob.pose, "bones", text="In") row.prop_search(pchan, "bbone_custom_handle_end", ob.pose, "bones", text="Out") + row = col.row() + row.active = pchan.use_bbone_custom_handles + row.prop(pchan, "use_bbone_relative_start_handle", text="Relative") + row.prop(pchan, "use_bbone_relative_end_handle", text="Relative") + diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 90fc88db37a..0cd63cd2314 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -533,10 +533,27 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB float difmat[4][4], result[3][3], imat3[3][3]; /* transform previous point inside this bone space */ - if (rest) - copy_v3_v3(h1, prev->bone->arm_head); - else - copy_v3_v3(h1, prev->pose_head); + if ((pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) && + (pchan->bboneflag & PCHAN_BBONE_CUSTOM_START_REL)) + { + /* Use delta movement (from restpose), and apply this relative to the current bone's head */ + if (rest) { + /* in restpose, arm_head == pose_head */ + h1[0] = h1[1] = h1[2] = 0.0f; + } + else { + float delta[3]; + sub_v3_v3v3(delta, prev->pose_head, prev->bone->arm_head); + sub_v3_v3v3(h1, pchan->pose_head, delta); + } + } + else { + /* Use bone head as absolute position */ + if (rest) + copy_v3_v3(h1, prev->bone->arm_head); + else + copy_v3_v3(h1, prev->pose_head); + } mul_m4_v3(imat, h1); if (prev->bone->segments > 1) { @@ -572,10 +589,27 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB float difmat[4][4], result[3][3], imat3[3][3]; /* transform next point inside this bone space */ - if (rest) - copy_v3_v3(h2, next->bone->arm_tail); - else - copy_v3_v3(h2, next->pose_tail); + if ((pchan->bboneflag & PCHAN_BBONE_CUSTOM_HANDLES) && + (pchan->bboneflag & PCHAN_BBONE_CUSTOM_END_REL)) + { + /* Use delta movement (from restpose), and apply this relative to the current bone's tail */ + if (rest) { + /* in restpose, arm_tail == pose_tail */ + h2[0] = h2[1] = h2[2] = 0.0f; + } + else { + float delta[3]; + sub_v3_v3v3(delta, next->pose_tail, next->bone->arm_tail); + add_v3_v3v3(h2, pchan->pose_tail, delta); + } + } + else { + /* Use bone tail as absolute position */ + if (rest) + copy_v3_v3(h2, next->bone->arm_tail); + else + copy_v3_v3(h2, next->pose_tail); + } mul_m4_v3(imat, h2); /* if next bone is B-bone too, use average handle direction */ diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 1c8832fa552..4d82e4528d6 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -332,6 +332,10 @@ typedef enum ePchan_DrawFlag { typedef enum ePchan_BBoneFlag { /* Use custom reference bones (for roll and handle alignment), instead of immediate neighbours */ PCHAN_BBONE_CUSTOM_HANDLES = (1 << 1), + /* Evaluate start handle as being "relative" */ + PCHAN_BBONE_CUSTOM_START_REL = (1 << 2), + /* Evaluate end handle as being "relative" */ + PCHAN_BBONE_CUSTOM_END_REL = (1 << 3), } ePchan_BBoneFlag; /* PoseChannel->rotmode and Object->rotmode */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 9e1bde70370..fb7d5141a6d 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -881,8 +881,8 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Custom Handle References", "Use custom reference bones as handles for B-Bones instead of next/previous bones, " "leave these blank to use only B-Bone offset properties to control the shape"); - //RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); - RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update"); + RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); prop = RNA_def_property(srna, "bbone_custom_handle_start", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bbone_prev"); @@ -893,6 +893,13 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL); + RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle", + "Use treat custom start handle position as a relative value"); + RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + prop = RNA_def_property(srna, "bbone_custom_handle_end", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "bbone_next"); RNA_def_property_struct_type(prop, "PoseBone"); @@ -902,6 +909,13 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL); + RNA_def_property_ui_text(prop, "Relative B-Bone End Handle", + "Use treat custom end handle position as a relative value"); + RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); + RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); + /* transform matrices - should be read-only since these are set directly by AnimSys evaluation */ prop = RNA_def_property(srna, "matrix_channel", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "chan_mat"); -- cgit v1.2.3