// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::GridValue(double, double, double) const
RNScalar R3Grid::
GridValue(RNScalar x, RNScalar y, RNScalar z) 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;
  if ((z < 0) || (z > grid_resolution[2]-1)) return 0.0;

  // Trilinear interpolation
  int ix1 = (int) x;
  int iy1 = (int) y;
  int iz1 = (int) z;
  int ix2 = ix1 + 1;
  int iy2 = iy1 + 1;
  int iz2 = iz1 + 1;
  if (ix2 >= grid_resolution[0]) ix2 = ix1;
  if (iy2 >= grid_resolution[1]) iy2 = iy1;
  if (iz2 >= grid_resolution[2]) iz2 = iz1;
  RNScalar dx = x - ix1;
  RNScalar dy = y - iy1;
  RNScalar dz = z - iz1;
  RNScalar value = 0.0;
  value += GridValue(ix1, iy1, iz1) * (1.0-dx) * (1.0-dy) * (1.0-dz);
  value += GridValue(ix1, iy1, iz2) * (1.0-dx) * (1.0-dy) * dz;
  value += GridValue(ix1, iy2, iz1) * (1.0-dx) * dy * (1.0-dz);
  value += GridValue(ix1, iy2, iz2) * (1.0-dx) * dy * dz;
  value += GridValue(ix2, iy1, iz1) * dx * (1.0-dy) * (1.0-dz);
  value += GridValue(ix2, iy1, iz2) * dx * (1.0-dy) * dz;
  value += GridValue(ix2, iy2, iz1) * dx * dy * (1.0-dz);
  value += GridValue(ix2, iy2, iz2) * dx * dy * dz;
  return value;
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x58(%rsp)
movsd %xmm0, 0x50(%rsp)
movsd %xmm1, 0x48(%rsp)
movsd %xmm2, 0x40(%rsp)
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
xorps %xmm0, %xmm0
ucomisd 0x50(%rsp), %xmm0
ja 0x56e9c
movq (%rsp), %rax
movsd 0x50(%rsp), %xmm0
movl 0x238(%rax), %eax
subl $0x1, %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x56eaa
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
jmp 0x5724c
xorps %xmm0, %xmm0
ucomisd 0x48(%rsp), %xmm0
ja 0x56ed2
movq (%rsp), %rax
movsd 0x48(%rsp), %xmm0
movl 0x23c(%rax), %eax
subl $0x1, %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x56ee0
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
jmp 0x5724c
xorps %xmm0, %xmm0
ucomisd 0x40(%rsp), %xmm0
ja 0x56f08
movq (%rsp), %rax
movsd 0x40(%rsp), %xmm0
movl 0x240(%rax), %eax
subl $0x1, %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x56f16
xorps %xmm0, %xmm0
movsd %xmm0, 0x60(%rsp)
jmp 0x5724c
movq (%rsp), %rcx
cvttsd2si 0x50(%rsp), %eax
movl %eax, 0x3c(%rsp)
cvttsd2si 0x48(%rsp), %eax
movl %eax, 0x38(%rsp)
cvttsd2si 0x40(%rsp), %eax
movl %eax, 0x34(%rsp)
movl 0x3c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x28(%rsp)
movl 0x30(%rsp), %eax
cmpl 0x238(%rcx), %eax
jl 0x56f6d
movl 0x3c(%rsp), %eax
movl %eax, 0x30(%rsp)
movq (%rsp), %rcx
movl 0x2c(%rsp), %eax
cmpl 0x23c(%rcx), %eax
jl 0x56f85
movl 0x38(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq (%rsp), %rcx
movl 0x28(%rsp), %eax
cmpl 0x240(%rcx), %eax
jl 0x56f9d
movl 0x34(%rsp), %eax
movl %eax, 0x28(%rsp)
movq (%rsp), %rdi
movsd 0x50(%rsp), %xmm0
cvtsi2sdl 0x3c(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x48(%rsp), %xmm0
cvtsi2sdl 0x38(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x40(%rsp), %xmm0
cvtsi2sdl 0x34(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x3c(%rsp), %esi
movl 0x38(%rsp), %edx
movl 0x34(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
movsd 0xdbfff(%rip), %xmm1    # 0x133008
subsd 0x20(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0xdbfed(%rip), %xmm1    # 0x133008
subsd 0x18(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0xdbfdb(%rip), %xmm2    # 0x133008
subsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x3c(%rsp), %esi
movl 0x38(%rsp), %edx
movl 0x28(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
movsd 0xdbfa4(%rip), %xmm1    # 0x133008
subsd 0x20(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0xdbf92(%rip), %xmm1    # 0x133008
subsd 0x18(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x3c(%rsp), %esi
movl 0x2c(%rsp), %edx
movl 0x34(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
movsd 0xdbf51(%rip), %xmm1    # 0x133008
subsd 0x20(%rsp), %xmm1
mulsd %xmm1, %xmm0
mulsd 0x18(%rsp), %xmm0
movsd 0xdbf39(%rip), %xmm2    # 0x133008
subsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x3c(%rsp), %esi
movl 0x2c(%rsp), %edx
movl 0x28(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
movsd 0xdbf02(%rip), %xmm1    # 0x133008
subsd 0x20(%rsp), %xmm1
mulsd %xmm1, %xmm0
mulsd 0x18(%rsp), %xmm0
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x30(%rsp), %esi
movl 0x38(%rsp), %edx
movl 0x34(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
mulsd 0x20(%rsp), %xmm0
movsd 0xdbeb5(%rip), %xmm1    # 0x133008
subsd 0x18(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0xdbea3(%rip), %xmm2    # 0x133008
subsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x30(%rsp), %esi
movl 0x38(%rsp), %edx
movl 0x28(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
mulsd 0x20(%rsp), %xmm0
movsd 0xdbe66(%rip), %xmm1    # 0x133008
subsd 0x18(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x30(%rsp), %esi
movl 0x2c(%rsp), %edx
movl 0x34(%rsp), %ecx
callq 0x6bad0
movq (%rsp), %rdi
mulsd 0x20(%rsp), %xmm0
mulsd 0x18(%rsp), %xmm0
movsd 0xdbe19(%rip), %xmm2    # 0x133008
subsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movl 0x30(%rsp), %esi
movl 0x2c(%rsp), %edx
movl 0x28(%rsp), %ecx
callq 0x6bad0
mulsd 0x20(%rsp), %xmm0
mulsd 0x18(%rsp), %xmm0
movsd 0x10(%rsp), %xmm2
movsd 0x8(%rsp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm0
addq $0x68, %rsp
retq
nopw (%rax,%rax)