// File: tomfunkhouser[P]gaps/apps/conf2img/conf2img.cpp
// Function: RenderConfiguration(gaps::RGBDConfiguration const&, gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&, double, double)
static void
RenderConfiguration(const RGBDConfiguration& configuration,
  const R3Point& target_viewpoint, const R3Vector& target_towards, const R3Vector& target_up,
  RNScalar min_affinity = 0.01, RNScalar min_affinity_ratio = 0.25)
{
  // Clear window
  glViewport(0, 0, width, height);
  glClearColor(background.R(), background.G(), background.B(), 0.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glEnable(GL_DEPTH_TEST);
  RNLoadRgb(1.0, 1.0, 1.0);

  // Draw images
  if (configuration.NImages() > 0) {
    // Create array of affinities
    RNArray<RGBDImage *> images;
    RNScalar *affinities = new RNScalar [ configuration.NImages() ];
    for (int i = 0; i < configuration.NImages(); i++) {
      RGBDImage *image = configuration.Image(i);
      RNScalar affinity = Affinity(image->WorldViewpoint(), image->WorldTowards(), target_viewpoint, target_towards);
      if (affinity < min_affinity) continue;
      affinities[images.NEntries()] = affinity;
      images.Insert(image);
    }

    // Sort images based on affinity
    for (int i = 0; i < images.NEntries(); i++) {
      for (int j = i+1; j < images.NEntries(); j++) {
        if (affinities[j] > affinities[i]) {
          RGBDImage *swap_image = images[j];
          images[j] = images[i];
          images[i] = swap_image;
          RNScalar swap_affinity = affinities[j];
          affinities[j] = affinities[i];
          affinities[i] = swap_affinity;
        }
      }
    }

    // Draw images with best affinity
    RNScalar best_affinity = affinities[0];
    if (best_affinity > 0) {
      for (int i = 0; i < images.NEntries(); i++) {
        RGBDImage *image = images.Kth(i);
        RNScalar affinity = affinities[i];
        if ((min_affinity_ratio > 0) && (affinity < min_affinity_ratio * best_affinity)) continue;
        image->ReadChannels();
        image->DrawSurfels(RGBD_PHOTO_COLOR_SCHEME);
        image->ReleaseChannels();
        printf("%d %s %g\n", i, image->Name(), affinity);
      }
    }

    // Delete array of affinities
    delete [] affinities;
  }
  
  // Draw surfaces
  for (int i = 0; i < configuration.NSurfaces(); i++) {
    RGBDSurface *surface = configuration.Surface(i);
    surface->ReadChannels();
    surface->DrawTexture(RGBD_PHOTO_COLOR_SCHEME);
    surface->ReleaseChannels();
  }
}

// Assembly:
subq $0x198, %rsp            # imm = 0x198
movq %rdi, 0x190(%rsp)
movq %rsi, 0x188(%rsp)
movq %rdx, 0x180(%rsp)
movq %rcx, 0x178(%rsp)
movsd %xmm0, 0x170(%rsp)
movsd %xmm1, 0x168(%rsp)
movl 0x22634d(%rip), %edx    # 0x255d9c
movl 0x22634b(%rip), %ecx    # 0x255da0
xorl %esi, %esi
movl %esi, %edi
callq 0x24230
leaq 0x22610b(%rip), %rdi    # 0x255b70
callq 0x30fa0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xb4(%rsp)
leaq 0x2260f2(%rip), %rdi    # 0x255b70
callq 0x30fb0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xb0(%rsp)
leaq 0x2260d9(%rip), %rdi    # 0x255b70
callq 0x30fc0
movss 0xb0(%rsp), %xmm1
movaps %xmm0, %xmm2
movss 0xb4(%rsp), %xmm0
cvtsd2ss %xmm2, %xmm2
xorps %xmm3, %xmm3
callq 0x24fe0
movl $0x4100, %edi           # imm = 0x4100
callq 0x24210
movl $0xb71, %edi            # imm = 0xB71
callq 0x24920
movsd 0x1af54f(%rip), %xmm2   # 0x1df028
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x30c80
movq 0x190(%rsp), %rdi
callq 0x304b0
cmpl $0x0, %eax
jle 0x3007c
leaq 0x158(%rsp), %rdi
callq 0x31130
movq 0x190(%rsp), %rdi
callq 0x304b0
movl %eax, 0xac(%rsp)
jmp 0x2fb1d
movl 0xac(%rsp), %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x24040
movq %rax, 0xa0(%rsp)
jmp 0x2fb4b
movq 0xa0(%rsp), %rax
movq %rax, 0x150(%rsp)
movl $0x0, 0x140(%rsp)
movl 0x140(%rsp), %eax
movl %eax, 0x98(%rsp)
movq 0x190(%rsp), %rdi
callq 0x304b0
movl %eax, 0x9c(%rsp)
jmp 0x2fb8a
movl 0x98(%rsp), %eax
movl 0x9c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2fcf6
movq 0x190(%rsp), %rdi
movl 0x140(%rsp), %esi
callq 0x304d0
movq %rax, 0x90(%rsp)
jmp 0x2fbbe
movq 0x90(%rsp), %rax
movq %rax, 0x138(%rsp)
movq 0x138(%rsp), %rsi
leaq 0x118(%rsp), %rdi
callq 0x30b20
jmp 0x2fbe5
movq 0x138(%rsp), %rsi
leaq 0x100(%rsp), %rdi
callq 0x30b70
jmp 0x2fbfc
movq 0x188(%rsp), %rdx
movq 0x180(%rsp), %rcx
leaq 0x118(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x30330
movsd %xmm0, 0x88(%rsp)
jmp 0x2fc2c
movsd 0x88(%rsp), %xmm0
movsd %xmm0, 0x130(%rsp)
movsd 0x130(%rsp), %xmm1
movsd 0x170(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2fc81
jmp 0x2fce0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x148(%rsp)
movl %eax, 0x144(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x311b0
jmp 0x30118
movsd 0x130(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0x158(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x30560
movsd 0x70(%rsp), %xmm0
movq 0x78(%rsp), %rdi
movl %eax, %ecx
movq 0x80(%rsp), %rax
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movq 0x138(%rsp), %rsi
callq 0x31140
jmp 0x2fcde
jmp 0x2fce0
movl 0x140(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x140(%rsp)
jmp 0x2fb66
movl $0x0, 0xfc(%rsp)
movl 0xfc(%rsp), %eax
movl %eax, 0x6c(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x30560
movl %eax, %ecx
movl 0x6c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2fed4
movl 0xfc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
movl 0xf8(%rsp), %eax
movl %eax, 0x68(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x30560
movl %eax, %ecx
movl 0x68(%rsp), %eax
cmpl %ecx, %eax
jge 0x2febc
movq 0x150(%rsp), %rax
movslq 0xf8(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x150(%rsp), %rax
movslq 0xfc(%rsp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x2fea4
movl 0xf8(%rsp), %esi
leaq 0x158(%rsp), %rdi
callq 0x31170
movq %rax, 0x60(%rsp)
jmp 0x2fda9
movq 0x60(%rsp), %rax
movq (%rax), %rax
movq %rax, 0xf0(%rsp)
movl 0xfc(%rsp), %esi
leaq 0x158(%rsp), %rdi
callq 0x31170
movq %rax, 0x58(%rsp)
jmp 0x2fdd4
movq 0x58(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movl 0xf8(%rsp), %esi
leaq 0x158(%rsp), %rdi
callq 0x31170
movq %rax, 0x50(%rsp)
jmp 0x2fdfc
movq 0x50(%rsp), %rax
movq 0x48(%rsp), %rcx
movq %rcx, (%rax)
movq 0xf0(%rsp), %rax
movq %rax, 0x38(%rsp)
movl 0xfc(%rsp), %esi
leaq 0x158(%rsp), %rdi
callq 0x31170
movq %rax, 0x40(%rsp)
jmp 0x2fe31
movq 0x40(%rsp), %rax
movq 0x38(%rsp), %rcx
movq %rcx, (%rax)
movq 0x150(%rsp), %rax
movslq 0xf8(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xe8(%rsp)
movq 0x150(%rsp), %rax
movslq 0xfc(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x150(%rsp), %rax
movslq 0xf8(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0xe8(%rsp), %xmm0
movq 0x150(%rsp), %rax
movslq 0xfc(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x2fea6
movl 0xf8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
jmp 0x2fd38
jmp 0x2febe
movl 0xfc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xfc(%rsp)
jmp 0x2fd01
movq 0x150(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0xe0(%rsp)
movsd 0xe0(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x30052
movl $0x0, 0xdc(%rsp)
movl 0xdc(%rsp), %eax
movl %eax, 0x34(%rsp)
leaq 0x158(%rsp), %rdi
callq 0x30560
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0x30050
movl 0xdc(%rsp), %esi
leaq 0x158(%rsp), %rdi
callq 0x30570
movq %rax, 0x28(%rsp)
jmp 0x2ff4b
movq 0x28(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0x150(%rsp), %rax
movslq 0xdc(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0xc8(%rsp)
movsd 0x168(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2ffae
movsd 0xc8(%rsp), %xmm1
movsd 0x168(%rsp), %xmm0
mulsd 0xe0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2ffae
jmp 0x3003a
movq 0xd0(%rsp), %rdi
movq (%rdi), %rax
movq 0xf8(%rax), %rax
callq *%rax
jmp 0x2ffc4
movq 0xd0(%rsp), %rdi
movq (%rdi), %rax
movq 0xe0(%rax), %rax
movl $0x1, %edx
movl %edx, %esi
callq *%rax
jmp 0x2ffe1
movq 0xd0(%rsp), %rdi
movq (%rdi), %rax
movq 0x148(%rax), %rax
callq *%rax
jmp 0x2fff7
movl 0xdc(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x31190
movq %rax, 0x20(%rsp)
jmp 0x30016
movq 0x20(%rsp), %rdx
movl 0x1c(%rsp), %esi
movsd 0xc8(%rsp), %xmm0
leaq 0x1af892(%rip), %rdi    # 0x1df8c1
movb $0x1, %al
callq 0x24090
jmp 0x30038
jmp 0x3003a
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x2ff0a
jmp 0x30052
movq 0x150(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x3006f
movq 0x10(%rsp), %rdi
callq 0x24db0
leaq 0x158(%rsp), %rdi
callq 0x311b0
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x190(%rsp), %rdi
callq 0x30540
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x30110
movq 0x190(%rsp), %rdi
movl 0xc4(%rsp), %esi
callq 0x311c0
movq %rax, 0xb8(%rsp)
movq 0xb8(%rsp), %rdi
movq (%rdi), %rax
callq *0x88(%rax)
movq 0xb8(%rsp), %rdi
movq (%rdi), %rax
movl $0x1, %esi
callq *0x78(%rax)
movq 0xb8(%rsp), %rdi
movq (%rdi), %rax
callq *0xa8(%rax)
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x30087
addq $0x198, %rsp            # imm = 0x198
retq
movq 0x148(%rsp), %rdi
callq 0x25290
nopw %cs:(%rax,%rax)