// File: /workspace/github_cpp_makefile_star2_O3/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
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %rbx
xorl %eax, %eax
movl %eax, 0xc(%rsp)
movl %eax, 0x4(%rsp)
movl %eax, 0x8(%rsp)
movl 0x4(%rdi), %eax
cmpl $0x81, %eax
jb 0xeb3e
leaq 0x69a7(%rip), %rdi      # 0x154db
xorl %eax, %eax
callq 0x8cb4
movl 0x4(%rbx), %eax
testl %eax, %eax
jle 0xeec5
movss (%r15), %xmm0
movss 0x4(%r15), %xmm1
movss 0x8(%r15), %xmm2
movss 0xc(%r15), %xmm3
movl %eax, %eax
leaq 0x10(%rbx), %rcx
xorl %edx, %edx
movsd 0x690b(%rip), %xmm4     # 0x15478
leaq 0x8(%rsp), %rsi
movsd 0x6906(%rip), %xmm5     # 0x15480
leaq 0x4(%rsp), %rdi
leaq 0xc(%rsp), %r8
movss -0x4(%rcx), %xmm6
mulss %xmm1, %xmm6
movss -0x8(%rcx), %xmm7
mulss %xmm0, %xmm7
addss %xmm6, %xmm7
movss (%rcx), %xmm6
mulss %xmm2, %xmm6
addss %xmm7, %xmm6
subss %xmm3, %xmm6
movss %xmm6, 0x230(%rsp,%rdx,4)
cvtss2sd %xmm6, %xmm6
ucomisd %xmm4, %xmm6
jbe 0xebca
movl $0x0, 0x30(%rsp,%rdx,4)
movq %rsi, %r9
jmp 0xebe8
ucomisd %xmm6, %xmm5
jbe 0xebdd
movl $0x1, 0x30(%rsp,%rdx,4)
movq %rdi, %r9
jmp 0xebe8
movl $0x2, 0x30(%rsp,%rdx,4)
movq %r8, %r9
incl (%r9)
incq %rdx
addq $0xc, %rcx
cmpq %rdx, %rax
jne 0xeb84
cmpl $0x0, 0x4(%rsp)
je 0xeec5
cmpl $0x0, 0x8(%rsp)
je 0xee79
movl 0x30(%rsp), %ecx
movl %ecx, 0x30(%rsp,%rax,4)
movss 0x230(%rsp), %xmm0
movss %xmm0, 0x230(%rsp,%rax,4)
leaq 0x14c0(%r14), %r8
movl $0x14c0, %r12d          # imm = 0x14C0
movq $-0x1028, %rcx          # imm = 0xEFD8
movl $0x1030, %edx           # imm = 0x1030
movl $0x1038, %esi           # imm = 0x1038
movl $0x102c, %edi           # imm = 0x102C
movl $0x188, %eax            # imm = 0x188
cmpb $0x0, (%r14,%r12)
jne 0xec77
incq %r12
addq $-0x188, %rcx           # imm = 0xFE78
addq %rax, %rdx
addq %rax, %rsi
addq %rax, %rdi
cmpq $-0x14c0, %rcx          # imm = 0xEB40
jne 0xec4f
callq 0x3598
movq %r8, 0x18(%rsp)
movb $0x0, (%r14,%r12)
movl $0x0, (%r14,%rdi)
cmpl $0x0, 0x4(%rbx)
jle 0xee50
leaq 0x8(%rbx), %r8
movaps 0x33e2(%rip), %xmm0     # 0x12080
movsd 0x67f2(%rip), %xmm1     # 0x15498
movsd 0x3482(%rip), %xmm2     # 0x12130
xorl %r10d, %r10d
xorl %ebp, %ebp
movq %r8, 0x10(%rsp)
cmpl $0x20, %r10d
je 0xeef2
leaq (,%rbp,2), %rax
addq %rbp, %rax
leaq (%r8,%rax,4), %r11
movl 0x30(%rsp,%rbp,4), %eax
testl %eax, %eax
je 0xed21
cmpl $0x2, %eax
jne 0xed5c
movss (%r11), %xmm3
movslq %r10d, %rax
leaq (%rax,%rax,2), %rax
leaq (%r14,%rax,4), %rax
movss %xmm3, -0x8(%rsi,%rax)
movss 0x4(%r11), %xmm3
movss %xmm3, -0x4(%rsi,%rax)
movss 0x8(%r11), %xmm3
movss %xmm3, (%rsi,%rax)
movl (%r14,%rdi), %r10d
incl %r10d
movl %r10d, (%r14,%rdi)
incq %rbp
movq %rbp, %r13
jmp 0xee40
movss (%r11), %xmm3
movslq %r10d, %r10
leaq (%r10,%r10,2), %r10
leaq (%r14,%r10,4), %r10
movss %xmm3, -0x8(%rsi,%r10)
movss 0x4(%r11), %xmm3
movss %xmm3, -0x4(%rsi,%r10)
movss 0x8(%r11), %xmm3
movss %xmm3, (%rsi,%r10)
movl (%r14,%rdi), %r10d
incl %r10d
movl %r10d, (%r14,%rdi)
leaq 0x1(%rbp), %r13
movl 0x34(%rsp,%rbp,4), %r9d
cmpl $0x2, %r9d
sete %r8b
cmpl %eax, %r9d
sete %al
orb %r8b, %al
je 0xed82
movq 0x10(%rsp), %r8
jmp 0xee40
cmpl $0x20, %r10d
movq 0x10(%rsp), %r8
je 0xeefb
movl 0x4(%rbx), %eax
cmpq %rax, %r13
movl %r13d, %eax
movl $0x0, %r9d
cmovaeq %r9, %rax
leaq (%rax,%rax,2), %rax
leaq (%r8,%rax,4), %rax
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
xorps %xmm7, %xmm7
cvtss2sd (%r15,%rbp,4), %xmm7
ucomisd %xmm7, %xmm1
movaps %xmm4, %xmm6
jbe 0xee05
ucomisd %xmm2, %xmm7
movaps %xmm5, %xmm6
jbe 0xee05
movss (%r11,%rbp,4), %xmm7
movss (%rax,%rbp,4), %xmm6
subss %xmm7, %xmm6
mulss %xmm3, %xmm6
addss %xmm7, %xmm6
movss %xmm6, 0x20(%rsp,%rbp,4)
incq %rbp
cmpq $0x3, %rbp
jne 0xedd3
movslq %r10d, %rax
leaq (%rax,%rax,2), %rax
leaq (%r14,%rax,4), %rax
movsd 0x20(%rsp), %xmm3
movsd %xmm3, (%rdx,%rax)
movss 0x28(%rsp), %xmm3
movss %xmm3, (%rsi,%rax)
movl (%r14,%rdi), %r10d
incl %r10d
movl %r10d, (%r14,%rdi)
movslq 0x4(%rbx), %rax
movq %r13, %rbp
cmpq %rax, %r13
jl 0xecb8
leaq 0x1028(%r14), %rax
subq %rcx, %r14
subq %rax, %rbx
sarq $0x3, %rbx
movabsq $0x7d6343eb1a1f58d1, %rax # imm = 0x7D6343EB1A1F58D1
imulq %rbx, %rax
cmpl $0x2, %eax
jbe 0xee9e
movq %r14, %rbx
jmp 0xeec5
subq %r14, %rbx
addq $-0x1028, %rbx          # imm = 0xEFD8
sarq $0x3, %rbx
movabsq $0x7d6343eb1a1f58d1, %rax # imm = 0x7D6343EB1A1F58D1
imulq %rbx, %rax
cmpl $0x2, %eax
jbe 0xeeda
xorl %ebx, %ebx
jmp 0xeec5
andl $0x3, %eax
movq 0x18(%rsp), %rcx
leaq (%rcx,%rax), %r15
cmpb $0x0, (%rcx,%rax)
movq %r14, %rbx
je 0xeec1
leaq 0x66a2(%rip), %rdi      # 0x1555c
xorl %eax, %eax
callq 0x8cb4
movb $0x1, (%r15)
movq %rbx, %rax
addq $0x438, %rsp            # imm = 0x438
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $0x3, %eax
leaq (%r14,%rax), %r15
addq $0x14c0, %r15           # imm = 0x14C0
xorl %ebx, %ebx
cmpb $0x0, (%r15)
jne 0xeeb3
jmp 0xeec1
leaq 0x65ff(%rip), %rdi      # 0x154f8
jmp 0xef02
leaq 0x6628(%rip), %rdi      # 0x1552a
xorl %eax, %eax
callq 0x9026
leal -0x14c0(%r12), %eax
cmpl $0x2, %eax
ja 0xeec5
leaq (%r14,%r12), %r15
cmpb $0x0, (%r14,%r12)
jne 0xeeb3
jmp 0xeec1
nop