// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3PointLight.cpp
// Function: gaps::R3PointLight::Reflection(gaps::R3Brdf const&, gaps::R3Point const&, gaps::R3Point const&, gaps::R3Vector const&) const
RNRgb R3PointLight::
Reflection(const R3Brdf& brdf, const R3Point& eye, 
    const R3Point& point, const R3Vector& normal) const
{
    // Check if light is active
    if (!IsActive()) return RNblack_rgb;

    // Get material properties
    const RNRgb& Dc = brdf.Diffuse();
    const RNRgb& Sc = brdf.Specular();
    RNScalar s = brdf.Shininess();

    // Get light properties
    RNScalar I = IntensityAtPoint(point);
    R3Vector L = DirectionFromPoint(point);
    const RNRgb& Ic = Color();

    // Compute geometric stuff
    RNScalar NL = normal.Dot(L);
    if (RNIsNegativeOrZero(NL)) return RNblack_rgb;
    R3Vector R = (2.0 * NL) * normal - L;
    R3Vector V = eye - point;
    V.Normalize();
    RNScalar VR = V.Dot(R);

    // Compute diffuse reflection
    RNRgb rgb = (I * NL) * Dc * Ic;

    // Compute specular reflection
    if (RNIsPositive(VR)) rgb += (I * pow(VR,s)) * Sc * Ic;

    // Return total reflection
    return rgb;
}

// Assembly:
subq $0x138, %rsp            # imm = 0x138
movq %rdi, 0x10(%rsp)
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movq %rdi, 0x130(%rsp)
movq %rsi, 0x128(%rsp)
movq %rdx, 0x120(%rsp)
movq %rcx, 0x118(%rsp)
movq %r8, 0x110(%rsp)
movq %r9, 0x108(%rsp)
movq 0x128(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x60940
cmpl $0x0, %eax
jne 0x61c91
movq 0x10(%rsp), %rdi
leaq 0x19df01(%rip), %rsi    # 0x1ffb88
callq 0xef300
jmp 0x61eae
movq 0x120(%rsp), %rdi
callq 0x48930
movq %rax, 0x100(%rsp)
movq 0x120(%rsp), %rdi
callq 0x48980
movq %rax, 0xf8(%rsp)
movq 0x120(%rsp), %rdi
callq 0x48ae0
movq 0x20(%rsp), %rdi
movsd %xmm0, 0xf0(%rsp)
movq 0x110(%rsp), %rsi
movq (%rdi), %rax
callq *0x40(%rax)
movq 0x20(%rsp), %rsi
movsd %xmm0, 0xe8(%rsp)
movq 0x110(%rsp), %rdx
movq (%rsi), %rax
leaq 0xd0(%rsp), %rdi
callq *0xb0(%rax)
movq 0x20(%rsp), %rdi
callq 0x2ba40
movq %rax, 0xc8(%rsp)
movq 0x108(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0xcdfe0
movsd %xmm0, 0xc0(%rsp)
movsd 0xc0(%rsp), %xmm0
leaq 0x19455d(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x49e40
cmpl $0x0, %eax
je 0x61d6f
movq 0x10(%rsp), %rdi
leaq 0x19de23(%rip), %rsi    # 0x1ffb88
callq 0xef300
jmp 0x61eae
movsd 0x12c2d9(%rip), %xmm0   # 0x18e050
mulsd 0xc0(%rsp), %xmm0
movq 0x108(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x2b630
leaq 0xa8(%rsp), %rdi
leaq 0x90(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
callq 0xcedc0
movq 0x118(%rsp), %rsi
movq 0x110(%rsp), %rdx
leaq 0x78(%rsp), %rdi
callq 0xccbd0
leaq 0x78(%rsp), %rdi
callq 0xce130
leaq 0x78(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0xcdfe0
movsd %xmm0, 0x70(%rsp)
movsd 0xe8(%rsp), %xmm0
mulsd 0xc0(%rsp), %xmm0
movq 0x100(%rsp), %rsi
leaq 0x58(%rsp), %rdi
callq 0x60a00
movq 0x10(%rsp), %rdi
movq 0xc8(%rsp), %rdx
leaq 0x58(%rsp), %rsi
callq 0x60990
movsd 0x70(%rsp), %xmm0
leaq 0x194472(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x4a000
cmpl $0x0, %eax
je 0x61eac
movsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x70(%rsp), %xmm0
movsd 0xf0(%rsp), %xmm1
callq 0x23260
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
mulsd %xmm1, %xmm0
movq 0xf8(%rsp), %rsi
leaq 0x28(%rsp), %rdi
callq 0x60a00
movq 0xc8(%rsp), %rdx
leaq 0x40(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x60990
movq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0xef500
jmp 0x61eae
movq 0x18(%rsp), %rax
addq $0x138, %rsp            # imm = 0x138
retq
nopl (%rax,%rax)