// File: tomfunkhouser[P]gaps/apps/confview/confview.cpp
// Function: ProcessRubberBox()
static int
ProcessRubberBox(void)
{
  // Create surface ...
  
  // Create rubber box (with sorted corners)
  R2Box rubber_box = R2null_box;
  rubber_box.Union(rubber_box_corners[0]);
  rubber_box.Union(rubber_box_corners[1]);
  if ((rubber_box.XLength() < 10) || (rubber_box.YLength() < 10)) {
    printf("Box is too small -- could not create surface\n");
    fflush(stdout);
    return 0;
  }
   
  // Create random set of points projecting inside rubber box
  int npoints = 0;
  int max_npoints = 1024;
  R3Point *points = new R3Point [ max_npoints ];
  for (int i = 0; i < 10 * max_npoints; i++) {
    int image_index = (int) (RNRandomScalar() * configuration.NImages());
    RGBDImage *image = configuration.Image(image_index);
    double x = RNRandomScalar() * image->NPixels(RN_X);
    double y = RNRandomScalar() * image->NPixels(RN_Y);
    R3Point world_position;
    if (!RGBDTransformImageToWorld(R2Point(x, y), world_position, image)) continue;
    R2Point viewport_position = viewer.ViewportPoint(world_position);
    if (!R2Contains(rubber_box, viewport_position)) continue;
    points[npoints++] = world_position;
    if (npoints >= max_npoints) break;
  }
  
  // Check number of points
  if (npoints < 3) {
    printf("Did not find enough points inside box -- could not create surface\n");
    delete [] points;
    fflush(stdout);
    return 0;
  }
  
  // Compute centroid and principle axes of points
  R3Point centroid = R3Centroid(npoints, points);
  R3Triad axes = R3PrincipleAxes(centroid, npoints, points);
  if (axes[2].Dot(viewer.Camera().Towards()) > 0) {
    axes = R3Triad(axes[0], -axes[1], -axes[2]);
  }
  
  // Compute axis vectors
  R3Vector normal = axes[2]; normal.Normalize();
  R3Vector up = viewer.Camera().Up();
  R3Vector right = normal % up; right.Normalize();
  up = right % normal; up.Normalize();
  
  // Compute radii of points
  RNScalar radius[2] = { 0, 0 };
  for (int i = 0; i < npoints; i++) {
    RNScalar dx = fabs((points[i] - centroid).Dot(right));
    RNScalar dy = fabs((points[i] - centroid).Dot(up));
    if (dx > radius[0]) radius[0] = dx;
    if (dy > radius[1]) radius[1] = dy;
  }

  // Delete points
  delete [] points;

  // Create surface
  R3Rectangle *rectangle = new R3Rectangle(centroid, right, up, radius[0], radius[1]);
  RGBDSurface *surface = new RGBDSurface(NULL, rectangle, texel_spacing);
  if (!surface) {
    printf("Ran out of memory -- could not create surface\n");
    fflush(stdout);
    return 0;
  }

  // Insert surface into configuration
  configuration.InsertSurface(surface);

  // Print message
  printf("Created surface %d\n", configuration.NSurfaces()-1);
  fflush(stdout);

  // Return success
  return 1;
}

// Assembly:
subq $0x348, %rsp            # imm = 0x348
leaq 0x2148ea(%rip), %rsi    # 0x23f998
leaq 0x318(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x117960
movq 0xe0(%rsp), %rdi
leaq 0x210bbe(%rip), %rsi    # 0x23bc90
callq 0x1189f0
jmp 0x2b0d9
leaq 0x210bc0(%rip), %rsi    # 0x23bca0
leaq 0x318(%rsp), %rdi
callq 0x1189f0
jmp 0x2b0ef
leaq 0x318(%rsp), %rdi
callq 0x2f340
movsd %xmm0, 0xd8(%rsp)
jmp 0x2b107
movsd 0xd8(%rsp), %xmm1
movsd 0x19bf50(%rip), %xmm0   # 0x1c7068
ucomisd %xmm1, %xmm0
ja 0x2b14d
leaq 0x318(%rsp), %rdi
callq 0x2f360
movsd %xmm0, 0xd0(%rsp)
jmp 0x2b136
movsd 0xd0(%rsp), %xmm1
movsd 0x19bf21(%rip), %xmm0   # 0x1c7068
ucomisd %xmm1, %xmm0
jbe 0x2b1a2
leaq 0x19c2b0(%rip), %rdi    # 0x1c7404
xorl %eax, %eax
callq 0x24090
jmp 0x2b15d
movq 0x209e2c(%rip), %rax    # 0x234f90
movq (%rax), %rdi
callq 0x24c20
jmp 0x2b16e
movl $0x0, 0x344(%rsp)
movl $0x1, 0x308(%rsp)
jmp 0x2ba67
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x310(%rsp)
movl %eax, 0x30c(%rsp)
jmp 0x2ba83
movl $0x0, 0x304(%rsp)
movl $0x400, 0x300(%rsp) # imm = 0x400
movslq 0x300(%rsp), %rax
movq %rax, 0xb8(%rsp)
movl $0x18, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
movq %rdi, 0xc0(%rsp)
callq 0x24040
movq %rax, 0xc8(%rsp)
jmp 0x2b1f5
movq 0xb8(%rsp), %rax
cmpq $0x0, %rax
je 0x2b265
movq 0xc8(%rsp), %rax
movq 0xb8(%rsp), %rcx
imulq $0x18, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0xa8(%rsp)
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0xed1a0
jmp 0x2b244
movq 0xa8(%rsp), %rcx
movq 0xa0(%rsp), %rax
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, 0xb0(%rsp)
jne 0x2b22d
movq 0xc8(%rsp), %rax
movq %rax, 0x2f8(%rsp)
movl $0x0, 0x2f4(%rsp)
movl 0x2f4(%rsp), %eax
imull $0xa, 0x300(%rsp), %ecx
cmpl %ecx, %eax
jge 0x2b4b3
callq 0x12b130
movsd %xmm0, 0x98(%rsp)
jmp 0x2b2a7
leaq 0x210932(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, 0x94(%rsp)
jmp 0x2b2bc
movsd 0x98(%rsp), %xmm0
movl 0x94(%rsp), %eax
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x2f0(%rsp)
movl 0x2f0(%rsp), %esi
leaq 0x2108f3(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x88(%rsp)
jmp 0x2b2fc
movq 0x88(%rsp), %rax
movq %rax, 0x2e8(%rsp)
callq 0x12b130
movsd %xmm0, 0x80(%rsp)
jmp 0x2b31c
movq 0x2e8(%rsp), %rdi
xorl %esi, %esi
callq 0x2ed50
movsd 0x80(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x2e0(%rsp)
callq 0x12b130
movsd %xmm0, 0x78(%rsp)
jmp 0x2b352
movq 0x2e8(%rsp), %rdi
movl $0x1, %esi
callq 0x2ed50
movsd 0x78(%rsp), %xmm0
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x2d8(%rsp)
leaq 0x2c0(%rsp), %rdi
callq 0xed1a0
jmp 0x2b38a
movsd 0x2e0(%rsp), %xmm0
movsd 0x2d8(%rsp), %xmm1
leaq 0x2b0(%rsp), %rdi
callq 0x11d5f0
jmp 0x2b3ab
movq 0x2e8(%rsp), %rdx
leaq 0x2b0(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0x300a0
movl %eax, 0x74(%rsp)
jmp 0x2b3ce
movl 0x74(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x2b3e0
jmp 0x2b413
jmp 0x2b49d
movq 0xc0(%rsp), %rsi
movq 0xc8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x310(%rsp)
movl %eax, 0x30c(%rsp)
callq 0x254b0
jmp 0x2ba83
leaq 0x2108c6(%rip), %rsi    # 0x23bce0
leaq 0x2a0(%rsp), %rdi
leaq 0x2c0(%rsp), %rdx
callq 0x4c830
jmp 0x2b431
leaq 0x318(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0xfbf20
movl %eax, 0x70(%rsp)
jmp 0x2b44c
movl 0x70(%rsp), %eax
cmpl $0x0, %eax
jne 0x2b457
jmp 0x2b49d
movq 0x2f8(%rsp), %rax
movslq 0x304(%rsp), %rcx
movl %ecx, %edx
incl %edx
movl %edx, 0x304(%rsp)
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0xed840
jmp 0x2b489
movl 0x304(%rsp), %eax
cmpl 0x300(%rsp), %eax
jl 0x2b49b
jmp 0x2b4b3
jmp 0x2b49d
movl 0x2f4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2f4(%rsp)
jmp 0x2b280
cmpl $0x3, 0x304(%rsp)
jge 0x2b516
leaq 0x19bf6e(%rip), %rdi    # 0x1c7432
xorl %eax, %eax
callq 0x24090
jmp 0x2b4cd
movq 0x2f8(%rsp), %rax
movq %rax, 0x68(%rsp)
cmpq $0x0, %rax
je 0x2b4ea
movq 0x68(%rsp), %rdi
callq 0x24dd0
movq 0x209a9f(%rip), %rax    # 0x234f90
movq (%rax), %rdi
callq 0x24c20
jmp 0x2b4fb
movl $0x0, 0x344(%rsp)
movl $0x1, 0x308(%rsp)
jmp 0x2ba67
movl 0x304(%rsp), %esi
movq 0x2f8(%rsp), %rdx
xorl %eax, %eax
movl %eax, %ecx
leaq 0x288(%rsp), %rdi
callq 0x9ddd0
jmp 0x2b538
movl 0x304(%rsp), %edx
movq 0x2f8(%rsp), %rcx
xorl %eax, %eax
movl %eax, %r9d
leaq 0x240(%rsp), %rdi
leaq 0x288(%rsp), %rsi
movq %r9, %r8
callq 0x9de90
jmp 0x2b566
leaq 0x240(%rsp), %rdi
movl $0x2, %esi
callq 0x2f380
movq %rax, 0x60(%rsp)
jmp 0x2b57f
leaq 0x21075a(%rip), %rdi    # 0x23bce0
callq 0x2e900
movq %rax, %rsi
leaq 0x228(%rsp), %rdi
callq 0x2ec10
jmp 0x2b59d
movq 0x60(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0xee920
movsd %xmm0, 0x58(%rsp)
jmp 0x2b5b7
movsd 0x58(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2b677
leaq 0x240(%rsp), %rdi
xorl %esi, %esi
callq 0x2f380
movq %rax, 0x50(%rsp)
jmp 0x2b5e0
leaq 0x240(%rsp), %rdi
movl $0x1, %esi
callq 0x2f380
movq %rax, 0x48(%rsp)
jmp 0x2b5f9
movq 0x48(%rsp), %rsi
leaq 0x1c8(%rsp), %rdi
callq 0xef600
jmp 0x2b60d
leaq 0x240(%rsp), %rdi
movl $0x2, %esi
callq 0x2f380
movq %rax, 0x40(%rsp)
jmp 0x2b626
movq 0x40(%rsp), %rsi
leaq 0x1b0(%rsp), %rdi
callq 0xef600
jmp 0x2b63a
movq 0x50(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
leaq 0x1c8(%rsp), %rdx
leaq 0x1b0(%rsp), %rcx
callq 0xe3bc0
jmp 0x2b65e
leaq 0x240(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x2f3a0
jmp 0x2b675
jmp 0x2b677
leaq 0x240(%rsp), %rdi
movl $0x2, %esi
callq 0x2f380
movq %rax, 0x38(%rsp)
jmp 0x2b690
movq 0x38(%rsp), %rsi
leaq 0x198(%rsp), %rdi
callq 0xee350
jmp 0x2b6a4
leaq 0x198(%rsp), %rdi
callq 0xeea70
jmp 0x2b6b3
leaq 0x210626(%rip), %rdi    # 0x23bce0
callq 0x2e900
movq %rax, %rdi
callq 0x2ec90
movq %rax, 0x30(%rsp)
jmp 0x2b6ce
movq 0x30(%rsp), %rsi
leaq 0x180(%rsp), %rdi
callq 0xee350
jmp 0x2b6e2
leaq 0x168(%rsp), %rdi
leaq 0x198(%rsp), %rsi
leaq 0x180(%rsp), %rdx
callq 0xef150
jmp 0x2b701
leaq 0x168(%rsp), %rdi
callq 0xeea70
jmp 0x2b710
leaq 0x150(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x198(%rsp), %rdx
callq 0xef150
jmp 0x2b72f
leaq 0x180(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0xeefd0
jmp 0x2b746
leaq 0x180(%rsp), %rdi
callq 0xeea70
jmp 0x2b755
leaq 0x140(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x244e0
movl $0x0, 0x13c(%rsp)
movl 0x13c(%rsp), %eax
cmpl 0x304(%rsp), %eax
jge 0x2b8b8
movq 0x2f8(%rsp), %rax
movslq 0x13c(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0x118(%rsp), %rdi
leaq 0x288(%rsp), %rdx
callq 0xed510
jmp 0x2b7b7
leaq 0x118(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0xee920
movsd %xmm0, 0x28(%rsp)
jmp 0x2b7d4
movsd 0x28(%rsp), %xmm0
movaps 0x19b8cf(%rip), %xmm1   # 0x1c70b0
pand %xmm1, %xmm0
movlpd %xmm0, 0x130(%rsp)
movq 0x2f8(%rsp), %rax
movslq 0x13c(%rsp), %rcx
leaq (%rcx,%rcx,2), %rcx
leaq (%rax,%rcx,8), %rsi
leaq 0xf8(%rsp), %rdi
leaq 0x288(%rsp), %rdx
callq 0xed510
jmp 0x2b81d
leaq 0xf8(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0xee920
movsd %xmm0, 0x20(%rsp)
jmp 0x2b83a
movsd 0x20(%rsp), %xmm0
movaps 0x19b869(%rip), %xmm1   # 0x1c70b0
pand %xmm1, %xmm0
movsd %xmm0, 0x110(%rsp)
movsd 0x130(%rsp), %xmm0
ucomisd 0x140(%rsp), %xmm0
jbe 0x2b87a
movsd 0x130(%rsp), %xmm0
movsd %xmm0, 0x140(%rsp)
movsd 0x110(%rsp), %xmm0
ucomisd 0x148(%rsp), %xmm0
jbe 0x2b8a0
movsd 0x110(%rsp), %xmm0
movsd %xmm0, 0x148(%rsp)
jmp 0x2b8a2
movl 0x13c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x13c(%rsp)
jmp 0x2b774
movq 0x2f8(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x2b8d5
movq 0x18(%rsp), %rdi
callq 0x24dd0
movl $0x78, %edi
callq 0x24a00
movq %rax, 0x10(%rsp)
jmp 0x2b8e6
movq 0x10(%rsp), %rdi
movsd 0x140(%rsp), %xmm0
movsd 0x148(%rsp), %xmm1
leaq 0x288(%rsp), %rsi
leaq 0x168(%rsp), %rdx
leaq 0x180(%rsp), %rcx
callq 0xcad90
jmp 0x2b91c
movq 0x10(%rsp), %rax
movq %rax, 0xf0(%rsp)
movl $0xa0, %edi
callq 0x24a00
movq %rax, 0x8(%rsp)
jmp 0x2b93a
movq 0x8(%rsp), %rdi
movq 0xf0(%rsp), %rdx
movsd 0x210539(%rip), %xmm0   # 0x23be88
xorl %eax, %eax
movl %eax, %esi
callq 0x38dc0
jmp 0x2b95a
movq 0x8(%rsp), %rax
movq %rax, 0xe8(%rsp)
cmpq $0x0, 0xe8(%rsp)
jne 0x2ba02
leaq 0x19baf8(%rip), %rdi    # 0x1c7475
xorl %eax, %eax
callq 0x24090
jmp 0x2b986
movq 0x209603(%rip), %rax    # 0x234f90
movq (%rax), %rdi
callq 0x24c20
jmp 0x2b997
movl $0x0, 0x344(%rsp)
movl $0x1, 0x308(%rsp)
jmp 0x2ba67
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x310(%rsp)
movl %eax, 0x30c(%rsp)
movl $0x78, %esi
callq 0x24a20
jmp 0x2ba83
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x310(%rsp)
movl %eax, 0x30c(%rsp)
movl $0xa0, %esi
callq 0x24a20
jmp 0x2ba83
movq 0xe8(%rsp), %rsi
leaq 0x2101cf(%rip), %rdi    # 0x23bbe0
callq 0x30750
jmp 0x2ba18
leaq 0x2101c1(%rip), %rdi    # 0x23bbe0
callq 0x2ecd0
movl %eax, 0x4(%rsp)
jmp 0x2ba2a
movl 0x4(%rsp), %esi
decl %esi
leaq 0x19ba6d(%rip), %rdi    # 0x1c74a4
xorl %eax, %eax
callq 0x24090
jmp 0x2ba40
movq 0x209549(%rip), %rax    # 0x234f90
movq (%rax), %rdi
callq 0x24c20
jmp 0x2ba51
movl $0x1, 0x344(%rsp)
movl $0x1, 0x308(%rsp)
leaq 0x318(%rsp), %rdi
callq 0x2f000
movl 0x344(%rsp), %eax
addq $0x348, %rsp            # imm = 0x348
retq
leaq 0x318(%rsp), %rdi
callq 0x2f000
movq 0x310(%rsp), %rdi
callq 0x252b0
nopl (%rax)