// File: FreeSlave[P]vhlt/hlrad/qrad.cpp
// Function: cutWindingWithGrid(patch_s*, dplane_t const*, dplane_t const*)
static void     cutWindingWithGrid (patch_t *patch, const dplane_t *plA, const dplane_t *plB)
	// This function has been rewritten because the original one is not totally correct and may fail to do what it claims.
{
	// patch->winding->m_NumPoints must > 0
	// plA->dist and plB->dist will not be used
	Winding *winding = NULL;
	vec_t chop;
	vec_t epsilon;
	const int max_gridsize = 64;
	vec_t gridstartA;
	vec_t gridstartB;
	int gridsizeA;
	int gridsizeB;
	vec_t gridchopA;
	vec_t gridchopB;
	int numstrips;
	
	winding = new Winding (*patch->winding); // perform all the operations on the copy
	chop = patch->chop;
	chop = qmax (1.0, chop);
	epsilon = 0.6;

	// optimize the grid
	{
		vec_t minA;
		vec_t maxA;
		vec_t minB;
		vec_t maxB;

		minA = minB = BOGUS_RANGE;
		maxA = maxB = -BOGUS_RANGE;
		for (int x = 0; x < winding->m_NumPoints; x++)
		{
			vec_t *point;
			vec_t dotA;
			vec_t dotB;
			point = winding->m_Points[x];
			dotA = DotProduct (point, plA->normal);
			minA = qmin (minA, dotA);
			maxA = qmax (maxA, dotA);
			dotB = DotProduct (point, plB->normal);
			minB = qmin (minB, dotB);
			maxB = qmax (maxB, dotB);
		}

		gridchopA = chop;
		gridsizeA = (int)ceil ((maxA - minA - 2 * epsilon) / gridchopA);
		gridsizeA = qmax (1, gridsizeA);
		if (gridsizeA > max_gridsize)
		{
			gridsizeA = max_gridsize;
			gridchopA = (maxA - minA) / (vec_t)gridsizeA;
		}
		gridstartA = (minA + maxA) / 2.0 - (gridsizeA / 2.0) * gridchopA;

		gridchopB = chop;
		gridsizeB = (int)ceil ((maxB - minB - 2 * epsilon) / gridchopB);
		gridsizeB = qmax (1, gridsizeB);
		if (gridsizeB > max_gridsize)
		{
			gridsizeB = max_gridsize;
			gridchopB = (maxB - minB) / (vec_t)gridsizeB;
		}
		gridstartB = (minB + maxB) / 2.0 - (gridsizeB / 2.0) * gridchopB;
	}
	
	// cut the winding by the direction of plane A and save into windingArray
	{
		g_numwindings = 0;
		for (int i = 1; i < gridsizeA; i++)
		{
			vec_t dist;
			Winding *front = NULL;
			Winding *back = NULL;

			dist = gridstartA + i * gridchopA;
			winding->Clip (plA->normal, dist, &front, &back);

			if (!front || front->WindingOnPlaneSide (plA->normal, dist, epsilon) == SIDE_ON) // ended
			{
				if (front)
				{
					delete front;
					front = NULL;
				}
				if (back)
				{
					delete back;
					back = NULL;
				}
				break;
			}
			if (!back || back->WindingOnPlaneSide (plA->normal, dist, epsilon) == SIDE_ON) // didn't begin
			{
				if (front)
				{
					delete front;
					front = NULL;
				}
				if (back)
				{
					delete back;
					back = NULL;
				}
				continue;
			}

			delete winding;
			winding = NULL;

			windingArray[g_numwindings] = back;
			g_numwindings++;
			back = NULL;

			winding = front;
			front = NULL;
		}

		windingArray[g_numwindings] = winding;
		g_numwindings++;
		winding = NULL;
	}
	
	// cut by the direction of plane B
	{
		numstrips = g_numwindings;
		for (int i = 0; i < numstrips; i++)
		{
			Winding *strip = windingArray[i];
			windingArray[i] = NULL;

			for (int j = 1; j < gridsizeB; j++)
			{
				vec_t dist;
				Winding *front = NULL;
				Winding *back = NULL;

				dist = gridstartB + j * gridchopB;
				strip->Clip (plB->normal, dist, &front, &back);
				
				if (!front || front->WindingOnPlaneSide (plB->normal, dist, epsilon) == SIDE_ON) // ended
				{
					if (front)
					{
						delete front;
						front = NULL;
					}
					if (back)
					{
						delete back;
						back = NULL;
					}
					break;
				}
				if (!back || back->WindingOnPlaneSide (plB->normal, dist, epsilon) == SIDE_ON) // didn't begin
				{
					if (front)
					{
						delete front;
						front = NULL;
					}
					if (back)
					{
						delete back;
						back = NULL;
					}
					continue;
				}

				delete strip;
				strip = NULL;

				windingArray[g_numwindings] = back;
				g_numwindings++;
				back = NULL;

				strip = front;
				front = NULL;
			}

			windingArray[g_numwindings] = strip;
			g_numwindings++;
			strip = NULL;
		}
	}

	delete patch->winding;
	patch->winding = NULL;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq %rdx, 0x120(%rsp)
movq $0x0, 0x118(%rsp)
movl $0x40, 0x10c(%rsp)
movl $0x20, %edi
callq 0x4320
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x78(%rsp)
movq 0x130(%rsp), %rax
movq 0x28(%rax), %rsi
callq 0xea00
jmp 0x5878e
movq 0x78(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x130(%rsp), %rax
movss 0x34(%rax), %xmm0
movss %xmm0, 0x114(%rsp)
movss 0x114(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x14a22(%rip), %xmm0    # 0x6d1e8
ucomisd %xmm1, %xmm0
jbe 0x587dc
movsd 0x14a14(%rip), %xmm0    # 0x6d1e8
movsd %xmm0, 0x70(%rsp)
jmp 0x587ef
movss 0x114(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x114(%rsp)
movss 0x163da(%rip), %xmm0    # 0x6ebe4
movss %xmm0, 0x110(%rsp)
movss 0x163c5(%rip), %xmm0    # 0x6ebe0
movss %xmm0, 0xd8(%rsp)
movss 0x163b4(%rip), %xmm0    # 0x6ebe0
movss %xmm0, 0xe0(%rsp)
movss 0x1537b(%rip), %xmm0    # 0x6dbb8
movss %xmm0, 0xd4(%rsp)
movss 0x1536a(%rip), %xmm0    # 0x6dbb8
movss %xmm0, 0xdc(%rsp)
movl $0x0, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
movq 0x118(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jae 0x58ab5
movq 0x118(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0xd0(%rsp), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0xc8(%rsp)
movq 0xc8(%rsp), %rax
movss (%rax), %xmm1
movq 0x128(%rsp), %rax
movss (%rax), %xmm2
movq 0xc8(%rsp), %rax
movss 0x4(%rax), %xmm0
movq 0x128(%rsp), %rax
mulss 0x4(%rax), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movq 0xc8(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0x128(%rsp), %rax
movss 0x8(%rax), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0xc4(%rsp)
movss 0xe0(%rsp), %xmm1
movss 0xc4(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x5892a
movss 0xe0(%rsp), %xmm0
movss %xmm0, 0x6c(%rsp)
jmp 0x58939
movss 0xc4(%rsp), %xmm0
movss %xmm0, 0x6c(%rsp)
movss 0x6c(%rsp), %xmm0
movss %xmm0, 0xe0(%rsp)
movss 0xdc(%rsp), %xmm0
ucomiss 0xc4(%rsp), %xmm0
jbe 0x5896c
movss 0xdc(%rsp), %xmm0
movss %xmm0, 0x68(%rsp)
jmp 0x5897b
movss 0xc4(%rsp), %xmm0
movss %xmm0, 0x68(%rsp)
movss 0x68(%rsp), %xmm0
movss %xmm0, 0xdc(%rsp)
movq 0xc8(%rsp), %rax
movss (%rax), %xmm1
movq 0x120(%rsp), %rax
movss (%rax), %xmm2
movq 0xc8(%rsp), %rax
movss 0x4(%rax), %xmm0
movq 0x120(%rsp), %rax
mulss 0x4(%rax), %xmm0
mulss %xmm2, %xmm1
addss %xmm0, %xmm1
movq 0xc8(%rsp), %rax
movss 0x8(%rax), %xmm0
movq 0x120(%rsp), %rax
movss 0x8(%rax), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0xc0(%rsp)
movss 0xd8(%rsp), %xmm1
movss 0xc0(%rsp), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x58a17
movss 0xd8(%rsp), %xmm0
movss %xmm0, 0x64(%rsp)
jmp 0x58a26
movss 0xc0(%rsp), %xmm0
movss %xmm0, 0x64(%rsp)
movss 0x64(%rsp), %xmm0
movss %xmm0, 0xd8(%rsp)
movss 0xd4(%rsp), %xmm0
ucomiss 0xc0(%rsp), %xmm0
jbe 0x58a59
movss 0xd4(%rsp), %xmm0
movss %xmm0, 0x60(%rsp)
jmp 0x58a68
movss 0xc0(%rsp), %xmm0
movss %xmm0, 0x60(%rsp)
movss 0x60(%rsp), %xmm0
movss %xmm0, 0xd4(%rsp)
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x58862
movq 0x78(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xe8(%rsp)
movl %eax, 0xe4(%rsp)
movl $0x20, %esi
callq 0x4330
jmp 0x59313
movss 0x114(%rsp), %xmm0
movss %xmm0, 0xf8(%rsp)
movss 0xdc(%rsp), %xmm0
subss 0xe0(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
addss %xmm1, %xmm1
subss %xmm1, %xmm0
divss 0xf8(%rsp), %xmm0
callq 0x8e20
cvttss2si %xmm0, %eax
movl %eax, 0x100(%rsp)
movl $0x1, %eax
cmpl 0x100(%rsp), %eax
jle 0x58b1c
movl $0x1, %eax
movl %eax, 0x5c(%rsp)
jmp 0x58b27
movl 0x100(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x5c(%rsp), %eax
movl %eax, 0x100(%rsp)
cmpl $0x40, 0x100(%rsp)
jle 0x58b6f
movl $0x40, 0x100(%rsp)
movss 0xdc(%rsp), %xmm0
subss 0xe0(%rsp), %xmm0
cvtsi2ssl 0x100(%rsp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0xf8(%rsp)
movss 0xe0(%rsp), %xmm0
addss 0xdc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x150ab(%rip), %xmm0    # 0x6dc38
divsd %xmm0, %xmm1
cvtsi2sdl 0x100(%rsp), %xmm0
movsd 0x15096(%rip), %xmm2    # 0x6dc38
divsd %xmm2, %xmm0
movss 0xf8(%rsp), %xmm2
cvtss2sd %xmm2, %xmm2
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x108(%rsp)
movss 0x114(%rsp), %xmm0
movss %xmm0, 0xf4(%rsp)
movss 0xd4(%rsp), %xmm0
subss 0xd8(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
addss %xmm1, %xmm1
subss %xmm1, %xmm0
divss 0xf4(%rsp), %xmm0
callq 0x8e20
cvttss2si %xmm0, %eax
movl %eax, 0xfc(%rsp)
movl $0x1, %eax
cmpl 0xfc(%rsp), %eax
jle 0x58c46
movl $0x1, %eax
movl %eax, 0x58(%rsp)
jmp 0x58c51
movl 0xfc(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0x58(%rsp), %eax
movl %eax, 0xfc(%rsp)
cmpl $0x40, 0xfc(%rsp)
jle 0x58c99
movl $0x40, 0xfc(%rsp)
movss 0xd4(%rsp), %xmm0
subss 0xd8(%rsp), %xmm0
cvtsi2ssl 0xfc(%rsp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, 0xf4(%rsp)
movss 0xd8(%rsp), %xmm0
addss 0xd4(%rsp), %xmm0
cvtss2sd %xmm0, %xmm1
movsd 0x14f81(%rip), %xmm0    # 0x6dc38
divsd %xmm0, %xmm1
cvtsi2sdl 0xfc(%rsp), %xmm0
movsd 0x14f6c(%rip), %xmm2    # 0x6dc38
divsd %xmm2, %xmm0
movss 0xf4(%rsp), %xmm2
cvtss2sd %xmm2, %xmm2
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x104(%rsp)
movl $0x0, 0x5536ecd(%rip)   # 0x558fbe0
movl $0x1, 0xbc(%rsp)
movl 0xbc(%rsp), %eax
cmpl 0x100(%rsp), %eax
jge 0x58f87
movq $0x0, 0xb0(%rsp)
movq $0x0, 0xa8(%rsp)
movss 0x108(%rsp), %xmm1
cvtsi2ssl 0xbc(%rsp), %xmm0
movss 0xf8(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0xb8(%rsp)
movq 0x118(%rsp), %rdi
movq 0x128(%rsp), %rsi
movss 0xb8(%rsp), %xmm0
leaq 0xb0(%rsp), %rdx
leaq 0xa8(%rsp), %rcx
movss 0x14de9(%rip), %xmm1    # 0x6db90
callq 0xf750
cmpq $0x0, 0xb0(%rsp)
je 0x58de3
movq 0xb0(%rsp), %rdi
movq 0x128(%rsp), %rsi
movss 0xb8(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
callq 0x102f0
cmpl $0x2, %eax
jne 0x58e52
cmpq $0x0, 0xb0(%rsp)
je 0x58e18
movq 0xb0(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpq $0x0, %rax
je 0x58e0c
movq 0x50(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0xb0(%rsp)
cmpq $0x0, 0xa8(%rsp)
je 0x58e4d
movq 0xa8(%rsp), %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0x58e41
movq 0x48(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0xa8(%rsp)
jmp 0x58f87
cmpq $0x0, 0xa8(%rsp)
je 0x58e89
movq 0xa8(%rsp), %rdi
movq 0x128(%rsp), %rsi
movss 0xb8(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
callq 0x102f0
cmpl $0x2, %eax
jne 0x58ef5
cmpq $0x0, 0xb0(%rsp)
je 0x58ebe
movq 0xb0(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, %rax
je 0x58eb2
movq 0x40(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0xb0(%rsp)
cmpq $0x0, 0xa8(%rsp)
je 0x58ef3
movq 0xa8(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, %rax
je 0x58ee7
movq 0x38(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0xa8(%rsp)
jmp 0x58f71
movq 0x118(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x58f13
movq 0x30(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x118(%rsp)
movq 0xa8(%rsp), %rdx
movl 0x5536cb3(%rip), %eax   # 0x558fbe0
movl %eax, %ecx
leaq 0x5516caa(%rip), %rax   # 0x556fbe0
movq %rdx, (%rax,%rcx,8)
movl 0x5536ca0(%rip), %eax   # 0x558fbe0
addl $0x1, %eax
movl %eax, 0x5536c97(%rip)   # 0x558fbe0
movq $0x0, 0xa8(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0x118(%rsp)
movq $0x0, 0xb0(%rsp)
movl 0xbc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xbc(%rsp)
jmp 0x58d1e
movq 0x118(%rsp), %rdx
movl 0x5536c4b(%rip), %eax   # 0x558fbe0
movl %eax, %ecx
leaq 0x5516c42(%rip), %rax   # 0x556fbe0
movq %rdx, (%rax,%rcx,8)
movl 0x5536c38(%rip), %eax   # 0x558fbe0
addl $0x1, %eax
movl %eax, 0x5536c2f(%rip)   # 0x558fbe0
movq $0x0, 0x118(%rsp)
movl 0x5536c1d(%rip), %eax   # 0x558fbe0
movl %eax, 0xf0(%rsp)
movl $0x0, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
cmpl 0xf0(%rsp), %eax
jge 0x592db
movslq 0xa4(%rsp), %rcx
leaq 0x5516be8(%rip), %rax   # 0x556fbe0
movq (%rax,%rcx,8), %rax
movq %rax, 0x98(%rsp)
movslq 0xa4(%rsp), %rcx
leaq 0x5516bcd(%rip), %rax   # 0x556fbe0
movq $0x0, (%rax,%rcx,8)
movl $0x1, 0x94(%rsp)
movl 0x94(%rsp), %eax
cmpl 0xfc(%rsp), %eax
jge 0x5928f
movq $0x0, 0x88(%rsp)
movq $0x0, 0x80(%rsp)
movss 0x104(%rsp), %xmm1
cvtsi2ssl 0x94(%rsp), %xmm0
movss 0xf4(%rsp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, 0x90(%rsp)
movq 0x98(%rsp), %rdi
movq 0x120(%rsp), %rsi
movss 0x90(%rsp), %xmm0
leaq 0x88(%rsp), %rdx
leaq 0x80(%rsp), %rcx
movss 0x14ae1(%rip), %xmm1    # 0x6db90
callq 0xf750
cmpq $0x0, 0x88(%rsp)
je 0x590eb
movq 0x88(%rsp), %rdi
movq 0x120(%rsp), %rsi
movss 0x90(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
callq 0x102f0
cmpl $0x2, %eax
jne 0x5915a
cmpq $0x0, 0x88(%rsp)
je 0x59120
movq 0x88(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x59114
movq 0x28(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x88(%rsp)
cmpq $0x0, 0x80(%rsp)
je 0x59155
movq 0x80(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x59149
movq 0x20(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x80(%rsp)
jmp 0x5928f
cmpq $0x0, 0x80(%rsp)
je 0x59191
movq 0x80(%rsp), %rdi
movq 0x120(%rsp), %rsi
movss 0x90(%rsp), %xmm0
movss 0x110(%rsp), %xmm1
callq 0x102f0
cmpl $0x2, %eax
jne 0x591fd
cmpq $0x0, 0x88(%rsp)
je 0x591c6
movq 0x88(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x591ba
movq 0x18(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x88(%rsp)
cmpq $0x0, 0x80(%rsp)
je 0x591fb
movq 0x80(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x591ef
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x80(%rsp)
jmp 0x59279
movq 0x98(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x5921b
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x98(%rsp)
movq 0x80(%rsp), %rdx
movl 0x55369ab(%rip), %eax   # 0x558fbe0
movl %eax, %ecx
leaq 0x55169a2(%rip), %rax   # 0x556fbe0
movq %rdx, (%rax,%rcx,8)
movl 0x5536998(%rip), %eax   # 0x558fbe0
addl $0x1, %eax
movl %eax, 0x553698f(%rip)   # 0x558fbe0
movq $0x0, 0x80(%rsp)
movq 0x88(%rsp), %rax
movq %rax, 0x98(%rsp)
movq $0x0, 0x88(%rsp)
movl 0x94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x94(%rsp)
jmp 0x59026
movq 0x98(%rsp), %rdx
movl 0x5536943(%rip), %eax   # 0x558fbe0
movl %eax, %ecx
leaq 0x551693a(%rip), %rax   # 0x556fbe0
movq %rdx, (%rax,%rcx,8)
movl 0x5536930(%rip), %eax   # 0x558fbe0
addl $0x1, %eax
movl %eax, 0x5536927(%rip)   # 0x558fbe0
movq $0x0, 0x98(%rsp)
movl 0xa4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa4(%rsp)
jmp 0x58fd5
movq 0x130(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x592fb
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x130(%rsp), %rax
movq $0x0, 0x28(%rax)
addq $0x138, %rsp            # imm = 0x138
retq
movq 0xe8(%rsp), %rdi
callq 0x45c0