// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/apps/scnview/scnview.cpp
// Function: Pick(gaps::R3Scene*, int, int, gaps::R3SceneNode**, gaps::R3Point*)
static int
Pick(R3Scene *scene, int x, int y,
  R3SceneNode **hit_node = NULL, R3Point *hit_position = NULL)
{
  // Clear window
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Set viewing transformation
  viewer->Camera().Load();

  // Set OpenGL stuff
  int pick_tolerance = 10;
  glPointSize(pick_tolerance);
  glDisable(GL_LIGHTING);
  glDisable(GL_MULTISAMPLE);

  // Draw leaf nodes with color indicating node index
  for (int i = 0; i < scene->NNodes(); i++) {
    R3SceneNode *node = scene->Node(i);
    if (node->NChildren() > 0) continue;
    R3Affine parent_transformation = node->CumulativeParentTransformation();
    parent_transformation.Push();
    int index = i + 1;
    unsigned char rgba[4];
    rgba[0] = (index >> 16) & 0xFF;
    rgba[1] = (index >> 8) & 0xFF;
    rgba[2] = index & 0xFF;
    rgba[3] = 0xFF;
    RNLoadRgba(rgba);
    node->Draw(R3_SURFACES_DRAW_FLAG);
    parent_transformation.Pop();
  }

  // Reset OpenGL stuff
  glEnable(GL_MULTISAMPLE);
  glPointSize(1);
  glFinish();

  // Read color buffer at cursor position
  unsigned char rgba[4];
  glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
  if ((rgba[0] == 0) && (rgba[1] == 0) && (rgba[2] == 0)) return 0;

  // Parse color value
  int r = rgba[0] & 0xFF;
  int g = rgba[1] & 0xFF;
  int b = rgba[2] & 0xFF;
  // int a = rgba[3] & 0xFF;
  int node_index = ((r << 16) | (g << 8) | b) - 1;
  if (node_index < 0) return 0;
  if (node_index >= scene->NNodes()) return 0;
 
  // Return hit node
  if (hit_node) {
   *hit_node = scene->Node(node_index);
  }

  // Return hit position
  if (hit_position) {
    GLfloat depth;
    GLdouble p[3];
    GLint viewport[4];
    GLdouble modelview_matrix[16];
    GLdouble projection_matrix[16];
    glGetIntegerv(GL_VIEWPORT, viewport);
    glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix);
    glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix);
    glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
    gluUnProject(x, y, depth, modelview_matrix, projection_matrix, viewport, &(p[0]), &(p[1]), &(p[2]));
    R3Point position(p[0], p[1], p[2]);
    *hit_position = position;
  }
  
  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
movq %r8, 0x18(%rsp)
movq %rcx, 0x20(%rsp)
movl %edx, 0x14(%rsp)
movl %esi, 0x10(%rsp)
movq %rdi, %r13
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
xorps %xmm2, %xmm2
xorps %xmm3, %xmm3
callq 0x21e20
movl $0x4100, %edi           # imm = 0x4100
callq 0x211e0
movq 0x11bff8(%rip), %rdi    # 0x1428e8
addq $0x8, %rdi
xorl %r15d, %r15d
xorl %esi, %esi
callq 0x404f0
movss 0xb370a(%rip), %xmm0    # 0xda010
callq 0x210a0
movl $0xb50, %edi            # imm = 0xB50
callq 0x211f0
movl $0x809d, %edi           # imm = 0x809D
callq 0x211f0
movl 0x14(%r13), %eax
testl %eax, %eax
jle 0x269ac
xorl %ebx, %ebx
leaq 0x100(%rsp), %r14
leaq 0x60(%rsp), %r12
movq 0x8(%r13), %rcx
movq (%rcx,%rbx,8), %rbp
cmpl $0x0, 0x2c(%rbp)
jle 0x2694d
incq %rbx
jmp 0x269a4
movq %r14, %rdi
movq %rbp, %rsi
callq 0x3c7fe
movq %r14, %rdi
callq 0x4521a
incq %rbx
movl %ebx, %eax
shrl $0x10, %eax
movb %al, 0x60(%rsp)
movb %bh, 0x61(%rsp)
movb %bl, 0x62(%rsp)
movb $-0x1, 0x63(%rsp)
movq %r12, %rdi
callq 0x21400
movl $0x2, %esi
movq %rbp, %rdi
xorl %edx, %edx
callq 0x3d1ec
movq %r14, %rdi
callq 0x45256
movq %r14, %rdi
callq 0x6fa30
movl 0x14(%r13), %eax
movslq %eax, %rcx
cmpq %rcx, %rbx
jl 0x2693a
movl $0x809d, %edi           # imm = 0x809D
callq 0x21810
movss 0xb3646(%rip), %xmm0    # 0xda004
callq 0x210a0
callq 0x22310
leaq 0x2c(%rsp), %rbx
movq %rbx, (%rsp)
movl 0x10(%rsp), %edi
movl 0x14(%rsp), %esi
movl $0x1, %edx
movl $0x1, %ecx
movl $0x1908, %r8d           # imm = 0x1908
movl $0x1401, %r9d           # imm = 0x1401
callq 0x213b0
movzbl (%rbx), %ecx
movb 0x1(%rbx), %al
movb 0x2(%rbx), %dl
movl %ecx, %esi
orb %al, %sil
orb %dl, %sil
je 0x26b25
movzbl %al, %eax
movzbl %dl, %edx
shll $0x10, %ecx
shll $0x8, %eax
orl %ecx, %eax
orl %edx, %eax
je 0x26b25
cmpl 0x14(%r13), %eax
jg 0x26b25
movq 0x20(%rsp), %rdx
testq %rdx, %rdx
je 0x26a43
movq 0x8(%r13), %rcx
movl %eax, %eax
movq -0x8(%rcx,%rax,8), %rax
movq %rax, (%rdx)
movq 0x18(%rsp), %rbp
testq %rbp, %rbp
je 0x26b1f
leaq 0x30(%rsp), %rsi
movl $0xba2, %edi            # imm = 0xBA2
callq 0x21870
leaq 0x100(%rsp), %r12
movl $0xba6, %edi            # imm = 0xBA6
movq %r12, %rsi
callq 0x21a40
leaq 0x60(%rsp), %r13
movl $0xba7, %edi            # imm = 0xBA7
movq %r13, %rsi
callq 0x21a40
leaq 0x28(%rsp), %r14
movq %r14, (%rsp)
movl $0x1, %r15d
movl 0x10(%rsp), %ebp
movl %ebp, %edi
movl 0x14(%rsp), %ebx
movl %ebx, %esi
movl $0x1, %edx
movl $0x1, %ecx
movl $0x1902, %r8d           # imm = 0x1902
movl $0x1406, %r9d           # imm = 0x1406
callq 0x213b0
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
cvtsi2sd %ebx, %xmm1
cvtss2sd (%r14), %xmm2
leaq 0x48(%rsp), %r8
leaq 0x50(%rsp), %r9
leaq 0x40(%rsp), %r14
movq %r12, %rdi
movq %r13, %rsi
leaq 0x30(%rsp), %rdx
movq %r14, %rcx
callq 0x22220
movsd (%r14), %xmm0
movsd 0x8(%r14), %xmm1
movsd 0x10(%r14), %xmm2
leaq 0xe8(%rsp), %rbx
movq %rbx, %rdi
callq 0x753ca
movq 0x18(%rsp), %rdi
movq %rbx, %rsi
callq 0x75732
jmp 0x26b25
movl $0x1, %r15d
movl %r15d, %eax
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x26b3c
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x6fa30
movq %rbx, %rdi
callq 0x220c0