// File: /workspace/github_cpp_makefile_star2_O1/FreeSlave[P]vhlt/hlvis/flow.cpp
// Function: ChopWinding(winding_t*, pstack_s*, plane_t const*)
inline winding_t*      ChopWinding(winding_t* const in, pstack_t* const stack, const plane_t* const split)
{
    vec_t           dists[128];
    int             sides[128];
    int             counts[3];
    vec_t           dot;
    int             i;
    vec3_t          mid;
    winding_t*      neww;

    counts[0] = counts[1] = counts[2] = 0;

    if (in->numpoints > (sizeof(sides) / sizeof(*sides)))
    {
        Error("Winding with too many sides!");
    }

    // determine sides for each point
    for (i = 0; i < in->numpoints; i++)
    {
        dot = DotProduct(in->points[i], split->normal);
        dot -= split->dist;
        dists[i] = dot;
        if (dot > ON_EPSILON)
        {
            sides[i] = SIDE_FRONT;
        }
        else if (dot < -ON_EPSILON)
        {
            sides[i] = SIDE_BACK;
        }
        else
        {
            sides[i] = SIDE_ON;
        }
        counts[sides[i]]++;
    }

    if (!counts[1])
    {
        return in;                                         // completely on front side
    }

    if (!counts[0])
    {
        FreeStackWinding(in, stack);
        return NULL;
    }

    sides[i] = sides[0];
    dists[i] = dists[0];

    neww = AllocStackWinding(stack);

    neww->numpoints = 0;

    for (i = 0; i < in->numpoints; i++)
    {
        vec_t* p1 = in->points[i];

        if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
        {
            Warning("ChopWinding : rejected(1) due to too many points\n");
            FreeStackWinding(neww, stack);
            return in;                                     // can't chop -- fall back to original
        }

        if (sides[i] == SIDE_ON)
        {
            VectorCopy(p1, neww->points[neww->numpoints]);
            neww->numpoints++;
            continue;
        }
        else if (sides[i] == SIDE_FRONT)
        {
            VectorCopy(p1, neww->points[neww->numpoints]);
            neww->numpoints++;
        }

        if ((sides[i + 1] == SIDE_ON) | (sides[i + 1] == sides[i])) // | instead of || for branch optimization
        {
            continue;
        }

        if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
        {
            Warning("ChopWinding : rejected(2) due to too many points\n");
            FreeStackWinding(neww, stack);
            return in;                                     // can't chop -- fall back to original
        }

        // generate a split point
        {
            unsigned tmp = i + 1;
            if (tmp >= in->numpoints)
            {
                tmp = 0;
            }
            const vec_t* p2 = in->points[tmp];

            dot = dists[i] / (dists[i] - dists[i + 1]);

            const vec_t* normal = split->normal;
            const vec_t dist = split->dist;
            unsigned int j;
            for (j = 0; j < 3; j++)
            {                                                  // avoid round off error when possible
                if (normal[j] < (1.0 - NORMAL_EPSILON))
                {
                    if (normal[j] > (-1.0 + NORMAL_EPSILON))
                    {
                        mid[j] = p1[j] + dot * (p2[j] - p1[j]);
                    }
                    else
                    {
                        mid[j] = -dist;
                    }
                }
                else
                {
                    mid[j] = dist;
                }
            }
        }

        VectorCopy(mid, neww->points[neww->numpoints]);
        neww->numpoints++;
    }

    // free the original winding
    FreeStackWinding(in, stack);

    return neww;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x458, %rsp            # imm = 0x458
movq %rdi, %r8
movl $0x0, 0x2c(%rsp)
movq $0x0, 0x24(%rsp)
cmpl $0x81, 0x4(%rdi)
movq %rsi, (%rsp)
movq %rdx, 0x8(%rsp)
jb 0xf030
leaq 0x64d1(%rip), %rdi      # 0x154eb
xorl %eax, %eax
movq %r8, %rbx
callq 0x8d9c
movq 0x8(%rsp), %rdx
movq %rbx, %r8
movq (%rsp), %rsi
movslq 0x4(%r8), %rcx
testq %rcx, %rcx
jle 0xf0db
movss (%rdx), %xmm0
movss 0x4(%rdx), %xmm1
movss 0x8(%rdx), %xmm2
movss 0xc(%rdx), %xmm3
leaq 0x10(%r8), %r9
xorl %eax, %eax
movsd 0x642a(%rip), %xmm4     # 0x15488
movsd 0x642a(%rip), %xmm5     # 0x15490
movss -0x4(%r9), %xmm6
mulss %xmm1, %xmm6
movss -0x8(%r9), %xmm7
mulss %xmm0, %xmm7
addss %xmm6, %xmm7
movss (%r9), %xmm6
mulss %xmm2, %xmm6
addss %xmm7, %xmm6
subss %xmm3, %xmm6
movss %xmm6, 0x250(%rsp,%rax,4)
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
jbe 0xf0ac
movl $0x0, 0x50(%rsp,%rax,4)
jmp 0xf0c4
ucomisd %xmm6, %xmm5
jbe 0xf0bc
movl $0x1, 0x50(%rsp,%rax,4)
jmp 0xf0c4
movl $0x2, 0x50(%rsp,%rax,4)
movslq 0x50(%rsp,%rax,4), %rdi
incl 0x24(%rsp,%rdi,4)
incq %rax
addq $0xc, %r9
cmpq %rax, %rcx
jne 0xf066
jmp 0xf0dd
xorl %eax, %eax
cmpl $0x0, 0x28(%rsp)
je 0xf438
cmpl $0x0, 0x24(%rsp)
je 0xf414
movl 0x50(%rsp), %ecx
movl %ecx, 0x50(%rsp,%rax,4)
movss 0x250(%rsp), %xmm0
movss %xmm0, 0x250(%rsp,%rax,4)
leaq 0x14c0(%rsi), %rax
movq %rax, 0x38(%rsp)
movl $0x14c0, %r13d          # imm = 0x14C0
movq $-0x1028, %rbp          # imm = 0xEFD8
movl $0x1038, %r12d          # imm = 0x1038
movl $0x1030, %r14d          # imm = 0x1030
movl $0x102c, %r15d          # imm = 0x102C
movl $0x188, %eax            # imm = 0x188
cmpb $0x0, (%rsi,%r13)
jne 0xf165
incq %r13
addq $-0x188, %rbp           # imm = 0xFE78
addq %rax, %r12
addq %rax, %r14
addq %rax, %r15
cmpq $-0x14c0, %rbp          # imm = 0xEB40
jne 0xf13d
callq 0x35a8
movb $0x0, (%rsi,%r13)
movl $0x0, (%rsi,%r15)
cmpl $0x0, 0x4(%r8)
jle 0xf3c2
leaq 0x8(%r8), %rax
leal -0x14c0(%r13), %ecx
movl %ecx, 0x20(%rsp)
movsd 0x6314(%rip), %xmm5     # 0x154a8
movsd 0x2f8c(%rip), %xmm6     # 0x12128
movq %rax, 0x30(%rsp)
movq %rax, %r9
xorl %ebx, %ebx
movslq (%rsi,%r15), %rdi
cmpq $0x20, %rdi
jne 0xf1dd
movq %r9, 0x10(%rsp)
movq %r8, 0x18(%rsp)
leaq 0x6347(%rip), %rdi      # 0x15508
xorl %eax, %eax
callq 0x910e
movl $0x1, %eax
cmpl $0x2, 0x20(%rsp)
jbe 0xf237
movq (%rsp), %rsi
jmp 0xf25e
leaq (%rbx,%rbx,2), %rax
movq 0x30(%rsp), %rcx
leaq (%rcx,%rax,4), %rax
movl 0x50(%rsp,%rbx,4), %ecx
testl %ecx, %ecx
je 0xf282
cmpl $0x2, %ecx
jne 0xf2b0
movss (%rax), %xmm0
leaq (%rdi,%rdi,2), %rcx
leaq (%rsi,%rcx,4), %rcx
movss %xmm0, -0x8(%r12,%rcx)
movss 0x4(%rax), %xmm0
movss %xmm0, -0x4(%r12,%rcx)
movss 0x8(%rax), %xmm0
movss %xmm0, (%r12,%rcx)
incl (%rsi,%r15)
movl $0x7, %eax
jmp 0xf3a1
movq (%rsp), %rsi
cmpb $0x0, (%rsi,%r13)
je 0xf259
leaq 0x6323(%rip), %rdi      # 0x1556c
xorl %eax, %eax
callq 0x8d9c
movl $0x1, %eax
movq (%rsp), %rsi
movb $0x1, (%rsi,%r13)
movq 0x18(%rsp), %r8
movq 0x8(%rsp), %rdx
movsd 0x6238(%rip), %xmm5     # 0x154a8
movsd 0x2eb0(%rip), %xmm6     # 0x12128
movq 0x10(%rsp), %r9
jmp 0xf3a1
movss (%rax), %xmm0
leaq (%rdi,%rdi,2), %rdi
leaq (%rsi,%rdi,4), %rdi
movss %xmm0, -0x8(%r12,%rdi)
movss 0x4(%rax), %xmm0
movss %xmm0, -0x4(%r12,%rdi)
movss 0x8(%rax), %xmm0
movss %xmm0, (%r12,%rdi)
incl (%rsi,%r15)
movl 0x54(%rsp,%rbx,4), %eax
cmpl $0x2, %eax
sete %dil
cmpl %ecx, %eax
sete %al
orb %dil, %al
movl $0x7, %eax
jne 0xf3a1
movslq (%rsi,%r15), %rax
cmpq $0x20, %rax
jne 0xf2ee
movq %r9, 0x10(%rsp)
movq %r8, 0x18(%rsp)
leaq 0x6251(%rip), %rdi      # 0x1553a
jmp 0xf1c1
leaq 0x1(%rbx), %rcx
movl 0x4(%r8), %edi
cmpq %rdi, %rcx
movl %ecx, %ecx
movl $0x0, %edi
cmovaeq %rdi, %rcx
leaq (%rcx,%rcx,2), %rcx
movq 0x30(%rsp), %rdi
leaq (%rdi,%rcx,4), %rcx
movss 0x250(%rsp,%rbx,4), %xmm0
movaps %xmm0, %xmm1
subss 0x254(%rsp,%rbx,4), %xmm1
divss %xmm1, %xmm0
movss 0xc(%rdx), %xmm1
movaps %xmm1, %xmm2
xorps 0x2d57(%rip), %xmm2     # 0x12090
xorl %edi, %edi
xorps %xmm4, %xmm4
cvtss2sd (%rdx,%rdi,4), %xmm4
ucomisd %xmm4, %xmm5
movaps %xmm1, %xmm3
jbe 0xf36c
ucomisd %xmm6, %xmm4
movaps %xmm2, %xmm3
jbe 0xf36c
movss (%r9,%rdi,4), %xmm4
movss (%rcx,%rdi,4), %xmm3
subss %xmm4, %xmm3
mulss %xmm0, %xmm3
addss %xmm4, %xmm3
movss %xmm3, 0x40(%rsp,%rdi,4)
incq %rdi
cmpq $0x3, %rdi
jne 0xf33b
leaq (%rax,%rax,2), %rax
leaq (%rsi,%rax,4), %rax
movsd 0x40(%rsp), %xmm0
movsd %xmm0, (%r14,%rax)
movss 0x48(%rsp), %xmm0
movss %xmm0, (%r12,%rax)
incl (%rsi,%r15)
xorl %eax, %eax
cmpl $0x7, %eax
je 0xf3ae
testl %eax, %eax
jne 0xf438
incq %rbx
movslq 0x4(%r8), %rax
addq $0xc, %r9
cmpq %rax, %rbx
jl 0xf1a6
subq %rsi, %r8
subq %rbp, %rsi
addq $-0x1028, %r8           # imm = 0xEFD8
sarq $0x3, %r8
movabsq $0x7d6343eb1a1f58d1, %rax # imm = 0x7D6343EB1A1F58D1
imulq %r8, %rax
cmpl $0x2, %eax
ja 0xf40f
andl $0x3, %eax
movq 0x38(%rsp), %rcx
leaq (%rcx,%rax), %rbx
cmpb $0x0, (%rcx,%rax)
je 0xf40c
leaq 0x616d(%rip), %rdi      # 0x1556c
xorl %eax, %eax
movq %rsi, %r14
callq 0x8d9c
movq %r14, %rsi
movb $0x1, (%rbx)
movq %rsi, %r8
jmp 0xf438
subq %rsi, %r8
addq $-0x1028, %r8           # imm = 0xEFD8
sarq $0x3, %r8
movabsq $0x7d6343eb1a1f58d1, %rax # imm = 0x7D6343EB1A1F58D1
imulq %r8, %rax
cmpl $0x2, %eax
jbe 0xf44d
xorl %r8d, %r8d
movq %r8, %rax
addq $0x458, %rsp            # imm = 0x458
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $0x3, %eax
leaq (%rsi,%rax), %rbx
addq $0x14c0, %rbx           # imm = 0x14C0
xorl %esi, %esi
cmpb $0x0, (%rbx)
jne 0xf3f8
jmp 0xf40c