// File: /workspace/github_cpp_makefile_star2_O3/FreeSlave[P]vhlt/hlvis/flow.cpp
// Function: ClipToSeperators(winding_t const*, winding_t const*, winding_t*, bool, pstack_s*)
inline static winding_t* ClipToSeperators(
    const winding_t* const source,
    const winding_t* const pass, 
    winding_t* const a_target,
    const bool flipclip, 
    pstack_t* const stack)
{
    int             i, j, k, l;
    plane_t         plane;
    vec3_t          v1, v2;
    float           d;
    int             counts[3];
    bool            fliptest;
    winding_t*      target = a_target;

    const unsigned int numpoints = source->numpoints;

    // check all combinations       
    for (i=0, l=1; i < numpoints; i++, l++)
    {
        if (l == numpoints)
        {
            l = 0;
        }

        VectorSubtract(source->points[l], source->points[i], v1);

        // fing a vertex of pass that makes a plane that puts all of the
        // vertexes of pass on the front side and all of the vertexes of
        // source on the back side
        for (j = 0; j < pass->numpoints; j++)
        {
            VectorSubtract(pass->points[j], source->points[i], v2);
            CrossProduct(v1, v2, plane.normal);
            if (VectorNormalize(plane.normal) < ON_EPSILON)
            {
                continue;
            }
            plane.dist = DotProduct(pass->points[j], plane.normal);

            // find out which side of the generated seperating plane has the
            // source portal
            fliptest = false;
            for (k = 0; k < numpoints; k++)
            {
                if ((k == i) | (k == l)) // | instead of || for branch optimization
                {
                    continue;
                }
                d = DotProduct(source->points[k], plane.normal) - plane.dist;
                if (d < -ON_EPSILON)
                {                                          // source is on the negative side, so we want all
                    // pass and target on the positive side
                    fliptest = false;
                    break;
                }
                else if (d > ON_EPSILON)
                {                                          // source is on the positive side, so we want all
                    // pass and target on the negative side
                    fliptest = true;
                    break;
                }
            }
            if (k == numpoints)
            {
                continue;                                  // planar with source portal
            }

            // flip the normal if the source portal is backwards
            if (fliptest)
            {
                VectorSubtract(vec3_origin, plane.normal, plane.normal);
                plane.dist = -plane.dist;
            }

            // if all of the pass portal points are now on the positive side,
            // this is the seperating plane
            counts[0] = counts[1] = counts[2] = 0;
            for (k = 0; k < pass->numpoints; k++)
            {
                if (k == j)
                {
                    continue;
                }
                d = DotProduct(pass->points[k], plane.normal) - plane.dist;
                if (d < -ON_EPSILON)
                {
                    break;
                }
                else if (d > ON_EPSILON)
                {
                    counts[0]++;
                }
                else
                {
                    counts[2]++;
                }
            }
            if (k != pass->numpoints)
            {
                continue;                                  // points on negative side, not a seperating plane
            }

            if (!counts[0])
            {
                continue;                                  // planar with seperating plane
            }

            // flip the normal if we want the back side
            if (flipclip)
            {
                VectorSubtract(vec3_origin, plane.normal, plane.normal);
                plane.dist = -plane.dist;
            }

	    if (target != NULL)
	    {
            // clip target by the seperating plane
            target = ChopWinding(target, stack, &plane);
            if (!target)
            {
                return NULL;                               // target is not visible
            }
	    }
	    else
	    {
        	AddPlane(stack, &plane);
	    }

#ifdef RVIS_LEVEL_1
            break; /* Antony was here */
#endif
        }
    }

    return target;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdx, %rax
movl 0x4(%rdi), %r13d
testq %r13, %r13
je 0xeaec
movq %rdi, %r15
leaq 0x8(%rdi), %r12
leaq 0x8(%rsi), %rbp
leaq 0x5761(%rip), %rdx      # 0x13df0
movsd (%rdx), %xmm13
movss 0x8(%rdx), %xmm14
addq $0x10, %r15
leaq 0x10(%rsi), %rdx
movq %rdx, 0x28(%rsp)
movl $0x1, %r14d
movaps 0x39cb(%rip), %xmm15    # 0x12080
xorl %ebx, %ebx
movq %r8, 0x20(%rsp)
movl %ecx, 0x1c(%rsp)
movq %rsi, (%rsp)
movaps %xmm13, 0x30(%rsp)
movss %xmm14, 0x18(%rsp)
cmpl %r13d, %r14d
movl $0x0, %edx
cmovel %edx, %r14d
movl 0x4(%rsi), %r11d
testl %r11d, %r11d
jle 0xe992
movslq %r14d, %rdx
leaq (%rdx,%rdx,2), %rsi
movss (%r12,%rsi,4), %xmm1
leaq (%rbx,%rbx,2), %rdi
movss (%r12,%rdi,4), %xmm3
subss %xmm3, %xmm1
movsd 0x4(%r12,%rsi,4), %xmm4
movsd 0x4(%r12,%rdi,4), %xmm5
subps %xmm5, %xmm4
movaps %xmm1, %xmm6
shufps $0xd4, %xmm4, %xmm6     # xmm6 = xmm6[0,1],xmm4[1,3]
shufps $0x52, %xmm4, %xmm6     # xmm6 = xmm6[2,0],xmm4[1,1]
xorps %xmm15, %xmm6
movaps %xmm4, %xmm7
xorps %xmm15, %xmm7
movl %edx, %edx
shufps $0xd4, %xmm5, %xmm3     # xmm3 = xmm3[0,1],xmm5[1,3]
shufps $0xe2, %xmm5, %xmm3     # xmm3 = xmm3[2,0],xmm5[2,3]
xorl %esi, %esi
leaq (%rsi,%rsi,2), %rdi
movss (%rbp,%rdi,4), %xmm9
movss 0x4(%rbp,%rdi,4), %xmm10
movaps %xmm10, %xmm8
subss %xmm5, %xmm8
movss 0x8(%rbp,%rdi,4), %xmm0
movaps %xmm0, %xmm11
unpcklps %xmm9, %xmm11           # xmm11 = xmm11[0],xmm9[0],xmm11[1],xmm9[1]
subps %xmm3, %xmm11
movaps %xmm11, %xmm12
shufps $0x0, %xmm11, %xmm12    # xmm12 = xmm12[0,0],xmm11[0,0]
movss %xmm8, %xmm12           # xmm12 = xmm8[0],xmm12[1,2,3]
mulps %xmm6, %xmm12
movaps %xmm4, %xmm2
mulps %xmm11, %xmm2
addps %xmm12, %xmm2
shufps $0x55, %xmm11, %xmm11   # xmm11 = xmm11[1,1,1,1]
mulss %xmm7, %xmm11
mulss %xmm1, %xmm8
addss %xmm11, %xmm8
movaps %xmm2, %xmm11
mulps %xmm2, %xmm11
shufps $0x55, %xmm11, %xmm11   # xmm11 = xmm11[1,1,1,1]
movaps %xmm2, %xmm12
mulss %xmm2, %xmm12
addss %xmm11, %xmm12
movaps %xmm8, %xmm11
mulss %xmm8, %xmm11
addss %xmm12, %xmm11
cvtss2sd %xmm11, %xmm11
sqrtsd %xmm11, %xmm11
movsd 0x3946(%rip), %xmm12    # 0x12118
ucomisd %xmm11, %xmm12
jbe 0xe7e5
xorps %xmm2, %xmm2
xorps %xmm8, %xmm8
jmp 0xe975
cvtps2pd %xmm2, %xmm2
movapd %xmm11, %xmm12
unpcklpd %xmm11, %xmm12          # xmm12 = xmm12[0],xmm11[0]
divpd %xmm12, %xmm2
cvtpd2ps %xmm2, %xmm2
cvtss2sd %xmm8, %xmm8
divsd %xmm11, %xmm8
cvtsd2ss %xmm8, %xmm8
cvtsd2ss %xmm11, %xmm11
cvtss2sd %xmm11, %xmm11
movsd 0x6c5b(%rip), %xmm12    # 0x15478
ucomisd %xmm11, %xmm12
ja 0xe975
movapd %xmm2, %xmm11
shufps $0x55, %xmm2, %xmm11    # xmm11 = xmm11[1,1],xmm2[1,1]
mulss %xmm11, %xmm10
mulss %xmm2, %xmm9
addss %xmm10, %xmm9
mulss %xmm8, %xmm0
addss %xmm9, %xmm0
movss %xmm0, 0x14(%rsp)
movq %r15, %r9
xorl %edi, %edi
cmpq %rdi, %rbx
je 0xe8ab
cmpq %rdi, %rdx
je 0xe8ab
movss -0x4(%r9), %xmm9
mulss %xmm11, %xmm9
movss -0x8(%r9), %xmm10
mulss %xmm2, %xmm10
addss %xmm9, %xmm10
movss (%r9), %xmm9
mulss %xmm8, %xmm9
addss %xmm10, %xmm9
subss %xmm0, %xmm9
cvtss2sd %xmm9, %xmm9
movsd 0x6be3(%rip), %xmm10    # 0x15480
ucomisd %xmm9, %xmm10
ja 0xe8bc
ucomisd %xmm12, %xmm9
ja 0xe8c6
incq %rdi
addq $0xc, %r9
cmpq %rdi, %r13
jne 0xe856
jmp 0xe975
cmpl %edi, %r13d
jne 0xe8e9
jmp 0xe975
movaps %xmm13, %xmm9
subps %xmm2, %xmm9
movaps %xmm14, %xmm2
subss %xmm8, %xmm2
xorps %xmm15, %xmm0
movss %xmm0, 0x14(%rsp)
movaps %xmm2, %xmm8
movaps %xmm9, %xmm2
movaps %xmm2, %xmm9
shufps $0x55, %xmm2, %xmm9     # xmm9 = xmm9[1,1],xmm2[1,1]
xorl %edi, %edi
movq 0x28(%rsp), %r9
xorl %r10d, %r10d
cmpq %rdi, %rsi
je 0xe94f
movss -0x4(%r9), %xmm10
mulss %xmm9, %xmm10
movss -0x8(%r9), %xmm11
mulss %xmm2, %xmm11
addss %xmm10, %xmm11
movss (%r9), %xmm10
mulss %xmm8, %xmm10
addss %xmm11, %xmm10
subss %xmm0, %xmm10
cvtss2sd %xmm10, %xmm10
movsd 0x6b42(%rip), %xmm11    # 0x15480
ucomisd %xmm10, %xmm11
ja 0xe95e
ucomisd %xmm12, %xmm10
jbe 0xe94f
incl %r10d
incq %rdi
addq $0xc, %r9
cmpq %rdi, %r11
jne 0xe8fc
movl %r11d, %edi
cmpl %r11d, %edi
sete %dil
testl %r10d, %r10d
setne %r9b
andb %dil, %r9b
cmpb $0x1, %r9b
je 0xe9a6
incq %rsi
cmpq %r11, %rsi
jne 0xe738
movlpd %xmm2, 0x8(%rsp)
movss %xmm8, 0x10(%rsp)
movq (%rsp), %rsi
incq %rbx
incl %r14d
cmpq %r13, %rbx
jne 0xe6d1
jmp 0xeaec
movlps %xmm2, 0x8(%rsp)
movss %xmm8, 0x10(%rsp)
testb %cl, %cl
je 0xe9de
movaps %xmm13, %xmm1
subps %xmm2, %xmm1
movlps %xmm1, 0x8(%rsp)
movaps %xmm14, %xmm2
subss %xmm8, %xmm2
movss %xmm2, 0x10(%rsp)
xorps %xmm15, %xmm0
movss %xmm0, 0x14(%rsp)
movaps %xmm1, %xmm2
testq %rax, %rax
je 0xea23
movq %rax, %rdi
movq %r8, %rsi
leaq 0x8(%rsp), %rdx
callq 0xeafb
movaps 0x3685(%rip), %xmm15    # 0x12080
movss 0x18(%rsp), %xmm14
movaps 0x30(%rsp), %xmm13
movl 0x1c(%rsp), %ecx
movq 0x20(%rsp), %r8
testq %rax, %rax
movq (%rsp), %rsi
jne 0xe992
jmp 0xeaea
movslq 0x14d0(%r8), %rax
movq 0x14d8(%r8), %r9
testq %rax, %rax
jle 0xeace
leaq 0x4(%r9), %rdx
xorl %esi, %esi
movq %rsi, %rdi
shlq $0x4, %rdi
movss 0xc(%r9,%rdi), %xmm1
subss %xmm0, %xmm1
andps 0x6857(%rip), %xmm1     # 0x152b0
cvtss2sd %xmm1, %xmm1
movsd 0x6a0b(%rip), %xmm3     # 0x15470
ucomisd %xmm1, %xmm3
jb 0xeabe
movss (%r9,%rdi), %xmm1
subss %xmm2, %xmm1
andps 0x6834(%rip), %xmm1     # 0x152b0
cvtss2sd %xmm1, %xmm1
ucomisd 0x69e8(%rip), %xmm1     # 0x15470
ja 0xeabe
xorl %edi, %edi
cmpq $0x2, %rdi
je 0xeae3
movss (%rdx,%rdi,4), %xmm1
subss 0xc(%rsp,%rdi,4), %xmm1
andps 0x680c(%rip), %xmm1     # 0x152b0
cvtss2sd %xmm1, %xmm1
incq %rdi
ucomisd 0x69bd(%rip), %xmm1     # 0x15470
jbe 0xea8c
decq %rdi
cmpq $0x1, %rdi
ja 0xeae3
incq %rsi
addq $0x10, %rdx
cmpq %rax, %rsi
jne 0xea40
shlq $0x4, %rax
movups 0x8(%rsp), %xmm0
movups %xmm0, (%r9,%rax)
incl 0x14d0(%r8)
xorl %eax, %eax
jmp 0xe98e
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq