[Bf-blender-cvs] [ed376e3] BendyBones: Bendy Bones: Curved Bone settings in EditMode act as "Rest Pose" (Experimental)

Joshua Leung noreply at git.blender.org
Tue May 17 16:40:27 CEST 2016


Commit: ed376e3595ba938caa16abfcd6724d74d1d6c6ed
Author: Joshua Leung
Date:   Sat May 14 11:46:34 2016 +1200
Branches: BendyBones
https://developer.blender.org/rBed376e3595ba938caa16abfcd6724d74d1d6c6ed

Bendy Bones: Curved Bone settings in EditMode act as "Rest Pose"  (Experimental)

The bendy bone settings (curve in/out, etc.) now exist on both Bone and PoseBone
levels. What this means is that the "Bone" level settings (i.e. what we had before)
are used for defining the rest pose curve for the bone (i.e. to fit things like
curved eyebrows, and so forth), while the "PoseBone" level settings (i.e. new stuff)
will be what animators play with to animate their characters.


Implementation Notes:
* All the BBone settings are now found in a new "Curved Bones" panel. This is located
  just below the Transform properties panels (instead of by "Deform"), so that it's
  easier to reach for animating.

  The segments and ease in+out settings are still also located in the "Deform" panel.
  I'm still unsure whether to remove them for good from there. For now, I've duplicated
  them, to be more convenient for animation tweaking (though it might also be a bit
  confusing)

* Ease In/Out is still a bone-level setting only (i.e. no posemode offsets/override).
  This may be subject to change still, but more investigation will be needed first.

* Scale In/Out is handled multiplicatively. That is,
  scaleIn_final = bone->scaleIn * pbone->scaleIn

* I've added a hacky "stripped down" copy of b_bone_spline_setup() for drawing
  the editmode previews of these bbone settings. Whether this is the final approach
  used is still open to debate. Better suggestions welcome, though this seems to be
  the simplest (least overhead) solution currently.

===================================================================

M	release/scripts/startup/bl_ui/properties_data_bone.py
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/editors/space_view3d/drawarmature.c
M	source/blender/makesdna/DNA_action_types.h
M	source/blender/makesdna/DNA_armature_types.h
M	source/blender/makesrna/intern/rna_armature.c
M	source/blender/makesrna/intern/rna_internal.h
M	source/blender/makesrna/intern/rna_pose.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py
index 1fc63b2..be74e07 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -146,6 +146,51 @@ class BONE_PT_transform_locks(BoneButtonsPanel, Panel):
             sub.prop(pchan, "lock_rotation_w", text="W")
 
 
+class BONE_PT_curved(BoneButtonsPanel, Panel):
+    bl_label = "Curved Bones"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        ob = context.object
+        bone = context.bone
+        arm = context.armature
+        pchan = None
+
+        if ob and bone:
+            pchan = ob.pose.bones[bone.name]
+            bbone = pchan
+        elif bone is None:
+            bone = context.edit_bone
+            bbone = bone
+        else:
+            bbone = bone
+
+        layout = self.layout
+        row = layout.row()
+
+        col = row.column()
+        col.prop(bone, "bbone_segments", text="Segments")
+
+        sub = col.column(align=True)
+        sub.prop(bone, "bbone_in", text="Ease In")    # XXX: have this also be an overlay?
+        sub.prop(bone, "bbone_out", text="Ease Out")  # XXX: have this also be an overlay?
+        sub.prop(bbone, "bbone_rollin", text="Roll In")
+        sub.prop(bbone, "bbone_rollout", text="Roll Out")
+
+        col = row.column()
+        sub = col.column(align=True)
+        sub.label(text="Curve XY Roll:")
+        sub.prop(bbone, "bbone_curveinx", text="In X")
+        sub.prop(bbone, "bbone_curveiny", text="In Y")
+        sub.prop(bbone, "bbone_curveoutx", text="Out X")
+        sub.prop(bbone, "bbone_curveouty", text="Out Y")
+
+        sub = col.column(align=True)
+        sub.label(text="Scale In/Out:")
+        sub.prop(bbone, "bbone_scalein", text="Scale In")
+        sub.prop(bbone, "bbone_scaleout", text="Scale Out")
+
+
 class BONE_PT_relations(BoneButtonsPanel, Panel):
     bl_label = "Relations"
 
@@ -372,18 +417,6 @@ class BONE_PT_deform(BoneButtonsPanel, Panel):
         sub.prop(bone, "bbone_segments", text="Segments")
         sub.prop(bone, "bbone_in", text="Ease In")
         sub.prop(bone, "bbone_out", text="Ease Out")
-        sub.prop(bone, "bbone_rollin", text="Roll In")
-        sub.prop(bone, "bbone_rollout", text="Roll Out")
-        
-        sub.label(text="Curve XY Roll:")
-        sub.prop(bone, "bbone_curveinx", text="In X")
-        sub.prop(bone, "bbone_curveiny", text="In Y")
-        sub.prop(bone, "bbone_curveoutx", text="Out X")
-        sub.prop(bone, "bbone_curveouty", text="Out Y")
-        
-        sub.label(text="Scale In/Out:")
-        sub.prop(bone, "bbone_scalein", text="Scale In")
-        sub.prop(bone, "bbone_scaleout", text="Scale Out")
 
 
 class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel):
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 51f1e78..8c27264 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -429,7 +429,7 @@ int bone_autoside_name(char name[MAXBONENAME], int UNUSED(strip_number), short a
 /* ************* B-Bone support ******************* */
 
 /* data has MAX_BBONE_SUBDIV+1 interpolated points, will become desired amount with equal distances */
-static void equalize_bezier(float *data, int desired)
+void equalize_bezier(float *data, int desired)
 {
 	float *fp, totdist, ddist, dist, fac1, fac2;
 	float pdist[MAX_BBONE_SUBDIV + 1];
@@ -604,21 +604,24 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
 	/* add extra effects (bbone properties)? */
 	if (!rest) {
 		/* add extra rolls */
-		roll1 += bone->roll1;
-		roll2 += bone->roll2;
+		roll1 += bone->roll1 + pchan->roll1;
+		roll2 += bone->roll2 + pchan->roll2;
 		
 		if (bone->flag & BONE_ADD_PARENT_END_ROLL) {
-			if (prev && prev->bone) {
-				roll1 += prev->bone->roll2;
+			if (prev) {
+				if (prev->bone)
+					roll1 += prev->bone->roll2;
+				
+				roll1 += prev->roll2;
 			}
 		}
 		
 		/* extra curve x / y */
-		h1[0] += bone->curveInX;
-		h1[2] += bone->curveInY;
+		h1[0] += bone->curveInX + pchan->curveInX;
+		h1[2] += bone->curveInY + pchan->curveInY;
 
-		h2[0] += bone->curveOutX;
-		h2[2] += bone->curveOutY;
+		h2[0] += bone->curveOutX + pchan->curveOutX;
+		h2[2] += bone->curveOutY + pchan->curveOutY;
 	}
 	
 	/* make curve */
@@ -648,12 +651,14 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
 		if (!rest) {
 			float scaleFactorIn = 1.0;
 			if (a <= bone->segments - 1) {
-				scaleFactorIn = 1.0f + (bone->scaleIn - 1.0f)  * ((1.0f * (bone->segments - a - 1)) / (1.0f * (bone->segments - 1)));
+				const float scaleIn = bone->scaleIn * pchan->scaleIn;
+				scaleFactorIn = 1.0f + (scaleIn - 1.0f)  * ((1.0f * (bone->segments - a - 1)) / (1.0f * (bone->segments - 1)));
 			}
 			
 			float scaleFactorOut = 1.0f;
 			if (a >= 0) {
-				scaleFactorOut = 1.0 + (bone->scaleOut - 1.0f) * ((1.0f * (a + 1))                  / (1.0f * (bone->segments - 1)));
+				const float scaleOut = bone->scaleOut * pchan->scaleOut;
+				scaleFactorOut = 1.0 + (scaleOut - 1.0f) * ((1.0f * (a + 1))                  / (1.0f * (bone->segments - 1)));
 			}
 			
 			float bscalemat[4][4], ibscalemat[4][4];
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 91febb3..7b7148b 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -1170,4 +1170,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
 			do_version_bones_super_bbone(&arm->bonebase);
 		}
 	}
+	if (!DNA_struct_elem_find(fd->filesdna, "bPoseChannel", "float", "scaleIn")) {
+		printf("VERSION PATCHING FOR SUPER POSEBONES --> POST-MERGE FIXME REMINDER...\n");
+		for (Object *ob = main->object.first; ob; ob = ob->id.next) {
+			if (ob->pose) {
+				for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+					/* see do_version_bones_super_bbone()... */
+					pchan->scaleIn = 1.0f;
+					pchan->scaleOut = 1.0f;
+				}
+			}
+		}
+	}
 }
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 5cda721..3621265 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -53,6 +53,7 @@
 #include "BKE_global.h"
 #include "BKE_modifier.h"
 #include "BKE_nla.h"
+#include "BKE_curve.h"
 
 
 #include "BIF_gl.h"
@@ -1093,19 +1094,116 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned
 	glPopMatrix();
 }
 
-static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, float xwidth, float length, float zwidth)
+/* XXX Hack - Refactor/Move/Reconsider how this can be best implemented... */
+#define BENDY_BONES_EDITMODE_PREVIEW
+
+#ifdef BENDY_BONES_EDITMODE_PREVIEW
+/* XXX: This is not exported for now, so just patching this over in the meantime... */
+extern void equalize_bezier(float *data, int desired);
+
+/* A partial copy of b_bone_spline_setup(), with just the parts for previewing editmode curve settings 
+ *
+ * This assumes that prev/next bones don't have any impact (since they should all still be in the "straight"
+ * position here anyway), and that we can simply apply the bbone settings to get the desired effect...
+ */
+static void ebone_spline_preview(EditBone *ebone, Mat4 result_array[MAX_BBONE_SUBDIV])
+{
+	float h1[3], h2[3], length, hlength1, hlength2, roll1 = 0.0f, roll2 = 0.0f;
+	float mat3[3][3];
+	float data[MAX_BBONE_SUBDIV + 1][4], *fp;
+	int a;
+	
+	length = ebone->length;
+	
+	hlength1 = ebone->ease1 * length * 0.390464f; /* 0.5f * sqrt(2) * kappa, the handle length for near-perfect circles */
+	hlength2 = ebone->ease2 * length * 0.390464f;
+	
+	/* find the handle points, since this is inside bone space, the
+	 * first point = (0, 0, 0)
+	 * last point =  (0, length, 0)
+	 *
+	 * we also just apply all the "extra effects", since they're the whole reason we're doing this...
+	 */
+	h1[0] = ebone->curveInX;
+	h1[1] = hlength1;
+	h1[2] = ebone->curveInY;
+	roll1 = ebone->roll1;
+	
+	h2[0] = ebone->curveOutX;
+	h2[1] = -hlength2;
+	h2[2] = ebone->curveOutY;
+	roll2 = ebone->roll2;
+	
+	/* make curve */
+	if (ebone->segments > MAX_BBONE_SUBDIV)
+		ebone->segments = MAX_BBONE_SUBDIV;
+
+	BKE_curve_forward_diff_bezier(0.0f,  h1[0],                               h2[0],                               0.0f,   data[0],     MAX_BBONE_SUBDIV, 4 * sizeof(float));
+	BKE_curve_forward_diff_bezier(0.0f,  h1[1],                               length + h2[1],                      length, data[0] + 1, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+	BKE_curve_forward_diff_bezier(0.0f,  h1[2],                               h2[2],                               0.0f,   data[0] + 2, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+	BKE_curve_forward_diff_bezier(roll1, roll1 + 0.390464f * (roll2 - roll1), roll2 - 0.390464f * (roll2 - roll1), roll2,  data[0] + 3, MAX_BBONE_SUBDIV, 4 * sizeof(float));
+
+	equalize_bezier(data[0], ebone->segments); /* note: does stride 4! */
+
+	/* make transformation matrices for the segments for drawing */
+	for (a = 0, fp = data[0]; a < ebone->segments; a++, fp += 4) {
+		sub_v3_v3v3(h1, fp + 4, fp);
+		vec_roll_to_mat3(h1, fp[3], mat3); /* fp[3] is roll */
+		
+		copy_m4_m3(result_array[a].mat, mat3);
+		copy_v3_v3(result_array[a].mat[3], fp);
+		
+		/* "extra" scale facs... */
+		{
+			float scaleFactorIn = 1.0;
+			if (a <= ebone->segments - 1) {
+				scaleFactorIn = 1.0f + (ebone->scaleIn - 1.0f)  * ((1.0f * (ebone->segments - a - 1)) / (1.0f * (ebone->segments - 1)));
+			}
+			
+			float scaleFactorOut = 1.0f;
+			if (a >= 0) {
+				scaleFactorOut = 1.0 + (ebone->scaleOut - 1.0f) * ((1.0f * (a + 1))                  / (1.0f * (ebone->segments - 1)));
+			}
+			
+			float bscalemat[4][4], ibscalemat[4][4];
+			float bscale[3];
+			
+			bscale[0] = 1.0f * scaleFactorIn * scaleFactorOut;
+			bscale[1] = 1.0f;
+			bscale[2] = 1.0f * scaleFactorIn * scaleFactorOut;
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list