// File: /workspace/github_cpp_makefile_star2_O2/FreeSlave[P]vhlt/hlrad/trace.cpp
// Function: TryMerge(opaqueface_t*, opaqueface_t const*)
bool TryMerge (opaqueface_t *f, const opaqueface_t *f2)
{
	if (!f->winding || !f2->winding)
	{
		return false;
	}
	if (fabs (f2->plane.dist - f->plane.dist) > ON_EPSILON
		|| fabs (f2->plane.normal[0] - f->plane.normal[0]) > NORMAL_EPSILON
		|| fabs (f2->plane.normal[1] - f->plane.normal[1]) > NORMAL_EPSILON
		|| fabs (f2->plane.normal[2] - f->plane.normal[2]) > NORMAL_EPSILON
		)
	{
		return false;
	}
#ifdef HLRAD_OPAQUE_ALPHATEST
	if ((f->tex_alphatest || f2->tex_alphatest) && f->texinfo != f2->texinfo)
	{
		return false;
	}
#endif

	Winding *w = f->winding;
	const Winding *w2 = f2->winding;
	const vec_t *pA, *pB, *pC, *pD, *p2A, *p2B, *p2C, *p2D;
	int i, i2;

	for (i = 0; i < w->m_NumPoints; i++)
	{
		for (i2 = 0; i2 < w2->m_NumPoints; i2++)
		{
			pA = w->m_Points[(i+w->m_NumPoints-1)%w->m_NumPoints];
			pB = w->m_Points[i];
			pC = w->m_Points[(i+1)%w->m_NumPoints];
			pD = w->m_Points[(i+2)%w->m_NumPoints];
			p2A = w2->m_Points[(i2+w2->m_NumPoints-1)%w2->m_NumPoints];
			p2B = w2->m_Points[i2];
			p2C = w2->m_Points[(i2+1)%w2->m_NumPoints];
			p2D = w2->m_Points[(i2+2)%w2->m_NumPoints];
			if (!VectorCompare (pB, p2C) || !VectorCompare (pC, p2B))
			{
				continue;
			}
			break;
		}
		if (i2 == w2->m_NumPoints)
		{
			continue;
		}
		break;
	}
	if (i == w->m_NumPoints)
	{
		return false;
	}

	const vec_t *normal = f->plane.normal;
	vec3_t e1, e2;
	dplane_t pl1, pl2;
	int side1, side2;

	VectorSubtract (p2D, pA, e1);
	CrossProduct (normal, e1, pl1.normal); // pointing outward
	if (VectorNormalize (pl1.normal) == 0.0)
	{
		Developer (DEVELOPER_LEVEL_WARNING, "Warning: TryMerge: Empty edge.\n");
		return false;
	}
	pl1.dist = DotProduct (pA, pl1.normal);
	if (DotProduct (pB, pl1.normal) - pl1.dist < -ON_EPSILON)
	{
		return false;
	}
	side1 = (DotProduct (pB, pl1.normal) - pl1.dist > ON_EPSILON)? 1: 0;

	VectorSubtract (pD, p2A, e2);
	CrossProduct (normal, e2, pl2.normal); // pointing outward
	if (VectorNormalize (pl2.normal) == 0.0)
	{
		Developer (DEVELOPER_LEVEL_WARNING, "Warning: TryMerge: Empty edge.\n");
		return false;
	}
	pl2.dist = DotProduct (p2A, pl2.normal);
	if (DotProduct (p2B, pl2.normal) - pl2.dist < -ON_EPSILON)
	{
		return false;
	}
	side2 = (DotProduct (p2B, pl2.normal) - pl2.dist > ON_EPSILON)? 1: 0;

	Winding *neww = new Winding (w->m_NumPoints + w2->m_NumPoints - 4 + side1 + side2);
	int j, k;
	k = 0;
	for (j = (i + 2) % w->m_NumPoints; j != i; j = (j + 1) % w->m_NumPoints)
	{
		VectorCopy (w->m_Points[j], neww->m_Points[k]);
		k++;
	}
	if (side1)
	{
		VectorCopy (w->m_Points[j], neww->m_Points[k]);
		k++;
	}
	for (j = (i2 + 2) % w2->m_NumPoints; j != i2; j = (j + 1) % w2->m_NumPoints)
	{
		VectorCopy (w2->m_Points[j], neww->m_Points[k]);
		k++;
	}
	if (side2)
	{
		VectorCopy (w2->m_Points[j], neww->m_Points[k]);
		k++;
	}
	neww->RemoveColinearPoints ();
	if (neww->m_NumPoints < 3)
	{
		Developer (DEVELOPER_LEVEL_WARNING, "Warning: TryMerge: Empty winding.\n");
		delete neww;
		neww = NULL;
	}
	delete f->winding;
	f->winding = neww;
	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq (%rdi), %r14
testq %r14, %r14
je 0x2e51c
movq (%rsi), %r15
testq %r15, %r15
je 0x2e51c
movss 0x14(%rsi), %xmm0
subss 0x14(%rdi), %xmm0
andps 0x6f86(%rip), %xmm0     # 0x352a0
cvtss2sd %xmm0, %xmm0
ucomisd 0x7282(%rip), %xmm0     # 0x355a8
ja 0x2e51c
movss 0x8(%rsi), %xmm0
subss 0x8(%rdi), %xmm0
andps 0x6f63(%rip), %xmm0     # 0x352a0
cvtss2sd %xmm0, %xmm0
ucomisd 0x3d37(%rip), %xmm0     # 0x32080
ja 0x2e51c
movss 0xc(%rsi), %xmm0
subss 0xc(%rdi), %xmm0
andps 0x6f40(%rip), %xmm0     # 0x352a0
cvtss2sd %xmm0, %xmm0
ucomisd 0x3d14(%rip), %xmm0     # 0x32080
ja 0x2e51c
movss 0x10(%rsi), %xmm0
subss 0x10(%rdi), %xmm0
andps 0x6f1d(%rip), %xmm0     # 0x352a0
cvtss2sd %xmm0, %xmm0
ucomisd 0x3cf1(%rip), %xmm0     # 0x32080
ja 0x2e51c
cmpb $0x0, 0x2c(%rdi)
jne 0x2e3a1
cmpb $0x1, 0x2c(%rsi)
jne 0x2e3ad
movl 0x28(%rdi), %eax
cmpl 0x28(%rsi), %eax
jne 0x2e51c
movq %rdi, 0x38(%rsp)
movq $0x0, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %r15, 0x40(%rsp)
movq 0x10(%rsp), %rbp
movl 0x8(%r14), %eax
cmpq %rax, %rbp
jae 0x2e518
movq %rcx, 0x8(%rsp)
leaq 0x1(%rbp), %rax
movq %rax, 0x10(%rsp)
leal -0x1(%rbp), %eax
movq %rax, 0x28(%rsp)
leal 0x2(%rbp), %eax
movl %eax, 0x34(%rsp)
movq %rbp, 0x48(%rsp)
imulq $0xc, %rbp, %rax
movq %rax, 0x70(%rsp)
xorl %ebx, %ebx
xorl %r8d, %r8d
movl 0x8(%r15), %ecx
cmpq %rcx, %r8
jae 0x2e501
movq 0x10(%r14), %r13
movl 0x8(%r14), %r12d
movq 0x28(%rsp), %rax
addl %r12d, %eax
xorl %edx, %edx
divl %r12d
imulq $0xc, %rdx, %rax
addq %r13, %rax
movq %rax, 0x8(%rsp)
movq 0x70(%rsp), %rax
leaq (%rax,%r13), %rdi
movl 0x34(%rsp), %eax
xorl %edx, %edx
divl %r12d
imulq $0xc, %rdx, %rax
addq %r13, %rax
movq %rax, 0x50(%rsp)
movq 0x10(%r15), %r14
leal (%r8,%rcx), %eax
decl %eax
xorl %edx, %edx
divl %ecx
imulq $0xc, %rdx, %rax
addq %r14, %rax
movq %rax, 0x58(%rsp)
leaq (%r14,%rbx), %rbp
leaq 0x1(%r8), %r15
cmpq %rcx, %r15
movl $0x0, %eax
cmovneq %r15, %rax
imulq $0xc, %rax, %rsi
addq %r14, %rsi
movq %r8, 0x20(%rsp)
leal 0x2(%r8), %eax
xorl %edx, %edx
divl %ecx
imulq $0xc, %rdx, %rax
addq %r14, %rax
movq %rax, 0x68(%rsp)
movq %rdi, 0x60(%rsp)
callq 0x1e86c
testb %al, %al
je 0x2e4cf
movq 0x10(%rsp), %rax
xorl %edx, %edx
divl %r12d
imulq $0xc, %rdx, %rax
addq %rax, %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x1e86c
testb %al, %al
jne 0x2e4e8
movq %rbp, %r13
addq $0xc, %rbx
movq %r15, %r8
movq 0x40(%rsp), %r15
movq 0x18(%rsp), %r14
jmp 0x2e407
movq 0x40(%rsp), %r15
movl 0x8(%r15), %ecx
addq %rbx, %r14
movq %r14, %r13
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r14
cmpl %r8d, %ecx
movq 0x8(%rsp), %rcx
je 0x2e3c5
movl 0x8(%r14), %eax
movq 0x48(%rsp), %rbp
cmpl %ebp, %eax
jne 0x2e532
xorl %ebx, %ebx
movl %ebx, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r8, 0x20(%rsp)
movq 0x68(%rsp), %rax
movss 0x4(%rax), %xmm1
subss 0x4(%rcx), %xmm1
movq 0x38(%rsp), %rbx
movss 0x8(%rbx), %xmm0
movss (%rax), %xmm2
movss 0x8(%rax), %xmm3
unpcklps %xmm2, %xmm3            # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movss (%rcx), %xmm2
movss 0x8(%rcx), %xmm4
unpcklps %xmm2, %xmm4            # xmm4 = xmm4[0],xmm2[0],xmm4[1],xmm2[1]
subps %xmm4, %xmm3
movsd 0xc(%rbx), %xmm2
movaps %xmm0, %xmm4
shufps $0xd4, %xmm2, %xmm4     # xmm4 = xmm4[0,1],xmm2[1,3]
shufps $0x52, %xmm2, %xmm4     # xmm4 = xmm4[2,0],xmm2[1,1]
mulss %xmm1, %xmm0
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
mulps %xmm4, %xmm1
movaps %xmm2, %xmm4
mulps %xmm3, %xmm4
subps %xmm1, %xmm4
leaq 0x90(%rsp), %rdi
movlps %xmm4, (%rdi)
shufps $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
mulss %xmm2, %xmm3
subss %xmm3, %xmm0
movss %xmm0, 0x8(%rdi)
movq %rcx, %r12
callq 0xc021
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x2e5d4
jp 0x2e5d4
leaq 0xb5ad(%rip), %rsi      # 0x39b70
xorl %ebx, %ebx
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x9045
jmp 0x2e51e
movss 0x90(%rsp), %xmm0
movss 0x94(%rsp), %xmm1
movss 0x4(%r12), %xmm2
mulss %xmm1, %xmm2
movss (%r12), %xmm3
mulss %xmm0, %xmm3
addss %xmm2, %xmm3
movss 0x98(%rsp), %xmm2
movss 0x8(%r12), %xmm4
mulss %xmm2, %xmm4
addss %xmm3, %xmm4
movss %xmm4, 0x9c(%rsp)
movq 0x60(%rsp), %rax
mulss 0x4(%rax), %xmm1
mulss (%rax), %xmm0
addss %xmm1, %xmm0
mulss 0x8(%rax), %xmm2
addss %xmm0, %xmm2
subss %xmm4, %xmm2
cvtss2sd %xmm2, %xmm0
movsd 0x6f4d(%rip), %xmm1     # 0x35598
ucomisd %xmm0, %xmm1
ja 0x2e51c
movsd %xmm0, 0x8(%rsp)
movq 0x50(%rsp), %rax
movss 0x4(%rax), %xmm1
movq 0x58(%rsp), %r12
subss 0x4(%r12), %xmm1
movss 0x8(%rbx), %xmm0
movss (%rax), %xmm2
movss 0x8(%rax), %xmm3
unpcklps %xmm2, %xmm3            # xmm3 = xmm3[0],xmm2[0],xmm3[1],xmm2[1]
movss (%r12), %xmm2
movss 0x8(%r12), %xmm4
unpcklps %xmm2, %xmm4            # xmm4 = xmm4[0],xmm2[0],xmm4[1],xmm2[1]
subps %xmm4, %xmm3
movsd 0xc(%rbx), %xmm2
movaps %xmm0, %xmm4
shufps $0xd4, %xmm2, %xmm4     # xmm4 = xmm4[0,1],xmm2[1,3]
shufps $0x52, %xmm2, %xmm4     # xmm4 = xmm4[2,0],xmm2[1,1]
mulss %xmm1, %xmm0
unpcklps %xmm3, %xmm1            # xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
mulps %xmm4, %xmm1
movaps %xmm2, %xmm4
mulps %xmm3, %xmm4
subps %xmm1, %xmm4
leaq 0x78(%rsp), %rdi
movlps %xmm4, (%rdi)
shufps $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
mulss %xmm2, %xmm3
subss %xmm3, %xmm0
movss %xmm0, 0x8(%rdi)
callq 0xc021
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x2e6e4
jnp 0x2e5bc
movss 0x78(%rsp), %xmm0
movss 0x7c(%rsp), %xmm1
movss 0x4(%r12), %xmm2
mulss %xmm1, %xmm2
movss (%r12), %xmm3
mulss %xmm0, %xmm3
addss %xmm2, %xmm3
movss 0x80(%rsp), %xmm2
movss 0x8(%r12), %xmm4
mulss %xmm2, %xmm4
addss %xmm3, %xmm4
movss %xmm4, 0x84(%rsp)
mulss 0x4(%r13), %xmm1
mulss (%r13), %xmm0
addss %xmm1, %xmm0
mulss 0x8(%r13), %xmm2
addss %xmm0, %xmm2
subss %xmm4, %xmm2
cvtss2sd %xmm2, %xmm1
movsd 0x6e44(%rip), %xmm0     # 0x35598
ucomisd %xmm1, %xmm0
ja 0x2e51c
movsd 0x6e42(%rip), %xmm0     # 0x355a8
xorl %ebx, %ebx
movsd 0x8(%rsp), %xmm2
ucomisd %xmm0, %xmm2
seta %bl
xorl %r13d, %r13d
movsd %xmm1, 0x28(%rsp)
ucomisd %xmm0, %xmm1
seta %r13b
pushq $0x20
popq %rdi
callq 0x42e0
movq %rax, %r14
movl 0x8(%r15), %eax
addl %r13d, %ebx
movq 0x18(%rsp), %r13
addl 0x8(%r13), %ebx
leal (%rax,%rbx), %esi
addl $-0x4, %esi
movq %r14, %rdi
callq 0xaa74
leal 0x2(%rbp), %eax
xorl %esi, %esi
xorl %edx, %edx
divl 0x8(%r13)
xorl %ecx, %ecx
movq 0x38(%rsp), %rbx
movq 0x20(%rsp), %r12
movsd 0x28(%rsp), %xmm1
cmpl %ebp, %edx
je 0x2e824
movq 0x10(%r13), %rax
movslq %edx, %rdi
imulq $0xc, %rdi, %rdi
movss (%rax,%rdi), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, (%rax,%rsi)
movq 0x10(%r13), %rax
movss 0x4(%rax,%rdi), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x4(%rax,%rsi)
movq 0x10(%r13), %rax
movss 0x8(%rax,%rdi), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x8(%rax,%rsi)
incq %rcx
incl %edx
movl %edx, %eax
xorl %edx, %edx
divl 0x8(%r13)
addq $0xc, %rsi
jmp 0x2e7cc
movsd 0x8(%rsp), %xmm0
ucomisd 0x6d76(%rip), %xmm0     # 0x355a8
jbe 0x2e87e
movq 0x10(%r13), %rax
movslq %ebp, %rdx
imulq $0xc, %rdx, %rdx
movss (%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
movl %ecx, %esi
imulq $0xc, %rsi, %rsi
movss %xmm0, (%rax,%rsi)
movq 0x10(%r13), %rax
movss 0x4(%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x4(%rax,%rsi)
movq 0x10(%r13), %rax
movss 0x8(%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x8(%rax,%rsi)
incq %rcx
leal 0x2(%r12), %eax
xorl %edx, %edx
divl 0x8(%r15)
movslq %ecx, %rax
shlq $0x20, %rcx
imulq $0xc, %rax, %rsi
movabsq $0x100000000, %rdi      # imm = 0x100000000
cmpl %r12d, %edx
je 0x2e8fa
movq 0x10(%r15), %rax
movslq %edx, %r8
imulq $0xc, %r8, %r8
movss (%rax,%r8), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, (%rax,%rsi)
movq 0x10(%r15), %rax
movss 0x4(%rax,%r8), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x4(%rax,%rsi)
movq 0x10(%r15), %rax
movss 0x8(%rax,%r8), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x8(%rax,%rsi)
incl %edx
movl %edx, %eax
xorl %edx, %edx
divl 0x8(%r15)
addq %rdi, %rcx
addq $0xc, %rsi
jmp 0x2e89e
ucomisd 0x6ca6(%rip), %xmm1     # 0x355a8
jbe 0x2e94d
movq 0x10(%r15), %rax
movslq %r12d, %rdx
imulq $0xc, %rdx, %rdx
movss (%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
sarq $0x20, %rcx
imulq $0xc, %rcx, %rcx
movss %xmm0, (%rax,%rcx)
movq 0x10(%r15), %rax
movss 0x4(%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x4(%rax,%rcx)
movq 0x10(%r15), %rax
movss 0x8(%rax,%rdx), %xmm0
movq 0x10(%r14), %rax
movss %xmm0, 0x8(%rax,%rcx)
movss 0x706f(%rip), %xmm0     # 0x359c4
movq %r14, %rdi
callq 0xae86
cmpl $0x2, 0x8(%r14)
ja 0x2e981
leaq 0xb225(%rip), %rsi      # 0x39b90
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x9045
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
xorl %r14d, %r14d
movq (%rbx), %rdi
testq %rdi, %rdi
je 0x2e98f
movq (%rdi), %rax
callq *0x8(%rax)
movq %r14, (%rbx)
movb $0x1, %bl
jmp 0x2e51e
movq %rax, %rbx
pushq $0x20
popq %rsi
movq %r14, %rdi
callq 0x42f0
movq %rbx, %rdi
callq 0x45a0