static inline void cgm_mcopy(float *dest, const float *src) { memcpy(dest, src, 16 * sizeof(float)); } static inline void cgm_mzero(float *m) { static float z[16]; cgm_mcopy(m, z); } static inline void cgm_midentity(float *m) { static float id[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; cgm_mcopy(m, id); } static inline void cgm_mmul(float *a, const float *b) { int i, j; float res[16]; float *resptr = res; float *arow = a; for(i=0; i<4; i++) { for(j=0; j<4; j++) { *resptr++ = arow[0] * b[j] + arow[1] * b[4 + j] + arow[2] * b[8 + j] + arow[3] * b[12 + j]; } arow += 4; } cgm_mcopy(a, res); } static inline void cgm_msubmatrix(float *m, int row, int col) { float orig[16]; int i, j, subi, subj; cgm_mcopy(orig, m); subi = 0; for(i=0; i<4; i++) { if(i == col) continue; subj = 0; for(j=0; j<4; j++) { if(j == row) continue; m[subi * 4 + subj++] = orig[i * 4 + j]; } subi++; } cgm_mupper3(m); } static inline void cgm_mupper3(float *m) { m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0.0f; m[15] = 1.0f; } static inline float cgm_msubdet(float *m, int row, int col) { cgm_msubmatrix(m, row, col); return cgm_mdet(m); } static inline float cgm_mcofactor(float *m, int row, int col) { float min = cgm_msubdet(m, row, col); return (row + col) & 1 ? -min : min; } static inline float cgm_mdet(float *m) { return m[0] * cgm_msubdet(m, 0, 0) - m[1] * cgm_msubdet(m, 0, 1) + m[2] * cgm_msubdet(m, 0, 2) - m[3] * cgm_msubdet(m, 0, 3); } static inline void cgm_mtranspose(float *m) { int i, j; for(i=0; i<4; i++) { for(j=0; j