// File: /workspace/github_cpp_makefile_star2_O3/alan0201tw[P]RayTracer/src/aabb.cpp
// Function: aabb::hit(ray const&, float, float) const
bool aabb::hit(const ray& _ray, float t_min, float t_max) const
{
    for (int a = 0; a < 3; a++)
    {
        float t0 = ffmin((min[a] - _ray.origin()[a]) / _ray.direction()[a],
                        (max[a] - _ray.origin()[a]) / _ray.direction()[a]);
        float t1 = ffmax((min[a] - _ray.origin()[a]) / _ray.direction()[a],
                        (max[a] - _ray.origin()[a]) / _ray.direction()[a]);
        t_min = ffmax(t0, t_min);
        t_max = ffmin(t1, t_max);
        if (t_max <= t_min)
        {
            return false;
        }
    }
    return true;

    // Reference : Andrew Kensler at Pixar ( mentioned in Ray Tracing: The Next Week, page 11 )

    // for (int a = 0; a < 3; a++)
    // {
    //     float invD = 1.0f / _ray.direction()[a];
    //     float t0 = (min[a] - _ray.origin()[a]) * invD;
    //     float t1 = (max[a] - _ray.origin()[a]) * invD;

    //     if(invD < 0.0f)
    //     {
    //         std::swap(t0, t1);
    //     }

    //     t_min = t0 > t_min ? t0 : t_min;
    //     t_max = t1 > t_max ? t1 : t_max;
        
    //     if(t_max <= t_min)
    //     {
    //         return false;
    //     }
    // }
    // return true;
}

// Assembly:
movsd (%rsi), %xmm2
movss 0x8(%rsi), %xmm3
movsd 0xc(%rsi), %xmm4
movss 0x14(%rsi), %xmm5
unpcklps %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
xorl %ecx, %ecx
xorl %eax, %eax
movss (%rdi,%rcx,4), %xmm0
movlps %xmm2, -0x10(%rsp)
movss %xmm3, -0x8(%rsp)
movss -0x10(%rsp,%rcx,4), %xmm6
movlps %xmm4, -0x20(%rsp)
movss %xmm5, -0x18(%rsp)
movss 0xc(%rdi,%rcx,4), %xmm7
unpcklps %xmm7, %xmm0            # xmm0 = xmm0[0],xmm7[0],xmm0[1],xmm7[1]
movss -0x20(%rsp,%rcx,4), %xmm7
movlps %xmm2, -0x30(%rsp)
movss %xmm3, -0x28(%rsp)
movss -0x30(%rsp,%rcx,4), %xmm8
movlps %xmm4, -0x40(%rsp)
movss %xmm5, -0x38(%rsp)
movss -0x40(%rsp,%rcx,4), %xmm9
movlps %xmm2, -0x10(%rsp)
movss %xmm3, -0x8(%rsp)
movss -0x10(%rsp,%rcx,4), %xmm10
unpcklps %xmm8, %xmm10           # xmm10 = xmm10[0],xmm8[0],xmm10[1],xmm8[1]
movlps %xmm4, -0x20(%rsp)
movss %xmm5, -0x18(%rsp)
movss -0x20(%rsp,%rcx,4), %xmm8
unpcklps %xmm9, %xmm8            # xmm8 = xmm8[0],xmm9[0],xmm8[1],xmm9[1]
movlps %xmm2, -0x30(%rsp)
movss %xmm3, -0x28(%rsp)
movss -0x30(%rsp,%rcx,4), %xmm9
unpcklps %xmm9, %xmm6            # xmm6 = xmm6[0],xmm9[0],xmm6[1],xmm9[1]
movlps %xmm4, -0x40(%rsp)
movss %xmm5, -0x38(%rsp)
movss -0x40(%rsp,%rcx,4), %xmm9
unpcklps %xmm9, %xmm7            # xmm7 = xmm7[0],xmm9[0],xmm7[1],xmm9[1]
movaps %xmm0, %xmm9
subps %xmm10, %xmm9
divps %xmm8, %xmm9
shufps $0xe1, %xmm0, %xmm0     # xmm0 = xmm0[1,0,2,3]
shufps $0xe1, %xmm6, %xmm6     # xmm6 = xmm6[1,0,2,3]
subps %xmm6, %xmm0
shufps $0xe1, %xmm7, %xmm7     # xmm7 = xmm7[1,0,2,3]
divps %xmm7, %xmm0
movaps %xmm0, %xmm6
cmpltps %xmm9, %xmm6
movaps %xmm0, %xmm7
shufps $0x1, %xmm9, %xmm7      # xmm7 = xmm7[1,0],xmm9[0,0]
shufps $0xe2, %xmm9, %xmm7     # xmm7 = xmm7[2,0],xmm9[2,3]
shufps $0x1, %xmm0, %xmm9      # xmm9 = xmm9[1,0],xmm0[0,0]
shufps $0xe2, %xmm0, %xmm9     # xmm9 = xmm9[2,0],xmm0[2,3]
andps %xmm6, %xmm7
andnps %xmm9, %xmm6
orps %xmm7, %xmm6
movaps %xmm6, %xmm0
shufps $0x1, %xmm1, %xmm0      # xmm0 = xmm0[1,0],xmm1[0,0]
shufps $0xe2, %xmm1, %xmm0     # xmm0 = xmm0[2,0],xmm1[2,3]
movaps %xmm1, %xmm7
shufps $0x1, %xmm6, %xmm7      # xmm7 = xmm7[1,0],xmm6[0,0]
shufps $0xe2, %xmm6, %xmm7     # xmm7 = xmm7[2,0],xmm6[2,3]
cmpltps %xmm0, %xmm7
andps %xmm7, %xmm6
andnps %xmm1, %xmm7
movaps %xmm7, %xmm1
orps %xmm6, %xmm1
pshufd $0x55, %xmm1, %xmm0     # xmm0 = xmm1[1,1,1,1]
ucomiss %xmm1, %xmm0
jae 0xc36d
cmpq $0x2, %rcx
leaq 0x1(%rcx), %rdx
setae %al
movq %rdx, %rcx
cmpq $0x3, %rdx
jne 0xc232
andb $0x1, %al
retq