diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-03-25 14:05:28 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-03-25 14:07:13 +0400 |
commit | d4cc81d5523b3e625b809baa4a57c73664fb13db (patch) | |
tree | 70b142d91bc26791984fceae4b160dd115db5a5c | |
parent | 62a03509574eac608f3199b4fd2ad8c00e14c789 (diff) |
Fix T38870: Freezes when jumping in front of a keyframe.
Issue was caused by inverting a degenerate matrix when
evaluating drivers.
Solved by using tweaked inverse code (same as used in Cycles).
Should have no affect on cases when matrix is not degenerate.
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_matrix.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 20 |
3 files changed, 24 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 415c84a776d..580a8a7a505 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -312,7 +312,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[ if (ob->parent) { /* 'subtract' parent's effects from owner */ mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv); - invert_m4_m4(imat, diff_mat); + invert_m4_m4_safe(imat, diff_mat); mul_m4_m4m4(mat, imat, mat); } else { @@ -323,7 +323,7 @@ void BKE_constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[ normalize_m4(diff_mat); zero_v3(diff_mat[3]); - invert_m4_m4(imat, diff_mat); + invert_m4_m4_safe(imat, diff_mat); mul_m4_m4m4(mat, imat, mat); } } diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index af251480ece..e59c557b327 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -166,6 +166,8 @@ void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon); bool has_zero_axis_m4(float matrix[4][4]); +void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]); + /****************************** Transformations ******************************/ void scale_m3_fl(float R[3][3], float scale); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index eb5c5f4aab4..3dd6c667494 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -2110,3 +2110,23 @@ bool has_zero_axis_m4(float matrix[4][4]) len_squared_v3(matrix[1]) < FLT_EPSILON || len_squared_v3(matrix[2]) < FLT_EPSILON; } + +void invert_m4_m4_safe(float Ainv[4][4], float A[4][4]) +{ + if (!invert_m4_m4(Ainv, A)) { + float Atemp[4][4]; + + copy_m4_m4(Atemp, A); + + /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should + * never be in this situation, but try to invert it anyway with tweak. + */ + Atemp[0][0] += 1e-8f; + Atemp[1][1] += 1e-8f; + Atemp[2][2] += 1e-8f; + + if (!invert_m4_m4(Ainv, Atemp)) { + return unit_m4(Ainv); + } + } +} |