// File: /workspace/github_cpp_makefile_star2_O3/alan0201tw[P]RayTracer/src/triangle.cpp
// Function: triangle::hit(ray const&, float, float, hit_record&) const
bool triangle::hit(const ray& _ray, float t_min, float t_max, hit_record& rec) const
{
    // Reference : 
    // https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection
    // https://github.com/netolcc06/BabyRayTracer/blob/master/Triangle.hpp
    vec3 v0v1 = v1 - v0;
    vec3 v0v2 = v2 - v0;
    vec3 pvec = cross(_ray.direction(), v0v2);
    float det = dot(v0v1, pvec);

    // culling
    //if(det < kEpsilon) return false;
    // no culling
    if (fabs(det) < kEpsilon) return false; 

    float invDet = 1.0f / det;

    vec3 tvec = _ray.origin() - v0;
    float u = dot(tvec, pvec) * invDet;
    if(u < 0 || u > 1) return false;

    vec3 qvec = cross(tvec, v0v1);
    float v = dot(_ray.direction(), qvec) * invDet;
    if(v < 0 || u + v > 1) return false;

    float t = dot(v0v2, qvec) * invDet;
    if (t < 0) return false;

    // fill in collision info
    rec.hit_point = _ray.point_at_parameter(t);
    if(dot(normal, _ray.direction()) > 0.0f)
        rec.normal = -1.0f * normal;
    else
        rec.normal = normal;
    rec.t = t;
    rec.u = u;
    rec.v = v;
    rec.material_ref = triangle_mat;

    return true;
}

// Assembly:
subq $0x38, %rsp
movss 0x14(%rdi), %xmm7
movss 0x8(%rdi), %xmm15
movss 0xc(%rdi), %xmm14
subss %xmm15, %xmm7
movss 0x18(%rdi), %xmm8
subss %xmm14, %xmm8
movss 0x10(%rdi), %xmm9
movss 0x20(%rdi), %xmm4
subss %xmm15, %xmm4
movss 0x24(%rdi), %xmm6
subss %xmm14, %xmm6
movss 0x28(%rdi), %xmm5
subss %xmm9, %xmm5
movsd 0xc(%rsi), %xmm2
movaps %xmm2, %xmm3
shufps $0x55, %xmm2, %xmm3     # xmm3 = xmm3[1,1],xmm2[1,1]
movss 0x14(%rsi), %xmm1
movaps %xmm6, %xmm0
mulss %xmm1, %xmm0
movaps %xmm3, %xmm11
mulss %xmm5, %xmm11
subss %xmm0, %xmm11
movaps %xmm4, %xmm0
movss %xmm1, 0x8(%rsp)
mulss %xmm1, %xmm0
movaps %xmm2, %xmm10
mulss %xmm5, %xmm10
subss %xmm0, %xmm10
movaps %xmm4, %xmm1
mulss %xmm3, %xmm1
movaps %xmm2, 0x10(%rsp)
movaps %xmm2, %xmm0
mulss %xmm6, %xmm0
subss %xmm1, %xmm0
movaps %xmm8, %xmm1
mulss %xmm10, %xmm1
movaps %xmm7, %xmm13
mulss %xmm11, %xmm13
subss %xmm1, %xmm13
movss 0x1c(%rdi), %xmm12
subss %xmm9, %xmm12
movaps %xmm12, %xmm1
mulss %xmm0, %xmm1
addss %xmm13, %xmm1
movaps 0x30d9c(%rip), %xmm13   # 0x3c490
andps %xmm1, %xmm13
movss 0x30da0(%rip), %xmm2    # 0x3c4a0
ucomiss %xmm13, %xmm2
jbe 0xb70d
xorl %eax, %eax
addq $0x38, %rsp
retq
movss %xmm8, 0xc(%rsp)
xorps 0x30c04(%rip), %xmm10   # 0x3c320
movss 0x30ae0(%rip), %xmm2    # 0x3c204
divss %xmm1, %xmm2
movsd (%rsi), %xmm13
movaps %xmm13, %xmm1
shufps $0x55, %xmm13, %xmm1    # xmm1 = xmm1[1,1],xmm13[1,1]
movss 0x8(%rsi), %xmm8
movaps %xmm13, 0x20(%rsp)
subss %xmm15, %xmm13
subss %xmm14, %xmm1
movaps %xmm8, %xmm14
subss %xmm9, %xmm14
mulss %xmm1, %xmm10
mulss %xmm13, %xmm11
addss %xmm10, %xmm11
movaps %xmm2, %xmm10
mulss %xmm14, %xmm0
addss %xmm11, %xmm0
mulss %xmm2, %xmm0
xorl %eax, %eax
xorps %xmm2, %xmm2
ucomiss %xmm0, %xmm2
ja 0xb708
ucomiss 0x30a7d(%rip), %xmm0    # 0x3c204
ja 0xb708
movaps %xmm8, %xmm15
movss 0xc(%rsp), %xmm8
movaps %xmm8, %xmm2
mulss %xmm14, %xmm2
movaps %xmm1, %xmm9
mulss %xmm12, %xmm9
subss %xmm2, %xmm9
mulss %xmm7, %xmm14
mulss %xmm13, %xmm12
subss %xmm14, %xmm12
mulss %xmm1, %xmm7
mulss %xmm8, %xmm13
subss %xmm7, %xmm13
mulss %xmm12, %xmm3
movaps 0x10(%rsp), %xmm1
mulss %xmm9, %xmm1
subss %xmm3, %xmm1
movss 0x8(%rsp), %xmm7
mulss %xmm13, %xmm7
addss %xmm1, %xmm7
mulss %xmm10, %xmm7
xorl %eax, %eax
xorps %xmm1, %xmm1
ucomiss %xmm7, %xmm1
ja 0xb708
movaps %xmm0, %xmm1
addss %xmm7, %xmm1
ucomiss 0x309f5(%rip), %xmm1    # 0x3c204
ja 0xb708
xorps 0x30b03(%rip), %xmm12   # 0x3c320
mulss %xmm12, %xmm6
mulss %xmm9, %xmm4
addss %xmm6, %xmm4
mulss %xmm13, %xmm5
addss %xmm4, %xmm5
mulss %xmm5, %xmm10
xorps %xmm1, %xmm1
ucomiss %xmm10, %xmm1
ja 0xb706
movq %rdi, %rcx
movaps %xmm10, %xmm2
unpcklps %xmm10, %xmm2           # xmm2 = xmm2[0],xmm10[0],xmm2[1],xmm10[1]
mulps 0x10(%rsp), %xmm2
movss 0x8(%rsp), %xmm3
mulss %xmm10, %xmm3
addps 0x20(%rsp), %xmm2
addss %xmm3, %xmm15
movlps %xmm2, 0xc(%rdx)
movss %xmm15, 0x14(%rdx)
movsd 0xc(%rsi), %xmm4
movsd 0x2c(%rdi), %xmm2
movaps %xmm4, %xmm3
mulps %xmm2, %xmm3
shufps $0x55, %xmm3, %xmm3     # xmm3 = xmm3[1,1,1,1]
mulss %xmm2, %xmm4
addss %xmm3, %xmm4
movss 0x34(%rdi), %xmm3
movss 0x14(%rsi), %xmm5
mulss %xmm3, %xmm5
addss %xmm4, %xmm5
ucomiss %xmm1, %xmm5
jbe 0xb8c0
movaps 0x30a71(%rip), %xmm1    # 0x3c320
xorps %xmm1, %xmm2
xorps %xmm1, %xmm3
movlps %xmm2, 0x18(%rdx)
movss %xmm3, 0x20(%rdx)
jmp 0xb8d1
leaq 0x2c(%rcx), %rax
movl 0x8(%rax), %esi
movl %esi, 0x20(%rdx)
movq (%rax), %rax
movq %rax, 0x18(%rdx)
movss %xmm10, (%rdx)
movss %xmm0, 0x4(%rdx)
movss %xmm7, 0x8(%rdx)
movq 0x38(%rcx), %rax
movq %rax, 0x28(%rdx)
addq $0x30, %rdx
addq $0x40, %rcx
movq %rdx, %rdi
movq %rcx, %rsi
callq 0x7a28
movb $0x1, %al
jmp 0xb708