// File: FreeSlave[P]vhlt/hlcsg/brushunion.cpp
// Function: CalculateSolidVolume(brushhull_t const*)
static vec_t    CalculateSolidVolume(const brushhull_t* const hull)
{
    // calculate polyhedron origin
    // subdivide face winding into triangles

    // for each face
    // calculate volume of triangle of face to origin
    // add subidivided volume chunk to total

    int             x = 0;
    vec_t           volume = 0.0;
    vec_t           inverse;
    vec3_t          midpoint = { 0.0, 0.0, 0.0 };

    bface_t*        face;

    for (face = hull->faces; face; face = face->next, x++)
    {
        vec3_t          facemid;

        face->w->getCenter(facemid);
        VectorAdd(midpoint, facemid, midpoint);
        Developer(DEVELOPER_LEVEL_MESSAGE, "Midpoint for face %d is %f %f %f\n", x, facemid[0], facemid[1], facemid[2]);
    }

    inverse = 1.0 / x;

    VectorScale(midpoint, inverse, midpoint);

    Developer(DEVELOPER_LEVEL_MESSAGE, "Midpoint for hull is %f %f %f\n", midpoint[0], midpoint[1], midpoint[2]);

    for (face = hull->faces; face; face = face->next, x++)
    {
        plane_t*        plane = &g_mapplanes[face->planenum];
        vec_t           area = face->w->getArea();
        vec_t           dist = DotProduct(plane->normal, midpoint);

        dist -= plane->dist;
        dist = fabs(dist);

        volume += area * dist / 3.0;
    }

    Developer(DEVELOPER_LEVEL_MESSAGE, "Volume for brush is %f\n", volume);

    return volume;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x4210
movq 0x70(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x19b04
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rdi
leaq 0x20(%rsp), %rsi
callq 0xe5c0
movsd 0x40(%rsp), %xmm0
addsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x48(%rsp), %xmm0
addsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x50(%rsp), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0x6c(%rsp), %edx
movsd 0x20(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movl $0x3, %edi
leaq 0x142ea(%rip), %rsi     # 0x2ddca
movb $0x3, %al
callq 0xc0f0
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x19a69
cvtsi2sdl 0x6c(%rsp), %xmm1
movsd 0x13666(%rip), %xmm0    # 0x2d178
divsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x40(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x48(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x50(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x40(%rsp), %xmm0
movsd 0x48(%rsp), %xmm1
movsd 0x50(%rsp), %xmm2
movl $0x3, %edi
leaq 0x1427c(%rip), %rsi     # 0x2ddec
movb $0x3, %al
callq 0xc0f0
movq 0x70(%rsp), %rax
movq 0x30(%rax), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x19c78
movq 0x38(%rsp), %rax
movslq 0x8(%rax), %rcx
leaq 0x20c0dff(%rip), %rax   # 0x20da9a0
shlq $0x6, %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movq 0x38(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0xe200
movsd %xmm0, 0x10(%rsp)
movq 0x18(%rsp), %rax
movsd (%rax), %xmm1
movsd 0x40(%rsp), %xmm2
movq 0x18(%rsp), %rax
movsd 0x8(%rax), %xmm0
mulsd 0x48(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movq 0x18(%rsp), %rax
movsd 0x10(%rax), %xmm0
movsd 0x50(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x18(%rsp), %rax
movsd 0x30(%rax), %xmm1
movsd 0x8(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
movaps 0x13883(%rip), %xmm1    # 0x2d4b0
pand %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x10(%rsp), %xmm0
mulsd 0x8(%rsp), %xmm0
movsd 0x140bd(%rip), %xmm1    # 0x2dd08
divsd %xmm1, %xmm0
addsd 0x60(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x38(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x19b85
movsd 0x60(%rsp), %xmm0
movl $0x3, %edi
leaq 0x14181(%rip), %rsi     # 0x2de0b
movb $0x1, %al
callq 0xc0f0
movsd 0x60(%rsp), %xmm0
addq $0x78, %rsp
retq
nopl (%rax)