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

  RNScalar neardist = 0.01;
  RNScalar fardist = 10.0;
  RNScalar aspect = (RNScalar) height / (RNScalar) width;
  RNScalar yfov = atan(aspect * tan(xfov));

  // TODO: Get node's centroid and radius in world coordinate system
  // Right now the code just assumes it's the world frame origin.
  R3Point centroid = R3Point(0.0, 0.0, 0.0);
  int cameras_to_make = 50; // TODO: Should be a flag.
  for (int ci = 0; ci < cameras_to_make; ++ci) {

    RNScalar min_elevation = RN_PI / 12.0; // TODO: Should be a flag.
    RNScalar max_elevation = 4.0 * RN_PI / 12.0; // TODO: Should be a flag.
    RNScalar elevation_range = max_elevation - min_elevation;

    // TODO It would probably be better if the sampling were stratified.
    RNScalar rotation = RNRandomScalar() * RN_TWO_PI;
    RNScalar elevation = RNRandomScalar() * elevation_range + min_elevation;

    RNScalar max_distance = 1.3;  // TODO: Should be a flag.
    RNScalar min_distance = 0.85; // TODO: Should be a flag.
    RNScalar distance_range = max_distance - min_distance;
    RNScalar distance = RNRandomScalar() * distance_range + min_distance;

    // Compute (x,y,z) from azimuth and elevation    
    RNScalar y = sin(elevation);
    RNScalar hyp = cos(elevation);
    RNScalar x = sin(rotation) * hyp;
    RNScalar z = cos(rotation) * hyp;
    R3Point viewpoint(distance*x,distance*y,distance*z);

    // Compute camera parameters
    R3Vector towards = centroid - viewpoint;
    towards.Normalize();
    R3Vector right = towards % R3xyz_triad[gravity_dimension];
    right.Normalize();
    R3Vector up = right % towards;
    up.Normalize();
    R3Camera camera(viewpoint, towards, up, xfov, yfov, neardist, fardist);

    char camera_name[1024];
    sprintf(camera_name, "%s#%i", "Cam", ci);
    Camera *insertable_camera = new Camera(camera, camera_name);
    cameras.Insert(insertable_camera);
    camera_count++;
  }

  // Print statistics
  if (print_verbose) {
    printf("Created random orbit cameras ...\n");
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Cameras = %d\n", camera_count++);
    fflush(stdout);
  }
}

// Assembly:
subq $0x618, %rsp            # imm = 0x618
leaq 0x608(%rsp), %rdi
callq 0x11bad0
leaq 0x608(%rsp), %rdi
callq 0x321a0
movl $0x0, 0x604(%rsp)
movsd 0x18f3ac(%rip), %xmm0   # 0x1bb020
movsd %xmm0, 0x5f8(%rsp)
movsd 0x18f3f3(%rip), %xmm0   # 0x1bb078
movsd %xmm0, 0x5f0(%rsp)
cvtsi2sdl 0x1fddf6(%rip), %xmm0 # 0x229a8c
cvtsi2sdl 0x1fddea(%rip), %xmm1 # 0x229a88
divsd %xmm1, %xmm0
movsd %xmm0, 0x5e8(%rsp)
movsd 0x5e8(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x1fddce(%rip), %xmm0   # 0x229a90
callq 0x234f0
movaps %xmm0, %xmm1
movsd 0x40(%rsp), %xmm0
mulsd %xmm1, %xmm0
callq 0x237e0
movsd %xmm0, 0x5e0(%rsp)
leaq 0x5c8(%rsp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0xd9f40
movl $0x32, 0x5c4(%rsp)
movl $0x0, 0x5c0(%rsp)
movl 0x5c0(%rsp), %eax
cmpl 0x5c4(%rsp), %eax
jge 0x2c062
leaq 0x19389f(%rip), %rax    # 0x1bf5c8
movsd (%rax), %xmm0
movsd 0x18f34b(%rip), %xmm1   # 0x1bb080
divsd %xmm1, %xmm0
movsd %xmm0, 0x5b8(%rsp)
movsd (%rax), %xmm0
movsd 0x18f31a(%rip), %xmm2   # 0x1bb068
mulsd %xmm2, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x5b0(%rsp)
movsd 0x5b0(%rsp), %xmm0
movsd 0x5b8(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x5a8(%rsp)
callq 0x11f4d0
leaq 0x19385e(%rip), %rax    # 0x1bf5e8
movsd (%rax), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x5a0(%rsp)
callq 0x11f4d0
movsd 0x5a8(%rsp), %xmm2
movsd 0x5b8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x598(%rsp)
movabsq $0x3ff4cccccccccccd, %rax # imm = 0x3FF4CCCCCCCCCCCD
movq %rax, 0x590(%rsp)
movabsq $0x3feb333333333333, %rax # imm = 0x3FEB333333333333
movq %rax, 0x588(%rsp)
movsd 0x590(%rsp), %xmm0
movsd 0x588(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x580(%rsp)
callq 0x11f4d0
movsd 0x580(%rsp), %xmm2
movsd 0x588(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x578(%rsp)
movsd 0x598(%rsp), %xmm0
callq 0x23170
movsd %xmm0, 0x570(%rsp)
movsd 0x598(%rsp), %xmm0
callq 0x24360
movsd %xmm0, 0x568(%rsp)
movsd 0x5a0(%rsp), %xmm0
callq 0x23170
movsd 0x568(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x560(%rsp)
movsd 0x5a0(%rsp), %xmm0
callq 0x24360
movsd 0x568(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x558(%rsp)
movsd 0x578(%rsp), %xmm2
movsd 0x560(%rsp), %xmm1
movaps %xmm2, %xmm0
mulsd %xmm1, %xmm0
movsd 0x570(%rsp), %xmm3
movaps %xmm2, %xmm1
mulsd %xmm3, %xmm1
movsd 0x558(%rsp), %xmm3
mulsd %xmm3, %xmm2
leaq 0x540(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xd9f40
movq 0x10(%rsp), %rdx
leaq 0x528(%rsp), %rdi
movq %rdi, 0x18(%rsp)
leaq 0x5c8(%rsp), %rsi
callq 0xda2a0
movq 0x18(%rsp), %rdi
callq 0xdb800
movl 0x1fdb69(%rip), %esi    # 0x229a84
leaq 0x20cb86(%rip), %rdi    # 0x238aa8
callq 0x32530
movq 0x18(%rsp), %rsi
movq %rax, %rdx
leaq 0x510(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xdbee0
movq 0x8(%rsp), %rdi
callq 0xdb800
movq 0x8(%rsp), %rsi
movq 0x18(%rsp), %rdx
leaq 0x4f8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xdbee0
movq 0x20(%rsp), %rdi
callq 0xdb800
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
movq 0x20(%rsp), %rcx
movsd 0x1fdb08(%rip), %xmm0   # 0x229a90
movsd 0x5e0(%rsp), %xmm1
movsd 0x5f8(%rsp), %xmm2
movsd 0x5f0(%rsp), %xmm3
leaq 0x468(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x67810
movl 0x5c0(%rsp), %ecx
leaq 0x18f767(%rip), %rsi    # 0x1bb72a
leaq 0x18f766(%rip), %rdx    # 0x1bb730
xorl %eax, %eax
leaq 0x60(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x23150
movl $0x98, %edi
callq 0x239b0
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x38(%rsp)
callq 0x32570
jmp 0x2c001
movq 0x38(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rsi
leaq 0x203b69(%rip), %rdi    # 0x22fb80
callq 0x32370
movl 0x604(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x604(%rsp)
movl 0x5c0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x5c0(%rsp)
jmp 0x2bd0e
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
movl $0x98, %esi
callq 0x239d0
jmp 0x2c0cc
cmpl $0x0, 0x203b4b(%rip)    # 0x22fbb4
je 0x2c0c4
leaq 0x18f6c2(%rip), %rdi    # 0x1bb734
movb $0x0, %al
callq 0x23090
leaq 0x608(%rsp), %rdi
callq 0x11bb90
leaq 0x18f3ad(%rip), %rdi    # 0x1bb43a
movb $0x1, %al
callq 0x23090
movl 0x604(%rsp), %esi
movl %esi, %eax
addl $0x1, %eax
movl %eax, 0x604(%rsp)
leaq 0x18f451(%rip), %rdi    # 0x1bb4ff
movb $0x0, %al
callq 0x23090
movq 0x1fced4(%rip), %rax    # 0x228f90
movq (%rax), %rdi
callq 0x23bc0
addq $0x618, %rsp            # imm = 0x618
retq
movq 0x50(%rsp), %rdi
callq 0x24250
nopw %cs:(%rax,%rax)