// File: /workspace/github_cpp_makefile_star2_O3/alan0201tw[P]RayTracer/src/util.cpp
// Function: perlin_interpolate(vec3 (*) [2][2], float, float, float)
float perlin_interpolate(vec3 _data[2][2][2], float _u, float _v, float _w)
{
    // Reference :
    // https://github.com/RayTracing/TheNextWeek/issues/6
    //
    // in the original implementation in the book, the dot product
    // will return negative results, causing the produced image haing
    // several dark bands. 
    // Accoring to the github issue, this can be resolved by rescaling
    // the interpolation result from [-1, 1] to [0, 1].

    float uu = _u * _u * (3 - 2 * _u);
    float vv = _v * _v * (3 - 2 * _v);
    float ww = _w * _w * (3 - 2 * _w);

    float accum = 0.0f;
    for(int i = 0; i < 2; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            for(int k = 0; k < 2; k++)
            {
                vec3 weight(_u - i, _v - j, _w - k);
                accum += (i * uu + (1 - i) * (1 - uu)) *
                         (j * vv + (1 - j) * (1 - vv)) *
                         (k * ww + (1 - k) * (1 - ww)) * dot(_data[i][j][k], weight);
            }
        }
    }
    return 0.5f * (accum + 1.0f);
}

// Assembly:
movaps %xmm0, %xmm3
mulss %xmm0, %xmm3
movss %xmm0, -0x4(%rsp)
movaps %xmm0, %xmm6
addss %xmm0, %xmm6
movss 0x276e0(%rip), %xmm4    # 0x3c4cc
movaps %xmm4, %xmm0
subss %xmm6, %xmm0
mulss %xmm3, %xmm0
movaps %xmm1, %xmm3
mulss %xmm1, %xmm3
movaps %xmm1, %xmm7
addss %xmm1, %xmm7
movaps %xmm4, %xmm6
subss %xmm7, %xmm6
mulss %xmm3, %xmm6
movaps %xmm2, %xmm3
mulss %xmm2, %xmm3
movaps %xmm2, %xmm7
addss %xmm2, %xmm7
subss %xmm7, %xmm4
mulss %xmm3, %xmm4
movss 0x273d6(%rip), %xmm7    # 0x3c204
movaps %xmm7, %xmm8
movss %xmm0, -0x8(%rsp)
subss %xmm0, %xmm8
movaps %xmm7, %xmm9
subss %xmm6, %xmm9
subss %xmm4, %xmm7
xorps %xmm3, %xmm3
movb $0x1, %al
xorl %ecx, %ecx
xorps %xmm10, %xmm10
cvtsi2ss %ecx, %xmm10
movss -0x4(%rsp), %xmm11
subss %xmm10, %xmm11
movl %ecx, %edx
xorl $0x1, %edx
xorps %xmm12, %xmm12
cvtsi2ss %edx, %xmm12
mulss %xmm8, %xmm12
mulss -0x8(%rsp), %xmm10
addss %xmm12, %xmm10
leaq (%rcx,%rcx,2), %rcx
shlq $0x4, %rcx
addq %rdi, %rcx
movb $0x1, %dl
xorl %r8d, %r8d
xorps %xmm12, %xmm12
cvtsi2ss %r8d, %xmm12
movaps %xmm1, %xmm13
subss %xmm12, %xmm13
movl %r8d, %esi
xorl $0x1, %esi
xorps %xmm14, %xmm14
cvtsi2ss %esi, %xmm14
mulss %xmm9, %xmm14
mulss %xmm6, %xmm12
addss %xmm14, %xmm12
mulss %xmm10, %xmm12
movb $0x1, %sil
leaq (%r8,%r8,2), %r8
leaq (%rcx,%r8,8), %r8
xorl %r9d, %r9d
xorps %xmm15, %xmm15
cvtsi2ss %r9d, %xmm15
movaps %xmm2, %xmm14
subss %xmm15, %xmm14
leaq (%r9,%r9,2), %r10
xorl $0x1, %r9d
xorps %xmm5, %xmm5
cvtsi2ss %r9d, %xmm5
mulss %xmm7, %xmm5
mulss %xmm4, %xmm15
addss %xmm5, %xmm15
mulss %xmm12, %xmm15
movss 0x4(%r8,%r10,4), %xmm5
mulss %xmm13, %xmm5
movss (%r8,%r10,4), %xmm0
mulss %xmm11, %xmm0
addss %xmm5, %xmm0
mulss 0x8(%r8,%r10,4), %xmm14
addss %xmm0, %xmm14
mulss %xmm15, %xmm14
addss %xmm14, %xmm3
movl $0x1, %r9d
testb $0x1, %sil
movl $0x0, %esi
jne 0x14ed8
movl $0x1, %r8d
testb $0x1, %dl
movl $0x0, %edx
jne 0x14e95
movl $0x1, %ecx
testb $0x1, %al
movl $0x0, %eax
jne 0x14e51
addss 0x27287(%rip), %xmm3    # 0x3c204
mulss 0x272bf(%rip), %xmm3    # 0x3c244
movaps %xmm3, %xmm0
retq