// File: /workspace/github_cpp_makefile_star2_O3/Crawler995[P]Cpp-Ray-Tracing/libs/render_engine.cpp
// Function: RenderEngine::ray_tracing_recursive(Ray3, GeometryUnion&, int)
Color RenderEngine::ray_tracing_recursive(
    Ray3 ray,
    GeometryUnion &geo_union,
    int reflect_times
) {
    IntersectResult res = geo_union.intersect(ray);
    if(res.geometry) {
        double specular_factor = res.geometry -> get_material() -> get_specular_factor();
        Color color = res.geometry -> get_material() -> sample(ray, res.position, res.normal);
        color = color.multiply(1.0 - specular_factor);

        if(specular_factor > 0 && reflect_times < max_reflect_times) {
            Vector3 dir = res.normal.scale(-2.0 * res.normal.dot(ray.get_dir())).add(ray.get_dir()).normalize();
            Ray3 reflect_ray(res.position, dir);

            Color reflect_color = ray_tracing_recursive(reflect_ray, geo_union, reflect_times + 1).multiply(specular_factor);
            
            color = color.add(reflect_color);
        }

        color.ensure_not_overflow();
        return color;
    }
    else {
        return Color(0, 0, 0);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movl %edx, %ebx
movq %rsi, %r14
movq %rdi, %r15
movapd 0x10(%rbp), %xmm0
movapd 0x20(%rbp), %xmm1
movaps 0x30(%rbp), %xmm2
movups %xmm2, 0x20(%rsp)
movupd %xmm1, 0x10(%rsp)
movupd %xmm0, (%rsp)
leaq -0x88(%rbp), %r12
movq %r12, %rdi
callq 0x331c
movq (%r12), %rax
testq %rax, %rax
je 0x52cd
leaq 0x10(%rbp), %r12
movq 0x8(%rax), %rdi
callq 0x3780
movsd %xmm0, -0x30(%rbp)
movq -0x88(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
movq -0x50(%rbp), %rcx
movq %rcx, 0x58(%rsp)
movups -0x60(%rbp), %xmm0
movups %xmm0, 0x48(%rsp)
movq -0x68(%rbp), %rcx
movq %rcx, 0x40(%rsp)
movups -0x78(%rbp), %xmm0
movups %xmm0, 0x30(%rsp)
movups (%r12), %xmm0
movups 0x10(%r12), %xmm1
movups 0x20(%r12), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
callq *(%rax)
leaq -0x40(%rbp), %r13
movq %rax, (%r13)
movl %edx, 0x8(%r13)
movsd 0xf2b(%rip), %xmm0      # 0x6098
subsd -0x30(%rbp), %xmm0
movq %r13, %rdi
callq 0x3612
movq %rax, (%r13)
movl %edx, 0x8(%r13)
xorpd %xmm0, %xmm0
movsd -0x30(%rbp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x52c2
cmpl %ebx, 0xc(%r15)
jle 0x52c2
leaq -0x100(%rbp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x2b8c
movq 0x10(%r13), %rax
movq %rax, 0x10(%rsp)
movupd (%r13), %xmm0
movupd %xmm0, (%rsp)
leaq -0x60(%rbp), %rdi
callq 0x2a3a
mulsd 0xfda(%rip), %xmm0      # 0x61b0
leaq -0xa0(%rbp), %rdi
movq %r15, -0x48(%rbp)
movq %rdi, %r15
leaq -0x60(%rbp), %rsi
callq 0x29da
leaq -0xe8(%rbp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x2b8c
movq 0x10(%r13), %rax
movq %rax, 0x10(%rsp)
movups (%r13), %xmm0
movups %xmm0, (%rsp)
leaq -0xd0(%rbp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x2950
leaq -0x118(%rbp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x28d2
movq 0x10(%r13), %rax
movq %rax, 0x28(%rsp)
movups (%r13), %xmm0
movups %xmm0, 0x18(%rsp)
leaq -0x78(%rbp), %rcx
movq 0x10(%rcx), %rax
movq %rax, 0x10(%rsp)
movups (%rcx), %xmm0
movups %xmm0, (%rsp)
movq %r12, %rdi
callq 0x2ae8
incl %ebx
movups (%r12), %xmm0
movupd 0x10(%r12), %xmm1
movups 0x20(%r12), %xmm2
movups %xmm2, 0x20(%rsp)
movupd %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq -0x48(%rbp), %rdi
movq %r14, %rsi
movl %ebx, %edx
callq 0x509e
movq %rax, (%r15)
movl %edx, 0x8(%r15)
leaq -0xa0(%rbp), %rdi
movsd -0x30(%rbp), %xmm0
callq 0x3612
leaq -0x40(%rbp), %rbx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x35f6
movq %rax, (%rbx)
movl %edx, 0x8(%rbx)
leaq -0x40(%rbp), %rdi
callq 0x366a
jmp 0x52dc
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x35c8
movq -0x40(%rbp), %rax
movl -0x38(%rbp), %edx
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop