// File: Lut99[P]RayTracer/src/lib/ObjectTree.cpp
// Function: cluster(std::vector<RayTracer::RenderObject*, std::allocator<RayTracer::RenderObject*>> const&, std::vector<RayTracer::RenderObject*, std::allocator<RayTracer::RenderObject*>>&, std::vector<RayTracer::RenderObject*, std::allocator<RayTracer::RenderObject*>>&)
void cluster(const vector<RenderObject*>& total, vector<RenderObject*>& left, vector<RenderObject*>& right) {
    // Nothing to be done if empty
    if (total.size() == 0) { return; }

    // Sort according to the three axis'
    vector<RenderObject*> ordered_x(total);
    vector<RenderObject*> ordered_y(total);
    vector<RenderObject*> ordered_z(total);
    sort(ordered_x.begin(), ordered_x.end(), sort_x);
    sort(ordered_y.begin(), ordered_y.end(), sort_y);
    sort(ordered_z.begin(), ordered_z.end(), sort_z);

    // For each of them, compute the largest boundingbox sizes
    size_t const half_size = total.size() / 2;
    BoundingBox bx1, bx2, by1, by2, bz1, bz2;
    for (size_t i = 0; i < half_size; i++) {
        bx1.merge(ordered_x.at(i)->box);
        by1.merge(ordered_y.at(i)->box);
        bz1.merge(ordered_z.at(i)->box);
    }
    for (size_t i = half_size; i < total.size(); i++) {
        bx2.merge(ordered_x.at(i)->box);
        by2.merge(ordered_y.at(i)->box);
        bz2.merge(ordered_z.at(i)->box);
    }

    // Set the splits with the smallest total BB
    double sx = bx1.size() + bx2.size();
    double sy = by1.size() + by2.size();
    double sz = bz1.size() + bz2.size();
    if (sx <= sy && sx <= sz) {
        // x is smallest
        vector<RenderObject*>::iterator halfway = ordered_x.begin() + half_size;
        left = vector<RenderObject*>(ordered_x.begin(), halfway);
        right = vector<RenderObject*>(halfway, ordered_x.end());
    } else if (sy <= sx && sy <= sz) {
        // y is smallest
        vector<RenderObject*>::iterator halfway = ordered_y.begin() + half_size;
        left = vector<RenderObject*>(ordered_y.begin(), halfway);
        right = vector<RenderObject*>(halfway, ordered_y.end());
    } else {
        // z is smallest
        vector<RenderObject*>::iterator halfway = ordered_z.begin() + half_size;
        left = vector<RenderObject*>(ordered_z.begin(), halfway);
        right = vector<RenderObject*>(halfway, ordered_z.end());
    }
}

// Assembly:
subq $0x488, %rsp            # imm = 0x488
movq %rdi, 0x480(%rsp)
movq %rsi, 0x478(%rsp)
movq %rdx, 0x470(%rsp)
movq 0x480(%rsp), %rdi
callq 0x15d790
cmpq $0x0, %rax
jne 0x16b1a7
jmp 0x16bbda
movq 0x480(%rsp), %rsi
leaq 0x458(%rsp), %rdi
callq 0x15d7d0
movq 0x480(%rsp), %rsi
leaq 0x440(%rsp), %rdi
callq 0x15d7d0
jmp 0x16b1d3
movq 0x480(%rsp), %rsi
leaq 0x418(%rsp), %rdi
callq 0x15d7d0
jmp 0x16b1ea
leaq 0x458(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x15ea20
movq 0xe0(%rsp), %rdi
movq %rax, 0x410(%rsp)
callq 0x15e860
movq %rax, 0x408(%rsp)
movq 0x410(%rsp), %rdi
movq 0x408(%rsp), %rsi
leaq -0x153(%rip), %rdx      # 0x16b0e0
callq 0x16d2e0
jmp 0x16b23a
leaq 0x440(%rsp), %rdi
movq %rdi, 0xd8(%rsp)
callq 0x15ea20
movq 0xd8(%rsp), %rdi
movq %rax, 0x400(%rsp)
callq 0x15e860
movq %rax, 0x3f8(%rsp)
movq 0x400(%rsp), %rdi
movq 0x3f8(%rsp), %rsi
leaq -0x173(%rip), %rdx      # 0x16b110
callq 0x16d2e0
jmp 0x16b28a
leaq 0x418(%rsp), %rdi
movq %rdi, 0xd0(%rsp)
callq 0x15ea20
movq 0xd0(%rsp), %rdi
movq %rax, 0x3f0(%rsp)
callq 0x15e860
movq %rax, 0x3e8(%rsp)
movq 0x3f0(%rsp), %rdi
movq 0x3e8(%rsp), %rsi
leaq -0x193(%rip), %rdx      # 0x16b140
callq 0x16d2e0
jmp 0x16b2da
movq 0x480(%rsp), %rdi
callq 0x15d790
shrq %rax
movq %rax, 0x3e0(%rsp)
leaq 0x3a0(%rsp), %rdi
callq 0x15a210
jmp 0x16b301
leaq 0x360(%rsp), %rdi
callq 0x15a210
jmp 0x16b310
leaq 0x320(%rsp), %rdi
callq 0x15a210
jmp 0x16b31f
leaq 0x2e0(%rsp), %rdi
callq 0x15a210
jmp 0x16b32e
leaq 0x2a0(%rsp), %rdi
callq 0x15a210
jmp 0x16b33d
leaq 0x260(%rsp), %rdi
callq 0x15a210
jmp 0x16b34c
movq $0x0, 0x258(%rsp)
movq 0x258(%rsp), %rax
cmpq 0x3e0(%rsp), %rax
jae 0x16b48b
movq 0x258(%rsp), %rsi
leaq 0x458(%rsp), %rdi
callq 0x15d980
movq %rax, 0xc8(%rsp)
jmp 0x16b38d
movq 0xc8(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x3a0(%rsp), %rdi
callq 0x16ad60
jmp 0x16b3ab
movq 0x258(%rsp), %rsi
leaq 0x440(%rsp), %rdi
callq 0x15d980
movq %rax, 0xc0(%rsp)
jmp 0x16b3ca
movq 0xc0(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x320(%rsp), %rdi
callq 0x16ad60
jmp 0x16b3e8
movq 0x258(%rsp), %rsi
leaq 0x418(%rsp), %rdi
callq 0x15d980
movq %rax, 0xb8(%rsp)
jmp 0x16b407
movq 0xb8(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x2a0(%rsp), %rdi
callq 0x16ad60
jmp 0x16b425
jmp 0x16b427
movq 0x258(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x258(%rsp)
jmp 0x16b358
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
jmp 0x16bbfc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
jmp 0x16bbef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
jmp 0x16bbe2
movq 0x3e0(%rsp), %rax
movq %rax, 0x250(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0x480(%rsp), %rdi
callq 0x15d790
movq %rax, %rcx
movq 0xb0(%rsp), %rax
cmpq %rcx, %rax
jae 0x16b59e
movq 0x250(%rsp), %rsi
leaq 0x458(%rsp), %rdi
callq 0x15d980
movq %rax, 0xa8(%rsp)
jmp 0x16b4eb
movq 0xa8(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x360(%rsp), %rdi
callq 0x16ad60
jmp 0x16b509
movq 0x250(%rsp), %rsi
leaq 0x440(%rsp), %rdi
callq 0x15d980
movq %rax, 0xa0(%rsp)
jmp 0x16b528
movq 0xa0(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x2e0(%rsp), %rdi
callq 0x16ad60
jmp 0x16b546
movq 0x250(%rsp), %rsi
leaq 0x418(%rsp), %rdi
callq 0x15d980
movq %rax, 0x98(%rsp)
jmp 0x16b565
movq 0x98(%rsp), %rax
movq (%rax), %rsi
addq $0x38, %rsi
leaq 0x260(%rsp), %rdi
callq 0x16ad60
jmp 0x16b583
jmp 0x16b585
movq 0x250(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x250(%rsp)
jmp 0x16b49b
leaq 0x3a0(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x90(%rsp)
jmp 0x16b5b6
leaq 0x360(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x88(%rsp)
jmp 0x16b5ce
movsd 0x88(%rsp), %xmm1
movsd 0x90(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x248(%rsp)
leaq 0x320(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x80(%rsp)
jmp 0x16b605
leaq 0x2e0(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x78(%rsp)
jmp 0x16b61a
movsd 0x78(%rsp), %xmm1
movsd 0x80(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x240(%rsp)
leaq 0x2a0(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x70(%rsp)
jmp 0x16b64b
leaq 0x260(%rsp), %rdi
callq 0x16af00
movsd %xmm0, 0x68(%rsp)
jmp 0x16b660
movsd 0x68(%rsp), %xmm1
movsd 0x70(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x238(%rsp)
movsd 0x248(%rsp), %xmm1
movsd 0x240(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x16b84c
movsd 0x248(%rsp), %xmm1
movsd 0x238(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x16b84c
leaq 0x458(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x15ea20
movq %rax, 0x228(%rsp)
movq 0x3e0(%rsp), %rsi
leaq 0x228(%rsp), %rdi
callq 0x16d330
movq 0x58(%rsp), %rdi
movq %rax, 0x230(%rsp)
callq 0x15ea20
movq %rax, 0x208(%rsp)
movq 0x230(%rsp), %rax
movq %rax, 0x200(%rsp)
leaq 0x1ff(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x15dbb0
movq 0x60(%rsp), %rcx
movq 0x208(%rsp), %rsi
movq 0x200(%rsp), %rdx
leaq 0x210(%rsp), %rdi
callq 0x16d370
jmp 0x16b740
movq 0x478(%rsp), %rdi
leaq 0x210(%rsp), %rsi
movq %rsi, 0x48(%rsp)
callq 0x15d940
movq 0x48(%rsp), %rdi
callq 0x15d8d0
leaq 0x1ff(%rsp), %rdi
callq 0x15dc70
movq 0x230(%rsp), %rax
movq %rax, 0x1d8(%rsp)
leaq 0x458(%rsp), %rdi
callq 0x15e860
movq %rax, 0x1d0(%rsp)
leaq 0x1cf(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x15dbb0
movq 0x50(%rsp), %rcx
movq 0x1d8(%rsp), %rsi
movq 0x1d0(%rsp), %rdx
leaq 0x1e0(%rsp), %rdi
callq 0x16d370
jmp 0x16b7cc
movq 0x470(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x15d940
leaq 0x1e0(%rsp), %rdi
callq 0x15d8d0
leaq 0x1cf(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbb3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0x1ff(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0x1cf(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
movsd 0x240(%rsp), %xmm1
movsd 0x248(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x16ba1f
movsd 0x240(%rsp), %xmm1
movsd 0x238(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jb 0x16ba1f
leaq 0x440(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x15ea20
movq %rax, 0x1b8(%rsp)
movq 0x3e0(%rsp), %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x16d330
movq 0x38(%rsp), %rdi
movq %rax, 0x1c0(%rsp)
callq 0x15ea20
movq %rax, 0x198(%rsp)
movq 0x1c0(%rsp), %rax
movq %rax, 0x190(%rsp)
leaq 0x18f(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x15dbb0
movq 0x40(%rsp), %rcx
movq 0x198(%rsp), %rsi
movq 0x190(%rsp), %rdx
leaq 0x1a0(%rsp), %rdi
callq 0x16d370
jmp 0x16b913
movq 0x478(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
movq %rsi, 0x28(%rsp)
callq 0x15d940
movq 0x28(%rsp), %rdi
callq 0x15d8d0
leaq 0x18f(%rsp), %rdi
callq 0x15dc70
movq 0x1c0(%rsp), %rax
movq %rax, 0x168(%rsp)
leaq 0x440(%rsp), %rdi
callq 0x15e860
movq %rax, 0x160(%rsp)
leaq 0x15f(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x15dbb0
movq 0x30(%rsp), %rcx
movq 0x168(%rsp), %rsi
movq 0x160(%rsp), %rdx
leaq 0x170(%rsp), %rdi
callq 0x16d370
jmp 0x16b99f
movq 0x470(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x15d940
leaq 0x170(%rsp), %rdi
callq 0x15d8d0
leaq 0x15f(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbb1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0x18f(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0x15f(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
leaq 0x418(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x15ea20
movq %rax, 0x148(%rsp)
movq 0x3e0(%rsp), %rsi
leaq 0x148(%rsp), %rdi
callq 0x16d330
movq 0x18(%rsp), %rdi
movq %rax, 0x150(%rsp)
callq 0x15ea20
movq %rax, 0x128(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x120(%rsp)
leaq 0x11f(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x15dbb0
movq 0x20(%rsp), %rcx
movq 0x128(%rsp), %rsi
movq 0x120(%rsp), %rdx
leaq 0x130(%rsp), %rdi
callq 0x16d370
jmp 0x16baae
movq 0x478(%rsp), %rdi
leaq 0x130(%rsp), %rsi
movq %rsi, 0x8(%rsp)
callq 0x15d940
movq 0x8(%rsp), %rdi
callq 0x15d8d0
leaq 0x11f(%rsp), %rdi
callq 0x15dc70
movq 0x150(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x418(%rsp), %rdi
callq 0x15e860
movq %rax, 0xf0(%rsp)
leaq 0xef(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x15dbb0
movq 0x10(%rsp), %rcx
movq 0xf8(%rsp), %rsi
movq 0xf0(%rsp), %rdx
leaq 0x100(%rsp), %rdi
callq 0x16d370
jmp 0x16bb3a
movq 0x470(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x15d940
leaq 0x100(%rsp), %rdi
callq 0x15d8d0
leaq 0xef(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbb1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0x11f(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x438(%rsp)
movl %eax, 0x434(%rsp)
leaq 0xef(%rsp), %rdi
callq 0x15dc70
jmp 0x16bbe2
jmp 0x16bbb3
leaq 0x418(%rsp), %rdi
callq 0x15d8d0
leaq 0x440(%rsp), %rdi
callq 0x15d8d0
leaq 0x458(%rsp), %rdi
callq 0x15d8d0
addq $0x488, %rsp            # imm = 0x488
retq
leaq 0x418(%rsp), %rdi
callq 0x15d8d0
leaq 0x440(%rsp), %rdi
callq 0x15d8d0
leaq 0x458(%rsp), %rdi
callq 0x15d8d0
movq 0x438(%rsp), %rdi
callq 0xd0a10
nopw %cs:(%rax,%rax)