From 7db9558cf6fc64545dcdb1c0291ec943a10600db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 Oct 2010 02:36:43 +0000 Subject: bugfix [#24291] Error parenting a child with any negative scaling coordinate the bug was in object_apply_mat4(), caused by applying a non-normalized matrix to the rotation. Blender 2.4x also had this problem, surprising nobody noticed!. --- source/blender/blenkernel/intern/object.c | 31 ++++++++++++++--------------- source/blender/blenlib/BLI_math_matrix.h | 2 ++ source/blender/blenlib/intern/math_matrix.c | 20 +++++++++++++++++++ 3 files changed, 37 insertions(+), 16 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 17e488c8353..79030e3adfa 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1698,29 +1698,28 @@ void object_mat3_to_rot(Object *ob, float mat[][3], int use_compat) /* see pchan_apply_mat4() for the equivalent 'pchan' function */ void object_apply_mat4(Object *ob, float mat[][4]) { - float mat3[3][3], tmat[3][3], imat[3][3]; + float mat3[3][3]; /* obmat -> 3x3 */ + float mat3_n[3][3]; /* obmat -> normalized, 3x3 */ + float imat3_n[3][3]; /* obmat -> normalized & inverted, 3x3 */ /* location */ copy_v3_v3(ob->loc, mat[3]); /* rotation */ copy_m3_m4(mat3, mat); - object_mat3_to_rot(ob, mat3, 0); - + /* so scale doesnt interfear with rotation [#24291] */ + normalize_m3_m3(mat3_n, mat3); + + object_mat3_to_rot(ob, mat3_n, 0); + /* scale */ -#if 0 - /* works fine except for neg scales */ - mat4_to_size(ob->size, mat); -#else - /* this is more complicated but works for negative scales */ - object_rot_to_mat3(ob, tmat); - invert_m3_m3(imat, tmat); - mul_m3_m3m3(tmat, imat, mat3); - - ob->size[0]= tmat[0][0]; - ob->size[1]= tmat[1][1]; - ob->size[2]= tmat[2][2]; -#endif + /* note: mat4_to_size(ob->size, mat) fails for negative scale */ + invert_m3_m3(imat3_n, mat3_n); + mul_m3_m3m3(mat3, imat3_n, mat3); + + ob->size[0]= mat3[0][0]; + ob->size[1]= mat3[1][1]; + ob->size[2]= mat3[2][2]; } void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 77ebcb24975..294546bb222 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -102,7 +102,9 @@ void transpose_m3(float R[3][3]); void transpose_m4(float R[4][4]); void normalize_m3(float R[3][3]); +void normalize_m3_m3(float R[3][3], float A[3][3]); void normalize_m4(float R[4][4]); +void normalize_m4_m4(float R[4][4], float A[4][4]); void orthogonalize_m3(float R[3][3], int axis); void orthogonalize_m4(float R[4][4], int axis); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3b5ffa2d442..197d3676367 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -750,6 +750,14 @@ void normalize_m3(float mat[][3]) normalize_v3(mat[2]); } +void normalize_m3_m3(float rmat[][3], float mat[][3]) +{ + normalize_v3_v3(rmat[0], mat[0]); + normalize_v3_v3(rmat[1], mat[1]); + normalize_v3_v3(rmat[2], mat[2]); +} + + void normalize_m4(float mat[][4]) { float len; @@ -762,6 +770,18 @@ void normalize_m4(float mat[][4]) if(len!=0.0) mat[2][3]/= len; } +void normalize_m4_m4(float rmat[][4], float mat[][4]) +{ + float len; + + len= normalize_v3_v3(rmat[0], mat[0]); + if(len!=0.0) rmat[0][3]= mat[0][3] / len; + len= normalize_v3_v3(rmat[1], mat[1]); + if(len!=0.0) rmat[1][3]= mat[1][3] / len; + len= normalize_v3_v3(rmat[2], mat[2]); + if(len!=0.0) rmat[2][3]= mat[2][3] / len;; +} + void adjoint_m3_m3(float m1[][3], float m[][3]) { m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1]; -- cgit v1.2.3