// File: /workspace/github_cpp_makefile_star2_O1/FreeSlave[P]vhlt/hlbsp/solidbsp.cpp
// Function: BuildSurfaceTree_r(surfacetree_t*, surfacetreenode_s*)
void BuildSurfaceTree_r (surfacetree_t *tree, surfacetreenode_t *node)
{
	node->size = node->leaffaces->size ();
#ifdef HLCSG_HLBSP_SOLIDHINT
	node->size_discardable = 0;
#endif
	if (node->size == 0)
	{
		node->isleaf = true;
		return;
	}

	VectorFill (node->mins, BOGUS_RANGE);
	VectorFill (node->maxs, -BOGUS_RANGE);
	for (std::vector< face_t * >::iterator i = node->leaffaces->begin (); i != node->leaffaces->end (); ++i)
	{
		face_t *f = *i;
		for (int x = 0; x < f->numpoints; x++)
		{
			VectorCompareMinimum (node->mins, f->pts[x], node->mins);
			VectorCompareMaximum (node->maxs, f->pts[x], node->maxs);
		}
#ifdef HLCSG_HLBSP_SOLIDHINT
		if (f->facestyle == face_discardable)
		{
			node->size_discardable++;
		}
#endif
	}

	int bestaxis = -1;
	{
		vec_t bestdelta = 0;
		for (int k = 0; k < 3; k++)
		{
			if (node->maxs[k] - node->mins[k] > bestdelta + ON_EPSILON)
			{
				bestaxis = k;
				bestdelta = node->maxs[k] - node->mins[k];
			}
		}
	}
	if (node->size <= 5 || tree->dontbuild == true || bestaxis == -1)
	{
		node->isleaf = true;
		return;
	}

	node->isleaf = false;
	vec_t dist, dist1, dist2;
	dist = (node->mins[bestaxis] + node->maxs[bestaxis]) / 2;
	dist1 = (3 * node->mins[bestaxis] + node->maxs[bestaxis]) / 4;
	dist2 = (node->mins[bestaxis] + 3 * node->maxs[bestaxis]) / 4;
	// Each child node is at most 3/4 the size of the parent node.
	// Most faces should be passed to a child node, faces left in the parent node are the ones whose dimensions are large enough to be comparable to the dimension of the parent node.
	node->nodefaces = new std::vector< face_t * >;
#ifdef HLCSG_HLBSP_SOLIDHINT
	node->nodefaces_discardablesize = 0;
#endif
	node->children[0] = (surfacetreenode_t *)malloc (sizeof (surfacetreenode_t));
	node->children[0]->leaffaces = new std::vector< face_t * >;
	node->children[1] = (surfacetreenode_t *)malloc (sizeof (surfacetreenode_t));
	node->children[1]->leaffaces = new std::vector< face_t * >;
	for (std::vector< face_t * >::iterator i = node->leaffaces->begin (); i != node->leaffaces->end (); ++i)
	{
		face_t *f = *i;
		vec_t low = BOGUS_RANGE;
		vec_t high = -BOGUS_RANGE;
		for (int x = 0; x < f->numpoints; x++)
		{
			low = qmin (low, f->pts[x][bestaxis]);
			high = qmax (high, f->pts[x][bestaxis]);
		}
		if (low < dist1 + ON_EPSILON && high > dist2 - ON_EPSILON)
		{
			node->nodefaces->push_back (f);
#ifdef HLCSG_HLBSP_SOLIDHINT
			if (f->facestyle == face_discardable)
			{
				node->nodefaces_discardablesize++;
			}
#endif
		}
		else if (low >= dist1 && high <= dist2)
		{
			if ((low + high) / 2 > dist)
			{
				node->children[0]->leaffaces->push_back (f);
			}
			else
			{
				node->children[1]->leaffaces->push_back (f);
			}
		}
		else if (low >= dist1)
		{
			node->children[0]->leaffaces->push_back (f);
		}
		else if (high <= dist2)
		{
			node->children[1]->leaffaces->push_back (f);
		}
	}
	if (node->children[0]->leaffaces->size () == node->leaffaces->size () || node->children[1]->leaffaces->size () == node->leaffaces->size ())
	{
		Warning ("BuildSurfaceTree_r: didn't split node with bound (%f,%f,%f)-(%f,%f,%f)", node->mins[0], node->mins[1], node->mins[2], node->maxs[0], node->maxs[1], node->maxs[2]);
		delete node->children[0]->leaffaces;
		delete node->children[1]->leaffaces;
		free (node->children[0]);
		free (node->children[1]);
		delete node->nodefaces;
		node->isleaf = true;
		return;
	}
	delete node->leaffaces;
	BuildSurfaceTree_r (tree, node->children[0]);
	BuildSurfaceTree_r (tree, node->children[1]);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %rbx
movq 0x60(%rsi), %r12
movq 0x8(%r12), %rax
subq (%r12), %rax
shrq $0x3, %rax
movl %eax, (%rsi)
movl $0x0, 0x4(%rsi)
testl %eax, %eax
je 0x17d8a
movq %rdi, %r14
movaps 0xa7eb(%rip), %xmm0     # 0x22470
movups %xmm0, 0x8(%rbx)
movaps 0xbad0(%rip), %xmm0     # 0x23760
movups %xmm0, 0x18(%rbx)
movapd 0xa7e4(%rip), %xmm0     # 0x22480
movupd %xmm0, 0x28(%rbx)
movq (%r12), %rcx
cmpq 0x8(%r12), %rcx
je 0x17d39
movq (%rcx), %rdx
cmpl $0x0, 0x2c(%rdx)
jle 0x17d27
leaq 0x48(%rdx), %rsi
xorl %edi, %edi
movsd 0x8(%rbx), %xmm0
movsd 0x10(%rbx), %xmm1
minsd -0x10(%rsi), %xmm0
movsd %xmm0, 0x8(%rbx)
minsd -0x8(%rsi), %xmm1
movsd %xmm1, 0x10(%rbx)
movsd 0x18(%rbx), %xmm0
minsd (%rsi), %xmm0
movsd %xmm0, 0x18(%rbx)
movsd 0x20(%rbx), %xmm0
maxsd -0x10(%rsi), %xmm0
movsd %xmm0, 0x20(%rbx)
movsd 0x28(%rbx), %xmm0
maxsd -0x8(%rsi), %xmm0
movsd %xmm0, 0x28(%rbx)
movsd 0x30(%rbx), %xmm0
maxsd (%rsi), %xmm0
movsd %xmm0, 0x30(%rbx)
incq %rdi
movslq 0x2c(%rdx), %r8
addq $0x18, %rsi
cmpq %r8, %rdi
jl 0x17cbf
cmpl $0x4, 0x30(%rdx)
jne 0x17d30
incl 0x4(%rbx)
addq $0x8, %rcx
jmp 0x17ca5
xorpd %xmm2, %xmm2
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %edx, %edx
movsd 0x9744(%rip), %xmm0     # 0x21490
movapd %xmm2, %xmm1
movsd 0x20(%rbx,%rdx,8), %xmm3
subsd 0x8(%rbx,%rdx,8), %xmm3
addsd %xmm0, %xmm1
ucomisd %xmm1, %xmm3
cmpltsd %xmm3, %xmm1
andpd %xmm1, %xmm3
andnpd %xmm2, %xmm1
cmoval %edx, %ecx
orpd %xmm3, %xmm1
incq %rdx
movapd %xmm1, %xmm2
cmpq $0x3, %rdx
jne 0x17d50
cmpl $0x6, %eax
jge 0x17d9d
movb $0x1, 0x38(%rbx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x0, (%r14)
jne 0x17d8a
cmpl $-0x1, %ecx
je 0x17d8a
movb $0x0, 0x38(%rbx)
movslq %ecx, %r13
movsd 0x8(%rbx,%r13,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x20(%rbx,%r13,8), %xmm0
movsd %xmm0, 0x20(%rsp)
movl $0x18, %edi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
xorl %ebp, %ebp
movq %rbp, 0x10(%rax)
movq %rax, 0x50(%rbx)
movl $0x0, 0x58(%rbx)
movl $0x68, %edi
callq 0x4400
movq %rax, %r15
movq %rax, 0x40(%rbx)
movl $0x18, %edi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rbp, 0x10(%rax)
movq %rax, 0x60(%r15)
movl $0x68, %edi
callq 0x4400
movq %rax, %r15
movq %rax, 0x48(%rbx)
movl $0x18, %edi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %rbp, 0x10(%rax)
movq %rax, 0x60(%r15)
movq (%r12), %rbp
movq 0x60(%rbx), %r12
movq 0x8(%r12), %rax
cmpq %rax, %rbp
je 0x1803a
movsd 0x8(%rsp), %xmm4
movapd %xmm4, %xmm0
movsd 0x20(%rsp), %xmm2
addsd %xmm2, %xmm0
mulsd 0x93ec(%rip), %xmm0     # 0x21260
movsd %xmm0, 0x30(%rsp)
movsd 0xb91e(%rip), %xmm0     # 0x237a0
movapd %xmm4, %xmm3
mulsd %xmm0, %xmm3
addsd %xmm2, %xmm3
movsd 0xb912(%rip), %xmm1     # 0x237a8
mulsd %xmm1, %xmm3
mulsd %xmm0, %xmm2
addsd %xmm4, %xmm2
mulsd %xmm1, %xmm2
movsd 0x95e2(%rip), %xmm4     # 0x21490
addsd %xmm3, %xmm4
movsd 0x95ee(%rip), %xmm5     # 0x214a8
movsd %xmm2, 0x20(%rsp)
addsd %xmm2, %xmm5
shlq $0x3, %r13
movsd 0xb8e0(%rip), %xmm6     # 0x237b0
movsd 0x95c0(%rip), %xmm7     # 0x21498
leaq 0x28(%rsp), %r15
movsd %xmm3, 0x8(%rsp)
movsd %xmm4, 0x18(%rsp)
movsd %xmm5, 0x10(%rsp)
movq (%rbp), %rax
movq %rax, 0x28(%rsp)
movslq 0x2c(%rax), %rdx
movapd %xmm7, %xmm1
movapd %xmm6, %xmm0
testq %rdx, %rdx
jle 0x17f39
leaq (%rax,%r13), %rcx
addq $0x38, %rcx
shlq $0x3, %rdx
leaq (%rdx,%rdx,2), %rdx
xorl %esi, %esi
movapd %xmm6, %xmm0
movapd %xmm7, %xmm1
movsd (%rcx,%rsi), %xmm2
minsd %xmm2, %xmm1
maxsd %xmm2, %xmm0
addq $0x18, %rsi
cmpq %rsi, %rdx
jne 0x17f23
ucomisd %xmm1, %xmm4
jbe 0x17f60
ucomisd %xmm5, %xmm0
jbe 0x17f60
movq 0x50(%rbx), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x17fc0
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x17fea
ucomisd %xmm3, %xmm1
jb 0x17f88
movsd 0x20(%rsp), %xmm2
ucomisd %xmm0, %xmm2
jb 0x17f88
addsd %xmm0, %xmm1
mulsd 0x92e2(%rip), %xmm1     # 0x21260
ucomisd 0x30(%rsp), %xmm1
jbe 0x17f9e
jmp 0x17fa4
ucomisd %xmm3, %xmm1
jae 0x17fa4
movsd 0x20(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jb 0x18024
movq 0x48(%rbx), %rcx
jmp 0x17fa8
movq 0x40(%rbx), %rcx
movq 0x60(%rcx), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x17ffa
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x18024
movq %r15, %rdx
callq 0x1a170
movsd 0x94c8(%rip), %xmm7     # 0x21498
movsd 0xb7d8(%rip), %xmm6     # 0x237b0
movsd 0x10(%rsp), %xmm5
movsd 0x18(%rsp), %xmm4
movsd 0x8(%rsp), %xmm3
movq 0x28(%rsp), %rax
cmpl $0x4, 0x30(%rax)
jne 0x18024
incl 0x58(%rbx)
jmp 0x18024
movq %r15, %rdx
callq 0x1a170
movsd 0x948e(%rip), %xmm7     # 0x21498
movsd 0xb79e(%rip), %xmm6     # 0x237b0
movsd 0x10(%rsp), %xmm5
movsd 0x18(%rsp), %xmm4
movsd 0x8(%rsp), %xmm3
addq $0x8, %rbp
movq 0x60(%rbx), %r12
movq 0x8(%r12), %rax
cmpq %rax, %rbp
jne 0x17eef
movq 0x40(%rbx), %rcx
movq 0x60(%rcx), %rcx
movq 0x8(%rcx), %rdx
subq (%rcx), %rdx
movq (%r12), %rdi
subq %rdi, %rax
cmpq %rax, %rdx
je 0x1806d
movq 0x48(%rbx), %rcx
movq 0x60(%rcx), %rcx
movq 0x8(%rcx), %rdx
subq (%rcx), %rdx
cmpq %rax, %rdx
jne 0x1813a
movsd 0x8(%rbx), %xmm0
movsd 0x10(%rbx), %xmm1
movsd 0x18(%rbx), %xmm2
movsd 0x20(%rbx), %xmm3
movsd 0x28(%rbx), %xmm4
movsd 0x30(%rbx), %xmm5
leaq 0xb786(%rip), %rdi      # 0x23818
movb $0x6, %al
callq 0xa2f6
movq 0x40(%rbx), %rax
movq 0x60(%rax), %r14
testq %r14, %r14
je 0x180c7
movq (%r14), %rdi
testq %rdi, %rdi
je 0x180ba
movq 0x10(%r14), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r14, %rdi
callq 0x4300
movq 0x48(%rbx), %rax
movq 0x60(%rax), %r14
testq %r14, %r14
je 0x180f5
movq (%r14), %rdi
testq %rdi, %rdi
je 0x180e8
movq 0x10(%r14), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r14, %rdi
callq 0x4300
movq 0x40(%rbx), %rdi
callq 0x4380
movq 0x48(%rbx), %rdi
callq 0x4380
movq 0x50(%rbx), %r14
testq %r14, %r14
je 0x17d8a
movq (%r14), %rdi
testq %rdi, %rdi
je 0x18128
movq 0x10(%r14), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r14, %rdi
callq 0x4300
jmp 0x17d8a
testq %rdi, %rdi
je 0x1814c
movq 0x10(%r12), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r12, %rdi
callq 0x4300
movq 0x40(%rbx), %rsi
movq %r14, %rdi
callq 0x17c48
movq 0x48(%rbx), %rsi
movq %r14, %rdi
callq 0x17c48
jmp 0x17d8e