diff options
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 83 |
1 files changed, 42 insertions, 41 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e4b60c12d64..8fedf37fb95 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -185,6 +185,10 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob) /* calculate delta of constraints evaluation */ invert_m4_m4(imat, cob->startmat); + /* XXX This would seem to be in wrong order. However, it does not work in 'right' order - would be nice to + * understand why premul is needed here instead of usual postmul? + * In any case, we **do not get a delta** here (e.g. startmat & matrix having same location, still gives + * a 'delta' with non-null translation component :/ ).*/ mul_m4_m4m4(delta, cob->matrix, imat); /* copy matrices back to source */ @@ -1967,7 +1971,7 @@ static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTa static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets) { #ifndef WITH_PYTHON - (void)con; (void)cob; (void)targets; /* unused */ + UNUSED_VARS(con, cob, targets); return; #else bPythonConstraint *data = con->data; @@ -2613,6 +2617,8 @@ static void stretchto_new_data(void *cdata) data->plane = 0; data->orglength = 0.0; data->bulge = 1.0; + data->bulge_max = 1.0f; + data->bulge_min = 1.0f; } static void stretchto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) @@ -2689,39 +2695,28 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t 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); + if (bulge > 1.0f) { + if (data->flag & STRETCHTOCON_USE_BULGE_MAX) { + float bulge_max = max_ff(data->bulge_max, 1.0f); + float hard = min_ff(bulge, bulge_max); + + float range = bulge_max - 1.0f; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, data->bulge_smooth); } - 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; + if (bulge < 1.0f) { + if (data->flag & STRETCHTOCON_USE_BULGE_MIN) { + float bulge_min = CLAMPIS(data->bulge_max, 0.0f, 1.0f); + float hard = max_ff(bulge, bulge_min); + + float range = 1.0f - bulge_min; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, data->bulge_smooth); } } @@ -3466,10 +3461,16 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra } /* transform normal into requested space */ - unit_m4(mat); - BKE_constraint_mat_convertspace(cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace); - invert_m4(mat); - mul_mat3_m4_v3(mat, no); + /* We cannot use BKE_constraint_mat_convertspace here, it does not take into account scaling... + * In theory we would not need it, but in this case we'd have to tweak SpaceTransform to also + * optionally ignore scaling when handling normals - simpler to directly call BKE_object_to_mat4 + * if needed! See T42447. */ + if (scon->projAxisSpace == CONSTRAINT_SPACE_WORLD) { + BKE_object_to_mat4(cob->ob, mat); + invert_m4(mat); + mul_mat3_m4_v3(mat, no); + } + /* Else, we remain in local space, nothing to do. */ if (normalize_v3(no) < FLT_EPSILON) { fail = true; @@ -4394,10 +4395,10 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con) if (con) { BKE_constraint_free_data(con); BLI_freelinkN(list, con); - return 1; + return true; } else - return 0; + return false; } /* ......... */ @@ -4661,15 +4662,15 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan) /* On bone-level, check if bone is on proxy-protected layer */ if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected)) - return 1; + return true; } else { /* FIXME: constraints on object-level are not handled well yet */ - return 1; + return true; } } - return 0; + return false; } /* -------- Target-Matrix Stuff ------- */ |