#include #include #include "matrix.h" //using namespace mallie; static inline float vdot(float a[3], float b[3]) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } static inline void vcross(float c[3], float a[3], float b[3]) { c[0] = a[1] * b[2] - a[2] * b[1]; c[1] = a[2] * b[0] - a[0] * b[2]; c[2] = a[0] * b[1] - a[1] * b[0]; } static inline float vlength(float v[3]) { float len2 = vdot(v, v); if (std::abs(len2) > 1.0e-30) { return sqrt(len2); } return 0.0f; } static void vnormalize(float v[3]) { float len = vlength(v); if (std::abs(len) > 1.0e-30) { float inv_len = 1.0f / len; v[0] *= inv_len; v[1] *= inv_len; v[2] *= inv_len; } } void Matrix::Print(float m[4][4]) { for (int i = 0; i < 4; i++) { printf("m[%d] = %f, %f, %f, %f\n", i, m[i][0], m[i][1], m[i][2], m[i][3]); } } void Matrix::LookAt(float m[4][4], float eye[3], float lookat[3], float up[3]) { float u[3], v[3]; float look[3]; look[0] = lookat[0] - eye[0]; look[1] = lookat[1] - eye[1]; look[2] = lookat[2] - eye[2]; vnormalize(look); vcross(u, look, up); vnormalize(u); vcross(v, u, look); vnormalize(v); #if 0 m[0][0] = u[0]; m[0][1] = v[0]; m[0][2] = -look[0]; m[0][3] = 0.0; m[1][0] = u[1]; m[1][1] = v[1]; m[1][2] = -look[1]; m[1][3] = 0.0; m[2][0] = u[2]; m[2][1] = v[2]; m[2][2] = -look[2]; m[2][3] = 0.0; m[3][0] = eye[0]; m[3][1] = eye[1]; m[3][2] = eye[2]; m[3][3] = 1.0; #else m[0][0] = u[0]; m[1][0] = v[0]; m[2][0] = -look[0]; m[3][0] = eye[0]; m[0][1] = u[1]; m[1][1] = v[1]; m[2][1] = -look[1]; m[3][1] = eye[1]; m[0][2] = u[2]; m[1][2] = v[2]; m[2][2] = -look[2]; m[3][2] = eye[2]; m[0][3] = 0.0; m[1][3] = 0.0; m[2][3] = 0.0; m[3][3] = 1.0; #endif } void Matrix::Inverse(float m[4][4]) { /* * codes from intel web * cramer's rule version */ int i, j; float tmp[12]; /* tmp array for pairs */ float tsrc[16]; /* array of transpose source matrix */ float det; /* determinant */ /* transpose matrix */ for (i = 0; i < 4; i++) { tsrc[i] = m[i][0]; tsrc[i + 4] = m[i][1]; tsrc[i + 8] = m[i][2]; tsrc[i + 12] = m[i][3]; } /* calculate pair for first 8 elements(cofactors) */ tmp[0] = tsrc[10] * tsrc[15]; tmp[1] = tsrc[11] * tsrc[14]; tmp[2] = tsrc[9] * tsrc[15]; tmp[3] = tsrc[11] * tsrc[13]; tmp[4] = tsrc[9] * tsrc[14]; tmp[5] = tsrc[10] * tsrc[13]; tmp[6] = tsrc[8] * tsrc[15]; tmp[7] = tsrc[11] * tsrc[12]; tmp[8] = tsrc[8] * tsrc[14]; tmp[9] = tsrc[10] * tsrc[12]; tmp[10] = tsrc[8] * tsrc[13]; tmp[11] = tsrc[9] * tsrc[12]; /* calculate first 8 elements(cofactors) */ m[0][0] = tmp[0] * tsrc[5] + tmp[3] * tsrc[6] + tmp[4] * tsrc[7]; m[0][0] -= tmp[1] * tsrc[5] + tmp[2] * tsrc[6] + tmp[5] * tsrc[7]; m[0][1] = tmp[1] * tsrc[4] + tmp[6] * tsrc[6] + tmp[9] * tsrc[7]; m[0][1] -= tmp[0] * tsrc[4] + tmp[7] * tsrc[6] + tmp[8] * tsrc[7]; m[0][2] = tmp[2] * tsrc[4] + tmp[7] * tsrc[5] + tmp[10] * tsrc[7]; m[0][2] -= tmp[3] * tsrc[4] + tmp[6] * tsrc[5] + tmp[11] * tsrc[7]; m[0][3] = tmp[5] * tsrc[4] + tmp[8] * tsrc[5] + tmp[11] * tsrc[6]; m[0][3] -= tmp[4] * tsrc[4] + tmp[9] * tsrc[5] + tmp[10] * tsrc[6]; m[1][0] = tmp[1] * tsrc[1] + tmp[2] * tsrc[2] + tmp[5] * tsrc[3]; m[1][0] -= tmp[0] * tsrc[1] + tmp[3] * tsrc[2] + tmp[4] * tsrc[3]; m[1][1] = tmp[0] * tsrc[0] + tmp[7] * tsrc[2] + tmp[8] * tsrc[3]; m[1][1] -= tmp[1] * tsrc[0] + tmp[6] * tsrc[2] + tmp[9] * tsrc[3]; m[1][2] = tmp[3] * tsrc[0] + tmp[6] * tsrc[1] + tmp[11] * tsrc[3]; m[1][2] -= tmp[2] * tsrc[0] + tmp[7] * tsrc[1] + tmp[10] * tsrc[3]; m[1][3] = tmp[4] * tsrc[0] + tmp[9] * tsrc[1] + tmp[10] * tsrc[2]; m[1][3] -= tmp[5] * tsrc[0] + tmp[8] * tsrc[1] + tmp[11] * tsrc[2]; /* calculate pairs for second 8 elements(cofactors) */ tmp[0] = tsrc[2] * tsrc[7]; tmp[1] = tsrc[3] * tsrc[6]; tmp[2] = tsrc[1] * tsrc[7]; tmp[3] = tsrc[3] * tsrc[5]; tmp[4] = tsrc[1] * tsrc[6]; tmp[5] = tsrc[2] * tsrc[5]; tmp[6] = tsrc[0] * tsrc[7]; tmp[7] = tsrc[3] * tsrc[4]; tmp[8] = tsrc[0] * tsrc[6]; tmp[9] = tsrc[2] * tsrc[4]; tmp[10] = tsrc[0] * tsrc[5]; tmp[11] = tsrc[1] * tsrc[4]; /* calculate second 8 elements(cofactors) */ m[2][0] = tmp[0] * tsrc[13] + tmp[3] * tsrc[14] + tmp[4] * tsrc[15]; m[2][0] -= tmp[1] * tsrc[13] + tmp[2] * tsrc[14] + tmp[5] * tsrc[15]; m[2][1] = tmp[1] * tsrc[12] + tmp[6] * tsrc[14] + tmp[9] * tsrc[15]; m[2][1] -= tmp[0] * tsrc[12] + tmp[7] * tsrc[14] + tmp[8] * tsrc[15]; m[2][2] = tmp[2] * tsrc[12] + tmp[7] * tsrc[13] + tmp[10] * tsrc[15]; m[2][2] -= tmp[3] * tsrc[12] + tmp[6] * tsrc[13] + tmp[11] * tsrc[15]; m[2][3] = tmp[5] * tsrc[12] + tmp[8] * tsrc[13] + tmp[11] * tsrc[14]; m[2][3] -= tmp[4] * tsrc[12] + tmp[9] * tsrc[13] + tmp[10] * tsrc[14]; m[3][0] = tmp[2] * tsrc[10] + tmp[5] * tsrc[11] + tmp[1] * tsrc[9]; m[3][0] -= tmp[4] * tsrc[11] + tmp[0] * tsrc[9] + tmp[3] * tsrc[10]; m[3][1] = tmp[8] * tsrc[11] + tmp[0] * tsrc[8] + tmp[7] * tsrc[10]; m[3][1] -= tmp[6] * tsrc[10] + tmp[9] * tsrc[11] + tmp[1] * tsrc[8]; m[3][2] = tmp[6] * tsrc[9] + tmp[11] * tsrc[11] + tmp[3] * tsrc[8]; m[3][2] -= tmp[10] * tsrc[11] + tmp[2] * tsrc[8] + tmp[7] * tsrc[9]; m[3][3] = tmp[10] * tsrc[10] + tmp[4] * tsrc[8] + tmp[9] * tsrc[9]; m[3][3] -= tmp[8] * tsrc[9] + tmp[11] * tsrc[0] + tmp[5] * tsrc[8]; /* calculate determinant */ det = tsrc[0] * m[0][0] + tsrc[1] * m[0][1] + tsrc[2] * m[0][2] + tsrc[3] * m[0][3]; /* calculate matrix inverse */ det = 1.0f / det; for (j = 0; j < 4; j++) { for (i = 0; i < 4; i++) { m[j][i] *= det; } } } void Matrix::Mult(float dst[4][4], float m0[4][4], float m1[4][4]) { for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { dst[i][j] = 0; for (int k = 0; k < 4; ++k) { dst[i][j] += m0[k][j] * m1[i][k]; } } } } void Matrix::MultV(float dst[3], float m[4][4], float v[3]) { // printf("v = %f, %f, %f\n", v[0], v[1], v[2]); dst[0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0]; dst[1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1]; dst[2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2]; // printf("m = %f, %f, %f\n", m[3][0], m[3][1], m[3][2]); // printf("dst = %f, %f, %f\n", dst[0], dst[1], dst[2]); }