// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %r9, %rbx
movq %r8, %r14
movq %rcx, %r13
movq %rsi, %r15
leaq 0x60(%rsp), %rsi
movq %rdx, (%rsi)
movq %r15, 0x8(%rsi)
leaq 0x78(%rsp), %r12
movq %r12, %rdi
callq 0xc5d7
leaq 0x48(%rsp), %rsi
movq %r13, (%rsi)
movq %r15, 0x8(%rsi)
leaq 0x60(%rsp), %r13
movq %r13, %rdi
callq 0xc5d7
movq %r14, %rdi
callq 0x17daa
leaq 0x18(%rsp), %rbp
movq %rbp, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x53de
leaq 0x48(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x52e8
movq %r13, %rdi
movq %r12, %rsi
callq 0xc836
movapd 0xdfe3(%rip), %xmm1     # 0x18020
andpd %xmm0, %xmm1
movsd 0xf40f(%rip), %xmm2     # 0x19458
ucomisd %xmm1, %xmm2
jbe 0xa063
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movsd 0xdfc5(%rip), %xmm1     # 0x18030
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movq %r14, %rdi
callq 0x17da4
leaq 0x18(%rsp), %rsi
movq %rax, (%rsi)
movq %r15, 0x8(%rsi)
leaq 0x30(%rsp), %r15
movq %r15, %rdi
callq 0xc5d7
leaq 0x48(%rsp), %rsi
movq %r15, %rdi
callq 0xc836
mulsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x1ff0a(%rip), %rdi     # 0x29fc0
leaq 0xf3be(%rip), %rsi      # 0x1947b
callq 0x32a0
xorl %eax, %eax
xorpd %xmm0, %xmm0
movsd 0x10(%rsp), %xmm1
ucomisd %xmm1, %xmm0
ja 0xa051
ucomisd 0xdf50(%rip), %xmm1     # 0x18030
ja 0xa051
movq 0x1fed3(%rip), %rdi     # 0x29fc0
leaq 0xf38a(%rip), %rsi      # 0x1947e
callq 0x32a0
movsd 0x78(%rsp), %xmm0
movsd 0x30(%rsp), %xmm1
movupd 0x38(%rsp), %xmm2
movupd 0x80(%rsp), %xmm3
movapd %xmm2, %xmm4
shufpd $0x1, %xmm1, %xmm4      # xmm4 = xmm4[1],xmm1[0]
mulpd %xmm3, %xmm4
mulsd %xmm3, %xmm1
shufpd $0x1, %xmm0, %xmm3      # xmm3 = xmm3[1],xmm0[0]
mulpd %xmm2, %xmm3
subpd %xmm4, %xmm3
mulsd %xmm2, %xmm0
subsd %xmm0, %xmm1
leaq 0x90(%rsp), %rsi
movapd %xmm3, (%rsi)
movsd %xmm1, 0x10(%rsi)
leaq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x52e8
movq %r14, %rdi
callq 0x17daa
movq %rax, %rdi
movq %r15, %rsi
callq 0xc836
mulsd 0x8(%rsp), %xmm0
xorl %eax, %eax
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
ja 0xa051
movsd 0x10(%rsp), %xmm1
addsd %xmm0, %xmm1
ucomisd 0xde9d(%rip), %xmm1     # 0x18030
ja 0xa051
movq 0x1fe20(%rip), %rdi     # 0x29fc0
leaq 0xf2da(%rip), %rsi      # 0x19481
callq 0x32a0
leaq 0x60(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0xc836
movsd 0x8(%rsp), %xmm1
mulsd %xmm0, %xmm1
ucomisd 0xf28b(%rip), %xmm1     # 0x19458
jbe 0xa04f
movq 0x1fde6(%rip), %rdi     # 0x29fc0
leaq 0xf2a3(%rip), %rsi      # 0x19484
movsd %xmm1, 0x8(%rsp)
callq 0x32a0
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rbx)
movb $0x1, %al
jmp 0xa051
nop