diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_matrix.c')
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 216 |
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 */ |