From ee387c6addb2a6c92b48525b0ee5b3b734430002 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 16 Apr 2014 18:20:27 +0200 Subject: Fix T39750: Bones disappearing with strange transforms. Fixed this issue and another similar one, and some minor optimizations. --- source/blender/blenkernel/intern/armature.c | 4 +- source/blender/editors/armature/armature_edit.c | 53 ++++++++++++++----------- 2 files changed, 32 insertions(+), 25 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index a8f533b8f55..b2b94992cb3 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1488,7 +1488,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]) normalize_v3_v3(nor, vec); - theta = 1 + nor[1]; + theta = 1.0f + nor[1]; /* With old algo, 1.0e-13f caused T23954 and T31333, 1.0e-6f caused T27675 and T30438, * so using 1.0e-9f as best compromise. @@ -1496,7 +1496,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[3][3]) * New algo is supposed much more precise, since less complex computations are performed, * but it uses two different threshold values... */ - if (theta > 1.0e-9f) { + if ((nor[0] || nor[2]) && theta > 1.0e-9f) { /* nor is *not* -Y. * We got these values for free... so be happy with it... ;) */ diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 52423c8fca7..4e81430b339 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -203,36 +203,43 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const bool axis_only) { float mat[3][3], nor[3]; + float vec[3], align_axis_proj[3], roll = 0.0f; + + BLI_ASSERT_UNIT_V3(align_axis); sub_v3_v3v3(nor, bone->tail, bone->head); + + /* if tail == head! */ + if (is_zero_v3(nor)) { + return roll; + } + vec_roll_to_mat3(nor, 0.0f, mat); - + /* check the bone isn't aligned with the axis */ - if (!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) { - float vec[3], align_axis_proj[3], roll; - - /* project the new_up_axis along the normal */ - project_v3_v3v3(vec, align_axis, nor); - sub_v3_v3v3(align_axis_proj, align_axis, vec); - - if (axis_only) { - if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI / 2.0)) { - negate_v3(align_axis_proj); - } - } - - roll = angle_v3v3(align_axis_proj, mat[2]); - - cross_v3_v3v3(vec, mat[2], align_axis_proj); - - if (dot_v3v3(vec, nor) < 0) { - roll = -roll; - } - + if (is_zero_v3(align_axis) || dot_v3v3(align_axis, mat[2]) <= (1.0f - FLT_EPSILON)) { return roll; } - return 0.0f; + /* project the new_up_axis along the normal */ + project_v3_v3v3(vec, align_axis, nor); + sub_v3_v3v3(align_axis_proj, align_axis, vec); + + if (axis_only) { + if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI / 2.0)) { + negate_v3(align_axis_proj); + } + } + + roll = angle_v3v3(align_axis_proj, mat[2]); + + cross_v3_v3v3(vec, mat[2], align_axis_proj); + + if (dot_v3v3(vec, nor) < 0.0f) { + roll = -roll; + } + + return roll; } -- cgit v1.2.3