// File: FreeSlave[P]vhlt/hlcsg/brush.cpp
// Function: MakeHullFaces(brush_s const*, brushhull_t*)
void            MakeHullFaces(const brush_t* const b, brushhull_t *h)
{
    bface_t*        f;
    bface_t*        f2;
#ifdef HLCSG_PRECISIONCLIP //#ifdef HLCSG_PRECISECLIP //vluzacn
#ifndef HLCSG_CUSTOMHULL
	bool warned = false;
#endif
#endif
#ifdef HLCSG_SORTSIDES
	// this will decrease AllocBlock amount
	SortSides (h);
#endif

restart:
    h->bounds.reset();

    // for each face in this brushes hull
    for (f = h->faces; f; f = f->next)
    {
        Winding* w = new Winding(f->plane->normal, f->plane->dist);
        for (f2 = h->faces; f2; f2 = f2->next)
        {
            if (f == f2)
            {
                continue;
            }
            const plane_t* p = &g_mapplanes[f2->planenum ^ 1];
            if (!w->Chop(p->normal, p->dist
#ifdef HLCSG_MakeHullFaces_PRECISE
				, NORMAL_EPSILON  // fix "invalid brush" in ExpandBrush
#endif
				))   // Nothing left to chop (getArea will return 0 for us in this case for below)
            {
                break;
            }
        }
#ifdef HLCSG_MakeHullFaces_PRECISE
		w->RemoveColinearPoints (ON_EPSILON);
#endif
        if (w->getArea() < 0.1)
        {
#ifdef HLCSG_PRECISIONCLIP //#ifdef HLCSG_PRECISECLIP //vluzacn
#ifndef HLCSG_CUSTOMHULL // this occurs when there are BEVEL faces.
			if(w->getArea() == 0 && !warned) //warn user when there's a bad brush (face not contributing)
			{
				Warning("Illegal Brush (plane doesn't contribute to final shape): Entity %i, Brush %i\n",
#ifdef HLCSG_COUNT_NEW
					b->originalentitynum, b->originalbrushnum
#else
					b->entitynum, b->brushnum
#endif
					);
				warned = true;
			}
#endif
#endif
            delete w;
            if (h->faces == f)
            {
                h->faces = f->next;
            }
            else
            {
                for (f2 = h->faces; f2->next != f; f2 = f2->next)
                {
                    ;
                }
                f2->next = f->next;
            }
            goto restart;
        }
        else
        {
            f->w = w;
            f->contents = CONTENTS_EMPTY;
            unsigned int    i;
            for (i = 0; i < w->m_NumPoints; i++)
            {
                h->bounds.add(w->m_Points[i]);
            }
        }
    }

    unsigned int    i;
    for (i = 0; i < 3; i++)
    {
        if (h->bounds.m_Mins[i] < -BOGUS_RANGE / 2 || h->bounds.m_Maxs[i] > BOGUS_RANGE / 2)
        {
            Fatal(assume_BRUSH_OUTSIDE_WORLD, "Entity %i, Brush %i: outside world(+/-%d): (%.0f,%.0f,%.0f)-(%.0f,%.0f,%.0f)",
#ifdef HLCSG_COUNT_NEW
				b->originalentitynum, b->originalbrushnum,
#else
                  b->entitynum, b->brushnum,
#endif
                  BOGUS_RANGE / 2,
                  h->bounds.m_Mins[0], h->bounds.m_Mins[1], h->bounds.m_Mins[2],
                  h->bounds.m_Maxs[0], h->bounds.m_Maxs[1], h->bounds.m_Maxs[2]);
        }
    }
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x48(%rsp), %rdi
callq 0x15800
movq 0x48(%rsp), %rdi
callq 0x12490
movq 0x48(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x15e23
movl $0x20, %edi
callq 0x43b0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
movq 0x40(%rsp), %rax
movq 0x10(%rax), %rsi
movsd 0x30(%rsi), %xmm0
callq 0xf770
jmp 0x15c56
movq 0x8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x48(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x15d06
movq 0x40(%rsp), %rax
cmpq 0x38(%rsp), %rax
jne 0x15caa
jmp 0x15cf4
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
movl $0x20, %esi
callq 0x43c0
jmp 0x15ee5
movq 0x38(%rsp), %rax
movl 0x8(%rax), %eax
xorl $0x1, %eax
movslq %eax, %rcx
leaq 0x20c4ce1(%rip), %rax   # 0x20da9a0
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movq 0x30(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x18(%rsp), %rax
movsd 0x30(%rax), %xmm0
movsd 0x14381(%rip), %xmm1    # 0x2a068
callq 0x10900
testb $0x1, %al
jne 0x15cf2
jmp 0x15d06
jmp 0x15cf4
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x15c6e
movq 0x30(%rsp), %rdi
movsd 0x17945(%rip), %xmm0    # 0x2d658
callq 0xf930
movq 0x30(%rsp), %rdi
callq 0xe200
movaps %xmm0, %xmm1
movsd 0x1797b(%rip), %xmm0    # 0x2d6a8
ucomisd %xmm1, %xmm0
jbe 0x15db2
movq 0x30(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x15d4c
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq 0x48(%rsp), %rax
movq 0x30(%rax), %rax
cmpq 0x40(%rsp), %rax
jne 0x15d6f
movq 0x40(%rsp), %rax
movq (%rax), %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x30(%rax)
jmp 0x15dad
movq 0x48(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq (%rax), %rax
cmpq 0x40(%rsp), %rax
je 0x15d9d
jmp 0x15d8e
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
jmp 0x15d7d
movq 0x40(%rsp), %rax
movq (%rax), %rcx
movq 0x38(%rsp), %rax
movq %rcx, (%rax)
jmp 0x15c08
movq 0x30(%rsp), %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x18(%rax)
movq 0x40(%rsp), %rax
movl $0xffffffff, 0x28(%rax) # imm = 0xFFFFFFFF
movl $0x0, 0x14(%rsp)
movl 0x14(%rsp), %eax
movq 0x30(%rsp), %rcx
cmpl 0x8(%rcx), %eax
jae 0x15e0d
movq 0x48(%rsp), %rdi
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rsi
movl 0x14(%rsp), %eax
imulq $0x18, %rax, %rax
addq %rax, %rsi
callq 0x122d0
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x15dd4
jmp 0x15e0f
jmp 0x15e11
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x40(%rsp)
jmp 0x15c20
movl $0x0, 0x10(%rsp)
cmpl $0x3, 0x10(%rsp)
jae 0x15ee0
movq 0x48(%rsp), %rax
movl 0x10(%rsp), %ecx
movsd 0x17851(%rip), %xmm0    # 0x2d698
ucomisd (%rax,%rcx,8), %xmm0
ja 0x15e6b
movq 0x48(%rsp), %rax
movl 0x10(%rsp), %ecx
movsd 0x18(%rax,%rcx,8), %xmm0
movsd 0x1783b(%rip), %xmm1    # 0x2d6a0
ucomisd %xmm1, %xmm0
jbe 0x15ece
movq 0x50(%rsp), %rax
movl (%rax), %edx
movq 0x50(%rsp), %rax
movl 0x4(%rax), %ecx
movq 0x48(%rsp), %rax
movsd (%rax), %xmm0
movq 0x48(%rsp), %rax
movsd 0x8(%rax), %xmm1
movq 0x48(%rsp), %rax
movsd 0x10(%rax), %xmm2
movq 0x48(%rsp), %rax
movsd 0x18(%rax), %xmm3
movq 0x48(%rsp), %rax
movsd 0x20(%rax), %xmm4
movq 0x48(%rsp), %rax
movsd 0x28(%rax), %xmm5
movl $0x7, %edi
leaq 0x1797a(%rip), %rsi     # 0x2d83b
movl $0x7fff, %r8d           # imm = 0x7FFF
movb $0x6, %al
callq 0xbbb0
jmp 0x15ed0
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x15e2b
addq $0x58, %rsp
retq
movq 0x28(%rsp), %rdi
callq 0x4650
nop