diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-07-08 03:18:40 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-07-08 03:28:07 +0300 |
commit | a92fc348f46755c34023eff4fc1d7f467241c616 (patch) | |
tree | e5fec5fc0a6ee29dcab4c203ba33a463f92c237f | |
parent | 7a3ea87bbff7a250e035d35c59f3784eec51bc47 (diff) |
Fix/Workaround non-uniform scaled bones failing w/ IK solver
Scaling a bone on the Y axis (for a stretch effect), wasn't supported by the IK solver.
Support this by solving as uniform scaled bones by matching the X,Z axis to the Y.
Requested by @pepeland, see D2088 for details.
-rw-r--r-- | source/blender/ikplugin/intern/iksolver_plugin.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index b3c83bffb3f..30dd5e45a2b 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -50,6 +50,8 @@ #include <string.h> /* memcpy */ +#define USE_NONUNIFORM_SCALE + /* ********************** THE IK SOLVER ******************* */ /* allocates PoseTree, and links that to root bone/channel */ @@ -542,6 +544,19 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose /* tell blender that this channel was controlled by IK, it's cleared on each BKE_pose_where_is() */ tree->pchan[a]->flag |= POSE_CHAIN; } + +#ifdef USE_NONUNIFORM_SCALE + float (*pchan_scale_data)[3] = MEM_mallocN(sizeof(float[3]) * tree->totchannel, __func__); + + for (a = 0; a < tree->totchannel; a++) { + mat4_to_size(pchan_scale_data[a], tree->pchan[a]->pose_mat); + + /* make uniform at y scale since this controls the length */ + normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][1]); + normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][1]); + } +#endif + /* 5. execute the IK solver */ execute_posetree(scene, ob, tree); @@ -556,6 +571,14 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose where_is_ik_bone(tree->pchan[a], tree->basis_change[a]); } +#ifdef USE_NONUNIFORM_SCALE + for (a = 0; a < tree->totchannel; a++) { + normalize_v3_length(pchan->pose_mat[0], pchan_scale_data[a][0]); + normalize_v3_length(pchan->pose_mat[2], pchan_scale_data[a][2]); + } + MEM_freeN(pchan_scale_data); +#endif + /* 7. and free */ BLI_remlink(&pchan->iktree, tree); free_posetree(tree); |