// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelConstraint.cpp
// Function: gaps::R3SurfelViewConstraint::Check(gaps::R3Point const&) const
int R3SurfelViewConstraint::
Check(const R3Point& point) const
{
  // Transform into camera coordinates (z is negative)
  R3Point camera_point = world_to_camera * point;
  RNScalar depth = -camera_point.Z();

  // Check if z is too near or far
  if (depth < neardist) return R3_SURFEL_CONSTRAINT_FAIL;
  if (depth > fardist) return R3_SURFEL_CONSTRAINT_FAIL;

  // Compute image position
  int ix = (int) (cx + fx*camera_point.X()/depth);
  int iy = (int) (cy + fy*camera_point.Y()/depth);

  // Check image position
  if (must_be_inside_frustum) {
    // Return fail if outside
    if ((ix < 0) || (ix >= w)) return R3_SURFEL_CONSTRAINT_FAIL;
    if ((iy < 0) || (iy >= h)) return R3_SURFEL_CONSTRAINT_FAIL;
  }
  else {
    // Snap to closest pixel on boundary
    if (ix < 0) ix = 0;
    if (ix >= w) ix = w-1;
    if (iy < 0) iy = 0;
    if (iy >= h) iy = h-1;
  }

  // Check if point is masked
  if (image_mask) {
    RNScalar mask_value = image_mask->GridValue(ix, iy);
    if (mask_value == R2_GRID_UNKNOWN_VALUE) return R3_SURFEL_CONSTRAINT_FAIL;
    if (mask_value == 0.0) return R3_SURFEL_CONSTRAINT_FAIL;
  }
  
  // Passed all tests
  return R3_SURFEL_CONSTRAINT_PASS;
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x68(%rsp)
movq %rsi, 0x60(%rsp)
movq 0x68(%rsp), %rsi
movq %rsi, 0x28(%rsp)
addq $0x150, %rsi            # imm = 0x150
movq 0x60(%rsp), %rdx
leaq 0x48(%rsp), %rdi
callq 0xdc230
leaq 0x48(%rsp), %rdi
callq 0x187a0
movq 0x28(%rsp), %rax
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x40(%rsp), %xmm1
movsd 0x1f8(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x5314b
movl $0x0, 0x74(%rsp)
jmp 0x53340
movq 0x28(%rsp), %rax
movsd 0x40(%rsp), %xmm0
ucomisd 0x200(%rax), %xmm0
jbe 0x5316d
movl $0x0, 0x74(%rsp)
jmp 0x53340
movq 0x28(%rsp), %rax
movsd 0x1e8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x1d8(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x187b0
movsd 0x8(%rsp), %xmm1
movq 0x28(%rsp), %rax
movaps %xmm0, %xmm2
movsd 0x10(%rsp), %xmm0
mulsd %xmm2, %xmm1
divsd 0x40(%rsp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, 0x3c(%rsp)
movsd 0x1f0(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x1e0(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x187c0
movsd 0x18(%rsp), %xmm1
movq 0x28(%rsp), %rax
movaps %xmm0, %xmm2
movsd 0x20(%rsp), %xmm0
mulsd %xmm2, %xmm1
divsd 0x40(%rsp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, 0x38(%rsp)
cmpl $0x0, 0x210(%rax)
je 0x53267
cmpl $0x0, 0x3c(%rsp)
jl 0x53233
movq 0x28(%rsp), %rcx
movl 0x3c(%rsp), %eax
cmpl 0x1d0(%rcx), %eax
jl 0x53240
movl $0x0, 0x74(%rsp)
jmp 0x53340
cmpl $0x0, 0x38(%rsp)
jl 0x53258
movq 0x28(%rsp), %rcx
movl 0x38(%rsp), %eax
cmpl 0x1d4(%rcx), %eax
jl 0x53265
movl $0x0, 0x74(%rsp)
jmp 0x53340
jmp 0x532cd
cmpl $0x0, 0x3c(%rsp)
jge 0x53276
movl $0x0, 0x3c(%rsp)
movq 0x28(%rsp), %rcx
movl 0x3c(%rsp), %eax
cmpl 0x1d0(%rcx), %eax
jl 0x53299
movq 0x28(%rsp), %rax
movl 0x1d0(%rax), %eax
subl $0x1, %eax
movl %eax, 0x3c(%rsp)
cmpl $0x0, 0x38(%rsp)
jge 0x532a8
movl $0x0, 0x38(%rsp)
movq 0x28(%rsp), %rcx
movl 0x38(%rsp), %eax
cmpl 0x1d4(%rcx), %eax
jl 0x532cb
movq 0x28(%rsp), %rax
movl 0x1d4(%rax), %eax
subl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x532cd
movq 0x28(%rsp), %rax
cmpq $0x0, 0x208(%rax)
je 0x53338
movq 0x28(%rsp), %rax
movq 0x208(%rax), %rdi
movl 0x3c(%rsp), %esi
movl 0x38(%rsp), %edx
callq 0x45350
movsd %xmm0, 0x30(%rsp)
movsd 0x30(%rsp), %xmm0
movsd 0x1520c7(%rip), %xmm1   # 0x1a53d0
ucomisd %xmm1, %xmm0
jne 0x5331b
jp 0x5331b
movl $0x0, 0x74(%rsp)
jmp 0x53340
movsd 0x30(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x53336
jp 0x53336
movl $0x0, 0x74(%rsp)
jmp 0x53340
jmp 0x53338
movl $0x2, 0x74(%rsp)
movl 0x74(%rsp), %eax
addq $0x78, %rsp
retq
nopl (%rax)