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:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-05-07 19:52:10 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-05-07 19:54:36 +0300
commit37eb1090148057e9c1ecaae6a94bf97c8e51dd61 (patch)
treecd03c47901faebd17035eccecf33e53eee4bd990 /source/blender
parentb1a77117189259cd75f99b91f88a64b810c9973a (diff)
Spline IK: support using both original scaling and volume preservation.
Add a new option that makes the Spline IK solver apply volume preservation on top of the original scaling, considering the pre-IK scale of the bone as the goal volume to be preserved. This basically works similar to the Stretch To constraint, and allows easily rigging a stretchy chain that uniformly follows its parent's scaling. Since the Stretch To behavior is more familiar, the new option is on by default for newly created Spline IK constraints.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/armature_update.c56
-rw-r--r--source/blender/blenkernel/intern/constraint.c1
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c7
4 files changed, 43 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index c71c2dc86cf..97326fa78f2 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -273,11 +273,12 @@ static void splineik_evaluate_bone(
/* first, adjust the point positions on the curve */
float curveLen = tree->points[index] - tree->points[index + 1];
float pointStart = state->curve_position;
+ float poseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length;
float baseScale = 1.0f;
if (ikData->yScaleMode == CONSTRAINT_SPLINEIK_YS_ORIGINAL) {
/* Carry over the bone Y scale to the curve range. */
- baseScale = len_v3v3(poseHead, poseTail) / pchan->bone->length;
+ baseScale = poseScale;
}
float pointEnd = pointStart + curveLen * baseScale * state->curve_scale;
@@ -394,24 +395,31 @@ static void splineik_evaluate_bone(
}
/* step 4: set the scaling factors for the axes */
- {
- /* only multiply the y-axis by the scaling factor to get nice volume-preservation */
- mul_v3_fl(poseMat[1], scaleFac);
- /* set the scaling factors of the x and z axes from... */
- switch (ikData->xzScaleMode) {
- case CONSTRAINT_SPLINEIK_XZS_ORIGINAL: {
- /* original scales get used */
- float scale;
+ /* Always multiply the y-axis by the scaling factor to get the correct length. */
+ mul_v3_fl(poseMat[1], scaleFac);
+
+ /* After that, apply x/z scaling modes. */
+ if (ikData->xzScaleMode != CONSTRAINT_SPLINEIK_XZS_NONE) {
+ /* First, apply the original scale if enabled. */
+ if (ikData->xzScaleMode == CONSTRAINT_SPLINEIK_XZS_ORIGINAL ||
+ (ikData->flag & CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE) != 0) {
+ float scale;
+
+ /* x-axis scale */
+ scale = len_v3(pchan->pose_mat[0]);
+ mul_v3_fl(poseMat[0], scale);
+ /* z-axis scale */
+ scale = len_v3(pchan->pose_mat[2]);
+ mul_v3_fl(poseMat[2], scale);
+
+ /* Adjust the scale factor used for volume preservation
+ * to consider the pre-IK scaling as the initial volume. */
+ scaleFac /= poseScale;
+ }
- /* x-axis scale */
- scale = len_v3(pchan->pose_mat[0]);
- mul_v3_fl(poseMat[0], scale);
- /* z-axis scale */
- scale = len_v3(pchan->pose_mat[2]);
- mul_v3_fl(poseMat[2], scale);
- break;
- }
+ /* Apply volume preservation. */
+ switch (ikData->xzScaleMode) {
case CONSTRAINT_SPLINEIK_XZS_INVERSE: {
/* old 'volume preservation' method using the inverse scale */
float scale;
@@ -483,14 +491,14 @@ static void splineik_evaluate_bone(
break;
}
}
+ }
- /* finally, multiply the x and z scaling by the radius of the curve too,
- * to allow automatic scales to get tweaked still
- */
- if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
- mul_v3_fl(poseMat[0], radius);
- mul_v3_fl(poseMat[2], radius);
- }
+ /* Finally, multiply the x and z scaling by the radius of the curve too,
+ * to allow automatic scales to get tweaked still.
+ */
+ if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
+ mul_v3_fl(poseMat[0], radius);
+ mul_v3_fl(poseMat[2], radius);
}
/* Blend the scaling of the matrix according to the influence. */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 282847fe220..2ccfcf45e46 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4235,6 +4235,7 @@ static void splineik_new_data(void *cdata)
data->bulge_min = 1.0f;
data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE;
+ data->flag = CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE;
}
static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index d3165efb647..3abd5b4456e 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -906,6 +906,9 @@ typedef enum eSplineIK_Flags {
/* for "volumetric" xz scale mode, limit the minimum or maximum scale values */
CONSTRAINT_SPLINEIK_USE_BULGE_MIN = (1 << 5),
CONSTRAINT_SPLINEIK_USE_BULGE_MAX = (1 << 6),
+
+ /* apply volume preservation over original scaling of the bone */
+ CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE = (1 << 7),
} eSplineIK_Flags;
/* bSplineIKConstraint->xzScaleMode */
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 49c1fa779ab..ef3ea19fa57 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -2604,6 +2604,13 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna)
"on top of the shape and scaling of the curve itself");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+ /* take original scaling of the bone into account in volume preservation */
+ prop = RNA_def_property(srna, "use_original_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE);
+ RNA_def_property_ui_text(
+ prop, "Use Original Scale", "Apply volume preservation over the original scaling");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
+
/* volume presevation for "volumetric" scale mode */
prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0, 100.f);