// File: tomfunkhouser[P]gaps/apps/scn2cam/scn2cam.cpp
// Function: CreateInteriorCameras()
static void
CreateInteriorCameras(void)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();
  int camera_count = 0;

  // Get useful variables
  RNScalar neardist = 0.01 * scene->BBox().DiagonalRadius();
  RNScalar fardist = 100 * scene->BBox().DiagonalRadius();
  RNScalar aspect = (RNScalar) height / (RNScalar) width;
  RNAngle yfov = atan(aspect * tan(xfov));
  int dim0 = (gravity_dimension + 1) % 3;
  int dim1 = (gravity_dimension + 2) % 3;
  int dim2 = gravity_dimension;
  R3Box bbox = scene->BBox();

  // Sample directions
  int nangles = (int) (RN_TWO_PI / angle_sampling + 0.5);
  RNScalar angle_spacing = (nangles > 1) ? RN_TWO_PI / nangles : RN_TWO_PI;

  // Sample positions
  int nx = (int) (bbox.AxisLength(dim0) / position_sampling) + 1;
  int ny = (int) (bbox.AxisLength(dim1) / position_sampling) + 1;
  RNScalar dx = bbox.AxisLength(dim0) / nx;
  RNScalar dy = bbox.AxisLength(dim1) / ny;
  for (int ix = 0; ix < nx; ix++) {
    for (int iy = 0; iy < ny; iy++) {
      // Choose one camera for each grid position
      R3Camera best_camera;

      // Get coordinates
      RNScalar x = bbox.Min()[dim0] + ix * dx;
      RNScalar y = bbox.Min()[dim1] + iy * dy;
      
      // For each angle
      for (int j = 0; j < nangles; j++) {
        // Compute jittered position
        R2Point position(x + position_sampling*RNRandomScalar(), y + position_sampling*RNRandomScalar());

        // Compute height
        RNScalar z = bbox.Min()[dim2] + eye_height;
        z += 2.0*(RNRandomScalar()-0.5) * eye_height_radius;
        if (z > bbox.Max()[dim2]) continue;

        // Compute direction
        RNScalar angle = (j+RNRandomScalar()) * angle_spacing;
        R2Vector direction = R2posx_vector;
        direction.Rotate(angle);
        direction.Normalize();

        // Compute camera
        R3Point viewpoint;
        viewpoint[dim0] = position[0];
        viewpoint[dim1] = position[1];
        viewpoint[dim2] = z;
        R3Vector towards;
        towards[dim0] = direction[0];
        towards[dim1] = direction[1];
        towards[dim2] = -0.2;
        towards.Normalize();
        R3Vector right = towards % R3xyz_triad[dim2];
        right.Normalize();
        R3Vector up = right % towards;
        up.Normalize();
        R3Camera camera(viewpoint, towards, up, xfov, yfov, neardist, fardist);

        // Compute score for camera
        camera.SetValue(SceneCoverageScore(camera, scene));
        if (camera.Value() == 0) continue;
        if (camera.Value() < min_score) continue;

        // Remember best camera
        if (camera.Value() > best_camera.Value()) {
          best_camera = camera;
        }
      }

      // Insert best camera for direction
      if (best_camera.Value() > 0) {
        if (print_debug) printf("INTERIOR %d %d : %g\n", ix, iy, best_camera.Value());
        char name[1024];
        sprintf(name, "C_%d_%d", ix, iy);
        Camera *camera = new Camera(best_camera, name);
        cameras.Insert(camera);
        camera_count++;
      }
    }
  }
        
  // Print statistics
  if (print_verbose) {
    printf("Created interior cameras ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Cameras = %d\n", camera_count++);
    fflush(stdout);
  }
}

// Assembly:
subq $0x7f8, %rsp            # imm = 0x7F8
leaq 0x7e8(%rsp), %rdi
callq 0x11bad0
leaq 0x7e8(%rsp), %rdi
callq 0x321a0
movl $0x0, 0x7e4(%rsp)
movq 0x205ba5(%rip), %rdi    # 0x22fc38
callq 0x32290
movq %rax, %rdi
callq 0x322b0
movaps %xmm0, %xmm1
movsd 0x190f75(%rip), %xmm0   # 0x1bb020
mulsd %xmm1, %xmm0
movsd %xmm0, 0x7d8(%rsp)
movq 0x205b79(%rip), %rdi    # 0x22fc38
callq 0x32290
movq %rax, %rdi
callq 0x322b0
movaps %xmm0, %xmm1
movsd 0x190f41(%rip), %xmm0   # 0x1bb018
mulsd %xmm1, %xmm0
movsd %xmm0, 0x7d0(%rsp)
cvtsi2sdl 0x1ff9a0(%rip), %xmm0 # 0x229a8c
cvtsi2sdl 0x1ff994(%rip), %xmm1 # 0x229a88
divsd %xmm1, %xmm0
movsd %xmm0, 0x7c8(%rsp)
movsd 0x7c8(%rsp), %xmm0
movsd %xmm0, 0x160(%rsp)
movsd 0x1ff975(%rip), %xmm0   # 0x229a90
callq 0x234f0
movaps %xmm0, %xmm1
movsd 0x160(%rsp), %xmm0
mulsd %xmm1, %xmm0
callq 0x237e0
movsd %xmm0, 0x7c0(%rsp)
movl 0x1ff940(%rip), %eax    # 0x229a84
addl $0x1, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %edx, 0x7bc(%rsp)
movl 0x1ff928(%rip), %eax    # 0x229a84
addl $0x2, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %edx, 0x7b8(%rsp)
movl 0x1ff910(%rip), %eax    # 0x229a84
movl %eax, 0x7b4(%rsp)
movq 0x205ab6(%rip), %rdi    # 0x22fc38
callq 0x32290
movq %rax, %rsi
leaq 0x778(%rsp), %rdi
callq 0xc4a10
leaq 0x19544a(%rip), %rax    # 0x1bf5e8
movsd (%rax), %xmm0
divsd 0x205a56(%rip), %xmm0   # 0x22fc00
movsd 0x190e7e(%rip), %xmm1   # 0x1bb030
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x774(%rsp)
cmpl $0x1, 0x774(%rsp)
jle 0x2a1ee
leaq 0x195416(%rip), %rax    # 0x1bf5e8
movsd (%rax), %xmm0
cvtsi2sdl 0x774(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x158(%rsp)
jmp 0x2a202
leaq 0x1953f3(%rip), %rax    # 0x1bf5e8
movsd (%rax), %xmm0
movsd %xmm0, 0x158(%rsp)
movsd 0x158(%rsp), %xmm0
movsd %xmm0, 0x768(%rsp)
movl 0x7bc(%rsp), %esi
leaq 0x778(%rsp), %rdi
callq 0x33410
movsd %xmm0, 0x150(%rsp)
jmp 0x2a233
movsd 0x150(%rsp), %xmm0
movsd 0x1ff884(%rip), %xmm1   # 0x229ac8
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
incl %eax
movl %eax, 0x764(%rsp)
movl 0x7b8(%rsp), %esi
leaq 0x778(%rsp), %rdi
callq 0x33410
movsd %xmm0, 0x148(%rsp)
jmp 0x2a274
movsd 0x148(%rsp), %xmm0
movsd 0x1ff843(%rip), %xmm1   # 0x229ac8
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
incl %eax
movl %eax, 0x750(%rsp)
movl 0x7bc(%rsp), %esi
leaq 0x778(%rsp), %rdi
callq 0x33410
movsd %xmm0, 0x140(%rsp)
jmp 0x2a2b5
movsd 0x140(%rsp), %xmm0
cvtsi2sdl 0x764(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x748(%rsp)
movl 0x7b8(%rsp), %esi
leaq 0x778(%rsp), %rdi
callq 0x33410
movsd %xmm0, 0x138(%rsp)
jmp 0x2a2f3
movsd 0x138(%rsp), %xmm0
cvtsi2sdl 0x750(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x740(%rsp)
movl $0x0, 0x73c(%rsp)
movl 0x73c(%rsp), %eax
cmpl 0x764(%rsp), %eax
jge 0x2ab4b
movl $0x0, 0x738(%rsp)
movl 0x738(%rsp), %eax
cmpl 0x750(%rsp), %eax
jge 0x2ab33
leaq 0x6a8(%rsp), %rdi
callq 0x67570
jmp 0x2a35f
leaq 0x778(%rsp), %rdi
callq 0x33460
movq %rax, 0x130(%rsp)
jmp 0x2a376
movq 0x130(%rsp), %rdi
movl 0x7bc(%rsp), %esi
callq 0x33470
movsd %xmm0, 0x128(%rsp)
jmp 0x2a395
movsd 0x128(%rsp), %xmm1
cvtsi2sdl 0x73c(%rsp), %xmm0
movsd 0x748(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x6a0(%rsp)
leaq 0x778(%rsp), %rdi
callq 0x33460
movq %rax, 0x120(%rsp)
jmp 0x2a3d8
movq 0x120(%rsp), %rdi
movl 0x7b8(%rsp), %esi
callq 0x33470
movsd %xmm0, 0x118(%rsp)
jmp 0x2a3f7
movsd 0x118(%rsp), %xmm1
cvtsi2sdl 0x738(%rsp), %xmm0
movsd 0x740(%rsp), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x698(%rsp)
movl $0x0, 0x694(%rsp)
movl 0x694(%rsp), %eax
cmpl 0x774(%rsp), %eax
jge 0x2aa0c
movsd 0x6a0(%rsp), %xmm0
movsd %xmm0, 0x100(%rsp)
movsd 0x1ff66c(%rip), %xmm0   # 0x229ac8
movsd %xmm0, 0x108(%rsp)
callq 0x11f4d0
movsd %xmm0, 0x110(%rsp)
jmp 0x2a475
movsd 0x100(%rsp), %xmm1
movsd 0x110(%rsp), %xmm2
movsd 0x108(%rsp), %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0xe0(%rsp)
movsd 0x698(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0x1ff60d(%rip), %xmm0   # 0x229ac8
movsd %xmm0, 0xf0(%rsp)
callq 0x11f4d0
movsd %xmm0, 0xf8(%rsp)
jmp 0x2a4d4
movsd 0xe0(%rsp), %xmm0
movsd 0xe8(%rsp), %xmm2
movsd 0xf8(%rsp), %xmm3
movsd 0xf0(%rsp), %xmm1
mulsd %xmm3, %xmm1
addsd %xmm2, %xmm1
leaq 0x680(%rsp), %rdi
callq 0x10e490
jmp 0x2a50f
leaq 0x778(%rsp), %rdi
callq 0x33460
movq %rax, 0xd8(%rsp)
jmp 0x2a526
movq 0xd8(%rsp), %rdi
movl 0x7b4(%rsp), %esi
callq 0x33470
movsd %xmm0, 0xd0(%rsp)
jmp 0x2a545
movsd 0xd0(%rsp), %xmm0
movsd 0x1ff542(%rip), %xmm1   # 0x229a98
addsd %xmm1, %xmm0
movsd %xmm0, 0x678(%rsp)
callq 0x11f4d0
movsd %xmm0, 0xc8(%rsp)
jmp 0x2a573
movsd 0xc8(%rsp), %xmm0
movsd 0x190ac4(%rip), %xmm1   # 0x1bb048
addsd %xmm1, %xmm0
addsd %xmm0, %xmm0
movsd 0x1ff50c(%rip), %xmm2   # 0x229aa0
movsd 0x678(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x678(%rsp)
movsd 0x678(%rsp), %xmm0
movsd %xmm0, 0xb8(%rsp)
leaq 0x778(%rsp), %rdi
callq 0x33490
movq %rax, 0xc0(%rsp)
jmp 0x2a5d7
movq 0xc0(%rsp), %rdi
movl 0x7b4(%rsp), %esi
callq 0x33470
movsd %xmm0, 0xb0(%rsp)
jmp 0x2a5f6
movsd 0xb8(%rsp), %xmm0
movsd 0xb0(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2a62c
jmp 0x2a9f6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x758(%rsp)
movl %eax, 0x754(%rsp)
jmp 0x2abd9
cvtsi2sdl 0x694(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
callq 0x11f4d0
movsd %xmm0, 0xa8(%rsp)
jmp 0x2a64e
movsd 0xa8(%rsp), %xmm1
movsd 0xa0(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd 0x768(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x670(%rsp)
leaq 0x20f527(%rip), %rsi    # 0x239ba8
leaq 0x660(%rsp), %rdi
callq 0x10efb0
jmp 0x2a690
movsd 0x670(%rsp), %xmm0
leaq 0x660(%rsp), %rdi
callq 0x10f4c0
jmp 0x2a6a8
leaq 0x660(%rsp), %rdi
callq 0x10f3e0
jmp 0x2a6b7
leaq 0x648(%rsp), %rdi
callq 0xd9f30
jmp 0x2a6c6
leaq 0x680(%rsp), %rdi
xorl %esi, %esi
callq 0x334a0
movq %rax, 0x98(%rsp)
jmp 0x2a6df
movq 0x98(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x88(%rsp)
movl 0x7bc(%rsp), %esi
leaq 0x648(%rsp), %rdi
callq 0x32510
movsd 0x88(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x680(%rsp), %rdi
movl $0x1, %esi
callq 0x334a0
movq %rax, 0x90(%rsp)
jmp 0x2a731
movq 0x90(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
movl 0x7b8(%rsp), %esi
leaq 0x648(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x32510
movsd 0x70(%rsp), %xmm0
movq 0x78(%rsp), %rdi
movsd %xmm0, (%rax)
movsd 0x678(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movl 0x7b4(%rsp), %esi
callq 0x32510
movsd 0x80(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x630(%rsp), %rdi
callq 0xdb090
jmp 0x2a7a5
leaq 0x660(%rsp), %rdi
xorl %esi, %esi
callq 0x334c0
movq %rax, 0x68(%rsp)
jmp 0x2a7bb
movq 0x68(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x58(%rsp)
movl 0x7bc(%rsp), %esi
leaq 0x630(%rsp), %rdi
callq 0x334e0
movq %rax, 0x60(%rsp)
jmp 0x2a7e5
movq 0x60(%rsp), %rax
movsd 0x58(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x660(%rsp), %rdi
movl $0x1, %esi
callq 0x334c0
movq %rax, 0x50(%rsp)
jmp 0x2a80d
movq 0x50(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
movl 0x7b8(%rsp), %esi
leaq 0x630(%rsp), %rdi
callq 0x334e0
movq %rax, 0x48(%rsp)
jmp 0x2a837
movq 0x48(%rsp), %rax
movsd 0x40(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x7b4(%rsp), %esi
leaq 0x630(%rsp), %rdi
callq 0x334e0
movq %rax, 0x38(%rsp)
jmp 0x2a861
movq 0x38(%rsp), %rax
movabsq $-0x4036666666666666, %rcx # imm = 0xBFC999999999999A
movq %rcx, (%rax)
leaq 0x630(%rsp), %rdi
callq 0xdb800
jmp 0x2a882
movl 0x7b4(%rsp), %esi
leaq 0x20e218(%rip), %rdi    # 0x238aa8
callq 0x32530
movq %rax, 0x30(%rsp)
jmp 0x2a89c
movq 0x30(%rsp), %rdx
leaq 0x618(%rsp), %rdi
leaq 0x630(%rsp), %rsi
callq 0xdbee0
jmp 0x2a8b8
leaq 0x618(%rsp), %rdi
callq 0xdb800
jmp 0x2a8c7
leaq 0x600(%rsp), %rdi
leaq 0x618(%rsp), %rsi
leaq 0x630(%rsp), %rdx
callq 0xdbee0
jmp 0x2a8e6
leaq 0x600(%rsp), %rdi
callq 0xdb800
jmp 0x2a8f5
movsd 0x1ff193(%rip), %xmm0   # 0x229a90
movsd 0x7c0(%rsp), %xmm1
movsd 0x7d8(%rsp), %xmm2
movsd 0x7d0(%rsp), %xmm3
leaq 0x570(%rsp), %rdi
leaq 0x648(%rsp), %rsi
leaq 0x630(%rsp), %rdx
leaq 0x600(%rsp), %rcx
callq 0x67810
jmp 0x2a93f
movq 0x2052f2(%rip), %rsi    # 0x22fc38
xorl %ecx, %ecx
movl %ecx, %edx
leaq 0x570(%rsp), %rdi
callq 0x2f130
movsd %xmm0, 0x28(%rsp)
jmp 0x2a95f
movsd 0x28(%rsp), %xmm0
leaq 0x570(%rsp), %rdi
callq 0x32350
leaq 0x570(%rsp), %rdi
callq 0x32550
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x2a98c
jp 0x2a98c
jmp 0x2a9f6
leaq 0x570(%rsp), %rdi
callq 0x32550
movaps %xmm0, %xmm1
movsd 0x20524c(%rip), %xmm0   # 0x22fbf0
ucomisd %xmm1, %xmm0
jbe 0x2a9ac
jmp 0x2a9f6
leaq 0x570(%rsp), %rdi
callq 0x32550
movsd %xmm0, 0x20(%rsp)
leaq 0x6a8(%rsp), %rdi
callq 0x32550
movaps %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2a9f4
leaq 0x6a8(%rsp), %rdi
leaq 0x570(%rsp), %rsi
callq 0x68860
jmp 0x2a9f2
jmp 0x2a9f4
jmp 0x2a9f6
movl 0x694(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x694(%rsp)
jmp 0x2a42e
leaq 0x6a8(%rsp), %rdi
callq 0x32550
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2ab1b
cmpl $0x0, 0x20518b(%rip)    # 0x22fbb8
je 0x2aa6c
movl 0x73c(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x738(%rsp), %eax
movl %eax, 0x1c(%rsp)
leaq 0x6a8(%rsp), %rdi
callq 0x32550
movl 0x18(%rsp), %esi
movl 0x1c(%rsp), %edx
leaq 0x190c0e(%rip), %rdi    # 0x1bb66f
movb $0x1, %al
callq 0x23090
jmp 0x2aa6a
jmp 0x2aa6c
movl 0x73c(%rsp), %edx
movl 0x738(%rsp), %ecx
leaq 0x190c03(%rip), %rsi    # 0x1bb684
xorl %eax, %eax
leaq 0x170(%rsp), %rdi
callq 0x23150
movl $0x98, %edi
callq 0x239b0
movq %rax, 0x10(%rsp)
jmp 0x2aaa1
movq 0x10(%rsp), %rdi
leaq 0x6a8(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x32570
jmp 0x2aabd
movq 0x10(%rsp), %rax
movq %rax, 0x168(%rsp)
movq 0x168(%rsp), %rsi
leaq 0x2050a7(%rip), %rdi    # 0x22fb80
callq 0x32370
jmp 0x2aae0
movl 0x7e4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7e4(%rsp)
jmp 0x2ab1b
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x758(%rsp)
movl %eax, 0x754(%rsp)
movl $0x98, %esi
callq 0x239d0
jmp 0x2abd9
jmp 0x2ab1d
movl 0x738(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x738(%rsp)
jmp 0x2a33c
jmp 0x2ab35
movl 0x73c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x73c(%rsp)
jmp 0x2a31d
cmpl $0x0, 0x205062(%rip)    # 0x22fbb4
je 0x2abc4
leaq 0x190b31(%rip), %rdi    # 0x1bb68c
xorl %eax, %eax
callq 0x23090
jmp 0x2ab64
leaq 0x7e8(%rsp), %rdi
callq 0x11bb90
movsd %xmm0, 0x8(%rsp)
jmp 0x2ab79
movsd 0x8(%rsp), %xmm0
leaq 0x1908b4(%rip), %rdi    # 0x1bb43a
movb $0x1, %al
callq 0x23090
jmp 0x2ab8f
movl 0x7e4(%rsp), %esi
movl %esi, %eax
incl %eax
movl %eax, 0x7e4(%rsp)
leaq 0x190957(%rip), %rdi    # 0x1bb4ff
xorl %eax, %eax
callq 0x23090
jmp 0x2abb1
movq 0x1fe3d8(%rip), %rax    # 0x228f90
movq (%rax), %rdi
callq 0x23bc0
jmp 0x2abc2
jmp 0x2abc4
leaq 0x778(%rsp), %rdi
callq 0x33500
addq $0x7f8, %rsp            # imm = 0x7F8
retq
leaq 0x778(%rsp), %rdi
callq 0x33500
movq 0x758(%rsp), %rdi
callq 0x24250
nopw %cs:(%rax,%rax)