// File: /workspace/github_cpp_makefile_star2_O3/IsaacLaw12[P]RayTracer/./src/Model.cpp
// Function: Model::test_intersection(Eigen::Matrix<double, 3, 1, 0, 3, 1>&, Eigen::Matrix<double, 3, 1, 0, 3, 1>&, Eigen::Matrix<double, 3, 1, 0, 3, 1>&, Ray&, double&)
bool Model::test_intersection(Eigen::Vector3d &vertex_a, Eigen::Vector3d &vertex_b, Eigen::Vector3d &vertex_c, Ray& ray, double& t_value){
    // Moller Trumbore Algorithm
    const double EPSILON = 0.0000001;
    Eigen::Vector3d edge_ba, edge_ca, pvec, qvec, origin_a;
    double det, invDet, u,v;
    edge_ba = vertex_b - vertex_a;
    edge_ca = vertex_c - vertex_a;
    pvec = ray.get_dir().cross(edge_ca);
    det = pvec.dot(edge_ba);
    if (abs(det) < EPSILON){
        // This ray is parallel to this triangle
        //std::cout << "abs(det): " << abs(det) << "\n";
        return false;
    }
    invDet = 1.0 / det;
    // Check that u is in bounds
    origin_a = ray.get_point() - vertex_a;
    u = (origin_a.dot(pvec)) * invDet;
    std::cout << "1\n";
    if (u < 0.0 || u > 1.0)
        return false;
    std::cout << "2\n";
    qvec = origin_a.cross(edge_ba);
    v = ray.get_dir().dot(qvec) * invDet;
    if (v < 0.0 || (u + v) > 1.0)
        return false;
    std::cout << "3\n";
    // At this stage we can compute t to find out where the intersection point is on the line.
    double t = invDet * edge_ca.dot(qvec);
    if (t > EPSILON){
        std::cout << "4\n";
        t_value = t;
        return true;
    }
    else {
        // This means that there is a line intersection but not a ray intersection.
        return false;
    }

}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x80, %rsp
movq %r9, %rbx
movq %r8, %r14
movq %rsi, %r15
movupd (%rdx), %xmm1
movupd (%rsi), %xmm0
subpd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
movsd 0x10(%rdx), %xmm2
movsd 0x10(%rsi), %xmm1
subsd %xmm1, %xmm2
movapd %xmm2, 0x30(%rsp)
movupd (%rcx), %xmm2
subpd %xmm0, %xmm2
movapd %xmm2, 0x50(%rsp)
movsd 0x10(%rcx), %xmm0
subsd %xmm1, %xmm0
movapd %xmm0, 0x60(%rsp)
movq %r8, %rdi
callq 0x15c86
movapd 0x50(%rsp), %xmm6
movapd %xmm6, %xmm4
unpckhpd %xmm6, %xmm4            # xmm4 = xmm4[1],xmm6[1]
movsd (%rax), %xmm0
movupd 0x8(%rax), %xmm1
movapd %xmm1, %xmm2
shufpd $0x1, %xmm0, %xmm2      # xmm2 = xmm2[1],xmm0[0]
movapd %xmm6, %xmm3
movapd 0x60(%rsp), %xmm5
shufpd $0x1, %xmm5, %xmm3      # xmm3 = xmm3[1],xmm5[0]
mulpd %xmm2, %xmm3
unpcklpd %xmm6, %xmm5            # xmm5 = xmm5[0],xmm6[0]
mulpd %xmm1, %xmm5
subpd %xmm3, %xmm5
mulsd %xmm6, %xmm1
mulsd %xmm0, %xmm4
subsd %xmm1, %xmm4
movapd 0x20(%rsp), %xmm0
mulpd %xmm5, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd 0x30(%rsp), %xmm0
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
movapd 0xb9e5(%rip), %xmm1     # 0x16020
andpd %xmm0, %xmm1
movsd 0xc8f1(%rip), %xmm2     # 0x16f38
ucomisd %xmm1, %xmm2
jbe 0xa65c
xorl %eax, %eax
addq $0x80, %rsp
popq %rbx
popq %r14
popq %r15
retq
movsd 0xb9cc(%rip), %xmm1     # 0x16030
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movq %r14, %rdi
movapd %xmm4, 0x10(%rsp)
movapd %xmm5, 0x40(%rsp)
callq 0x15c80
movupd (%rax), %xmm1
movupd (%r15), %xmm0
movsd 0x10(%rax), %xmm2
subsd 0x10(%r15), %xmm2
subpd %xmm0, %xmm1
movapd %xmm1, 0x70(%rsp)
movapd 0x40(%rsp), %xmm3
mulpd %xmm1, %xmm3
movapd %xmm3, %xmm0
unpckhpd %xmm3, %xmm0            # xmm0 = xmm0[1],xmm3[1]
addsd %xmm3, %xmm0
movapd 0x10(%rsp), %xmm1
movapd %xmm2, 0x40(%rsp)
mulsd %xmm2, %xmm1
movapd %xmm1, 0x10(%rsp)
movapd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
movapd %xmm1, 0x10(%rsp)
movapd 0x10(%rsp), %xmm0
mulsd 0x8(%rsp), %xmm0
movapd %xmm0, 0x10(%rsp)
movq 0x158d3(%rip), %rdi     # 0x1ffc8
leaq 0xc85f(%rip), %rsi      # 0x16f5b
movl $0x2, %edx
callq 0x32f0
movapd 0x10(%rsp), %xmm1
xorl %eax, %eax
xorpd %xmm0, %xmm0
ucomisd %xmm1, %xmm0
ja 0xa64f
ucomisd 0xb90c(%rip), %xmm1     # 0x16030
ja 0xa64f
movq 0x15897(%rip), %rdi     # 0x1ffc8
leaq 0xc826(%rip), %rsi      # 0x16f5e
movl $0x2, %edx
callq 0x32f0
movapd 0x70(%rsp), %xmm4
movapd %xmm4, %xmm0
unpckhpd %xmm4, %xmm0            # xmm0 = xmm0[1],xmm4[1]
movapd 0x20(%rsp), %xmm3
movapd %xmm3, %xmm6
unpckhpd %xmm3, %xmm6            # xmm6 = xmm6[1],xmm3[1]
movapd 0x40(%rsp), %xmm5
movapd %xmm5, %xmm1
unpcklpd %xmm4, %xmm1            # xmm1 = xmm1[0],xmm4[0]
movapd %xmm3, %xmm2
movapd 0x30(%rsp), %xmm7
shufpd $0x1, %xmm7, %xmm2      # xmm2 = xmm2[1],xmm7[0]
mulpd %xmm1, %xmm2
movapd %xmm4, %xmm1
shufpd $0x1, %xmm3, %xmm1      # xmm1 = xmm1[1],xmm3[0]
unpcklpd %xmm5, %xmm7            # xmm7 = xmm7[0],xmm5[0]
mulpd %xmm1, %xmm7
subpd %xmm2, %xmm7
movapd %xmm7, 0x30(%rsp)
mulsd %xmm3, %xmm0
mulsd %xmm4, %xmm6
subsd %xmm0, %xmm6
movapd %xmm6, 0x20(%rsp)
movq %r14, %rdi
callq 0x15c86
movupd (%rax), %xmm0
mulpd 0x30(%rsp), %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movsd 0x10(%rax), %xmm0
mulsd 0x20(%rsp), %xmm0
addsd %xmm1, %xmm0
mulsd 0x8(%rsp), %xmm0
xorl %eax, %eax
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0xa64f
movapd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
ucomisd 0xb82f(%rip), %xmm1     # 0x16030
ja 0xa64f
movq 0x157ba(%rip), %rdi     # 0x1ffc8
leaq 0xc74c(%rip), %rsi      # 0x16f61
movl $0x2, %edx
callq 0x32f0
movapd 0x50(%rsp), %xmm1
mulpd 0x30(%rsp), %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movapd 0x60(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
ucomisd 0xc6df(%rip), %xmm0     # 0x16f38
jbe 0xa64d
movq 0x15762(%rip), %rdi     # 0x1ffc8
leaq 0xc6f7(%rip), %rsi      # 0x16f64
movl $0x2, %edx
movsd %xmm0, 0x8(%rsp)
callq 0x32f0
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rbx)
movb $0x1, %al
jmp 0xa64f