// File: /workspace/github_cpp_makefile_star2_O2/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)
andl $0x0, 0x4(%rsi)
testl %eax, %eax
je 0x15c27
movaps 0x9b6b(%rip), %xmm0     # 0x1f3c0
movups %xmm0, 0x8(%rbx)
movaps 0xae30(%rip), %xmm0     # 0x20690
movups %xmm0, 0x18(%rbx)
movaps 0x9b65(%rip), %xmm0     # 0x1f3d0
movups %xmm0, 0x28(%rbx)
movq (%r15), %rcx
xorl %edx, %edx
movsd 0x8b6c(%rip), %xmm0     # 0x1e3e8
movsd 0xae4c(%rip), %xmm1     # 0x206d0
movapd %xmm1, %xmm2
movapd %xmm1, %xmm3
movapd %xmm0, %xmm4
movapd %xmm0, %xmm5
cmpq 0x8(%r15), %rcx
je 0x15907
movq (%rcx), %rsi
leaq 0x48(%rsi), %r10
xorl %r8d, %r8d
movslq 0x2c(%rsi), %r9
cmpq %r9, %r8
jge 0x158f6
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
addq $0x18, %r10
jmp 0x158a4
cmpl $0x4, 0x30(%rsi)
jne 0x15901
incl %edx
movl %edx, 0x4(%rbx)
addq $0x8, %rcx
jmp 0x15894
pushq $-0x1
popq %rcx
xorpd %xmm1, %xmm1
xorl %edx, %edx
movsd 0x8ac8(%rip), %xmm0     # 0x1e3e0
cmpq $0x3, %rdx
je 0x15953
movsd 0x20(%rbx,%rdx,8), %xmm2
subsd 0x8(%rbx,%rdx,8), %xmm2
movapd %xmm1, %xmm3
addsd %xmm0, %xmm3
ucomisd %xmm3, %xmm2
cmpltsd %xmm2, %xmm3
andpd %xmm3, %xmm2
cmoval %edx, %ecx
andnpd %xmm1, %xmm3
orpd %xmm2, %xmm3
incq %rdx
movapd %xmm3, %xmm1
jmp 0x15918
cmpl $0x6, %eax
jl 0x15c27
cmpb $0x0, (%rdi)
jne 0x15c27
cmpl $-0x1, %ecx
je 0x15c27
movq %rdi, 0x18(%rsp)
movb $0x0, 0x38(%rbx)
movslq %ecx, %r14
movsd 0x8(%rbx,%r14,8), %xmm0
movsd 0x20(%rbx,%r14,8), %xmm3
movapd %xmm0, %xmm1
addsd %xmm3, %xmm1
mulsd 0x8818(%rip), %xmm1     # 0x1e1b0
movsd %xmm1, 0x20(%rsp)
movsd 0xad32(%rip), %xmm1     # 0x206d8
movapd %xmm0, %xmm4
mulsd %xmm1, %xmm4
addsd %xmm3, %xmm4
movsd 0xad26(%rip), %xmm2     # 0x206e0
mulsd %xmm2, %xmm4
movsd %xmm4, 0x8(%rsp)
mulsd %xmm1, %xmm3
addsd %xmm0, %xmm3
mulsd %xmm2, %xmm3
movsd %xmm3, (%rsp)
pushq $0x18
popq %r12
movq %r12, %rdi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq %rax, 0x50(%rbx)
andl $0x0, 0x58(%rbx)
pushq $0x68
popq %r13
movq %r13, %rdi
callq 0x4410
movq %rax, %rbp
movq %rax, 0x40(%rbx)
movq %r12, %rdi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq %rax, 0x60(%rbp)
movq %r13, %rdi
callq 0x4410
movq %rax, %r13
movq %rax, 0x48(%rbx)
movq %r12, %rdi
callq 0x42f0
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq %rax, 0x60(%r13)
movq (%r15), %r13
movsd 0x898b(%rip), %xmm0     # 0x1e3e0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x8997(%rip), %xmm0     # 0x1e400
addsd (%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
shlq $0x3, %r14
xorl %ebp, %ebp
leaq 0x10(%rsp), %r12
cmpq 0x8(%r15), %r13
je 0x15b5e
movq (%r13), %rcx
movq %rcx, 0x10(%rsp)
movl 0x2c(%rcx), %eax
testl %eax, %eax
cmovlel %ebp, %eax
imulq $0x18, %rax, %rax
addq %r14, %rcx
addq $0x38, %rcx
xorl %edx, %edx
movsd 0x8939(%rip), %xmm0     # 0x1e3e8
movsd 0xac19(%rip), %xmm1     # 0x206d0
cmpq %rdx, %rax
je 0x15acf
movsd (%rcx,%rdx), %xmm2
minsd %xmm2, %xmm0
maxsd %xmm2, %xmm1
addq $0x18, %rdx
jmp 0x15ab7
movsd 0x30(%rsp), %xmm2
ucomisd %xmm0, %xmm2
jbe 0x15aff
ucomisd 0x28(%rsp), %xmm1
jbe 0x15aff
movq 0x50(%rbx), %rdi
movq %r12, %rsi
callq 0x17a0a
movq 0x10(%rsp), %rax
cmpl $0x4, 0x30(%rax)
jne 0x15b51
incl 0x58(%rbx)
jmp 0x15b51
ucomisd 0x8(%rsp), %xmm0
jb 0x15b28
movsd (%rsp), %xmm2
ucomisd %xmm1, %xmm2
jb 0x15b28
addsd %xmm1, %xmm0
mulsd 0x8692(%rip), %xmm0     # 0x1e1b0
ucomisd 0x20(%rsp), %xmm0
jbe 0x15b3b
jmp 0x15b41
ucomisd 0x8(%rsp), %xmm0
jae 0x15b41
movsd (%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x15b51
movq 0x48(%rbx), %rax
jmp 0x15b45
movq 0x40(%rbx), %rax
movq 0x60(%rax), %rdi
movq %r12, %rsi
callq 0x17a0a
addq $0x8, %r13
movq 0x60(%rbx), %r15
jmp 0x15a7f
movq 0x40(%rbx), %rax
movq 0x60(%rax), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
subq (%r15), %r13
cmpq %r13, %rcx
je 0x15b8d
movq 0x48(%rbx), %rax
movq 0x60(%rax), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq %r13, %rcx
jne 0x15c3a
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 0xab8e(%rip), %rdi      # 0x20740
movb $0x6, %al
callq 0x8e95
movq 0x40(%rbx), %rax
movq 0x60(%rax), %r14
testq %r14, %r14
je 0x15bce
movq %r14, %rdi
callq 0x17c4c
pushq $0x18
popq %rsi
movq %r14, %rdi
callq 0x4300
movq 0x48(%rbx), %rax
movq 0x60(%rax), %r14
testq %r14, %r14
je 0x15bee
movq %r14, %rdi
callq 0x17c4c
pushq $0x18
popq %rsi
movq %r14, %rdi
callq 0x4300
movq 0x40(%rbx), %rdi
callq 0x4390
movq 0x48(%rbx), %rdi
callq 0x4390
movq 0x50(%rbx), %r14
testq %r14, %r14
je 0x15c1c
movq %r14, %rdi
callq 0x17c4c
pushq $0x18
popq %rsi
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
movq %r15, %rdi
callq 0x17c4c
pushq $0x18
popq %rsi
movq %r15, %rdi
callq 0x4300
movq 0x40(%rbx), %rsi
movq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0x15820
movq 0x48(%rbx), %rsi
movq %r14, %rdi
callq 0x15820
jmp 0x15c2b