// File: tomfunkhouser[P]gaps/apps/confview/confview.cpp
// Function: CheckVisibility(gaps::RGBDImage*, gaps::R3Point const&)
static int
CheckVisibility(RGBDImage *image, const R3Point& world_position)
{
  // Check world position
  if (world_position == R3unknown_point) return 1;

  // Get/check point depth
  R3Vector vector = world_position - image->WorldViewpoint();
  RNScalar point_depth = vector.Dot(image->WorldTowards());
  if (RNIsNegativeOrZero(point_depth)) return 0;

  // Get/check projection into image
  R2Point image_position;
  if (!image->TransformWorldToImage(world_position, image_position)) return 0;

  // Get/check image depth channel
  R2Grid *depth_channel = image->DepthChannel();
  if (depth_channel) {
    // Get/check image depth
    int image_ix = image_position.X() + 0.5;
    int image_iy = image_position.Y() + 0.5;
    if ((image_ix < 0) || (image_ix > image->NPixels(RN_X))) return 0;
    if ((image_iy < 0) || (image_iy > image->NPixels(RN_Y))) return 0;
    RNScalar image_depth = image->PixelDepth(image_ix, image_iy);
    if ((image_depth == R2_GRID_UNKNOWN_VALUE) || (image_depth == 0)) return 1;

    // If depth is not within 10% of image depth, then probably not 
    if (image_depth < 0.9 * point_depth) return 0;
    if (image_depth > 1.1 * point_depth) return 0;
  }

  // Passed all tests
  return 1;
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0x98(%rsp)
movq %rsi, 0x90(%rsp)
movq 0x90(%rsp), %rdi
leaq 0x210d82(%rip), %rsi    # 0x23f418
callq 0xed340
cmpl $0x0, %eax
je 0x2e6b0
movl $0x1, 0xa4(%rsp)
jmp 0x2e8eb
movq 0x90(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x98(%rsp), %rsi
leaq 0x60(%rsp), %rdi
callq 0x2eaa0
movq 0x10(%rsp), %rsi
leaq 0x78(%rsp), %rdi
leaq 0x60(%rsp), %rdx
callq 0xed510
movq 0x98(%rsp), %rsi
leaq 0x40(%rsp), %rdi
callq 0x2eb20
leaq 0x78(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0xee920
movsd %xmm0, 0x58(%rsp)
movsd 0x58(%rsp), %xmm0
leaq 0x207bd1(%rip), %rax    # 0x2362e8
movsd (%rax), %xmm1
callq 0x2ed00
cmpl $0x0, %eax
je 0x2e735
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
leaq 0x30(%rsp), %rdi
callq 0x11d5e0
movq 0x98(%rsp), %rdi
movq 0x90(%rsp), %rsi
movq (%rdi), %rax
leaq 0x30(%rsp), %rdx
callq *0xb0(%rax)
cmpl $0x0, %eax
jne 0x2e772
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
movq 0x98(%rsp), %rdi
callq 0x2ea50
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x2e8e0
leaq 0x30(%rsp), %rdi
callq 0x2ed30
movsd 0x19888e(%rip), %xmm1   # 0x1c7030
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x24(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x2ed40
movsd 0x198870(%rip), %xmm1   # 0x1c7030
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x20(%rsp)
cmpl $0x0, 0x24(%rsp)
jl 0x2e7f4
movl 0x24(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x98(%rsp), %rdi
xorl %esi, %esi
callq 0x2ed50
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jle 0x2e804
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
cmpl $0x0, 0x20(%rsp)
jl 0x2e82f
movl 0x20(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x98(%rsp), %rdi
movl $0x1, %esi
callq 0x2ed50
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jle 0x2e83f
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
movq 0x98(%rsp), %rdi
movl 0x24(%rsp), %esi
movl 0x20(%rsp), %edx
callq 0x2ed90
movsd %xmm0, 0x18(%rsp)
movsd 0x18(%rsp), %xmm0
movsd 0x198828(%rip), %xmm1   # 0x1c7090
ucomisd %xmm1, %xmm0
jne 0x2e872
jp 0x2e872
jmp 0x2e883
movsd 0x18(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x2e890
jp 0x2e890
movl $0x1, 0xa4(%rsp)
jmp 0x2e8eb
movsd 0x18(%rsp), %xmm1
movsd 0x1987b2(%rip), %xmm0   # 0x1c7050
mulsd 0x58(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2e8b7
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
movsd 0x18(%rsp), %xmm0
movsd 0x198783(%rip), %xmm1   # 0x1c7048
mulsd 0x58(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2e8de
movl $0x0, 0xa4(%rsp)
jmp 0x2e8eb
jmp 0x2e8e0
movl $0x1, 0xa4(%rsp)
movl 0xa4(%rsp), %eax
addq $0xa8, %rsp
retq
nopw (%rax,%rax)