// File: /workspace/github_cpp_makefile_star2_O1/srajangarg[P]raytracer/src/main.cpp
// Function: getShadedColor(Primitive const&, Vec3 const&, Ray const&)
RGB
getShadedColor(Primitive const & primitive, Vec3 const & pos, Ray const & ray)
{
  RGB amb(0, 0, 0), lamb(0, 0, 0), spec(0, 0, 0);
  RGB C(primitive.getColor()), S, I;
  Vec3 r, u, n, i;
  bool use_dist;

  double ma = primitive.getMaterial().getMA();
  double ms = primitive.getMaterial().getMS();
  double ml = primitive.getMaterial().getML();
  double msp = primitive.getMaterial().getMSP();
  double msm = primitive.getMaterial().getMSM();
  double reach_light, ratio = 0, trans;
  
  // ambient component : Ma * C * A
  amb = ma * C * world->getAmbientLightColor();
  
  for (auto it = world->lightsBegin(); it != world->lightsEnd(); it++)
  {  
    trans = 1;
    auto light = *it;
    vector<Ray> shadows = light->getShadowRays(pos, use_dist);
    reach_light = shadows.size();

    // iterate over shadows
    for (auto shadow : shadows)
    {
      auto inter = world->intersect(shadow);

      if (inter != NULL) {
        // if the light is passing through a transparent object, consider it
        if (inter->getMaterial().getMT() > 0)
            trans = inter->getMaterial().getMT();
        // else decrease the number of shadow rays reaching the object
        else if (not use_dist or (shadow.minT() > 0 and shadow.minT() < 1))
            reach_light--;
      }
    }

    // how many shadow rays did not collide
    ratio = reach_light / (double) shadows.size();
    // if none of them passed thorugh, skip lambertian and specular
    if (ratio < EPS)
      continue;

    // normal and incidence vectors, light color
    n = primitive.calculateNormal(pos);
    i = light->getIncidenceVector(pos);
    I = light->getColor(pos);

    // lambertian component : Ml * C * I * max(i.n, 0)
    lamb += trans * ratio * ml * C * I * std::max(i * n, (double)0);

    // S                    : Msm * C + (1-Msm) * RBG(1, 1, 1)  
    // r                    : 2(i.n)n  - i   
    S = msm * C + (1 - msm) * RGB(1, 1, 1); 
    r = 2*((i * n) * n) - i;
    u = ray.direction();
    u.normalize();

    // specular component   : Ms * S * I * (max(-r.u, 0))^Msp                 
    spec += trans * ratio * ms * S * I * pow(std::max(-r*u, (double)0), msp);
  }

  return amb + spec + lamb;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x198, %rsp            # imm = 0x198
movq %rcx, 0x188(%rsp)
movq %rdx, %r15
movq %rdi, 0x128(%rsp)
movsd 0x108(%rsi), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x110(%rsi), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x118(%rsi), %xmm0
movsd %xmm0, 0x68(%rsp)
movss 0x120(%rsi), %xmm0
movss %xmm0, 0x9c(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0x128(%rsi), %xmm0
movsd %xmm0, 0x180(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0x124(%rsi), %xmm0
movsd %xmm0, 0x178(%rsp)
movss 0x130(%rsi), %xmm0
movss %xmm0, 0x20(%rsp)
movq %rsi, 0x190(%rsp)
xorps %xmm0, %xmm0
cvtss2sd 0x12c(%rsi), %xmm0
movsd %xmm0, 0x170(%rsp)
movq 0xfd48(%rip), %rsi      # 0x38528
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
callq 0x283a8
movsd 0x68(%rsp), %xmm1
movsd (%rbx), %xmm0
movsd %xmm0, 0x120(%rsp)
movsd 0x8(%rbx), %xmm0
movsd %xmm0, 0x118(%rsp)
movsd 0x10(%rbx), %xmm0
movsd %xmm0, 0x110(%rsp)
movq 0xfd02(%rip), %rax      # 0x38528
movq 0x20(%rax), %rbp
cmpq 0x28(%rax), %rbp
je 0x28edc
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
movsd 0x10(%rsp), %xmm2
mulsd %xmm0, %xmm2
movsd 0x8(%rsp), %xmm3
mulsd %xmm0, %xmm3
mulsd %xmm0, %xmm1
movsd 0x38e3(%rip), %xmm4     # 0x2c140
subsd %xmm0, %xmm4
addsd %xmm4, %xmm2
movsd %xmm2, 0x168(%rsp)
addsd %xmm4, %xmm3
movsd %xmm3, 0x160(%rsp)
addsd %xmm1, %xmm4
movsd %xmm4, 0x158(%rsp)
leaq 0xd0(%rsp), %rbx
xorpd %xmm0, %xmm0
movsd %xmm0, 0x40(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0x60(%rsp)
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0x48(%rsp)
movsd %xmm0, 0x58(%rsp)
movq (%rbp), %r13
movq (%r13), %rax
leaq 0xb8(%rsp), %rdi
movq %r13, %rsi
movq %r15, %rdx
leaq 0x7(%rsp), %rcx
callq *0x28(%rax)
movq 0xb8(%rsp), %r12
movq 0xc0(%rsp), %r14
movq %r14, %rax
subq %r12, %rax
sarq $0x6, %rax
movq %rax, %xmm0
punpckldq 0x5b23(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x5b2b(%rip), %xmm0     # 0x2e430
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd %xmm1, 0x20(%rsp)
movsd 0x3821(%rip), %xmm0     # 0x2c140
cmpq %r12, %r14
je 0x28a43
movsd %xmm0, 0x18(%rsp)
movsd (%r12), %xmm0
movsd %xmm0, 0xd0(%rsp)
movsd 0x8(%r12), %xmm0
movsd %xmm0, 0xd8(%rsp)
movsd 0x10(%r12), %xmm0
movsd %xmm0, 0xe0(%rsp)
movsd 0x18(%r12), %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0x20(%r12), %xmm0
movsd %xmm0, 0xf0(%rsp)
movsd 0x28(%r12), %xmm0
movsd %xmm0, 0xf8(%rsp)
movsd 0x30(%r12), %xmm0
movsd %xmm0, 0x100(%rsp)
movsd 0x38(%r12), %xmm0
movsd %xmm0, 0x108(%rsp)
movq 0xfb74(%rip), %rdi      # 0x38528
movq %rbx, %rsi
callq 0x282fc
testq %rax, %rax
je 0x289ea
movss 0x138(%rax), %xmm0
ucomiss 0x5a70(%rip), %xmm0     # 0x2e440
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
jbe 0x289f8
cvtss2sd %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
jmp 0x28a34
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
jmp 0x28a34
cmpb $0x1, 0x7(%rsp)
jne 0x28a20
movsd 0x100(%rsp), %xmm0
ucomisd 0x3748(%rip), %xmm0     # 0x2c158
jbe 0x28a34
movsd 0x3726(%rip), %xmm1     # 0x2c140
ucomisd %xmm0, %xmm1
jbe 0x28a34
movapd 0x20(%rsp), %xmm0
addsd 0x59d2(%rip), %xmm0     # 0x2e400
movapd %xmm0, 0x20(%rsp)
addq $0x40, %r12
cmpq %r14, %r12
jne 0x2892e
jmp 0x28a55
movsd %xmm0, 0x18(%rsp)
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
movq 0xc0(%rsp), %rax
subq 0xb8(%rsp), %rax
sarq $0x6, %rax
movq %rax, %xmm0
punpckldq 0x59aa(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x59b2(%rip), %xmm0     # 0x2e430
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
movapd 0x20(%rsp), %xmm4
divsd %xmm1, %xmm4
movsd 0x596c(%rip), %xmm0     # 0x2e408
movapd %xmm4, 0x20(%rsp)
ucomisd %xmm4, %xmm0
ja 0x28e9c
movq 0x190(%rsp), %rsi
movq (%rsi), %rax
movq %rbx, %rdi
movq %r15, %rdx
callq *0x18(%rax)
movsd 0xd0(%rsp), %xmm0
movaps %xmm0, 0xa0(%rsp)
movsd 0xd8(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
movsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x88(%rsp)
movq (%r13), %rax
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq *0x20(%rax)
movsd 0xd0(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movsd 0xd8(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movq (%r13), %rax
movq %rbx, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq *0x18(%rax)
movsd 0xd0(%rsp), %xmm7
movsd 0xd8(%rsp), %xmm6
movsd 0xe0(%rsp), %xmm5
movsd 0x18(%rsp), %xmm0
mulsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
mulsd 0x178(%rsp), %xmm0
movsd 0x10(%rsp), %xmm9
mulsd %xmm0, %xmm9
movsd 0x8(%rsp), %xmm10
mulsd %xmm0, %xmm10
mulsd 0x68(%rsp), %xmm0
mulsd %xmm7, %xmm9
mulsd %xmm6, %xmm10
mulsd %xmm5, %xmm0
movsd 0x90(%rsp), %xmm4
movapd %xmm4, %xmm1
movsd 0x78(%rsp), %xmm12
mulsd %xmm12, %xmm1
movsd 0x70(%rsp), %xmm13
movapd %xmm13, %xmm2
movapd 0xa0(%rsp), %xmm3
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
movsd 0x80(%rsp), %xmm11
movapd %xmm11, %xmm8
movsd 0x88(%rsp), %xmm1
mulsd %xmm1, %xmm8
addsd %xmm2, %xmm8
xorpd %xmm14, %xmm14
maxsd %xmm8, %xmm14
mulsd %xmm14, %xmm9
mulsd %xmm14, %xmm10
mulsd %xmm0, %xmm14
mulsd %xmm8, %xmm3
mulsd %xmm8, %xmm4
mulsd %xmm1, %xmm8
addsd %xmm3, %xmm3
addsd %xmm4, %xmm4
addsd %xmm8, %xmm8
subsd %xmm13, %xmm3
subsd %xmm12, %xmm4
subsd %xmm11, %xmm8
movq 0x188(%rsp), %rax
movsd 0x18(%rax), %xmm11
movsd 0x20(%rax), %xmm2
movsd 0x28(%rax), %xmm12
movapd %xmm2, %xmm0
mulsd %xmm2, %xmm0
movapd %xmm11, %xmm1
mulsd %xmm11, %xmm1
addsd %xmm0, %xmm1
movapd %xmm12, %xmm0
mulsd %xmm12, %xmm0
addsd %xmm1, %xmm0
ucomisd 0x34d0(%rip), %xmm0     # 0x2c158
jb 0x28c93
sqrtsd %xmm0, %xmm0
jmp 0x28d6a
movapd %xmm3, 0xa0(%rsp)
movsd %xmm4, 0x90(%rsp)
movsd %xmm5, 0x20(%rsp)
movsd %xmm6, 0x88(%rsp)
movsd %xmm7, 0x80(%rsp)
movsd %xmm8, 0x78(%rsp)
movsd %xmm9, 0x70(%rsp)
movsd %xmm10, 0x150(%rsp)
movsd %xmm2, 0x148(%rsp)
movsd %xmm11, 0x140(%rsp)
movsd %xmm14, 0x138(%rsp)
movsd %xmm12, 0x130(%rsp)
callq 0x4280
movsd 0x130(%rsp), %xmm12
movsd 0x138(%rsp), %xmm14
movsd 0x140(%rsp), %xmm11
movsd 0x148(%rsp), %xmm2
movsd 0x150(%rsp), %xmm10
movsd 0x70(%rsp), %xmm9
movsd 0x78(%rsp), %xmm8
movsd 0x80(%rsp), %xmm7
movsd 0x88(%rsp), %xmm6
movsd 0x20(%rsp), %xmm5
movsd 0x90(%rsp), %xmm4
movapd 0xa0(%rsp), %xmm3
movsd 0x60(%rsp), %xmm1
addsd %xmm9, %xmm1
movsd %xmm1, 0x60(%rsp)
movsd 0x50(%rsp), %xmm1
addsd %xmm10, %xmm1
movsd %xmm1, 0x50(%rsp)
movsd 0x40(%rsp), %xmm1
addsd %xmm14, %xmm1
movsd %xmm1, 0x40(%rsp)
movsd 0x339b(%rip), %xmm1     # 0x2c140
divsd %xmm0, %xmm1
mulsd %xmm1, %xmm2
mulsd %xmm4, %xmm2
mulsd %xmm1, %xmm11
mulsd %xmm1, %xmm12
mulsd %xmm12, %xmm8
movsd 0x18(%rsp), %xmm0
mulsd 0x180(%rsp), %xmm0
movsd 0x168(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm7, %xmm1
movsd %xmm1, 0x20(%rsp)
movsd 0x160(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm6, %xmm1
movsd %xmm1, 0xa0(%rsp)
mulsd 0x158(%rsp), %xmm0
mulsd %xmm5, %xmm0
movsd %xmm0, 0x18(%rsp)
xorpd 0x3c15(%rip), %xmm3     # 0x2ca30
mulsd %xmm11, %xmm3
subsd %xmm2, %xmm3
subsd %xmm8, %xmm3
xorpd %xmm0, %xmm0
maxsd %xmm3, %xmm0
movsd 0x170(%rsp), %xmm1
callq 0x45b0
movsd 0x20(%rsp), %xmm1
mulsd %xmm0, %xmm1
movsd 0xa0(%rsp), %xmm2
mulsd %xmm0, %xmm2
movsd 0x18(%rsp), %xmm3
mulsd %xmm0, %xmm3
movsd 0x58(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x48(%rsp), %xmm0
addsd %xmm2, %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x38(%rsp), %xmm0
addsd %xmm3, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
movq 0xb8(%rsp), %rdi
testq %rdi, %rdi
je 0x28ec5
movq 0xc8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4320
movsd 0x8(%rsp), %xmm3
movsd 0x10(%rsp), %xmm2
addq $0x8, %rbp
movq 0xf658(%rip), %rax      # 0x38528
cmpq 0x28(%rax), %rbp
jne 0x288b8
jmp 0x28f10
xorpd %xmm0, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd %xmm0, 0x48(%rsp)
movsd %xmm0, 0x38(%rsp)
movsd %xmm0, 0x60(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm0, 0x40(%rsp)
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm3
xorps %xmm0, %xmm0
cvtss2sd 0x9c(%rsp), %xmm0
movsd 0x68(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd 0x110(%rsp), %xmm1
addsd 0x38(%rsp), %xmm1
addsd 0x40(%rsp), %xmm1
mulsd %xmm0, %xmm3
mulsd 0x118(%rsp), %xmm3
addsd 0x48(%rsp), %xmm3
addsd 0x50(%rsp), %xmm3
mulsd %xmm0, %xmm2
mulsd 0x120(%rsp), %xmm2
addsd 0x58(%rsp), %xmm2
addsd 0x60(%rsp), %xmm2
movq 0x128(%rsp), %rax
movsd %xmm2, (%rax)
movsd %xmm3, 0x8(%rax)
movsd %xmm1, 0x10(%rax)
addq $0x198, %rsp            # imm = 0x198
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x28f9b
jmp 0x28f9b
jmp 0x28f9b
movq %rax, %rbx
movq 0xb8(%rsp), %rdi
testq %rdi, %rdi
je 0x28fbb
movq 0xc8(%rsp), %rsi
subq %rdi, %rsi
callq 0x4320
movq %rbx, %rdi
callq 0x45c0