// File: /workspace/github_cpp_makefile_star2_O3/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), %r15
movq 0x8(%r15), %rax
subq (%r15), %rax
shrq $0x3, %rax
movl %eax, (%rsi)
movl $0x0, 0x4(%rsi)
testl %eax, %eax
je 0x17db2
movaps 0x9b64(%rip), %xmm0     # 0x21460
movups %xmm0, 0x8(%rbx)
movaps 0xae29(%rip), %xmm0     # 0x22730
movups %xmm0, 0x18(%rbx)
movapd 0x9b5d(%rip), %xmm0     # 0x21470
movupd %xmm0, 0x28(%rbx)
movq (%r15), %rcx
cmpq 0x8(%r15), %rcx
je 0x179bc
movsd 0x8b5b(%rip), %xmm0     # 0x20488
movsd 0xae3b(%rip), %xmm1     # 0x22770
xorl %edx, %edx
movapd %xmm1, %xmm2
movapd %xmm1, %xmm3
movapd %xmm0, %xmm4
movapd %xmm0, %xmm5
movq (%rcx), %rsi
cmpl $0x0, 0x2c(%rsi)
jle 0x179a7
leaq 0x48(%rsi), %r10
xorl %r8d, %r8d
minsd -0x10(%r10), %xmm5
movsd %xmm5, 0x8(%rbx)
minsd -0x8(%r10), %xmm4
movsd %xmm4, 0x10(%rbx)
minsd (%r10), %xmm0
movsd %xmm0, 0x18(%rbx)
maxsd -0x10(%r10), %xmm3
movsd %xmm3, 0x20(%rbx)
maxsd -0x8(%r10), %xmm2
movsd %xmm2, 0x28(%rbx)
maxsd (%r10), %xmm1
movsd %xmm1, 0x30(%rbx)
incq %r8
movslq 0x2c(%rsi), %r9
addq $0x18, %r10
cmpq %r9, %r8
jl 0x17957
cmpl $0x4, 0x30(%rsi)
jne 0x179b2
incl %edx
movl %edx, 0x4(%rbx)
addq $0x8, %rcx
cmpq 0x8(%r15), %rcx
jne 0x17947
xorpd %xmm2, %xmm2
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %edx, %edx
movsd 0x8ab1(%rip), %xmm0     # 0x20480
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 0x179d3
cmpl $0x6, %eax
jl 0x17db2
cmpb $0x0, (%rdi)
jne 0x17db2
cmpl $-0x1, %ecx
je 0x17db2
movq %rdi, 0x28(%rsp)
movb $0x0, 0x38(%rbx)
movslq %ecx, %rbp
movsd 0x8(%rbx,%rbp,8), %xmm0
movsd %xmm0, (%rsp)
movsd 0x20(%rbx,%rbp,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movl $0x18, %edi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
xorl %r14d, %r14d
movq %r14, 0x10(%rax)
movq %rax, 0x50(%rbx)
movl $0x0, 0x58(%rbx)
movl $0x68, %edi
callq 0x4400
movq %rax, %r13
movq %rax, 0x40(%rbx)
movl $0x18, %edi
callq 0x42f0
movq %rax, %r12
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %r14, 0x10(%rax)
movq %rax, 0x60(%r13)
movl $0x68, %edi
callq 0x4400
movq %rax, %r13
movq %rax, 0x48(%rbx)
movl $0x18, %edi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
movq %r14, 0x10(%rax)
movq %rax, 0x60(%r13)
movq (%r15), %rdi
cmpq 0x8(%r15), %rdi
je 0x17cc3
movsd (%rsp), %xmm2
movapd %xmm2, %xmm0
movsd 0x8(%rsp), %xmm3
addsd %xmm3, %xmm0
mulsd 0x8765(%rip), %xmm0     # 0x20250
movsd %xmm0, 0x30(%rsp)
movsd 0xac7f(%rip), %xmm0     # 0x22778
movapd %xmm2, %xmm4
mulsd %xmm0, %xmm4
addsd %xmm3, %xmm4
movsd 0xac73(%rip), %xmm1     # 0x22780
mulsd %xmm1, %xmm4
mulsd %xmm0, %xmm3
addsd %xmm2, %xmm3
mulsd %xmm1, %xmm3
movsd 0x895b(%rip), %xmm5     # 0x20480
addsd %xmm4, %xmm5
movsd 0x896f(%rip), %xmm6     # 0x204a0
addsd %xmm3, %xmm6
shlq $0x3, %rbp
movsd 0xac2f(%rip), %xmm7     # 0x22770
movsd 0x893e(%rip), %xmm8     # 0x20488
leaq 0x20(%rsp), %r12
movq %rdi, %r13
movsd %xmm3, 0x8(%rsp)
movsd %xmm4, (%rsp)
movsd %xmm5, 0x18(%rsp)
movsd %xmm6, 0x10(%rsp)
movq (%r13), %rax
movq %rax, 0x20(%rsp)
movslq 0x2c(%rax), %rdx
movapd %xmm8, %xmm1
movapd %xmm7, %xmm0
testq %rdx, %rdx
jle 0x17bb5
leaq (%rax,%rbp), %rcx
addq $0x38, %rcx
shlq $0x3, %rdx
leaq (%rdx,%rdx,2), %rdx
xorl %esi, %esi
movapd %xmm7, %xmm0
movapd %xmm8, %xmm1
movsd (%rcx,%rsi), %xmm2
minsd %xmm2, %xmm1
maxsd %xmm2, %xmm0
addq $0x18, %rsi
cmpq %rsi, %rdx
jne 0x17b9f
ucomisd %xmm1, %xmm5
jbe 0x17bdc
ucomisd %xmm6, %xmm0
jbe 0x17bdc
movq 0x50(%rbx), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x17c30
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x17c60
ucomisd %xmm4, %xmm1
jb 0x17bfe
ucomisd %xmm0, %xmm3
jb 0x17bfe
addsd %xmm0, %xmm1
mulsd 0x865c(%rip), %xmm1     # 0x20250
ucomisd 0x30(%rsp), %xmm1
jbe 0x17c0e
jmp 0x17c14
ucomisd %xmm4, %xmm1
jae 0x17c14
ucomisd %xmm0, %xmm3
jb 0x17ca0
movq 0x48(%rbx), %rcx
jmp 0x17c18
movq 0x40(%rbx), %rcx
movq 0x60(%rcx), %rdi
movq 0x8(%rdi), %rsi
cmpq 0x10(%rdi), %rsi
je 0x17c70
movq %rax, (%rsi)
addq $0x8, 0x8(%rdi)
jmp 0x17ca0
movq %r12, %rdx
callq 0x19e32
movsd 0x8847(%rip), %xmm8     # 0x20488
movsd 0xab27(%rip), %xmm7     # 0x22770
movsd 0x10(%rsp), %xmm6
movsd 0x18(%rsp), %xmm5
movsd (%rsp), %xmm4
movsd 0x8(%rsp), %xmm3
movq 0x20(%rsp), %rax
cmpl $0x4, 0x30(%rax)
jne 0x17ca0
incl 0x58(%rbx)
jmp 0x17ca0
movq %r12, %rdx
callq 0x19e32
movsd 0x8807(%rip), %xmm8     # 0x20488
movsd 0xaae7(%rip), %xmm7     # 0x22770
movsd 0x10(%rsp), %xmm6
movsd 0x18(%rsp), %xmm5
movsd (%rsp), %xmm4
movsd 0x8(%rsp), %xmm3
addq $0x8, %r13
movq 0x60(%rbx), %r15
cmpq 0x8(%r15), %r13
jne 0x17b69
movq 0x40(%rbx), %rax
movq 0x60(%rax), %r12
movq (%r12), %r14
movq (%r15), %rdi
jmp 0x17cc6
movq %rdi, %r13
movq 0x8(%r12), %rax
subq %r14, %rax
subq %rdi, %r13
cmpq %r13, %rax
je 0x17cee
movq 0x48(%rbx), %rax
movq 0x60(%rax), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq %r13, %rcx
jne 0x17dc5
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 0xaacd(%rip), %rdi      # 0x227e0
movb $0x6, %al
callq 0xa20e
movq 0x40(%rbx), %rax
movq 0x60(%rax), %r14
testq %r14, %r14
je 0x17d3b
movq (%r14), %rdi
testq %rdi, %rdi
je 0x17d3b
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 0x17d69
movq (%r14), %rdi
testq %rdi, %rdi
je 0x17d69
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 0x17da5
movq (%r14), %rdi
testq %rdi, %rdi
je 0x17da5
movq 0x10(%r14), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r14, %rdi
callq 0x4300
movb $0x1, 0x38(%rbx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testq %rdi, %rdi
je 0x17dd6
movq 0x10(%r15), %rsi
subq %rdi, %rsi
callq 0x4300
movl $0x18, %esi
movq %r15, %rdi
callq 0x4300
movq 0x40(%rbx), %rsi
movq 0x28(%rsp), %r14
movq %r14, %rdi
callq 0x178c4
movq 0x48(%rbx), %rsi
movq %r14, %rdi
callq 0x178c4
jmp 0x17db6