// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelConstraint.cpp
// Function: gaps::R3SurfelPlanarGridConstraint::Check(gaps::R3Point const&) const
int R3SurfelPlanarGridConstraint::
Check(const R3Point& point) const
{
  // Check distance from point to plane
  RNLength offplane_distance = R3Distance(grid->Plane(), point);
  if (offplane_distance > max_offplane_distance) return R3_SURFEL_CONSTRAINT_FAIL;

  // Get grid value
  RNScalar grid_value = grid_operand;
  if (grid_value_type != R3_SURFEL_CONSTRAINT_OPERAND) grid_value = grid->WorldValue(point);
  if (grid_value == R2_GRID_UNKNOWN_VALUE) return R3_SURFEL_CONSTRAINT_FAIL;

  // Get surfel value
  RNScalar surfel_value = surfel_operand;
  if (surfel_value_type == R3_SURFEL_CONSTRAINT_X) surfel_value = point.X();
  else if (surfel_value_type == R3_SURFEL_CONSTRAINT_Y) surfel_value = point.Y();
  else if (surfel_value_type == R3_SURFEL_CONSTRAINT_Z) surfel_value = point.Z();

  // Compare values
  switch (comparison_type) {
  case R3_SURFEL_CONSTRAINT_NOT_EQUAL: 
    return (RNIsNotEqual(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  case R3_SURFEL_CONSTRAINT_EQUAL: 
    return (RNIsEqual(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  case R3_SURFEL_CONSTRAINT_GREATER: 
    return (RNIsGreater(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  case R3_SURFEL_CONSTRAINT_GREATER_OR_EQUAL: 
    return (RNIsGreaterOrEqual(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  case R3_SURFEL_CONSTRAINT_LESS: 
    return (RNIsLess(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  case R3_SURFEL_CONSTRAINT_LESS_OR_EQUAL: 
    return (RNIsLessOrEqual(surfel_value, grid_value, epsilon)) ?
      R3_SURFEL_CONSTRAINT_PASS : R3_SURFEL_CONSTRAINT_FAIL;
  }

  // Did not pass test
  return R3_SURFEL_CONSTRAINT_FAIL;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x38(%rsp)
movq %rsi, 0x30(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x8(%rax), %rdi
callq 0x54840
movq %rax, %rdi
movq 0x30(%rsp), %rsi
callq 0x444d0
movq 0x10(%rsp), %rax
movsd %xmm0, 0x28(%rsp)
movsd 0x28(%rsp), %xmm0
ucomisd 0x10(%rax), %xmm0
jbe 0x51de3
movl $0x0, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x30(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
cmpl $0x0, 0x20(%rax)
je 0x51e12
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq 0x30(%rsp), %rsi
callq 0x54870
movsd %xmm0, 0x20(%rsp)
movsd 0x20(%rsp), %xmm0
movsd 0x1535b0(%rip), %xmm1   # 0x1a53d0
ucomisd %xmm1, %xmm0
jne 0x51e35
jp 0x51e35
movl $0x0, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x28(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
cmpl $0x2, 0x1c(%rax)
jne 0x51e5d
movq 0x30(%rsp), %rdi
callq 0x187b0
movsd %xmm0, 0x18(%rsp)
jmp 0x51e99
movq 0x10(%rsp), %rax
cmpl $0x3, 0x1c(%rax)
jne 0x51e7a
movq 0x30(%rsp), %rdi
callq 0x187c0
movsd %xmm0, 0x18(%rsp)
jmp 0x51e97
movq 0x10(%rsp), %rax
cmpl $0x4, 0x1c(%rax)
jne 0x51e95
movq 0x30(%rsp), %rdi
callq 0x187a0
movsd %xmm0, 0x18(%rsp)
jmp 0x51e97
jmp 0x51e99
movq 0x10(%rsp), %rax
movl 0x18(%rax), %eax
movq %rax, 0x8(%rsp)
subq $0x5, %rax
ja 0x51fee
movq 0x8(%rsp), %rax
leaq 0x153534(%rip), %rcx    # 0x1a53f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x547b0
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x4fe80
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x44e60
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x547e0
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x44e90
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movq 0x10(%rsp), %rax
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x38(%rax), %xmm2
callq 0x54810
movl %eax, %edx
xorl %eax, %eax
movl $0x2, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, 0x44(%rsp)
jmp 0x51ff6
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nop