// File: alan0201tw[P]RayTracer/src/bvh.cpp
// Function: bvh_node::bvh_node(std::vector<std::shared_ptr<hitable>, std::allocator<std::shared_ptr<hitable>>> const&, float, float)
bvh_node::bvh_node(const std::vector<hitable_reference>& _list, float _t0, float _t1)
{
    list = _list;

    int list_size = (int)list.size();

    //std::cout << "list_size = " << list_size << "\n";

    int random_axis = int(3 * drand48());
    if(random_axis == 0)
    {
        // Reference : 
        // according to https://stackoverflow.com/questions/12308243/trying-to-use-qsort-with-vector
        // using std::sort with functor is the fastest, comparing to qsort and
        // std::sort with custom function as compare operator
        std::sort(list.begin(), list.end(), box_x_compare());
    }
    else if(random_axis == 1)
    {
        std::sort(list.begin(), list.end(), box_y_compare());
    }
    else
    {
        std::sort(list.begin(), list.end(), box_z_compare());
    }

    // edge cases when the bounding volume contains only one or two elements
    if(list_size == 1)
    {
        left = right = _list[0];
    }
    else if(list_size == 2)
    {
        left = _list[0];
        right = _list[1];
    }
    else
    {
        int half_size = list_size / 2;
        std::vector<hitable_reference> left_list(list.begin(), list.begin() + half_size);
        std::vector<hitable_reference> right_list(list.begin() + half_size, list.end());

        left = std::make_shared<bvh_node>(left_list, _t0, _t1);
        right = std::make_shared<bvh_node>(right_list, _t0, _t1);
    }

    aabb box_left, box_right;
    if(left->bounding_box(_t0, _t1, box_left) == false || right->bounding_box(_t0, _t1, box_right) == false)
    {
        std::cerr << "No bounding box in bvh_node constructor!\n";
    }
    box = surrounding_box(box_left, box_right);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x230, %rsp            # imm = 0x230
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movss %xmm0, -0x14(%rbp)
movss %xmm1, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x8b20
movq -0x198(%rbp), %rdi
leaq 0x9c1a5(%rip), %rax     # 0xaf300
movq %rax, (%rdi)
addq $0x8, %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x139d0
movq -0x198(%rbp), %rdi
addq $0x18, %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x139d0
movq -0x198(%rbp), %rdi
addq $0x28, %rdi
callq 0x10630
jmp 0x13197
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x1b0(%rbp)
callq 0x8b80
movq -0x1b0(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x9620
jmp 0x131c0
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
callq 0x9870
movl %eax, -0x28(%rbp)
callq 0x7480
movaps %xmm0, %xmm1
movsd 0x6b195(%rip), %xmm0    # 0x7e378
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0x13255
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x1b8(%rbp)
callq 0x9b10
movq -0x1b8(%rbp), %rdi
movq %rax, -0x38(%rbp)
callq 0x9b40
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x139f0
jmp 0x1322e
jmp 0x132d5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x136f3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x136e7
cmpl $0x1, -0x2c(%rbp)
jne 0x13297
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x1c0(%rbp)
callq 0x9b10
movq -0x1c0(%rbp), %rdi
movq %rax, -0x50(%rbp)
callq 0x9b40
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x13a30
jmp 0x13295
jmp 0x132d3
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x9b10
movq -0x1c8(%rbp), %rdi
movq %rax, -0x68(%rbp)
callq 0x9b40
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x13a70
jmp 0x132d1
jmp 0x132d3
jmp 0x132d5
cmpl $0x1, -0x28(%rbp)
jne 0x13313
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10580
movq -0x198(%rbp), %rdi
movq %rax, %rsi
addq $0x18, %rdi
callq 0xa4c0
movq -0x198(%rbp), %rdi
movq %rax, %rsi
addq $0x8, %rdi
callq 0xa4c0
jmp 0x13585
cmpl $0x2, -0x28(%rbp)
jne 0x1335f
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10580
movq -0x198(%rbp), %rdi
movq %rax, %rsi
addq $0x8, %rdi
callq 0xa4c0
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x10580
movq -0x198(%rbp), %rdi
movq %rax, %rsi
addq $0x18, %rdi
callq 0xa4c0
jmp 0x13583
movq -0x198(%rbp), %rdi
movl -0x28(%rbp), %eax
movl %eax, %ecx
shrl $0x1f, %ecx
addl %ecx, %eax
sarl %eax
movl %eax, -0x78(%rbp)
addq $0x40, %rdi
movq %rdi, -0x1d8(%rbp)
callq 0x9b10
movq -0x1d8(%rbp), %rdi
movq %rax, -0x98(%rbp)
callq 0x9b10
movq %rax, -0xa8(%rbp)
movslq -0x78(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0xa3c0
movq %rax, -0xa0(%rbp)
leaq -0xa9(%rbp), %rdi
movq %rdi, -0x1d0(%rbp)
callq 0x93c0
movq -0x1d0(%rbp), %rcx
movq -0x98(%rbp), %rsi
movq -0xa0(%rbp), %rdx
leaq -0x90(%rbp), %rdi
callq 0x13ab0
jmp 0x133ec
leaq -0xa9(%rbp), %rdi
callq 0xa990
movq -0x198(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x9b10
movq %rax, -0xd8(%rbp)
movslq -0x78(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xa3c0
movq -0x1e8(%rbp), %rdi
movq %rax, -0xd0(%rbp)
callq 0x9b40
movq %rax, -0xe0(%rbp)
leaq -0xe1(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0x93c0
movq -0x1e0(%rbp), %rcx
movq -0xd0(%rbp), %rsi
movq -0xe0(%rbp), %rdx
leaq -0xc8(%rbp), %rdi
callq 0x13ab0
jmp 0x13476
leaq -0xe1(%rbp), %rdi
callq 0xa990
leaq -0xf8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x14(%rbp), %rdx
leaq -0x18(%rbp), %rcx
callq 0x13b30
jmp 0x1349f
movq -0x198(%rbp), %rdi
addq $0x8, %rdi
leaq -0xf8(%rbp), %rsi
movq %rsi, -0x1f0(%rbp)
callq 0x13bb0
movq -0x1f0(%rbp), %rdi
callq 0x13be0
leaq -0x108(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
leaq -0x14(%rbp), %rdx
leaq -0x18(%rbp), %rcx
callq 0x13b30
jmp 0x134e6
movq -0x198(%rbp), %rdi
addq $0x18, %rdi
leaq -0x108(%rbp), %rsi
callq 0x13bb0
leaq -0x108(%rbp), %rdi
callq 0x13be0
leaq -0xc8(%rbp), %rdi
callq 0x92d0
leaq -0x90(%rbp), %rdi
callq 0x92d0
jmp 0x13583
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xa9(%rbp), %rdi
callq 0xa990
jmp 0x136e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xe1(%rbp), %rdi
callq 0xa990
jmp 0x13572
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x92d0
leaq -0x90(%rbp), %rdi
callq 0x92d0
jmp 0x136e7
jmp 0x13585
leaq -0x120(%rbp), %rdi
callq 0x10630
jmp 0x13593
leaq -0x138(%rbp), %rdi
callq 0x10630
jmp 0x135a1
movq -0x198(%rbp), %rdi
addq $0x8, %rdi
callq 0x105a0
movq %rax, %rdi
movss -0x14(%rbp), %xmm0
movss -0x18(%rbp), %xmm1
movq (%rdi), %rax
movq 0x8(%rax), %rax
leaq -0x120(%rbp), %rsi
callq *%rax
movb %al, -0x1f1(%rbp)
jmp 0x135d6
movb -0x1f1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x1362b
movq -0x198(%rbp), %rdi
addq $0x18, %rdi
callq 0x105a0
movq %rax, %rdi
movss -0x14(%rbp), %xmm0
movss -0x18(%rbp), %xmm1
movq (%rdi), %rax
movq 0x8(%rax), %rax
leaq -0x138(%rbp), %rsi
callq *%rax
movb %al, -0x1f2(%rbp)
jmp 0x1361b
movb -0x1f2(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x13642
movq 0x9c9ae(%rip), %rdi     # 0xaffe0
leaq 0x6ad47(%rip), %rsi     # 0x7e380
callq 0x74e0
jmp 0x13640
jmp 0x13642
movq -0x110(%rbp), %rax
movq %rax, -0x160(%rbp)
movups -0x120(%rbp), %xmm0
movaps %xmm0, -0x170(%rbp)
movq -0x128(%rbp), %rax
movq %rax, -0x180(%rbp)
movups -0x138(%rbp), %xmm0
movaps %xmm0, -0x190(%rbp)
movq -0x180(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x28(%rax)
movaps -0x190(%rbp), %xmm0
movups %xmm0, 0x18(%rax)
movq -0x160(%rbp), %rcx
movq %rcx, 0x10(%rax)
movaps -0x170(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x150(%rbp), %rdi
callq 0x1af90
jmp 0x136b6
movq -0x198(%rbp), %rax
movq -0x150(%rbp), %rcx
movq %rcx, 0x28(%rax)
movq -0x148(%rbp), %rcx
movq %rcx, 0x30(%rax)
movq -0x140(%rbp), %rcx
movq %rcx, 0x38(%rax)
addq $0x230, %rsp            # imm = 0x230
popq %rbp
retq
movq -0x1b0(%rbp), %rdi
callq 0x92d0
movq -0x1a0(%rbp), %rdi
callq 0x8e00
movq -0x1a8(%rbp), %rdi
callq 0x8e00
movq -0x20(%rbp), %rdi
callq 0x7860
nopw %cs:(%rax,%rax)