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.
This commit is contained in:
Campbell Barton 2016-07-08 10:18:40 +10:00
parent 7a3ea87bbf
commit a92fc348f4
Notes: blender-bot 2023-02-14 07:46:43 +01:00
Referenced by issue #48898, shaders are remove from metaballs on cycles render
Referenced by issue #48815, Translate node's 'Relative' checkbox has the same tooltip as blur node's 'Relative' checkbox
Referenced by issue #48814, Displace modifier ignores 'Simple' subdivision if scale is unapplied
1 changed files with 23 additions and 0 deletions

View File

@ -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);