// File: tomfunkhouser[P]gaps/apps/confview/confview.cpp
// Function: AlignWithAxes()
static void 
AlignWithAxes(void)
{
  // Check images and surfaces
  if (configuration.NImages() == 0) return;
  
  // Compute posz = average image up vector
  R3Vector posz = R3zero_vector;
  for (int i = 0; i < configuration.NImages(); i++) {
    RGBDImage *image = configuration.Image(i);
    posz += image->WorldUp();
  }

  // Compute origin and posy by averaging positions and normals of pixels
  int count = 0;
  R3Point origin = R3zero_point;
  R3Vector posy = R3zero_vector;
  for (int i = 0; i < configuration.NImages(); i++) {
    RGBDImage *image = configuration.Image(i);
    int ix = image->NPixels(RN_X)/2;
    int iy = image->NPixels(RN_Y)/2;
    R3Point world_position;
    if (RGBDTransformImageToWorld(R2Point(ix, iy), world_position, image)) {
      posy += -(image->PixelWorldNormal(ix, iy));
      origin += world_position;
      count++;
    }
  }

  // Compute averages
  if (count > 0) origin /= count;
  else return;

  // Compute orthogonal triad of axes
  posy.Normalize();
  posz.Normalize();
  R3Vector posx = posy % posz; posx.Normalize();
  posz = posx % posy; posz.Normalize();
  R3Triad axes(posx, posy, posz);
  
  // Compute transformation
  R3CoordSystem cs(origin, axes);
  R3Affine transformation(cs.InverseMatrix(), 0);

  // Apply transformation
  configuration.Transform(transformation);
}

// Assembly:
subq $0x3a8, %rsp            # imm = 0x3A8
leaq 0x20ff72(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
cmpl $0x0, %eax
jne 0x2bc7d
jmp 0x2bfdc
leaq 0x390(%rsp), %rdi
leaq 0x2137a4(%rip), %rsi    # 0x23f430
callq 0xee350
movl $0x0, 0x38c(%rsp)
movl 0x38c(%rsp), %eax
movl %eax, 0x48(%rsp)
leaq 0x20ff32(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, %ecx
movl 0x48(%rsp), %eax
cmpl %ecx, %eax
jge 0x2bd15
movl 0x38c(%rsp), %esi
leaq 0x20ff15(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x380(%rsp)
movq 0x380(%rsp), %rsi
leaq 0x368(%rsp), %rdi
callq 0x2eb70
leaq 0x390(%rsp), %rdi
leaq 0x368(%rsp), %rsi
callq 0xef240
movl 0x38c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38c(%rsp)
jmp 0x2bc9c
movl $0x0, 0x364(%rsp)
leaq 0x348(%rsp), %rdi
leaq 0x213611(%rip), %rsi    # 0x23f340
callq 0xed1f0
leaq 0x330(%rsp), %rdi
leaq 0x2136ed(%rip), %rsi    # 0x23f430
callq 0xee350
movl $0x0, 0x32c(%rsp)
movl 0x32c(%rsp), %eax
movl %eax, 0x44(%rsp)
leaq 0x20fe7b(%rip), %rdi    # 0x23bbe0
callq 0x2ea00
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jge 0x2beab
movl 0x32c(%rsp), %esi
leaq 0x20fe5a(%rip), %rdi    # 0x23bbe0
callq 0x2ea20
movq %rax, 0x320(%rsp)
movq 0x320(%rsp), %rdi
xorl %esi, %esi
callq 0x2ed50
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x31c(%rsp)
movq 0x320(%rsp), %rdi
movl $0x1, %esi
callq 0x2ed50
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, 0x318(%rsp)
leaq 0x300(%rsp), %rdi
callq 0xed1a0
cvtsi2sdl 0x31c(%rsp), %xmm0
cvtsi2sdl 0x318(%rsp), %xmm1
leaq 0x2f0(%rsp), %rdi
callq 0x11d5f0
movq 0x320(%rsp), %rdx
leaq 0x2f0(%rsp), %rdi
leaq 0x300(%rsp), %rsi
callq 0x300a0
cmpl $0x0, %eax
je 0x2be93
movq 0x320(%rsp), %rsi
movl 0x31c(%rsp), %edx
movl 0x318(%rsp), %ecx
leaq 0x2c0(%rsp), %rdi
callq 0x3e4c0
leaq 0x2d8(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0xef600
leaq 0x330(%rsp), %rdi
leaq 0x2d8(%rsp), %rsi
callq 0xef240
leaq 0x348(%rsp), %rdi
leaq 0x300(%rsp), %rsi
callq 0xede80
movl 0x364(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x364(%rsp)
jmp 0x2be95
movl 0x32c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x32c(%rsp)
jmp 0x2bd53
cmpl $0x0, 0x364(%rsp)
jle 0x2becd
cvtsi2sdl 0x364(%rsp), %xmm0
leaq 0x348(%rsp), %rdi
callq 0xedfc0
jmp 0x2bed2
jmp 0x2bfdc
leaq 0x330(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0xeea70
leaq 0x390(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0xeea70
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
leaq 0x2a8(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xef150
movq 0x8(%rsp), %rdi
callq 0xeea70
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
leaq 0x290(%rsp), %rdi
movq %rdi, (%rsp)
callq 0xef150
movq (%rsp), %rsi
movq 0x18(%rsp), %rdi
callq 0xeefd0
movq 0x18(%rsp), %rdi
callq 0xeea70
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rcx
leaq 0x248(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0xe3bc0
movq 0x20(%rsp), %rdx
leaq 0x1e8(%rsp), %rdi
movq %rdi, 0x28(%rsp)
leaq 0x348(%rsp), %rsi
callq 0xe34b0
movq 0x28(%rsp), %rsi
leaq 0x58(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xe3580
movq 0x30(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
xorl %edx, %edx
callq 0xe23c0
movq 0x38(%rsp), %rsi
leaq 0x20fc18(%rip), %rdi    # 0x23bbe0
callq 0x308b0
jmp 0x2bfcf
leaq 0xd8(%rsp), %rdi
callq 0xe2460
addq $0x3a8, %rsp            # imm = 0x3A8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0xe2460
movq 0x50(%rsp), %rdi
callq 0x252b0
nopl (%rax)