Math Lib: add transpose_m3_m3, m3_m4, m4_m4
[blender.git] / source / blender / blenlib / intern / math_matrix.c
index 888587e055c9ef5ab5ffcf4ec18cb50ff29e63ea..293e90c87130cf12967e26cb470e7552eb008284 100644 (file)
@@ -514,6 +514,16 @@ void mul_project_m4_v3(float mat[4][4], float vec[3])
        vec[2] /= w;
 }
 
+void mul_v3_project_m4_v3(float r[3], float mat[4][4], const float vec[3])
+{
+       const float w = mul_project_m4_v3_zfac(mat, vec);
+       mul_v3_m4v3(r, mat, vec);
+
+       r[0] /= w;
+       r[1] /= w;
+       r[2] /= w;
+}
+
 void mul_v2_project_m4_v3(float r[2], float mat[4][4], const float vec[3])
 {
        const float w = mul_project_m4_v3_zfac(mat, vec);
@@ -629,7 +639,7 @@ void mul_mat3_m4_fl(float m[4][4], float f)
                        m[i][j] *= f;
 }
 
-void negate_m3(float m[4][4])
+void negate_m3(float m[3][3])
 {
        int i, j;
 
@@ -866,6 +876,37 @@ void transpose_m3(float mat[3][3])
        mat[2][1] = t;
 }
 
+void transpose_m3_m3(float rmat[3][3], float mat[3][3])
+{
+       BLI_assert(rmat != mat);
+
+       rmat[0][0] = mat[0][0];
+       rmat[0][1] = mat[1][0];
+       rmat[0][2] = mat[2][0];
+       rmat[1][0] = mat[0][1];
+       rmat[1][1] = mat[1][1];
+       rmat[1][2] = mat[2][1];
+       rmat[2][0] = mat[0][2];
+       rmat[2][1] = mat[1][2];
+       rmat[2][2] = mat[2][2];
+}
+
+/* seems obscure but in-fact a common operation */
+void transpose_m3_m4(float rmat[3][3], float mat[4][4])
+{
+       BLI_assert(&rmat[0][0] != &mat[0][0]);
+
+       rmat[0][0] = mat[0][0];
+       rmat[0][1] = mat[1][0];
+       rmat[0][2] = mat[2][0];
+       rmat[1][0] = mat[0][1];
+       rmat[1][1] = mat[1][1];
+       rmat[1][2] = mat[2][1];
+       rmat[2][0] = mat[0][2];
+       rmat[2][1] = mat[1][2];
+       rmat[2][2] = mat[2][2];
+}
+
 void transpose_m4(float mat[4][4])
 {
        float t;
@@ -892,6 +933,28 @@ void transpose_m4(float mat[4][4])
        mat[3][2] = t;
 }
 
+void transpose_m4_m4(float rmat[4][4], float mat[4][4])
+{
+       BLI_assert(rmat != mat);
+
+       rmat[0][0] = mat[0][0];
+       rmat[0][1] = mat[1][0];
+       rmat[0][2] = mat[2][0];
+       rmat[0][3] = mat[3][0];
+       rmat[1][0] = mat[0][1];
+       rmat[1][1] = mat[1][1];
+       rmat[1][2] = mat[2][1];
+       rmat[1][3] = mat[3][1];
+       rmat[2][0] = mat[0][2];
+       rmat[2][1] = mat[1][2];
+       rmat[2][2] = mat[2][2];
+       rmat[2][3] = mat[3][2];
+       rmat[3][0] = mat[0][3];
+       rmat[3][1] = mat[1][3];
+       rmat[3][2] = mat[2][3];
+       rmat[3][3] = mat[3][3];
+}
+
 int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit)
 {
        if (compare_v4v4(mat1[0], mat2[0], limit))
@@ -1135,8 +1198,7 @@ bool is_uniform_scaled_m3(float m[3][3])
        float t[3][3];
        float l1, l2, l3, l4, l5, l6;
 
-       copy_m3_m3(t, m);
-       transpose_m3(t);
+       transpose_m3_m3(t, m);
 
        l1 = len_squared_v3(m[0]);
        l2 = len_squared_v3(m[1]);
@@ -1403,9 +1465,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
        /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
        normalize_m3_m3(mat3_n, mat3);
        if (is_negative_m3(mat3)) {
-               negate_v3(mat3_n[0]);
-               negate_v3(mat3_n[1]);
-               negate_v3(mat3_n[2]);
+               negate_m3(mat3_n);
        }
 
        /* rotation */
@@ -1415,11 +1475,19 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3])
        /* scale */
        /* note: mat4_to_size(ob->size, mat) fails for negative scale */
        invert_m3_m3(imat3_n, mat3_n);
+
+       /* better not edit mat3 */
+#if 0
        mul_m3_m3m3(mat3, imat3_n, mat3);
 
        size[0] = mat3[0][0];
        size[1] = mat3[1][1];
        size[2] = mat3[2][2];
+#else
+       size[0] = dot_m3_v3_row_x(imat3_n, mat3[0]);
+       size[1] = dot_m3_v3_row_y(imat3_n, mat3[1]);
+       size[2] = dot_m3_v3_row_z(imat3_n, mat3[2]);
+#endif
 }
 
 void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4])
@@ -1444,9 +1512,7 @@ void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4])
        /* so scale doesn't interfere with rotation [#24291] */
        /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
        if (is_negative_m3(mat3)) {
-               negate_v3(mat3_n[0]);
-               negate_v3(mat3_n[1]);
-               negate_v3(mat3_n[2]);
+               negate_m3(mat3_n);
        }
 
        mat3_to_quat(quat, mat3_n);