// File: tomfunkhouser[P]gaps/apps/scn2cam/scn2cam.cpp
// Function: RenderImageWithRayCasting(gaps::R2Grid&, gaps::R3Camera const&, gaps::R3Scene*, gaps::R3SceneNode*, gaps::R3SceneNode*, int)
static void
RenderImageWithRayCasting(R2Grid& image, const R3Camera& camera, R3Scene *scene, R3SceneNode *root_node,  R3SceneNode *selected_node, int image_type)
{
  // Clear image
  image.Clear(R2_GRID_UNKNOWN_VALUE);

  // Setup viewer
  R2Viewport viewport(0, 0, image.XResolution(), image.YResolution());
  R3Viewer viewer(camera, viewport);

  // Render image with ray casting
  for (int iy = 0; iy < image.YResolution(); iy++) {
    for (int ix = 0; ix < image.XResolution(); ix++) {
      R3Ray ray = viewer.WorldRay(ix, iy);
      R3SceneNode *intersection_node = NULL;
      if (root_node->Intersects(ray, &intersection_node)) {
        if (intersection_node) {
          if (!selected_node || (selected_node == intersection_node)) {
            if (image_type == NODE_INDEX_IMAGE) {
              image.SetGridValue(ix, iy, intersection_node->SceneIndex());
            }
          }
        }
      }
    }
  }
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x170(%rsp)
movq %rsi, 0x168(%rsp)
movq %rdx, 0x160(%rsp)
movq %rcx, 0x158(%rsp)
movq %r8, 0x150(%rsp)
movl %r9d, 0x14c(%rsp)
movq 0x170(%rsp), %rdi
movsd 0x18b8b9(%rip), %xmm0   # 0x1bb090
callq 0xf4df0
movq 0x170(%rsp), %rdi
callq 0x33710
movl %eax, 0x3c(%rsp)
movq 0x170(%rsp), %rdi
callq 0x33730
movl 0x3c(%rsp), %ecx
movl %eax, %r8d
leaq 0x13c(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x68f00
movq 0x168(%rsp), %rsi
leaq 0x90(%rsp), %rdi
leaq 0x13c(%rsp), %rdx
callq 0x64150
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x170(%rsp), %rdi
callq 0x33730
movl %eax, 0x38(%rsp)
jmp 0x2f858
movl 0x34(%rsp), %eax
movl 0x38(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2f9e0
movl $0x0, 0x78(%rsp)
movl 0x78(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x170(%rsp), %rdi
callq 0x33710
movl %eax, 0x30(%rsp)
jmp 0x2f88b
movl 0x2c(%rsp), %eax
movl 0x30(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2f9c8
cvtsi2sdl 0x78(%rsp), %xmm0
cvtsi2sdl 0x8c(%rsp), %xmm1
leaq 0x48(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x65ad0
jmp 0x2f8be
movq $0x0, 0x40(%rsp)
movq 0x158(%rsp), %rdi
leaq 0x1fa9c2(%rip), %rax    # 0x22a298
movsd (%rax), %xmm1
movq %rsp, %rax
movq $0x0, 0x8(%rax)
movq $0x0, (%rax)
xorl %eax, %eax
movl %eax, %r9d
leaq 0x48(%rsp), %rsi
leaq 0x40(%rsp), %rdx
xorps %xmm0, %xmm0
movq %r9, %rcx
movq %r9, %r8
callq 0x61810
movl %eax, 0x28(%rsp)
jmp 0x2f90f
movl 0x28(%rsp), %eax
cmpl $0x0, %eax
je 0x2f9b6
cmpq $0x0, 0x40(%rsp)
je 0x2f9b4
cmpq $0x0, 0x150(%rsp)
je 0x2f942
movq 0x150(%rsp), %rax
cmpq 0x40(%rsp), %rax
jne 0x2f9b2
cmpl $0x0, 0x14c(%rsp)
jne 0x2f9b0
movq 0x170(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x78(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x8c(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x40(%rsp), %rdi
callq 0x335a0
movq 0x18(%rsp), %rdi
movl 0x20(%rsp), %esi
movl 0x24(%rsp), %edx
cvtsi2sd %eax, %xmm0
callq 0x33680
jmp 0x2f98e
jmp 0x2f9b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x80(%rsp)
movl %eax, 0x7c(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x64230
jmp 0x2f9f5
jmp 0x2f9b2
jmp 0x2f9b4
jmp 0x2f9b6
jmp 0x2f9b8
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x2f870
jmp 0x2f9ca
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x2f83a
leaq 0x90(%rsp), %rdi
callq 0x64230
addq $0x178, %rsp            # imm = 0x178
retq
movq 0x80(%rsp), %rdi
callq 0x24250
nopw %cs:(%rax,%rax)