Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern/math_matrix.c')
-rw-r--r--source/blender/blenlib/intern/math_matrix.c216
1 files changed, 196 insertions, 20 deletions
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 888587e055c..228bb1008b1 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -186,26 +186,7 @@ void mul_m4_m4m4(float m1[4][4], float m3_[4][4], float m2_[4][4])
copy_m4_m4(m3, m3_);
/* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0] + m2[0][3] * m3[3][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1] + m2[0][3] * m3[3][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2] + m2[0][3] * m3[3][2];
- m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3] + m2[0][3] * m3[3][3];
-
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0] + m2[1][3] * m3[3][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1] + m2[1][3] * m3[3][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2] + m2[1][3] * m3[3][2];
- m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3] + m2[1][3] * m3[3][3];
-
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0] + m2[2][3] * m3[3][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1] + m2[2][3] * m3[3][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2] + m2[2][3] * m3[3][2];
- m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3] + m2[2][3] * m3[3][3];
-
- m1[3][0] = m2[3][0] * m3[0][0] + m2[3][1] * m3[1][0] + m2[3][2] * m3[2][0] + m2[3][3] * m3[3][0];
- m1[3][1] = m2[3][0] * m3[0][1] + m2[3][1] * m3[1][1] + m2[3][2] * m3[2][1] + m2[3][3] * m3[3][1];
- m1[3][2] = m2[3][0] * m3[0][2] + m2[3][1] * m3[1][2] + m2[3][2] * m3[2][2] + m2[3][3] * m3[3][2];
- m1[3][3] = m2[3][0] * m3[0][3] + m2[3][1] * m3[1][3] + m2[3][2] * m3[2][3] + m2[3][3] * m3[3][3];
-
+ mul_m4_m4m4_q(m1, m3, m2);
}
void mul_m3_m3m3(float m1[3][3], float m3_[3][3], float m2_[3][3])
@@ -291,6 +272,88 @@ void mul_m4_m3m4(float m1[4][4], float m3_[3][3], float m2_[4][4])
m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
+void mul_m4_m4m4_q(float m1[4][4], float m3[4][4], float m2[4][4])
+{
+ /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0] + m2[0][3] * m3[3][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1] + m2[0][3] * m3[3][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2] + m2[0][3] * m3[3][2];
+ m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3] + m2[0][3] * m3[3][3];
+
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0] + m2[1][3] * m3[3][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1] + m2[1][3] * m3[3][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2] + m2[1][3] * m3[3][2];
+ m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3] + m2[1][3] * m3[3][3];
+
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0] + m2[2][3] * m3[3][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1] + m2[2][3] * m3[3][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2] + m2[2][3] * m3[3][2];
+ m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3] + m2[2][3] * m3[3][3];
+
+ m1[3][0] = m2[3][0] * m3[0][0] + m2[3][1] * m3[1][0] + m2[3][2] * m3[2][0] + m2[3][3] * m3[3][0];
+ m1[3][1] = m2[3][0] * m3[0][1] + m2[3][1] * m3[1][1] + m2[3][2] * m3[2][1] + m2[3][3] * m3[3][1];
+ m1[3][2] = m2[3][0] * m3[0][2] + m2[3][1] * m3[1][2] + m2[3][2] * m3[2][2] + m2[3][3] * m3[3][2];
+ m1[3][3] = m2[3][0] * m3[0][3] + m2[3][1] * m3[1][3] + m2[3][2] * m3[2][3] + m2[3][3] * m3[3][3];
+}
+
+void mul_m4_m3m4_q(float m1[4][4], float m3[4][4], float m2[3][3])
+{
+ /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ m1[0][3] = m2[0][0] * m3[0][3] + m2[0][1] * m3[1][3] + m2[0][2] * m3[2][3];
+
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[1][3] = m2[1][0] * m3[0][3] + m2[1][1] * m3[1][3] + m2[1][2] * m3[2][3];
+
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[2][3] = m2[2][0] * m3[0][3] + m2[2][1] * m3[1][3] + m2[2][2] * m3[2][3];
+
+ m1[3][0] = m3[3][0];
+ m1[3][1] = m3[3][1];
+ m1[3][2] = m3[3][2];
+ m1[3][3] = m3[3][3];
+}
+
+
+
+void mul_serie_m3(float answ[3][3],
+ float m1[3][3], float m2[3][3], float m3[3][3],
+ float m4[3][3], float m5[3][3], float m6[3][3],
+ float m7[3][3], float m8[3][3])
+{
+ float temp[3][3];
+
+ if (m1 == NULL || m2 == NULL) return;
+
+ mul_m3_m3m3(answ, m2, m1);
+ if (m3) {
+ mul_m3_m3m3(temp, m3, answ);
+ if (m4) {
+ mul_m3_m3m3(answ, m4, temp);
+ if (m5) {
+ mul_m3_m3m3(temp, m5, answ);
+ if (m6) {
+ mul_m3_m3m3(answ, m6, temp);
+ if (m7) {
+ mul_m3_m3m3(temp, m7, answ);
+ if (m8) {
+ mul_m3_m3m3(answ, m8, temp);
+ }
+ else copy_m3_m3(answ, temp);
+ }
+ }
+ else copy_m3_m3(answ, temp);
+ }
+ }
+ else copy_m3_m3(answ, temp);
+ }
+}
/** \name Macro helpers for: mul_m3_series
* \{ */
@@ -493,6 +556,22 @@ void mul_m2v2(float mat[2][2], float vec[2])
mul_v2_m2v2(vec, mat, vec);
}
+void mul_v4_m4v3(float out[4], float mat[][4], const float vec[3])
+{
+ out[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ out[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ out[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+ out[3] = vec[0] * mat[0][3] + vec[1] * mat[1][3] + mat[2][3] * vec[2] + mat[3][3];
+}
+
+void mul_v3_m4v3_q(float out[3], float mat[][4], const float vec[3])
+{
+ out[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ out[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ out[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+
+}
+
/* same as mul_m4_v3() but doesnt apply translation component */
void mul_mat3_m4_v3(float mat[4][4], float vec[3])
{
@@ -1478,11 +1557,19 @@ void scale_m4_fl(float m[4][4], float scale)
m[3][0] = m[3][1] = m[3][2] = 0.0;
}
+void scale_m4(float m[][4], float x, float y, float z)
+{
+ m[0][0]*=x; m[0][1]*=x; m[0][2]*=x; m[0][3]*=x;
+ m[1][0]*=y; m[1][1]*=y; m[1][2]*=y; m[1][3]*=y;
+ m[2][0]*=z; m[2][1]*=z; m[2][2]*=z; m[2][3]*=z;
+}
+
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
+ mat[3][3] += (Tx * mat[0][3] + Ty * mat[1][3] + Tz * mat[2][3]);
}
void rotate_m4(float mat[4][4], const char axis, const float angle)
@@ -1554,6 +1641,60 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
mul_m4_m4m4(mat, mat, tmat);
}
+void rotate_m4_right(float mat[][4], const char axis)
+{
+#define COORD(x,y) (4*x + y)
+ const static char mrotx[] = {1, 2};
+ const static char mrotxn[] = {2, 1};
+
+ const static char mroty[] = {2, 0};
+ const static char mrotyn[] = {0, 2};
+
+ const static char mrotz[] = {0, 1};
+ const static char mrotzn[] = {1, 0};
+
+#undef COORD
+
+ const char * rotmat;
+ float tmpf;
+ int i;
+
+
+ switch(axis)
+ {
+ case 'X':
+ rotmat = mrotx;
+ break;
+ case (char)-'X':
+ rotmat = mrotxn;
+ break;
+ case 'Y':
+ rotmat = mroty;
+ break;
+ case (char)-'Y':
+ rotmat = mrotyn;
+ break;
+ case 'Z':
+ rotmat = mrotz;
+ break;
+ case (char)-'Z':
+ rotmat = mrotzn;
+ break;
+ default:
+ BLI_assert(0);
+
+ }
+
+ for(i=0; i<3; i++)
+ {
+ tmpf = mat[rotmat[1]][i];
+ mat[rotmat[1]][i] = -1.0f*mat[rotmat[0]][i];
+ mat[rotmat[0]][i] = tmpf;
+
+ }
+
+}
+
void blend_m3_m3m3(float out[3][3], float dst[3][3], float src[3][3], const float srcweight)
{
float srot[3][3], drot[3][3];
@@ -2194,6 +2335,41 @@ void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon)
mul_m4_series(Ainv, U, Wm, V);
}
+void mat4_ortho_set(float m[][4], float left, float right, float bottom, float top, float nearVal, float farVal)
+{
+ m[0][0] = 2/(right-left); m[1][0] = 0; m[2][0] = 0; m[3][0] = -(right+left)/(right-left);
+ m[0][1] = 0; m[1][1] = 2/(top-bottom); m[2][1] = 0; m[3][1] = -(top+bottom)/(top-bottom);
+ m[0][2] = 0; m[1][2] = 0; m[2][2] = -2/(farVal-nearVal); m[3][2] = -(farVal+nearVal)/(farVal-nearVal);
+ m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
+}
+
+void mat4_frustum_set(float m[][4], float left, float right, float bottom, float top, float nearVal, float farVal)
+{
+ m[0][0] = 2*nearVal/(right-left); m[1][0] = 0; m[2][0] = (right+left)/(right-left); m[3][0] = 0;
+ m[0][1] = 0; m[1][1] = 2*nearVal/(top-bottom); m[2][1] = (top+bottom)/(top-bottom); m[3][1] = 0;
+ m[0][2] = 0; m[1][2] = 0; m[2][2] = -(farVal+nearVal)/(farVal-nearVal); m[3][2] = -2*farVal*nearVal/(farVal-nearVal);
+ m[0][3] = 0; m[1][3] = 0; m[2][3] = -1; m[3][3] = 0;
+}
+
+/* Loosly based on Mesa implementation of gluLookAt */
+void mat4_look_from_origin(float m[4][4], float lookdir[3], float camup[3])
+{
+ float side[3];
+
+ normalize_v3(lookdir);
+
+ cross_v3_v3v3(side, lookdir, camup);
+
+ normalize_v3(side);
+
+ cross_v3_v3v3(camup, side, lookdir);
+
+ m[0][0] = side [0]; m[1][0] = side [1]; m[2][0] = side [2]; m[3][0] = 0;
+ m[0][1] = camup [0]; m[1][1] = camup [1]; m[2][1] = camup [2]; m[3][1] = 0;
+ m[0][2] = -lookdir[0]; m[1][2] = -lookdir[1]; m[2][2] = -lookdir[2]; m[3][2] = 0;
+ m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
+}
+
void pseudoinverse_m3_m3(float Ainv[3][3], float A[3][3], float epsilon)
{
/* try regular inverse when possible, otherwise fall back to slow svd */