// File: /workspace/github_cpp_makefile_star2_O2/srajangarg[P]raytracer/src/main.cpp
// Function: importSceneToWorld(SceneInstance*, Mat4, int)
void
importSceneToWorld(SceneInstance * inst, Mat4 localToWorld, int time)
{
  if (inst == NULL)
    return;

  Mat4 nodeXform;
  inst->computeTransform(nodeXform, time);
  localToWorld = localToWorld * nodeXform;
  SceneGroup * g = inst->getChild();

  if (g == NULL)   // for example if the whole scene fails to load
  {
    std::cout << "ERROR: We arrived at an instance with no child?!" << std::endl;
    return;
  }

  int ccount = g->getChildCount();

  for (int i = 0; i < ccount; i++)
  {
    importSceneToWorld(g->getChild(i), localToWorld, 0);
  }

  CameraInfo f;

  if (g->computeCamera(f, time))
  {
    viewToWorld = localToWorld;

    if (view != NULL)
      delete view;

    Vec3 eye(0.0, 0.0, 0.0);
    Vec3 LL(f.sides[FRUS_LEFT], f.sides[FRUS_BOTTOM], -f.sides[FRUS_NEAR]);
    Vec3 UL(f.sides[FRUS_LEFT], f.sides[FRUS_TOP], -f.sides[FRUS_NEAR]);
    Vec3 LR(f.sides[FRUS_RIGHT], f.sides[FRUS_BOTTOM], -f.sides[FRUS_NEAR]);
    Vec3 UR(f.sides[FRUS_RIGHT], f.sides[FRUS_TOP], -f.sides[FRUS_NEAR]);
    view = new View(eye, LL, UL, LR, UR, IMAGE_WIDTH, IMAGE_HEIGHT, RAYS_PER_PIXEL_EDGE);
  }

  LightInfo l;

  if (g->computeLight(l, time))
  {
    if (l.type == LIGHT_AMBIENT)
    {
      RGB amb = world->getAmbientLightColor();
      world->setAmbientLightColor(amb + l.color);
    }
    else if (l.type == LIGHT_DIRECTIONAL)
    {
      DirectionalLight * li = new DirectionalLight(l.color);
      Vec3 dir(0, 0, -1);
      li->setDirection(localToWorld * dir);
      world->addLight(li);
    }
    else if (l.type == LIGHT_POINT)
    {
      PointLight * li = new PointLight(l.color, l.falloff, l.deadDistance);
      Vec3 pos(0, 0, 0);
      li->setPosition(localToWorld * pos);
      world->addLight(li);
    }
    else if (l.type == LIGHT_AREA)
    { 
      AreaLight * li = new AreaLight(l.color, l.falloff, l.deadDistance, l.offset);
      Vec3 pos(0, 0, 0);
      li->setPosition(localToWorld * pos);
      world->addLight(li);
    }
    else if (l.type == LIGHT_SPOT)
    {
      throw "oh no";
    }
  }

  double r;
  MaterialInfo m;

  if (g->computeSphere(r, m, time))
  {
    Material mat(m.k[0], m.k[1], m.k[2], m.k[3], m.k[4], m.k[MAT_MS], m.k[5], m.k[6]);
    Sphere * sph = new Sphere(r, m.color, mat, localToWorld);
    world->addPrimitive(sph);
  }

  TriangleMesh * t;
  unordered_map<MeshVertex*, vector<pair<Triangle*, int>> > vertexToTriangles;

  if (g->computeMesh(t, m, time))
  {
    Material mat(m.k[0], m.k[1], m.k[2], m.k[3], m.k[4], m.k[MAT_MS], m.k[5], m.k[6]);

    for (auto it = t->triangles.begin(); it != t->triangles.end(); ++it)
    {
      Triangle * tri = new Triangle(
        t->vertices[ (**it).ind[0] ]->pos,
        t->vertices[ (**it).ind[1] ]->pos,
        t->vertices[ (**it).ind[2] ]->pos,
        m.color, mat, localToWorld, smooth_normals);
      world->addPrimitive(tri);

      if (smooth_normals)
      {
        // map vertex to which triangles this verttex belongs to
        for (int i = 0; i < 3; ++i)
        {
          if(vertexToTriangles.find(t->vertices[(**it).ind[i]]) == vertexToTriangles.end())
            vertexToTriangles[t->vertices[(**it).ind[i]]] = {make_pair(tri, i)};
          else
            vertexToTriangles[t->vertices[(**it).ind[i]]].push_back(make_pair(tri, i));
        }
      }
    }

    if (smooth_normals)
    {
      // calculate average normal at each vertex, and place them at norms
      // in each of the respective triangles
      for (auto it : vertexToTriangles)
      { 
          Vec3 res(0, 0, 0);

          for (auto tripair : it.second)
            res += tripair.first->calculateFaceNormal();
          res.normalize();
          for (auto tripair : it.second)
              tripair.first->norms[tripair.second] = res;
      }
    }
  }

  std::cout << "Imported scene file" << std::endl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2e8, %rsp            # imm = 0x2E8
testq %rdi, %rdi
je 0x1ffcd
movl %edx, %ebp
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x268(%rsp), %r15
movq %r15, %rsi
callq 0x6084
leaq 0xd0(%rsp), %r12
movq %r12, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x624e
movq %rbx, %rdi
movq %r12, %rsi
callq 0x61ac
movq %r14, %rdi
callq 0x5ff2
testq %rax, %rax
je 0x1fadf
movq %rax, %r14
movl %ebp, 0x8(%rsp)
movq %rax, %rdi
callq 0x5806
movl %eax, %r15d
xorl %r12d, %r12d
testl %eax, %eax
cmovlel %r12d, %r15d
leaq 0x1e8(%rsp), %r13
cmpl %r12d, %r15d
je 0x1f92b
movq %r14, %rdi
movl %r12d, %esi
callq 0x5814
movq %rax, %rbp
movq %r13, %rdi
movq %rbx, %rsi
callq 0x1e5b8
movq %rbp, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x1f874
incl %r12d
jmp 0x1f8fb
leaq 0x198(%rsp), %rsi
movq %r14, %rdi
movl 0x8(%rsp), %ebp
movl %ebp, %edx
callq 0x5994
testb %al, %al
je 0x1fa47
leaq 0xfc08(%rip), %rdi      # 0x2f558
movq %rbx, %rsi
callq 0x61ac
movq 0xfbf1(%rip), %rdi      # 0x2f550
testq %rdi, %rdi
je 0x1f96a
movq (%rdi), %rax
callq *0x8(%rax)
leaq 0xd0(%rsp), %rax
andq $0x0, 0x10(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, (%rax)
movsd 0x1a0(%rsp), %xmm0
movsd 0x1c0(%rsp), %xmm1
xorpd 0x1799(%rip), %xmm1     # 0x21130
leaq 0x50(%rsp), %rax
movsd %xmm0, (%rax)
movupd 0x1a8(%rsp), %xmm2
leaq 0x170(%rsp), %rbp
movapd %xmm2, (%rbp)
leaq 0x10(%rsp), %r15
movlpd %xmm2, (%r15)
shufpd $0x1, %xmm1, %xmm2      # xmm2 = xmm2[1],xmm1[0]
movupd %xmm2, 0x8(%rax)
movsd 0x1b8(%rsp), %xmm2
leaq 0x90(%rsp), %r12
movsd %xmm0, (%r12)
movsd %xmm2, 0x8(%r12)
movlpd %xmm1, 0x10(%r12)
movlpd %xmm1, 0x10(%rbp)
movsd %xmm2, 0x8(%r15)
movlpd %xmm1, 0x10(%r15)
movl $0x90, %edi
callq 0x4320
movq %rax, %r13
subq $0x8, %rsp
movl $0x200, %eax            # imm = 0x200
movq %r13, %rdi
leaq 0xd8(%rsp), %rsi
leaq 0x58(%rsp), %rdx
movq %r12, %rcx
movq %rbp, %r8
movq %r15, %r9
pushq $0x2
pushq %rax
pushq %rax
callq 0x1e744
addq $0x20, %rsp
movq %r13, 0xfb0d(%rip)      # 0x2f550
movl 0x8(%rsp), %ebp
xorpd %xmm0, %xmm0
leaq 0x50(%rsp), %rsi
movupd %xmm0, 0x8(%rsi)
andq $0x0, 0x18(%rsi)
movq %r14, %rdi
movl %ebp, %edx
callq 0x5930
testb %al, %al
je 0x1fc20
movl 0x50(%rsp), %eax
cmpq $0x4, %rax
ja 0x1fc20
leaq 0x58(%rsp), %r15
leaq 0x39be(%rip), %rcx      # 0x23444
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xfab2(%rip), %rsi      # 0x2f548
leaq 0xd0(%rsp), %r15
movq %r15, %rdi
callq 0x1eb66
movsd 0x10(%r15), %xmm0
addsd 0x68(%rsp), %xmm0
movupd 0x58(%rsp), %xmm1
addpd (%r15), %xmm1
movq 0xfa84(%rip), %rdi      # 0x2f548
leaq 0x1d0(%rsp), %rsi
movapd %xmm1, (%rsi)
movsd %xmm0, 0x10(%rsi)
callq 0x1eb5c
jmp 0x1fc20
movq 0xf4ea(%rip), %rdi      # 0x2efd0
leaq 0x396b(%rip), %rsi      # 0x23458
callq 0x4300
movq %rax, %rdi
callq 0x4190
jmp 0x1ffcd
pushq $0x50
popq %rdi
callq 0x4320
movq %rax, %r12
movsd 0x70(%rsp), %xmm0
movsd 0x80(%rsp), %xmm1
movq %rax, %rdi
movq %r15, %rsi
callq 0x1ce8e
xorpd %xmm0, %xmm0
leaq 0xd0(%rsp), %rdx
movapd %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x90(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1e3bb
movq %r12, %rdi
movq %r15, %rsi
callq 0x1cf32
jmp 0x1fc11
pushq $0x58
popq %rdi
callq 0x4320
movq %rax, %r12
movsd 0x70(%rsp), %xmm0
movsd 0x80(%rsp), %xmm1
movsd 0x88(%rsp), %xmm2
movq %rax, %rdi
movq %r15, %rsi
callq 0x1d030
xorpd %xmm0, %xmm0
leaq 0xd0(%rsp), %rdx
movapd %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x90(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1e3bb
movq %r12, %rdi
movq %r15, %rsi
callq 0x1d0da
jmp 0x1fc11
pushq $0x50
popq %rdi
callq 0x4320
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x1d2a4
xorpd %xmm0, %xmm0
leaq 0xd0(%rsp), %rdx
movapd %xmm0, (%rdx)
movabsq $-0x4010000000000000, %rax # imm = 0xBFF0000000000000
movq %rax, 0x10(%rdx)
leaq 0x90(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x1e3bb
movq %r12, %rdi
movq %r15, %rsi
callq 0x1d2d8
movq 0xf930(%rip), %rdi      # 0x2f548
movq %r12, %rsi
callq 0x1eb46
leaq 0x108(%rsp), %rax
xorpd %xmm0, %xmm0
movupd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
leaq 0x48(%rsp), %rsi
leaq 0xd0(%rsp), %rdx
movq %r14, %rdi
movl %ebp, %ecx
callq 0x58a4
testb %al, %al
je 0x1fcdf
cvtsd2ss 0xf0(%rsp), %xmm0
movupd 0xe0(%rsp), %xmm1
cvtpd2ps %xmm1, %xmm1
movupd 0xf8(%rsp), %xmm2
cvtpd2ps 0xd0(%rsp), %xmm3
unpcklpd %xmm1, %xmm3            # xmm3 = xmm3[0],xmm1[0]
leaq 0x90(%rsp), %r12
movapd %xmm3, (%r12)
movss %xmm0, 0x10(%r12)
movss %xmm1, 0x14(%r12)
cvtpd2ps %xmm2, %xmm0
movlpd %xmm0, 0x18(%r12)
movl $0x148, %edi            # imm = 0x148
callq 0x4320
movq %rax, %r15
movsd 0x48(%rsp), %xmm0
movq %rax, %rdi
leaq 0x108(%rsp), %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x1d7ac
movq 0xf871(%rip), %rdi      # 0x2f548
movq %r15, %rsi
callq 0x1eb30
leaq 0xc0(%rsp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorpd %xmm0, %xmm0
movupd %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movupd %xmm0, -0x8(%rax)
movq %rsp, %rsi
leaq 0xd0(%rsp), %rdx
movq %r14, %rdi
movl %ebp, %ecx
callq 0x5832
testb %al, %al
je 0x1ffa5
movq %rbx, 0x8(%rsp)
cvtsd2ss 0xf0(%rsp), %xmm0
movupd 0xe0(%rsp), %xmm1
movupd 0xf8(%rsp), %xmm2
cvtpd2ps %xmm1, %xmm1
cvtpd2ps 0xd0(%rsp), %xmm3
unpcklpd %xmm1, %xmm3            # xmm3 = xmm3[0],xmm1[0]
leaq 0x170(%rsp), %rax
movapd %xmm3, (%rax)
movss %xmm0, 0x10(%rax)
movss %xmm1, 0x14(%rax)
cvtpd2ps %xmm2, %xmm0
movlpd %xmm0, 0x18(%rax)
movq (%rsp), %rbx
movq 0x18(%rbx), %r14
leaq 0x20(%rsp), %r12
leaq 0x90(%rsp), %r13
leaq 0x10(%rsp), %rbp
cmpq 0x20(%rbx), %r14
je 0x1fea6
movl $0x1d8, %edi            # imm = 0x1D8
callq 0x4320
movq %rax, %r15
movq (%r14), %rax
movslq (%rax), %rcx
movq (%rbx), %rdi
movq (%rdi,%rcx,8), %rsi
movslq 0x4(%rax), %rcx
movq (%rdi,%rcx,8), %rdx
movslq 0x8(%rax), %rax
movq (%rdi,%rax,8), %rcx
movzbl 0xf816(%rip), %eax      # 0x2f5e0
movq %r15, %rdi
leaq 0x108(%rsp), %r8
leaq 0x170(%rsp), %r9
pushq %rax
pushq 0x10(%rsp)
callq 0x1da2a
popq %rax
popq %rcx
movq 0xf758(%rip), %rdi      # 0x2f548
movq %r15, %rsi
callq 0x1eb30
cmpb $0x1, 0xf7e1(%rip)      # 0x2f5e0
jne 0x1fe99
xorl %ebx, %ebx
cmpq $0x3, %rbx
je 0x1fe99
movq (%rsp), %rax
movq (%r14), %rcx
movslq (%rcx,%rbx,4), %rsi
shlq $0x3, %rsi
addq (%rax), %rsi
movq %r13, %rdi
callq 0x20766
testq %rax, %rax
je 0x1fe60
movq (%rsp), %rax
movq (%r14), %rcx
movslq (%rcx,%rbx,4), %rsi
shlq $0x3, %rsi
addq (%rax), %rsi
movq %r13, %rdi
callq 0x207e2
movq %r15, 0x10(%rsp)
movl %ebx, 0x18(%rsp)
movq %rax, %rdi
movq %rbp, %rsi
callq 0x20c4a
jmp 0x1fe91
movq %r15, 0x10(%rsp)
movl %ebx, 0x18(%rsp)
movq (%rsp), %rax
movq (%r14), %rcx
movslq (%rcx,%rbx,4), %rsi
shlq $0x3, %rsi
addq (%rax), %rsi
movq %r13, %rdi
callq 0x207e2
movq %rax, %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0x20b0c
incq %rbx
jmp 0x1fe07
addq $0x8, %r14
movq (%rsp), %rbx
jmp 0x1fd8f
cmpb $0x0, 0xf733(%rip)      # 0x2f5e0
je 0x1ffa5
movq 0xa0(%rsp), %r13
leaq 0x10(%rsp), %rbx
leaq 0x30(%rsp), %r15
leaq 0x150(%rsp), %r12
testq %r13, %r13
je 0x1ffa5
leaq 0x8(%r13), %rsi
movq %rbx, %rdi
callq 0x205aa
andq $0x0, 0x40(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x30(%rsp)
movq 0x18(%rsp), %rbp
movq 0x20(%rsp), %r14
cmpq %r14, %rbp
je 0x1ff3d
movq (%rbp), %rsi
movq %r12, %rdi
callq 0x1e006
movapd 0x150(%rsp), %xmm0
addpd 0x30(%rsp), %xmm0
movapd %xmm0, 0x30(%rsp)
movsd 0x160(%rsp), %xmm0
addsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
addq $0x10, %rbp
jmp 0x1fefc
movq %r15, %rdi
callq 0xa1b2
movq 0x18(%rsp), %rax
movq 0x20(%rsp), %rcx
cmpq %rcx, %rax
je 0x1ff92
movq (%rax), %rdx
movslq 0x8(%rax), %rsi
imulq $0x18, %rsi, %rsi
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x140(%rdx,%rsi)
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x148(%rdx,%rsi)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x150(%rdx,%rsi)
addq $0x10, %rax
jmp 0x1ff4f
leaq 0x18(%rsp), %rdi
callq 0x2060e
movq (%r13), %r13
jmp 0x1fecd
movq 0xf024(%rip), %rdi      # 0x2efd0
leaq 0x34dc(%rip), %rsi      # 0x2348f
callq 0x4300
movq %rax, %rdi
callq 0x4190
leaq 0x90(%rsp), %rdi
callq 0x206a8
addq $0x2e8, %rsp            # imm = 0x2E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x8
popq %rdi
callq 0x41a0
leaq 0x349b(%rip), %rcx      # 0x23489
movq %rcx, (%rax)
movq 0xefc8(%rip), %rsi      # 0x2efc0
movq %rax, %rdi
xorl %edx, %edx
callq 0x4580
jmp 0x2000b
movq %rax, %rbx
pushq $0x58
jmp 0x20010
movq %rax, %rbx
pushq $0x50
popq %rsi
movq %r12, %rdi
jmp 0x2002e
movq %rax, %rbx
movl $0x148, %esi            # imm = 0x148
movq %r15, %rdi
jmp 0x2002e
movq %rax, %rbx
movl $0x90, %esi
movq %r13, %rdi
callq 0x4330
jmp 0x20074
jmp 0x20064
jmp 0x20055
jmp 0x20064
movq %rax, %rbx
movl $0x1d8, %esi            # imm = 0x1D8
movq %r15, %rdi
callq 0x4330
jmp 0x20067
jmp 0x20064
jmp 0x20064
jmp 0x20064
jmp 0x20064
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x2060e
jmp 0x20067
movq %rax, %rbx
leaq 0x90(%rsp), %rdi
callq 0x206a8
movq %rbx, %rdi
callq 0x45c0