static inline int m4_inverse(double *mr, double *ma) { double mtemp[9], mdet = m4_det(ma); int i, j, sign; if (fabs(mdet) == 0.0) return 0; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { sign = 1 - ((i +j) % 2) * 2; m4_submat(ma, mtemp, i, j); mr[i+j*4] = (m3_det(mtemp) * sign) / mdet; } } return 1; }
int m4x4_invert(m4x4_t matrix) { float mdet = m4_det( matrix ); m3x3_t mtemp; int i, j, sign; m4x4_t m4x4_temp; if ( fabs( mdet ) < 0.0000000001 ) //% 0.0005 return 1; memcpy(m4x4_temp, matrix, sizeof(m4x4_t)); for ( i = 0; i < 4; i++ ) for ( j = 0; j < 4; j++ ) { sign = 1 - ( (i +j) % 2 ) * 2; m4_submat( m4x4_temp, mtemp, i, j ); matrix[i+j*4] = ( m3_det( mtemp ) * sign ) / mdet; } return 0; }
static void ExtrapolateTexcoords( const float *axyz, const float *ast, const float *bxyz, const float *bst, const float *cxyz, const float *cst, const float *axyz_new, float *ast_out, const float *bxyz_new, float *bst_out, const float *cxyz_new, float *cst_out ){ vec4_t scoeffs, tcoeffs; float md; m4x4_t solvematrix; vec3_t norm; vec3_t dab, dac; VectorSubtract( bxyz, axyz, dab ); VectorSubtract( cxyz, axyz, dac ); CrossProduct( dab, dac, norm ); // assume: // s = f(x, y, z) // s(v + norm) = s(v) when n ortho xyz // s(v) = DotProduct(v, scoeffs) + scoeffs[3] // solve: // scoeffs * (axyz, 1) == ast[0] // scoeffs * (bxyz, 1) == bst[0] // scoeffs * (cxyz, 1) == cst[0] // scoeffs * (norm, 0) == 0 // scoeffs * [axyz, 1 | bxyz, 1 | cxyz, 1 | norm, 0] = [ast[0], bst[0], cst[0], 0] solvematrix[0] = axyz[0]; solvematrix[4] = axyz[1]; solvematrix[8] = axyz[2]; solvematrix[12] = 1; solvematrix[1] = bxyz[0]; solvematrix[5] = bxyz[1]; solvematrix[9] = bxyz[2]; solvematrix[13] = 1; solvematrix[2] = cxyz[0]; solvematrix[6] = cxyz[1]; solvematrix[10] = cxyz[2]; solvematrix[14] = 1; solvematrix[3] = norm[0]; solvematrix[7] = norm[1]; solvematrix[11] = norm[2]; solvematrix[15] = 0; md = m4_det( solvematrix ); if ( md * md < 1e-10 ) { Sys_Printf( "Cannot invert some matrix, some texcoords aren't extrapolated!" ); return; } m4x4_invert( solvematrix ); scoeffs[0] = ast[0]; scoeffs[1] = bst[0]; scoeffs[2] = cst[0]; scoeffs[3] = 0; m4x4_transform_vec4( solvematrix, scoeffs ); tcoeffs[0] = ast[1]; tcoeffs[1] = bst[1]; tcoeffs[2] = cst[1]; tcoeffs[3] = 0; m4x4_transform_vec4( solvematrix, tcoeffs ); ast_out[0] = scoeffs[0] * axyz_new[0] + scoeffs[1] * axyz_new[1] + scoeffs[2] * axyz_new[2] + scoeffs[3]; ast_out[1] = tcoeffs[0] * axyz_new[0] + tcoeffs[1] * axyz_new[1] + tcoeffs[2] * axyz_new[2] + tcoeffs[3]; bst_out[0] = scoeffs[0] * bxyz_new[0] + scoeffs[1] * bxyz_new[1] + scoeffs[2] * bxyz_new[2] + scoeffs[3]; bst_out[1] = tcoeffs[0] * bxyz_new[0] + tcoeffs[1] * bxyz_new[1] + tcoeffs[2] * bxyz_new[2] + tcoeffs[3]; cst_out[0] = scoeffs[0] * cxyz_new[0] + scoeffs[1] * cxyz_new[1] + scoeffs[2] * cxyz_new[2] + scoeffs[3]; cst_out[1] = tcoeffs[0] * cxyz_new[0] + tcoeffs[1] * cxyz_new[1] + tcoeffs[2] * cxyz_new[2] + tcoeffs[3]; }