// File: /workspace/github_cpp_makefile_star2_O2/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 $0x438, %rsp            # imm = 0x438
andl $0x0, 0x14(%rsp)
andl $0x0, 0xc(%rsp)
movq %rdx, %r15
andl $0x0, 0x10(%rsp)
movq %rsi, %r14
movq %rdi, %rbx
movl 0x4(%rdi), %ecx
cmpl $0x81, %ecx
jb 0xcd26
leaq 0x670f(%rip), %rdi      # 0x1342b
xorl %eax, %eax
callq 0x795f
movl 0x4(%rbx), %ecx
leaq 0x8(%rbx), %rax
xorl %edx, %edx
testl %ecx, %ecx
cmovlel %edx, %ecx
leaq 0x10(%rbx), %rsi
movsd 0x668b(%rip), %xmm0     # 0x133c8
leaq 0x10(%rsp), %rdi
movsd 0x6686(%rip), %xmm1     # 0x133d0
leaq 0xc(%rsp), %r8
leaq 0x14(%rsp), %r9
cmpq %rdx, %rcx
je 0xcdcd
movss -0x8(%rsi), %xmm2
movss -0x4(%rsi), %xmm3
mulss 0x4(%r15), %xmm3
mulss (%r15), %xmm2
movss (%rsi), %xmm4
mulss 0x8(%r15), %xmm4
addss %xmm3, %xmm2
addss %xmm2, %xmm4
subss 0xc(%r15), %xmm4
movss %xmm4, 0x230(%rsp,%rdx,4)
cvtss2sd %xmm4, %xmm2
ucomisd %xmm0, %xmm2
jbe 0xcda3
andl $0x0, 0x30(%rsp,%rdx,4)
movq %rdi, %r10
jmp 0xcdc1
ucomisd %xmm2, %xmm1
jbe 0xcdb6
movl $0x1, 0x30(%rsp,%rdx,4)
movq %r8, %r10
jmp 0xcdc1
movl $0x2, 0x30(%rsp,%rdx,4)
movq %r9, %r10
incl (%r10)
incq %rdx
addq $0xc, %rsi
jmp 0xcd54
cmpl $0x0, 0xc(%rsp)
je 0xd056
cmpl $0x0, 0x10(%rsp)
je 0xd023
movl 0x30(%rsp), %edx
movl %edx, 0x30(%rsp,%rcx,4)
movss 0x230(%rsp), %xmm0
movss %xmm0, 0x230(%rsp,%rcx,4)
movl $0x14c0, %esi           # imm = 0x14C0
movq $-0xea0, %rdx           # imm = 0xF160
xorl %ecx, %ecx
cmpq $0x498, %rcx            # imm = 0x498
je 0xd06b
leaq 0x1(%rsi), %rdi
addq $-0x188, %rdx           # imm = 0xFE78
addq $0x188, %rcx            # imm = 0x188
cmpb $0x0, (%r14,%rsi)
movq %rdi, %rsi
je 0xce0b
movb $0x0, -0x1(%r14,%rdi)
movq %r14, %r12
subq %rdx, %r12
movq %r12, 0x18(%rsp)
andl $0x0, 0xea4(%r14,%rcx)
xorl %edi, %edi
leaq (%r14,%rcx), %r9
movaps 0x63b5(%rip), %xmm0     # 0x13210
movsd 0x6585(%rip), %xmm1     # 0x133e8
movsd 0x322d(%rip), %xmm2     # 0x10098
xorl %r10d, %r10d
xorl %r13d, %r13d
movslq 0x4(%rbx), %r8
cmpq %r8, %r13
jge 0xd02a
cmpl $0x20, %r10d
je 0xd034
movq %r13, %rbp
imulq $0xc, %r13, %r11
addq %rax, %r11
movl 0x30(%rsp,%r13,4), %r8d
movslq %r10d, %r13
testl %r8d, %r8d
je 0xcefa
cmpl $0x2, %r8d
jne 0xcf40
movss (%r11), %xmm3
imulq $0xc, %r13, %r8
movss %xmm3, 0xea8(%r8,%r9)
movss 0x4(%r11), %xmm3
movss %xmm3, 0xeac(%r8,%r9)
movss 0x8(%r11), %xmm3
movss %xmm3, 0xeb0(%r8,%r9)
movl 0xea4(%r14,%rcx), %r10d
incl %r10d
movl %r10d, 0xea4(%r14,%rcx)
incq %rbp
movq %rbp, %r13
jmp 0xce71
movss (%r11), %xmm3
imulq $0xc, %r13, %r10
movss %xmm3, 0xea8(%r10,%r9)
movss 0x4(%r11), %xmm3
movss %xmm3, 0xeac(%r10,%r9)
movss 0x8(%r11), %xmm3
movss %xmm3, 0xeb0(%r10,%r9)
movl 0xea4(%r14,%rcx), %r10d
incl %r10d
movl %r10d, 0xea4(%r14,%rcx)
leaq 0x1(%rbp), %r13
movl 0x34(%rsp,%rbp,4), %edx
cmpl $0x2, %edx
sete %sil
cmpl %r8d, %edx
sete %dl
orb %sil, %dl
jne 0xce71
cmpl $0x20, %r10d
je 0xd03d
movl 0x4(%rbx), %edx
cmpq %rdx, %r13
movl %r13d, %edx
cmovaeq %rdi, %rdx
imulq $0xc, %rdx, %r8
addq %rax, %r8
movss 0x230(%rsp,%rbp,4), %xmm3
movaps %xmm3, %xmm4
subss 0x234(%rsp,%rbp,4), %xmm4
divss %xmm4, %xmm3
movss 0xc(%r15), %xmm4
movaps %xmm4, %xmm5
xorps %xmm0, %xmm5
xorl %ebp, %ebp
cmpq $0x3, %rbp
je 0xcfe4
cvtss2sd (%r15,%rbp,4), %xmm7
ucomisd %xmm7, %xmm1
movaps %xmm4, %xmm6
jbe 0xcfd9
ucomisd %xmm2, %xmm7
movaps %xmm5, %xmm6
jbe 0xcfd9
movss (%r11,%rbp,4), %xmm7
movss (%r8,%rbp,4), %xmm6
subss %xmm7, %xmm6
mulss %xmm3, %xmm6
addss %xmm7, %xmm6
movss %xmm6, 0x20(%rsp,%rbp,4)
incq %rbp
jmp 0xcfa3
movslq %r10d, %rdx
imulq $0xc, %rdx, %rdx
movsd 0x20(%rsp), %xmm3
movsd %xmm3, 0xea8(%rdx,%r9)
movss 0x28(%rsp), %xmm3
movss %xmm3, 0xeb0(%rdx,%r9)
movl 0xea4(%r14,%rcx), %r10d
incl %r10d
movl %r10d, 0xea4(%r14,%rcx)
jmp 0xce71
movq %rbx, %r12
xorl %ebx, %ebx
jmp 0xd04b
movq %rbx, %r12
movq 0x18(%rsp), %rbx
jmp 0xd04b
leaq 0x640d(%rip), %rdi      # 0x13448
jmp 0xd044
leaq 0x6436(%rip), %rdi      # 0x1347a
xorl %eax, %eax
callq 0x7cd5
movq %r12, %rdi
movq %r14, %rsi
callq 0xcc52
movq %rbx, %rax
addq $0x438, %rsp            # imm = 0x438
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x645a(%rip), %rdi      # 0x134cc
xorl %eax, %eax
callq 0x795f
nopl (%rax)