// File: /workspace/github_cpp_makefile_star2_O1/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 $0x18, %rsp
movss 0x14(%rdi), %xmm6
movss 0x8(%rdi), %xmm14
movss 0xc(%rdi), %xmm13
subss %xmm14, %xmm6
movss 0x18(%rdi), %xmm8
subss %xmm13, %xmm8
movss 0x10(%rdi), %xmm15
movss 0x20(%rdi), %xmm3
subss %xmm14, %xmm3
movss 0x24(%rdi), %xmm5
subss %xmm13, %xmm5
movss 0x28(%rdi), %xmm4
subss %xmm15, %xmm4
movsd 0xc(%rsi), %xmm2
movss 0x14(%rsi), %xmm1
movaps %xmm2, %xmm9
shufps $0x55, %xmm2, %xmm9     # xmm9 = xmm9[1,1],xmm2[1,1]
movaps %xmm5, %xmm0
mulss %xmm1, %xmm0
movaps %xmm9, %xmm10
mulss %xmm4, %xmm10
subss %xmm0, %xmm10
movaps %xmm3, %xmm0
movss %xmm1, 0xc(%rsp)
mulss %xmm1, %xmm0
movaps %xmm2, %xmm7
mulss %xmm4, %xmm7
subss %xmm0, %xmm7
movaps %xmm3, %xmm1
mulss %xmm9, %xmm1
movaps %xmm2, %xmm0
mulss %xmm5, %xmm0
subss %xmm1, %xmm0
movss %xmm8, 0x14(%rsp)
movaps %xmm8, %xmm1
mulss %xmm7, %xmm1
movaps %xmm6, %xmm12
mulss %xmm10, %xmm12
subss %xmm1, %xmm12
movss 0x1c(%rdi), %xmm11
subss %xmm15, %xmm11
movaps %xmm11, %xmm1
mulss %xmm0, %xmm1
addss %xmm12, %xmm1
movaps 0x30b8f(%rip), %xmm12   # 0x3c470
andps %xmm1, %xmm12
movss 0x30b92(%rip), %xmm8    # 0x3c480
ucomiss %xmm12, %xmm8
jbe 0xb8fb
xorl %eax, %eax
addq $0x18, %rsp
retq
movss %xmm5, 0x10(%rsp)
xorps 0x309f8(%rip), %xmm7    # 0x3c300
movss 0x30917(%rip), %xmm8    # 0x3c228
divss %xmm1, %xmm8
movsd (%rsi), %xmm5
movss 0x8(%rsi), %xmm1
movaps %xmm5, %xmm12
subss %xmm14, %xmm12
shufps $0x55, %xmm5, %xmm5     # xmm5 = xmm5[1,1,1,1]
subss %xmm13, %xmm5
movaps %xmm1, %xmm13
subss %xmm15, %xmm13
mulss %xmm5, %xmm7
mulss %xmm12, %xmm10
addss %xmm7, %xmm10
mulss %xmm13, %xmm0
addss %xmm10, %xmm0
mulss %xmm8, %xmm0
xorl %eax, %eax
xorps %xmm7, %xmm7
ucomiss %xmm0, %xmm7
ja 0xb8f6
ucomiss 0x308c0(%rip), %xmm0    # 0x3c228
ja 0xb8f6
movaps %xmm1, %xmm14
movaps %xmm8, %xmm10
movss 0x14(%rsp), %xmm1
movaps %xmm1, %xmm8
mulss %xmm13, %xmm8
movaps %xmm5, %xmm7
mulss %xmm11, %xmm7
subss %xmm8, %xmm7
mulss %xmm6, %xmm13
mulss %xmm12, %xmm11
subss %xmm13, %xmm11
mulss %xmm5, %xmm6
mulss %xmm1, %xmm12
subss %xmm6, %xmm12
mulss %xmm11, %xmm9
mulss %xmm7, %xmm2
subss %xmm9, %xmm2
movss 0xc(%rsp), %xmm6
mulss %xmm12, %xmm6
addss %xmm2, %xmm6
mulss %xmm10, %xmm6
xorl %eax, %eax
xorps %xmm2, %xmm2
ucomiss %xmm6, %xmm2
ja 0xb8f6
movaps %xmm0, %xmm2
addss %xmm6, %xmm2
ucomiss 0x3083f(%rip), %xmm2    # 0x3c228
ja 0xb8f6
movaps %xmm10, %xmm8
xorps 0x30905(%rip), %xmm11   # 0x3c300
movss 0x10(%rsp), %xmm1
mulss %xmm11, %xmm1
mulss %xmm7, %xmm3
addss %xmm1, %xmm3
mulss %xmm12, %xmm4
addss %xmm3, %xmm4
mulss %xmm4, %xmm8
xorps %xmm1, %xmm1
ucomiss %xmm8, %xmm1
setbe %al
ja 0xb8f6
movq %rdi, %rcx
movss 0xc(%rsi), %xmm2
mulss %xmm8, %xmm2
movss 0x10(%rsi), %xmm3
mulss %xmm8, %xmm3
movss 0xc(%rsp), %xmm4
mulss %xmm8, %xmm4
addss (%rsi), %xmm2
addss 0x4(%rsi), %xmm3
unpcklps %xmm3, %xmm2            # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
addss %xmm4, %xmm14
movlps %xmm2, 0xc(%rdx)
movss %xmm14, 0x14(%rdx)
movsd 0xc(%rsi), %xmm5
movss 0x2c(%rdi), %xmm2
movss 0x30(%rdi), %xmm3
movaps %xmm2, %xmm4
mulss %xmm5, %xmm4
shufps $0x55, %xmm5, %xmm5     # xmm5 = xmm5[1,1,1,1]
mulss %xmm3, %xmm5
addss %xmm4, %xmm5
movss 0x34(%rdi), %xmm4
movss 0x14(%rsi), %xmm7
mulss %xmm4, %xmm7
addss %xmm5, %xmm7
ucomiss %xmm1, %xmm7
jbe 0xbabd
movaps 0x30857(%rip), %xmm1    # 0x3c300
xorps %xmm1, %xmm4
unpcklps %xmm3, %xmm2            # xmm2 = xmm2[0],xmm3[0],xmm2[1],xmm3[1]
xorps %xmm1, %xmm2
movlps %xmm2, 0x18(%rdx)
movss %xmm4, 0x20(%rdx)
jmp 0xbace
leaq 0x2c(%rcx), %rax
movl 0x8(%rax), %esi
movl %esi, 0x20(%rdx)
movq (%rax), %rax
movq %rax, 0x18(%rdx)
movss %xmm8, (%rdx)
movss %xmm0, 0x4(%rdx)
movss %xmm6, 0x8(%rdx)
movq 0x38(%rcx), %rax
movq %rax, 0x28(%rdx)
addq $0x30, %rdx
addq $0x40, %rcx
movq %rdx, %rdi
movq %rcx, %rsi
callq 0x7a04
movb $0x1, %al
jmp 0xb8f6
nop