// File: tomfunkhouser[P]gaps/apps/confview/confview.cpp
// Function: Pick(int, int, gaps::RGBDSurface**, gaps::RGBDImage**, gaps::R3Point*, int)
static int
Pick(int x, int y,
  RGBDSurface **picked_surface = NULL, RGBDImage **picked_image = NULL,
  R3Point *picked_position = NULL, int pick_tolerance = 10)
{
  // Initialize pick results
  int pick_result = 0;
  if (picked_surface) *picked_surface = NULL;
  if (picked_image) *picked_image = NULL;
  if (picked_position) *picked_position = R3unknown_point;

  // Draw everything
  viewer.Load();
  glClearColor(0.0, 0.0, 0.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glPointSize(pick_tolerance);
  glLineWidth(pick_tolerance);
  if (picked_image || !picked_surface) {
    if (show_cameras) DrawCameras(RGBD_INDEX_COLOR_SCHEME);
    if (show_bboxes) DrawBBoxes(RGBD_INDEX_COLOR_SCHEME);
    if (show_points) DrawPoints(RGBD_INDEX_COLOR_SCHEME);
    if (show_surfels) DrawSurfels(RGBD_INDEX_COLOR_SCHEME);
    if (show_quads) DrawQuads(RGBD_INDEX_COLOR_SCHEME);
  }
  if (picked_surface || !picked_image) {
    if (show_faces || show_textures) DrawFaces(RGBD_INDEX_COLOR_SCHEME);
  }
  glPointSize(1.0);
  glLineWidth(1.0);
  glFinish();

  // Read color buffer at cursor position
  unsigned char rgba[4];
  glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
  int r = rgba[0] & 0xFF;
  int g = rgba[1] & 0xFF;
  int b = rgba[2] & 0xFF;
  // int a = rgba[3] & 0xFF;

  // Figure out what was picked
  if (r > 0) {
    // Picked surface
    int surface_index = (int) ((configuration.NSurfaces()*r/255.0) + 0.5) - 1;
    if ((surface_index < 0) || (surface_index >= configuration.NSurfaces())) return 0;
    if (picked_surface) *picked_surface = configuration.Surface(surface_index);
    pick_result = RGBD_SURFACE_SELECTION;
  }
  else if ((g > 0) || (b > 0)) {
    // Picked image
    int image_index = (int) ((configuration.NImages()*((g << 8) | b) / 65535.0) + 0.5) - 1;
    if ((image_index < 0) || (image_index >= configuration.NImages())) return 0;
    if (picked_image) *picked_image = configuration.Image(image_index);
    pick_result = RGBD_IMAGE_SELECTION;
  }
  else {
    // Picked background
    return RGBD_NO_SELECTION;
  }

  // Return position
  if (picked_position) {
    // Find 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]);
    *picked_position = position;
  }

  // Return success
  return pick_result;
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movl %edi, 0x1a0(%rsp)
movl %esi, 0x19c(%rsp)
movq %rdx, 0x190(%rsp)
movq %rcx, 0x188(%rsp)
movq %r8, 0x180(%rsp)
movl %r9d, 0x17c(%rsp)
movl $0x0, 0x178(%rsp)
cmpq $0x0, 0x190(%rsp)
je 0x2ac0a
movq 0x190(%rsp), %rax
movq $0x0, (%rax)
cmpq $0x0, 0x188(%rsp)
je 0x2ac24
movq 0x188(%rsp), %rax
movq $0x0, (%rax)
cmpq $0x0, 0x180(%rsp)
je 0x2ac43
movq 0x180(%rsp), %rdi
leaq 0x2147da(%rip), %rsi    # 0x23f418
callq 0xed840
leaq 0x211096(%rip), %rdi    # 0x23bce0
callq 0x2f2e0
xorps %xmm2, %xmm2
movss 0x19c43e(%rip), %xmm3   # 0x1c7098
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x25000
movl $0x4100, %edi           # imm = 0x4100
callq 0x24220
cvtsi2ssl 0x17c(%rsp), %xmm0
callq 0x240b0
cvtsi2ssl 0x17c(%rsp), %xmm0
callq 0x25340
cmpq $0x0, 0x188(%rsp)
jne 0x2aca1
cmpq $0x0, 0x190(%rsp)
jne 0x2ad11
cmpl $0x0, 0x20ae28(%rip)    # 0x235ad0
je 0x2acb4
movl $0x3, %edi
callq 0x294d0
cmpl $0x0, 0x2110d9(%rip)    # 0x23bd94
je 0x2acc7
movl $0x3, %edi
callq 0x29590
cmpl $0x0, 0x2110de(%rip)    # 0x23bdac
je 0x2acdf
movl $0x3, %edi
movl $0x1, %esi
callq 0x29bf0
cmpl $0x0, 0x2110ca(%rip)    # 0x23bdb0
je 0x2acf7
movl $0x3, %edi
movl $0x1, %esi
callq 0x29cb0
cmpl $0x0, 0x2110b6(%rip)    # 0x23bdb4
je 0x2ad0f
movl $0x3, %edi
movl $0x1, %esi
callq 0x29d70
jmp 0x2ad11
cmpq $0x0, 0x190(%rsp)
jne 0x2ad27
cmpq $0x0, 0x188(%rsp)
jne 0x2ad45
cmpl $0x0, 0x211072(%rip)    # 0x23bda0
jne 0x2ad39
cmpl $0x0, 0x211081(%rip)    # 0x23bdb8
je 0x2ad43
movl $0x3, %edi
callq 0x29a40
jmp 0x2ad45
movss 0x19c34b(%rip), %xmm0   # 0x1c7098
callq 0x240b0
movss 0x19c33e(%rip), %xmm0   # 0x1c7098
callq 0x25340
callq 0x25560
movl 0x1a0(%rsp), %edi
movl 0x19c(%rsp), %esi
leaq 0x174(%rsp), %rax
movl $0x1, %ecx
movl $0x1908, %r8d           # imm = 0x1908
movl $0x1401, %r9d           # imm = 0x1401
movl %ecx, %edx
movq %rax, (%rsp)
callq 0x24430
movzbl 0x174(%rsp), %eax
andl $0xff, %eax
movl %eax, 0x170(%rsp)
movzbl 0x175(%rsp), %eax
andl $0xff, %eax
movl %eax, 0x16c(%rsp)
movzbl 0x176(%rsp), %eax
andl $0xff, %eax
movl %eax, 0x168(%rsp)
cmpl $0x0, 0x170(%rsp)
jle 0x2ae95
leaq 0x210df9(%rip), %rdi    # 0x23bbe0
callq 0x2ecd0
imull 0x170(%rsp), %eax
cvtsi2sd %eax, %xmm0
movsd 0x19c260(%rip), %xmm1   # 0x1c7060
divsd %xmm1, %xmm0
movsd 0x19c224(%rip), %xmm1   # 0x1c7030
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
subl $0x1, %eax
movl %eax, 0x164(%rsp)
cmpl $0x0, 0x164(%rsp)
jl 0x2ae49
movl 0x164(%rsp), %eax
movl %eax, 0x14(%rsp)
leaq 0x210da6(%rip), %rdi    # 0x23bbe0
callq 0x2ecd0
movl %eax, %ecx
movl 0x14(%rsp), %eax
cmpl %ecx, %eax
jl 0x2ae59
movl $0x0, 0x1a4(%rsp)
jmp 0x2b08f
cmpq $0x0, 0x190(%rsp)
je 0x2ae85
movl 0x164(%rsp), %esi
leaq 0x210d6e(%rip), %rdi    # 0x23bbe0
callq 0x2f050
movq %rax, %rcx
movq 0x190(%rsp), %rax
movq %rcx, (%rax)
movl $0x2, 0x178(%rsp)
jmp 0x2af7d
cmpl $0x0, 0x16c(%rsp)
jg 0x2aead
cmpl $0x0, 0x168(%rsp)
jle 0x2af6b
leaq 0x210d2c(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl 0x16c(%rsp), %ecx
shll $0x8, %ecx
orl 0x168(%rsp), %ecx
imull %ecx, %eax
cvtsi2sd %eax, %xmm0
movsd 0x19c17f(%rip), %xmm1   # 0x1c7058
divsd %xmm1, %xmm0
movsd 0x19c14b(%rip), %xmm1   # 0x1c7030
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
subl $0x1, %eax
movl %eax, 0x160(%rsp)
cmpl $0x0, 0x160(%rsp)
jl 0x2af22
movl 0x160(%rsp), %eax
movl %eax, 0x10(%rsp)
leaq 0x210ccd(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, %ecx
movl 0x10(%rsp), %eax
cmpl %ecx, %eax
jl 0x2af32
movl $0x0, 0x1a4(%rsp)
jmp 0x2b08f
cmpq $0x0, 0x188(%rsp)
je 0x2af5e
movl 0x160(%rsp), %esi
leaq 0x210c95(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, %rcx
movq 0x188(%rsp), %rax
movq %rcx, (%rax)
movl $0x1, 0x178(%rsp)
jmp 0x2af7b
movl $0x0, 0x1a4(%rsp)
jmp 0x2b08f
jmp 0x2af7d
cmpq $0x0, 0x180(%rsp)
je 0x2b081
leaq 0x130(%rsp), %rsi
movl $0xba2, %edi            # imm = 0xBA2
callq 0x249a0
leaq 0xb0(%rsp), %rsi
movl $0xba6, %edi            # imm = 0xBA6
callq 0x24bc0
leaq 0x30(%rsp), %rsi
movl $0xba7, %edi            # imm = 0xBA7
callq 0x24bc0
movl 0x1a0(%rsp), %edi
movl 0x19c(%rsp), %esi
movl $0x1, %ecx
movl $0x1902, %r8d           # imm = 0x1902
movl $0x1406, %r9d           # imm = 0x1406
leaq 0x15c(%rsp), %rax
movl %ecx, %edx
movq %rax, (%rsp)
callq 0x24430
cvtsi2sdl 0x1a0(%rsp), %xmm0
cvtsi2sdl 0x19c(%rsp), %xmm1
movss 0x15c(%rsp), %xmm2
cvtss2sd %xmm2, %xmm2
leaq 0xb0(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x130(%rsp), %rdx
leaq 0x140(%rsp), %rcx
leaq 0x140(%rsp), %r8
addq $0x8, %r8
leaq 0x140(%rsp), %r9
addq $0x10, %r9
callq 0x25430
movsd 0x140(%rsp), %xmm0
movsd 0x148(%rsp), %xmm1
movsd 0x150(%rsp), %xmm2
leaq 0x18(%rsp), %rdi
callq 0xed1b0
movq 0x180(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0xed840
movl 0x178(%rsp), %eax
movl %eax, 0x1a4(%rsp)
movl 0x1a4(%rsp), %eax
addq $0x1a8, %rsp            # imm = 0x1A8
retq
nop