// File: 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:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x158(%rsp)
movq %rsi, 0x150(%rsp)
movq %rdx, 0x148(%rsp)
movq %rcx, 0x140(%rsp)
movq %r8, 0x138(%rsp)
movq %r9, 0x130(%rsp)
movsd 0x453d1(%rip), %xmm0    # 0x62100
movsd %xmm0, 0x128(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x11e20
leaq 0xf8(%rsp), %rdi
callq 0x11e20
leaq 0xe0(%rsp), %rdi
callq 0x11e20
leaq 0xc8(%rsp), %rdi
callq 0x11e20
leaq 0xb0(%rsp), %rdi
callq 0x11e20
movq 0x148(%rsp), %rsi
movq 0x150(%rsp), %rdx
leaq 0x78(%rsp), %rdi
callq 0x9e80
leaq 0x110(%rsp), %rdi
leaq 0x78(%rsp), %rsi
callq 0x1e190
movq 0x140(%rsp), %rsi
movq 0x150(%rsp), %rdx
leaq 0x60(%rsp), %rdi
callq 0x9e80
leaq 0xf8(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x1e190
movq 0x138(%rsp), %rdi
callq 0x5cba0
movq %rax, %rsi
leaq 0x48(%rsp), %rdi
leaq 0xf8(%rsp), %rdx
callq 0xa000
leaq 0xe0(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x9d10
leaq 0xe0(%rsp), %rdi
leaq 0x110(%rsp), %rsi
callq 0x1e440
movsd %xmm0, 0xa8(%rsp)
movsd 0xa8(%rsp), %xmm0
callq 0x6540
movaps %xmm0, %xmm1
movsd 0x452c4(%rip), %xmm0    # 0x62100
ucomisd %xmm1, %xmm0
jbe 0x1ce4f
movb $0x0, 0x167(%rsp)
jmp 0x1d047
movsd 0x401b1(%rip), %xmm0    # 0x5d008
divsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
movq 0x138(%rsp), %rdi
callq 0x5cb90
movq %rax, %rsi
movq 0x150(%rsp), %rdx
leaq 0x30(%rsp), %rdi
callq 0x9e80
leaq 0xb0(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x1e190
leaq 0xb0(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x1e440
mulsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0x7e0f5(%rip), %rdi     # 0x9afc0
leaq 0x45251(%rip), %rsi     # 0x62123
callq 0x4360
xorps %xmm0, %xmm0
ucomisd 0x98(%rsp), %xmm0
ja 0x1cefc
movsd 0x98(%rsp), %xmm0
movsd 0x40112(%rip), %xmm1    # 0x5d008
ucomisd %xmm1, %xmm0
jbe 0x1cf09
movb $0x0, 0x167(%rsp)
jmp 0x1d047
movq 0x7e0b0(%rip), %rdi     # 0x9afc0
leaq 0x4520f(%rip), %rsi     # 0x62126
callq 0x4360
leaq 0x18(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0x110(%rsp), %rdx
callq 0xa000
leaq 0xc8(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x9d10
movq 0x138(%rsp), %rdi
callq 0x5cba0
movq %rax, %rdi
leaq 0xc8(%rsp), %rsi
callq 0x1e440
mulsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x90(%rsp), %xmm0
ja 0x1cfa5
movsd 0x98(%rsp), %xmm0
addsd 0x90(%rsp), %xmm0
movsd 0x40069(%rip), %xmm1    # 0x5d008
ucomisd %xmm1, %xmm0
jbe 0x1cfb2
movb $0x0, 0x167(%rsp)
jmp 0x1d047
movq 0x7e007(%rip), %rdi     # 0x9afc0
leaq 0x45169(%rip), %rsi     # 0x62129
callq 0x4360
movsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x1e440
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x10(%rsp), %xmm0
movsd 0x450f6(%rip), %xmm1    # 0x62100
ucomisd %xmm1, %xmm0
jbe 0x1d03f
movq 0x7dfa9(%rip), %rdi     # 0x9afc0
leaq 0x4510e(%rip), %rsi     # 0x6212c
callq 0x4360
movsd 0x10(%rsp), %xmm0
movq 0x130(%rsp), %rax
movsd %xmm0, (%rax)
movb $0x1, 0x167(%rsp)
jmp 0x1d047
movb $0x0, 0x167(%rsp)
movb 0x167(%rsp), %al
andb $0x1, %al
addq $0x168, %rsp            # imm = 0x168
retq
nopl (%rax,%rax)