// File: FreeSlave[P]vhlt/hlrad/qradutil.cpp
// Function: InvertMatrix(matrix_t const&, matrix_t&)
bool InvertMatrix (const matrix_t &m, matrix_t &m_inverse)
{
	double texplanes[2][4];
	double faceplane[4];
	int i;
	double texaxis[2][3];
	double normalaxis[3];
	double det, sqrlen1, sqrlen2, sqrlen3;
	double texorg[3];

	for (i = 0; i < 4; i++)
	{
		texplanes[0][i] = m.v[i][0];
		texplanes[1][i] = m.v[i][1];
		faceplane[i] = m.v[i][2];
	}

	sqrlen1 = DotProduct (texplanes[0], texplanes[0]);
	sqrlen2 = DotProduct (texplanes[1], texplanes[1]);
	sqrlen3 = DotProduct (faceplane, faceplane);
	if (sqrlen1 <= NORMAL_EPSILON * NORMAL_EPSILON || sqrlen2 <= NORMAL_EPSILON * NORMAL_EPSILON || sqrlen3 <= NORMAL_EPSILON * NORMAL_EPSILON)
		// s gradient, t gradient or face normal is too close to 0
	{
		return false;
	}

	CrossProduct (texplanes[0], texplanes[1], normalaxis);
	det = DotProduct (normalaxis, faceplane);
	if (det * det <= sqrlen1 * sqrlen2 * sqrlen3 * NORMAL_EPSILON * NORMAL_EPSILON)
		// s gradient, t gradient and face normal are coplanar
	{
		return false;
	}
	VectorScale (normalaxis, 1 / det, normalaxis);

	CrossProduct (texplanes[1], faceplane, texaxis[0]);
	VectorScale (texaxis[0], 1 / det, texaxis[0]);

	CrossProduct (faceplane, texplanes[0], texaxis[1]);
	VectorScale (texaxis[1], 1 / det, texaxis[1]);

	VectorScale (normalaxis, -faceplane[3], texorg);
	VectorMA (texorg, -texplanes[0][3], texaxis[0], texorg);
	VectorMA (texorg, -texplanes[1][3], texaxis[1], texorg);
	
	VectorCopy (texaxis[0], m_inverse.v[0]);
	VectorCopy (texaxis[1], m_inverse.v[1]);
	VectorCopy (normalaxis, m_inverse.v[2]);
	VectorCopy (texorg, m_inverse.v[3]);
	return true;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movl $0x0, 0x1c(%rsp)
cmpl $0x4, 0x1c(%rsp)
jge 0x5e1d1
movq 0x88(%rsp), %rax
movslq 0x1c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movslq 0x1c(%rsp), %rax
movsd %xmm0, 0x40(%rsp,%rax,8)
movq 0x88(%rsp), %rax
movslq 0x1c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movslq 0x1c(%rsp), %rax
movsd %xmm0, 0x60(%rsp,%rax,8)
movq 0x88(%rsp), %rax
movslq 0x1c(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movslq 0x1c(%rsp), %rax
movsd %xmm0, 0x20(%rsp,%rax,8)
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x5e13f
movsd 0x40(%rsp), %xmm1
movsd 0x40(%rsp), %xmm2
movsd 0x48(%rsp), %xmm0
mulsd 0x48(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
movsd 0x50(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x50(%rsp)
movsd 0x60(%rsp), %xmm1
movsd 0x60(%rsp), %xmm2
movsd 0x68(%rsp), %xmm0
mulsd 0x68(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
movsd 0x70(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x58(%rsp)
movsd 0x20(%rsp), %xmm1
movsd 0x20(%rsp), %xmm2
movsd 0x28(%rsp), %xmm0
mulsd 0x28(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x30(%rsp), %xmm0
movsd 0x30(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x60(%rsp)
movsd 0x13609(%rip), %xmm0    # 0x71890
ucomisd -0x50(%rsp), %xmm0
jae 0x5e2af
movsd 0x135f9(%rip), %xmm0    # 0x71890
ucomisd -0x58(%rsp), %xmm0
jae 0x5e2af
movsd 0x135e9(%rip), %xmm0    # 0x71890
ucomisd -0x60(%rsp), %xmm0
jb 0x5e2bc
movb $0x0, 0x97(%rsp)
jmp 0x5e959
movsd 0x48(%rsp), %xmm0
movsd 0x70(%rsp), %xmm2
movsd 0x50(%rsp), %xmm1
mulsd 0x68(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rsp)
movsd 0x50(%rsp), %xmm0
movsd 0x60(%rsp), %xmm2
movsd 0x40(%rsp), %xmm1
mulsd 0x70(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rsp)
movsd 0x40(%rsp), %xmm0
movsd 0x68(%rsp), %xmm2
movsd 0x48(%rsp), %xmm1
mulsd 0x60(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rsp)
movsd -0x40(%rsp), %xmm1
movsd 0x20(%rsp), %xmm2
movsd -0x38(%rsp), %xmm0
mulsd 0x28(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd -0x30(%rsp), %xmm0
movsd 0x30(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x48(%rsp)
movsd -0x48(%rsp), %xmm1
mulsd -0x48(%rsp), %xmm1
movsd -0x50(%rsp), %xmm0
mulsd -0x58(%rsp), %xmm0
mulsd -0x60(%rsp), %xmm0
movsd 0xbc95(%rip), %xmm2     # 0x6a068
mulsd %xmm2, %xmm0
movsd 0xbc89(%rip), %xmm2     # 0x6a068
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x5e3f6
movb $0x0, 0x97(%rsp)
jmp 0x5e959
movsd -0x40(%rsp), %xmm0
movsd 0xede4(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x40(%rsp)
movsd -0x38(%rsp), %xmm0
movsd 0xedc6(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x38(%rsp)
movsd -0x30(%rsp), %xmm0
movsd 0xeda8(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x30(%rsp)
movsd 0x68(%rsp), %xmm0
movsd 0x30(%rsp), %xmm2
movsd 0x70(%rsp), %xmm1
mulsd 0x28(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rsp)
movsd 0x70(%rsp), %xmm0
movsd 0x20(%rsp), %xmm2
movsd 0x60(%rsp), %xmm1
mulsd 0x30(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rsp)
movsd 0x60(%rsp), %xmm0
movsd 0x28(%rsp), %xmm2
movsd 0x68(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x10(%rsp)
movsd -0x20(%rsp), %xmm0
movsd 0xecd3(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rsp)
movsd -0x18(%rsp), %xmm0
movsd 0xecb5(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x18(%rsp)
movsd -0x10(%rsp), %xmm0
movsd 0xec97(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x10(%rsp)
movsd 0x28(%rsp), %xmm0
movsd 0x50(%rsp), %xmm2
movsd 0x30(%rsp), %xmm1
mulsd 0x48(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rsp)
movsd 0x30(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
movsd 0x20(%rsp), %xmm1
mulsd 0x50(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rsp)
movsd 0x20(%rsp), %xmm0
movsd 0x48(%rsp), %xmm2
movsd 0x28(%rsp), %xmm1
mulsd 0x40(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd -0x8(%rsp), %xmm0
movsd 0xebc3(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x8(%rsp)
movsd (%rsp), %xmm0
movsd 0xeba6(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, (%rsp)
movsd 0x8(%rsp), %xmm0
movsd 0xeb89(%rip), %xmm1     # 0x6d1e8
divsd -0x48(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd -0x40(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rsp)
movsd -0x38(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rsp)
movsd -0x30(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rsp)
movsd -0x80(%rsp), %xmm1
movsd 0x58(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x20(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rsp)
movsd -0x78(%rsp), %xmm1
movsd 0x58(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x18(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rsp)
movsd -0x70(%rsp), %xmm1
movsd 0x58(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x10(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rsp)
movsd -0x80(%rsp), %xmm1
movsd 0x78(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd -0x8(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x80(%rsp)
movsd -0x78(%rsp), %xmm1
movsd 0x78(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd (%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rsp)
movsd -0x70(%rsp), %xmm1
movsd 0x78(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd 0x8(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rsp)
movsd -0x20(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, (%rax)
movsd -0x18(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x4(%rax)
movsd -0x10(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x8(%rax)
movsd -0x8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0xc(%rax)
movsd (%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x10(%rax)
movsd 0x8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x14(%rax)
movsd -0x40(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x18(%rax)
movsd -0x38(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x1c(%rax)
movsd -0x30(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x20(%rax)
movsd -0x80(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x24(%rax)
movsd -0x78(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x28(%rax)
movsd -0x70(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x80(%rsp), %rax
movss %xmm0, 0x2c(%rax)
movb $0x1, 0x97(%rsp)
movb 0x97(%rsp), %al
andb $0x1, %al
addq $0x98, %rsp
retq
nopw (%rax,%rax)