diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-10-14 13:49:58 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2014-10-14 13:51:36 +0400 |
commit | 20c233f3af344579fb14ea6cf1617e0c4021a31e (patch) | |
tree | 29a8d71b53dcfc255c7eb2dd587982aa77749902 /source | |
parent | 3620e3e3316f2d818ecc9f6f290b8fd2d1a530a1 (diff) |
Yet another tweak to stretch volume variation.
Make sure the 1.0 value is not affected by smoothing, and min/max limits
never go above or below 1.0 respectively. This was a request by
animators since not modifying the mesh in its rest pose is regarded as
crucial.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 51 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 30 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 4 |
3 files changed, 54 insertions, 31 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 3a9eb31f061..97515244422 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2613,6 +2613,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,37 +2691,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 bulge_smoothed; - - bulge_smoothed = bulge_median + bulge_range * atanf(bulge - bulge_median) / (0.5f * M_PI); - - 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); } } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index d8da0a12b50..bd1b5f2c269 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -114,6 +114,19 @@ static void do_version_constraints_radians_degrees_270_5(ListBase *lb) } } +static void do_version_constraints_stretch_to_limits(ListBase *lb) +{ + bConstraint *con; + + for (con = lb->first; con; con = con->next) { + if (con->type == CONSTRAINT_TYPE_STRETCHTO) { + bStretchToConstraint *data = (bStretchToConstraint *)con->data; + data->bulge_min = 1.0f; + data->bulge_max = 1.0f; + } + } +} + void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) { if (!MAIN_VERSION_ATLEAST(main, 270, 0)) { @@ -405,4 +418,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) image->gen_color[3] = 1.0f; } } + + if (!DNA_struct_elem_find(fd->filesdna, "bStretchToConstraint", "float", "bulge_min")) { + Object *ob; + + /* Update Transform constraint (again :|). */ + for (ob = main->object.first; ob; ob = ob->id.next) { + do_version_constraints_stretch_to_limits(&ob->constraints); + + if (ob->pose) { + /* Bones constraints! */ + bPoseChannel *pchan; + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + do_version_constraints_stretch_to_limits(&pchan->constraints); + } + } + } + } } diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index aab2d35c0e4..77355dbad0e 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1377,12 +1377,12 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "bulge_min", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 0.0, 1.0f); RNA_def_property_ui_text(prop, "Volume Variation Minimum", "Minimum volume stretching factor"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "bulge_max", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 1.0, 100.0f); RNA_def_property_ui_text(prop, "Volume Variation Maximum", "Maximum volume stretching factor"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); |