diff options
author | Joshua Leung <aligorith@gmail.com> | 2015-01-13 08:06:53 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2015-01-13 08:06:53 +0300 |
commit | f0361fcf54e8d15790e2bad5c7402f6af3c24083 (patch) | |
tree | 0d396f70b1a96504ba112bf251c417ceb513bd27 /source/blender/blenkernel/intern | |
parent | f453df5b0382a895edb23753a73b6d9b9cbea6ed (diff) |
Pataz-Gooseberry Request: Limits on Volume Preservation for Spline IK
This commit adds a new type of volume preservation mode to Spline IK
which makes it possible to set limits on the minimum and maximum
scaling of bone "fatness".
* The old volume preseving mode has been kept but renamed, to avoid
breaking old rigs. "Volume Presevation" uses the new method, while
"Inverse Preservation" is the old one.
* The code and settings for this new xz scale mode are directly lifted
from the improved Stretch To constraint
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index df57db21e3b..88b46efc9e6 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2166,9 +2166,9 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o mul_v3_fl(poseMat[2], scale); break; } - case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: + case CONSTRAINT_SPLINEIK_XZS_INVERSE: { - /* 'volume preservation' */ + /* old 'volume preservation' method using the inverse scale */ float scale; /* calculate volume preservation factor which is @@ -2189,6 +2189,54 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o mul_v3_fl(poseMat[2], scale); break; } + case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: + { + /* improved volume preservation based on the Stretch To constraint */ + float scale; + + /* as the basis for volume preservation, we use the inverse scale factor... */ + if (fabsf(scaleFac) != 0.0f) { + /* NOTE: The method here is taken wholesale from the Stretch To constraint */ + float bulge = powf(1.0f / fabsf(scaleFac), ikData->bulge); + + if (bulge > 1.0f) { + if (ikData->flag & STRETCHTOCON_USE_BULGE_MAX) { + float bulge_max = max_ff(ikData->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, ikData->bulge_smooth); + } + } + if (bulge < 1.0f) { + if (ikData->flag & STRETCHTOCON_USE_BULGE_MIN) { + float bulge_min = CLAMPIS(ikData->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, ikData->bulge_smooth); + } + } + + /* compute scale factor for xz axes from this value */ + scale = sqrt(bulge); + } + else { + /* no scaling, so scale factor is simple */ + scale = 1.0f; + } + + /* apply the scaling (assuming normalised scale) */ + mul_v3_fl(poseMat[0], scale); + mul_v3_fl(poseMat[2], scale); + break; + } } /* finally, multiply the x and z scaling by the radius of the curve too, |