forked from bartvdbraak/blender
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.
This commit is contained in:
parent
62a0350957
commit
d4cc81d552
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user