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:
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py3
-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
5 files changed, 46 insertions, 24 deletions
diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index fec90fef590..f5b36d6cfd0 100644
--- a/release/scripts/startup/bl_ui/properties_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -801,6 +801,9 @@ class ConstraintButtonsPanel:
layout.prop(con, "y_scale_mode")
layout.prop(con, "xz_scale_mode")
+ if con.xz_scale_mode in {'INVERSE_PRESERVE', 'VOLUME_PRESERVE'}:
+ layout.prop(con, "use_original_scale")
+
if con.xz_scale_mode == 'VOLUME_PRESERVE':
layout.prop(con, "bulge", text="Volume Variation")
split = layout.split()
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);