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:
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r--source/blender/blenkernel/intern/constraint.c83
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 ------- */