// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::GridValue(double, double) const
RNScalar R2Grid::
GridValue(RNScalar x, RNScalar y) const
{
  // Check if within bounds
  if ((x < 0) || (x > grid_resolution[0]-1)) return 0.0;
  if ((y < 0) || (y > grid_resolution[1]-1)) return 0.0;

  // Bilinear interpolation
  int ix1 = (int) x;
  int iy1 = (int) y;
  int ix2 = ix1 + 1;
  int iy2 = iy1 + 1;
  if (ix2 >= grid_resolution[0]) ix2 = ix1;
  if (iy2 >= grid_resolution[1]) iy2 = iy1;
  RNScalar dx = x - ix1;
  RNScalar dy = y - iy1;
  RNScalar value11 = GridValue(ix1, iy1);
  RNScalar value12 = GridValue(ix1, iy2);
  RNScalar value21 = GridValue(ix2, iy1);
  RNScalar value22 = GridValue(ix2, iy2);
  RNScalar weight11 = (1.0-dx) * (1.0-dy);
  RNScalar weight12 = (1.0-dx) * dy;
  RNScalar weight21 = dx * (1.0-dy);
  RNScalar weight22 = dx * dy;
  RNScalar value = 0;
  RNScalar weight = 0;
  if (value11 != R2_GRID_UNKNOWN_VALUE) { value += weight11 * value11; weight += weight11; }
  if (value12 != R2_GRID_UNKNOWN_VALUE) { value += weight12 * value12; weight += weight12; }
  if (value21 != R2_GRID_UNKNOWN_VALUE) { value += weight21 * value21; weight += weight21; }
  if (value22 != R2_GRID_UNKNOWN_VALUE) { value += weight22 * value22; weight += weight22; }
  if (weight == 0) return R2_GRID_UNKNOWN_VALUE;
  return value / weight;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movsd %xmm0, 0x80(%rsp)
movsd %xmm1, 0x78(%rsp)
movq 0x88(%rsp), %rax
movq %rax, (%rsp)
xorps %xmm0, %xmm0
ucomisd 0x80(%rsp), %xmm0
ja 0xa8448
movq (%rsp), %rax
movsd 0x80(%rsp), %xmm0
movl 0xc0(%rax), %eax
subl $0x1, %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa8459
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0xa875d
xorps %xmm0, %xmm0
ucomisd 0x78(%rsp), %xmm0
ja 0xa8481
movq (%rsp), %rax
movsd 0x78(%rsp), %xmm0
movl 0xc4(%rax), %eax
subl $0x1, %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xa8492
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0xa875d
movq (%rsp), %rcx
cvttsd2si 0x80(%rsp), %eax
movl %eax, 0x74(%rsp)
cvttsd2si 0x78(%rsp), %eax
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
movl 0x70(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x68(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0xc0(%rcx), %eax
jl 0xa84d7
movl 0x74(%rsp), %eax
movl %eax, 0x6c(%rsp)
movq (%rsp), %rcx
movl 0x68(%rsp), %eax
cmpl 0xc4(%rcx), %eax
jl 0xa84ef
movl 0x70(%rsp), %eax
movl %eax, 0x68(%rsp)
movq (%rsp), %rdi
movsd 0x80(%rsp), %xmm0
cvtsi2sdl 0x74(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x78(%rsp), %xmm0
cvtsi2sdl 0x70(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
movl 0x74(%rsp), %esi
movl 0x70(%rsp), %edx
callq 0xb92a0
movq (%rsp), %rdi
movsd %xmm0, 0x50(%rsp)
movl 0x74(%rsp), %esi
movl 0x68(%rsp), %edx
callq 0xb92a0
movq (%rsp), %rdi
movsd %xmm0, 0x48(%rsp)
movl 0x6c(%rsp), %esi
movl 0x70(%rsp), %edx
callq 0xb92a0
movq (%rsp), %rdi
movsd %xmm0, 0x40(%rsp)
movl 0x6c(%rsp), %esi
movl 0x68(%rsp), %edx
callq 0xb92a0
movsd %xmm0, 0x38(%rsp)
movsd 0x8aa86(%rip), %xmm0    # 0x133008
subsd 0x60(%rsp), %xmm0
movsd 0x8aa78(%rip), %xmm1    # 0x133008
subsd 0x58(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x8aa60(%rip), %xmm0    # 0x133008
subsd 0x60(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x60(%rsp), %xmm0
movsd 0x8aa40(%rip), %xmm1    # 0x133008
subsd 0x58(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x60(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x10(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x50(%rsp), %xmm0
movsd 0x8b8a6(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa8614
jp 0xa8614
jmp 0xa8646
movsd 0x30(%rsp), %xmm0
movsd 0x50(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x30(%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x8b85c(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa865e
jp 0xa865e
jmp 0xa8690
movsd 0x28(%rsp), %xmm0
movsd 0x48(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x28(%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x40(%rsp), %xmm0
movsd 0x8b812(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa86a8
jp 0xa86a8
jmp 0xa86da
movsd 0x20(%rsp), %xmm0
movsd 0x40(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x20(%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x38(%rsp), %xmm0
movsd 0x8b7c8(%rip), %xmm1    # 0x133eb0
ucomisd %xmm1, %xmm0
jne 0xa86f2
jp 0xa86f2
jmp 0xa8724
movsd 0x18(%rsp), %xmm0
movsd 0x38(%rsp), %xmm2
movsd 0x10(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x18(%rsp), %xmm0
addsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa8748
jp 0xa8748
movsd 0x8b773(%rip), %xmm0    # 0x133eb0
movsd %xmm0, 0x90(%rsp)
jmp 0xa875d
movsd 0x10(%rsp), %xmm0
divsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
movsd 0x90(%rsp), %xmm0
addq $0x98, %rsp
retq
nop