// File: /workspace/github_cpp_makefile_star2_O3/IsaacLaw12[P]RayTracer/./src/Sphere.cpp
// Function: Sphere::intersect_ray(Ray&, Eigen::Matrix<double, 3, 1, 0, 3, 1>&)
double Sphere::intersect_ray(Ray& ray, Eigen::Vector3d &hit_normal){
    const Eigen::Vector3d &ray_pt = ray.get_point();
    const Eigen::Vector3d &ray_dir = ray.get_dir();
    double t_value = -1;
    double v = (sphere_center - ray_pt).dot(ray_dir);
    double c = (sphere_center - ray_pt).norm();
    // Either the ray went the wrong way, or there was no intersection
    if (v < 0 || ((radius*radius) < (c*c - v*v))){
        return t_value;
    }
    double dr = (ray_pt + (v * ray_dir) - sphere_center).norm();
    double intersection_offset = sqrt( radius*radius - dr*dr);
    t_value = v - intersection_offset;

    Eigen::Vector3d intersection_point = ray_pt + ray_dir * t_value;
    hit_normal = (intersection_point - sphere_center).normalized();
    return t_value;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r14
movq %rsi, %rdi
callq 0x15c80
movq %rax, %r15
movq %r12, %rdi
callq 0x15c86
movupd 0x1b8(%r14), %xmm5
movupd (%r15), %xmm2
movapd %xmm5, %xmm0
subpd %xmm2, %xmm0
movupd (%rax), %xmm7
movapd %xmm0, %xmm1
mulpd %xmm7, %xmm1
movapd %xmm1, %xmm9
unpckhpd %xmm1, %xmm9            # xmm9 = xmm9[1],xmm1[1]
addsd %xmm1, %xmm9
movsd 0x1c8(%r14), %xmm4
movsd 0x10(%r15), %xmm3
movapd %xmm4, %xmm8
subsd %xmm3, %xmm8
movsd 0x10(%rax), %xmm6
movapd %xmm8, %xmm10
mulsd %xmm6, %xmm10
addsd %xmm9, %xmm10
movsd 0x8ef7(%rip), %xmm1     # 0x16eb8
xorpd %xmm9, %xmm9
ucomisd %xmm10, %xmm9
ja 0xe123
mulpd %xmm0, %xmm0
movapd %xmm0, %xmm9
unpckhpd %xmm0, %xmm9            # xmm9 = xmm9[1],xmm0[1]
addsd %xmm0, %xmm9
mulsd %xmm8, %xmm8
addsd %xmm9, %xmm8
sqrtsd %xmm8, %xmm8
movsd 0x190(%r14), %xmm0
mulsd %xmm0, %xmm0
movapd %xmm10, %xmm9
mulsd %xmm10, %xmm9
mulsd %xmm8, %xmm8
subsd %xmm9, %xmm8
ucomisd %xmm0, %xmm8
ja 0xe123
movq %rax, %r12
movapd %xmm10, %xmm1
unpcklpd %xmm10, %xmm1           # xmm1 = xmm1[0],xmm10[0]
mulpd %xmm1, %xmm7
addpd %xmm7, %xmm2
subpd %xmm5, %xmm2
mulpd %xmm2, %xmm2
movapd %xmm2, %xmm1
unpckhpd %xmm2, %xmm1            # xmm1 = xmm1[1],xmm2[1]
addsd %xmm2, %xmm1
mulsd %xmm10, %xmm6
addsd %xmm6, %xmm3
subsd %xmm4, %xmm3
mulsd %xmm3, %xmm3
addsd %xmm1, %xmm3
xorps %xmm1, %xmm1
sqrtsd %xmm3, %xmm1
mulsd %xmm1, %xmm1
subsd %xmm1, %xmm0
xorpd %xmm4, %xmm4
ucomisd %xmm4, %xmm0
jb 0xe07c
sqrtsd %xmm0, %xmm0
jmp 0xe091
movapd %xmm10, (%rsp)
callq 0x3240
xorpd %xmm4, %xmm4
movapd (%rsp), %xmm10
subsd %xmm0, %xmm10
movupd (%r15), %xmm1
movupd (%r12), %xmm2
movapd %xmm10, %xmm0
unpcklpd %xmm10, %xmm0           # xmm0 = xmm0[0],xmm10[0]
mulpd %xmm2, %xmm0
addpd %xmm1, %xmm0
movsd 0x10(%r12), %xmm1
mulsd %xmm10, %xmm1
addsd 0x10(%r15), %xmm1
movupd 0x1b8(%r14), %xmm2
subpd %xmm2, %xmm0
movapd %xmm0, %xmm2
mulpd %xmm0, %xmm2
movapd %xmm2, %xmm3
unpckhpd %xmm2, %xmm3            # xmm3 = xmm3[1],xmm2[1]
addsd %xmm2, %xmm3
subsd 0x1c8(%r14), %xmm1
movapd %xmm1, %xmm2
mulsd %xmm1, %xmm2
addsd %xmm3, %xmm2
ucomisd %xmm4, %xmm2
jbe 0xe115
movq %xmm2, %xmm2            # xmm2 = xmm2[0],zero
sqrtpd %xmm2, %xmm2
divsd %xmm2, %xmm1
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
divpd %xmm2, %xmm0
movupd %xmm0, (%rbx)
movsd %xmm1, 0x10(%rbx)
movapd %xmm10, %xmm1
movapd %xmm1, %xmm0
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nop