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:
authorLukas Tönne <lukas.toenne@gmail.com>2014-10-13 21:51:46 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-10-13 21:58:53 +0400
commitf9cbb908a3fbd73970920def8356993b9e016d1d (patch)
tree7d9745c33b831bd1cafbcdd610a156f5322fd916 /source/blender/blenkernel/intern/constraint.c
parentaf346f991827fef81b21fe30370d84bc338d6461 (diff)
Integrated limits for volume preservation in stretch-to constraints.
Currently the volume variation feature in stretch constraints is unlimited. This has to be compensated by riggers by adding scale limit constraints, but these are unaware of the stretch orientation and can lead to flipping. Also the stretch calculation itself is not working properly and can lead to collapsing volume. The patch fixes this with several modifications: - Interpret the volume variation factor as exponent, which works better with large values for artistic purposes. - Add integrated limits to the volume "bulge" factor, so secondary constraints for compensation become unnecessary - Add a smoothness factor to make limits less visible. Eventually a generic volume preservation constraint would be nicer, because multiple constraints currently implement volume variation of their own. This feature could actually work very nicely independent from other constraint features. Differential Revision: https://developer.blender.org/D826
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r--source/blender/blenkernel/intern/constraint.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index ee7bad773fa..e4b60c12d64 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2658,7 +2658,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
if (VALID_CONS_TARGET(ct)) {
float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
float totmat[3][3];
- float dist;
+ float dist, bulge;
/* store scaling before destroying obmat */
mat4_to_size(size, cob->matrix);
@@ -2676,7 +2676,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* vec[2] /= size[2];*/
/* dist = normalize_v3(vec);*/
-
+
dist = len_v3v3(cob->matrix[3], ct->matrix[3]);
/* Only Y constrained object axis scale should be used, to keep same length when scaling it. */
dist /= size[1];
@@ -2684,23 +2684,60 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
/* data->orglength==0 occurs on first run, and after 'R' button is clicked */
if (data->orglength == 0)
data->orglength = dist;
- if (data->bulge == 0)
- data->bulge = 1.0;
-
+
scale[1] = dist / data->orglength;
+
+ bulge = powf(data->orglength / dist, data->bulge);
+
+ if (data->flag & STRETCHTOCON_USE_BULGE_MAX) {
+ const float bulge_median = ((data->flag & STRETCHTOCON_USE_BULGE_MIN) ?
+ 0.5f * (data->bulge_min + data->bulge_max) : 0.0f);
+ const float bulge_range = data->bulge_max - bulge_median;
+ float x, bulge_smoothed;
+
+ x = bulge_range != 0.0f ? (bulge - bulge_median) / bulge_range : 0.0f;
+ CLAMP(x, -1.0f, 1.0f);
+ bulge_smoothed = bulge_median + bulge_range * sinf(0.5f*M_PI * x);
+
+ if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
+ CLAMP_MIN(bulge, data->bulge_min);
+ }
+ CLAMP_MAX(bulge, data->bulge_max);
+
+ bulge = interpf(bulge_smoothed, bulge, data->bulge_smooth);
+ }
+ else if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
+ /* The quadratic formula below creates a smooth asymptote
+ * of the clamped bulge value. By scaling x with the inverse smooth factor
+ * the smoothed area becomes smaller ("less smoothing").
+ * For very small smoothing factor below epsilon it is replaced
+ * by the clamped version to avoid floating point precision issues.
+ */
+ const float epsilon = 0.000001f;
+ if (data->bulge_smooth < epsilon) {
+ CLAMP_MIN(bulge, data->bulge_min);
+ }
+ else {
+ float scale = data->bulge_smooth;
+ float inv_scale = 1.0f / scale;
+ float x = (bulge - data->bulge_min) * 0.5f * inv_scale;
+ bulge = scale * (x + sqrtf((x * x) + 1.0f)) + data->bulge_min;
+ }
+ }
+
switch (data->volmode) {
/* volume preserving scaling */
case VOLUME_XZ:
- scale[0] = 1.0f - sqrtf(data->bulge) + sqrtf(data->bulge * (data->orglength / dist));
+ scale[0] = sqrtf(bulge);
scale[2] = scale[0];
break;
case VOLUME_X:
- scale[0] = 1.0f + data->bulge * (data->orglength / dist - 1);
+ scale[0] = bulge;
scale[2] = 1.0;
break;
case VOLUME_Z:
scale[0] = 1.0;
- scale[2] = 1.0f + data->bulge * (data->orglength / dist - 1);
+ scale[2] = bulge;
break;
/* don't care for volume */
case NO_VOLUME: