// File: FreeSlave[P]vhlt/hlrad/mathutil.cpp
// Function: GetAlternateOrigin(float const*, float const*, patch_s const*, float (&) [3])
void GetAlternateOrigin (const vec3_t pos, const vec3_t normal, const patch_t *patch, vec3_t &origin)
{
	const dplane_t *faceplane;
	const vec_t *faceplaneoffset;
	const vec_t *facenormal;
	dplane_t clipplane;
	Winding w;

	faceplane = getPlaneFromFaceNumber (patch->faceNumber);
	faceplaneoffset = g_face_offset[patch->faceNumber];
	facenormal = faceplane->normal;
	VectorCopy (normal, clipplane.normal);
	clipplane.dist = DotProduct (pos, clipplane.normal);
	
	w = *patch->winding;
	if (w.WindingOnPlaneSide (clipplane.normal, clipplane.dist) != SIDE_CROSS)
	{
		VectorCopy (patch->origin, origin);
	}
	else
	{
		w.Clip (clipplane, false);
		if (w.m_NumPoints == 0)
		{
			VectorCopy (patch->origin, origin);
		}
		else
		{
			vec3_t center;
			bool found;
			vec3_t bestpoint;
			vec_t bestdist = -1.0;
			vec3_t point;
			vec_t dist;
			vec3_t v;

			w.getCenter (center);
			found = false;

			VectorMA (center, PATCH_HUNT_OFFSET, facenormal, point);
			if (HuntForWorld (point, faceplaneoffset, faceplane, 2, 1.0, PATCH_HUNT_OFFSET))
			{
				VectorSubtract (point, center, v);
				dist = VectorLength (v);
				if (!found || dist < bestdist)
				{
					found = true;
					VectorCopy (point, bestpoint);
					bestdist = dist;
				}
			}
			if (!found)
			{
				for (int i = 0; i < w.m_NumPoints; i++)
				{
					const vec_t *p1;
					const vec_t *p2;
					p1 = w.m_Points[i];
					p2 = w.m_Points[(i + 1) % w.m_NumPoints];
					VectorAdd (p1, p2, point);
					VectorAdd (point, center, point);
					VectorScale (point, 1.0/3.0, point);
					VectorMA (point, PATCH_HUNT_OFFSET, facenormal, point);
					if (HuntForWorld (point, faceplaneoffset, faceplane, 1, 0.0, PATCH_HUNT_OFFSET))
					{
						VectorSubtract (point, center, v);
						dist = VectorLength (v);
						if (!found || dist < bestdist)
						{
							found = true;
							VectorCopy (point, bestpoint);
							bestdist = dist;
						}
					}
				}
			}

			if (found)
			{
				VectorCopy (bestpoint, origin);
			}
			else
			{
				VectorCopy (patch->origin, origin);
			}
		}
	}
}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq %rdx, 0xe0(%rsp)
movq %rcx, 0xd8(%rsp)
leaq 0x88(%rsp), %rdi
callq 0xe730
movq 0xe0(%rsp), %rax
movl 0x58(%rax), %edi
callq 0x5ce10
movq %rax, 0x20(%rsp)
jmp 0x4ca0b
movq 0x20(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0xe0(%rsp), %rax
movslq 0x58(%rax), %rax
leaq (%rax,%rax,2), %rcx
leaq 0x5420fe1(%rip), %rax   # 0x546da10
leaq (%rax,%rcx,4), %rax
movq %rax, 0xc8(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xe8(%rsp), %rax
movss (%rax), %xmm0
movss %xmm0, 0xac(%rsp)
movq 0xe8(%rsp), %rax
movss 0x4(%rax), %xmm0
movss %xmm0, 0xb0(%rsp)
movq 0xe8(%rsp), %rax
movss 0x8(%rax), %xmm0
movss %xmm0, 0xb4(%rsp)
movq 0xf0(%rsp), %rax
movss (%rax), %xmm1
movss 0x4(%rax), %xmm0
movss 0xac(%rsp), %xmm2
movss 0xb0(%rsp), %xmm3
mulss %xmm3, %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movss 0x8(%rax), %xmm0
movss 0xb4(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0xb8(%rsp)
movq 0xe0(%rsp), %rax
movq 0x28(%rax), %rsi
leaq 0x88(%rsp), %rdi
callq 0xe8e0
jmp 0x4caf5
movss 0xb8(%rsp), %xmm0
leaq 0x88(%rsp), %rdi
leaq 0xac(%rsp), %rsi
movss 0x2107a(%rip), %xmm1    # 0x6db90
callq 0x102f0
movl %eax, 0x1c(%rsp)
jmp 0x4cb21
movl 0x1c(%rsp), %eax
cmpl $-0x2, %eax
je 0x4cb9f
movq 0xe0(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, (%rax)
movq 0xe0(%rsp), %rax
movss 0xc(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x4(%rax)
movq 0xe0(%rsp), %rax
movss 0x10(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x8(%rax)
jmp 0x4d174
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
leaq 0x88(%rsp), %rdi
callq 0xea90
jmp 0x4d189
leaq 0x88(%rsp), %rdi
leaq 0xac(%rsp), %rsi
xorl %edx, %edx
movss 0x20fd7(%rip), %xmm0    # 0x6db90
callq 0x10450
jmp 0x4cbc0
cmpl $0x0, 0x90(%rsp)
jne 0x4cc1c
movq 0xe0(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, (%rax)
movq 0xe0(%rsp), %rax
movss 0xc(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x4(%rax)
movq 0xe0(%rsp), %rax
movss 0x10(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x8(%rax)
jmp 0x4d172
movl $0xbf800000, 0x5c(%rsp) # imm = 0xBF800000
leaq 0x88(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0xe060
jmp 0x4cc38
movb $0x0, 0x6f(%rsp)
movss 0x70(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x20891(%rip), %xmm2    # 0x6d4f0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x74(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x54(%rsp)
movss 0x78(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x58(%rsp)
movq 0xc8(%rsp), %rsi
movq 0xd0(%rsp), %rdx
leaq 0x50(%rsp), %rdi
movl $0x2, %ecx
movss 0x1d35f(%rip), %xmm0    # 0x6a04c
movss 0x21e3f(%rip), %xmm1    # 0x6eb34
callq 0x5d2d0
movq %rax, 0x10(%rsp)
jmp 0x4cd01
movq 0x10(%rsp), %rax
cmpq $0x0, %rax
je 0x4cddc
movss 0x50(%rsp), %xmm0
subss 0x70(%rsp), %xmm0
movss %xmm0, 0x40(%rsp)
movss 0x54(%rsp), %xmm0
subss 0x74(%rsp), %xmm0
movss %xmm0, 0x44(%rsp)
movss 0x58(%rsp), %xmm0
subss 0x78(%rsp), %xmm0
movss %xmm0, 0x48(%rsp)
movss 0x40(%rsp), %xmm0
mulss 0x40(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movss 0x44(%rsp), %xmm1
mulss 0x44(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
movss 0x48(%rsp), %xmm1
mulss 0x48(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
callq 0x4270
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x4c(%rsp)
testb $0x1, 0x6f(%rsp)
je 0x4cda5
movss 0x4c(%rsp), %xmm1
movss 0x5c(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x4cdda
movb $0x1, 0x6f(%rsp)
movss 0x50(%rsp), %xmm0
movss %xmm0, 0x60(%rsp)
movss 0x54(%rsp), %xmm0
movss %xmm0, 0x64(%rsp)
movss 0x58(%rsp), %xmm0
movss %xmm0, 0x68(%rsp)
movss 0x4c(%rsp), %xmm0
movss %xmm0, 0x5c(%rsp)
jmp 0x4cddc
testb $0x1, 0x6f(%rsp)
jne 0x4d0e2
movl $0x0, 0x3c(%rsp)
movl 0x3c(%rsp), %eax
cmpl 0x90(%rsp), %eax
jae 0x4d0e0
movq 0x98(%rsp), %rax
movslq 0x3c(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,4), %rax
movq %rax, 0x30(%rsp)
movq 0x98(%rsp), %rax
movq %rax, (%rsp)
movl 0x3c(%rsp), %eax
incl %eax
movl 0x90(%rsp), %ecx
xorl %edx, %edx
divl %ecx
movq (%rsp), %rax
movl %edx, %ecx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,4), %rax
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rax
movss (%rax), %xmm0
movq 0x28(%rsp), %rax
movss (%rax), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x50(%rsp)
movq 0x30(%rsp), %rax
movss 0x4(%rax), %xmm0
movq 0x28(%rsp), %rax
movss 0x4(%rax), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x54(%rsp)
movq 0x30(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0x28(%rsp), %rax
movss 0x8(%rax), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x58(%rsp)
movss 0x50(%rsp), %xmm0
movss 0x70(%rsp), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x54(%rsp), %xmm0
movss 0x74(%rsp), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x54(%rsp)
movss 0x58(%rsp), %xmm0
movss 0x78(%rsp), %xmm1
addss %xmm1, %xmm0
movss %xmm0, 0x58(%rsp)
movss 0x50(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x21c32(%rip), %xmm1    # 0x6eb28
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x54(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x54(%rsp)
movss 0x58(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x58(%rsp)
movss 0x50(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x2059a(%rip), %xmm2    # 0x6d4f0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x50(%rsp)
movss 0x54(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x54(%rsp)
movss 0x58(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movq 0xc0(%rsp), %rax
movss 0x8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x58(%rsp)
movq 0xc8(%rsp), %rsi
movq 0xd0(%rsp), %rdx
leaq 0x50(%rsp), %rdi
movl $0x1, %ecx
xorps %xmm0, %xmm0
movss 0x21b4d(%rip), %xmm1    # 0x6eb34
callq 0x5d2d0
movq %rax, 0x8(%rsp)
jmp 0x4cff3
movq 0x8(%rsp), %rax
cmpq $0x0, %rax
je 0x4d0ce
movss 0x50(%rsp), %xmm0
subss 0x70(%rsp), %xmm0
movss %xmm0, 0x40(%rsp)
movss 0x54(%rsp), %xmm0
subss 0x74(%rsp), %xmm0
movss %xmm0, 0x44(%rsp)
movss 0x58(%rsp), %xmm0
subss 0x78(%rsp), %xmm0
movss %xmm0, 0x48(%rsp)
movss 0x40(%rsp), %xmm0
mulss 0x40(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movss 0x44(%rsp), %xmm1
mulss 0x44(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
movss 0x48(%rsp), %xmm1
mulss 0x48(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
addsd %xmm1, %xmm0
callq 0x4270
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x4c(%rsp)
testb $0x1, 0x6f(%rsp)
je 0x4d097
movss 0x4c(%rsp), %xmm1
movss 0x5c(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x4d0cc
movb $0x1, 0x6f(%rsp)
movss 0x50(%rsp), %xmm0
movss %xmm0, 0x60(%rsp)
movss 0x54(%rsp), %xmm0
movss %xmm0, 0x64(%rsp)
movss 0x58(%rsp), %xmm0
movss %xmm0, 0x68(%rsp)
movss 0x4c(%rsp), %xmm0
movss %xmm0, 0x5c(%rsp)
jmp 0x4d0ce
jmp 0x4d0d0
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x4cdef
jmp 0x4d0e2
testb $0x1, 0x6f(%rsp)
je 0x4d123
movss 0x60(%rsp), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, (%rax)
movss 0x64(%rsp), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x4(%rax)
movss 0x68(%rsp), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x8(%rax)
jmp 0x4d170
movq 0xe0(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, (%rax)
movq 0xe0(%rsp), %rax
movss 0xc(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x4(%rax)
movq 0xe0(%rsp), %rax
movss 0x10(%rax), %xmm0
movq 0xd8(%rsp), %rax
movss %xmm0, 0x8(%rax)
jmp 0x4d172
jmp 0x4d174
leaq 0x88(%rsp), %rdi
callq 0xea90
addq $0xf8, %rsp
retq
movq 0x80(%rsp), %rdi
callq 0x45c0
nopw %cs:(%rax,%rax)