il_mat il_mat_transpose(il_mat a) { il_mat res = il_mat_identity(); int x, y; for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { res.data[y*4 + x] = a.data[x*4 + y]; } } return res; }
il_mat il_mat_invert(il_mat a) { il_mat res = il_mat_identity(); // for every column .. for (int col = 0; col < 4; ++col) { float diagonalfield = a.data[col*4+col]; // if we have a weird matrix with zero on the diagonal .. float eps = 0.0001; if (fabs(diagonalfield) < eps) { // SIIIGH. // Okay, let's go hunting for a row with a better diagonal to use // keep in mind, row swapping is also a linear operation! for (int row = 0; row < 4; ++row) if (row != col) if (fabs(a.data[row*4+col]) >= eps) { swaprow(&a, row, col); swaprow(&res,row, col); } diagonalfield = a.data[col*4+col]; // recompute // if it still fails, we probably have a denatured matrix and are proper f****d. assert(fabs(diagonalfield) >= eps); } // for every row .. for (int row = 0; row < 4; ++row) { // if it's not on the diagonal .. if (row != col) { float field = a.data[row*4+col]; // bring this field to 0 by subtracting the row that's on the diagonal for this column addrow(&a, /* src */ col, /* dst */ row, /* factor */ -field/diagonalfield); // do the same to identity addrow(&res,/* src */ col, /* dst */ row, /* factor */ -field/diagonalfield); } } // and finally, bring the diagonal to 1 mulrow(&a, col, 1/diagonalfield); mulrow(&res,col, 1/diagonalfield); } // Success! Because a is now id, res is now a^-1. Math is fun! return res; }
void camera_init(void *self) { ilG_camera* camera = self; camera->projection_matrix = il_mat_identity(NULL); camera->sensitivity = 0.002; }