// File: tomfunkhouser[P]gaps/apps/gapsview/gapsview.cpp
// Function: DrawImageDepths(ImageData*, gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&, gaps::R3Vector const&, double, double, double)
static void
DrawImageDepths(ImageData *data, const R3Point& viewpoint,
  const R3Vector& towards, const R3Vector& right, const R3Vector& up,
  RNAngle xfov, RNAngle yfov, RNLength image_billboard_depth)
{
  // Check if drawing image depths
  if (!show_image_depths) return;

  // Check image data
  int w = data->image_width;
  int h = data->image_height;
  if (w == 0) return;
  if (h == 0) return;
  if (data->depth_image.XResolution() != w) return;
  if (data->depth_image.YResolution() != h) return;
  
  // Load texture
  LoadTexture(data);
  if (data->texture_id == 0) return;

  // Enable texture
  glBindTexture(GL_TEXTURE_2D, data->texture_id);
  glEnable(GL_TEXTURE_2D);
  glDisable(GL_LIGHTING);
  RNLoadRgb(1, 1, 1);

  // Check if have ray images
  if ((data->ray_origin_images[0].XResolution() == w) &&
      (data->ray_origin_images[1].XResolution() == w) &&
      (data->ray_origin_images[2].XResolution() == w) && 
      (data->ray_origin_images[0].YResolution() == h) &&
      (data->ray_origin_images[1].YResolution() == h) &&
      (data->ray_origin_images[2].YResolution() == h) && 
      (data->ray_direction_images[0].XResolution() == w) &&
      (data->ray_direction_images[1].XResolution() == w) &&
      (data->ray_direction_images[2].XResolution() == w) && 
      (data->ray_direction_images[0].YResolution() == h) &&
      (data->ray_direction_images[1].YResolution() == h) &&
      (data->ray_direction_images[2].YResolution() == h)) {
    RNGrfxBegin(RN_GRFX_POINTS);
    for (int ix = 0; ix < w; ix++) {
      for (int iy = 0; iy < h; iy++) {
        // Get/check depth
        double depth = data->depth_image.GridValue(ix, iy);
        if ((depth <= 0) || (depth == R2_GRID_UNKNOWN_VALUE)) continue;

        // Get/check ray direction
        double dx = data->ray_direction_images[0].GridValue(ix, iy);    
        double dy = data->ray_direction_images[1].GridValue(ix, iy);    
        double dz = data->ray_direction_images[2].GridValue(ix, iy);
        R3Vector direction(dx, dy, dz);
        if (direction.IsZero()) continue;

        // Get ray origin
        double ox = data->ray_origin_images[0].GridValue(ix, iy);    
        double oy = data->ray_origin_images[1].GridValue(ix, iy);    
        double oz = data->ray_origin_images[2].GridValue(ix, iy);    
        R3Point origin(ox, oy, oz);

        // Get point position
        RNScalar t = depth * direction.Dot(towards);
        R3Point p = origin + t * direction;

        // Get texture coordinates
        double u = (double) ix / (double) w;
        double v = (double) iy / (double) h;

        // Draw point
        R3LoadTextureCoords(u, v);
        R3LoadPoint(p);
      }
    }
    RNGrfxEnd();
  }
  else {
    // Compute view plane rectangle in world coordinates
    R3Vector dx = 2.0 * right * image_billboard_depth * tan(xfov);
    R3Vector dy = 2.0 * up * image_billboard_depth * tan(yfov);
    R3Point origin = viewpoint + towards * image_billboard_depth;
    R3Point lower_left = origin - 0.5*dx - 0.5*dy;

    // Backproject pixels from the view plane rectangle
    RNGrfxBegin(RN_GRFX_POINTS);
    for (int ix = 0; ix < w; ix++) {
      for (int iy = 0; iy < h; iy++) {
        double depth = data->depth_image.GridValue(ix, iy);
        if ((depth <= 0) || (depth == R2_GRID_UNKNOWN_VALUE)) continue;
        double u = (double) ix / (double) w;
        double v = (double) iy / (double) h;
        R3Point pA = lower_left + u*dx + v*dy;
        R3Vector vA = pA - viewpoint;
        double dA = vA.Dot(towards);
        if (dA <= 0) continue;
        R3Point p = viewpoint + vA * depth / dA;
        R3LoadTextureCoords(u, v);
        R3LoadPoint(p);
      }
    }
    RNGrfxEnd();
  }
  
  // Disable texture
  glDisable(GL_TEXTURE_2D);
}

// Assembly:
subq $0x328, %rsp            # imm = 0x328
movq %rdi, 0x320(%rsp)
movq %rsi, 0x318(%rsp)
movq %rdx, 0x310(%rsp)
movq %rcx, 0x308(%rsp)
movq %r8, 0x300(%rsp)
movsd %xmm0, 0x2f8(%rsp)
movsd %xmm1, 0x2f0(%rsp)
movsd %xmm2, 0x2e8(%rsp)
cmpl $0x0, 0x2c9843(%rip)    # 0x2feef4
jne 0x356b8
jmp 0x36039
movq 0x320(%rsp), %rax
movl 0x768(%rax), %eax
movl %eax, 0x2e4(%rsp)
movq 0x320(%rsp), %rax
movl 0x76c(%rax), %eax
movl %eax, 0x2e0(%rsp)
cmpl $0x0, 0x2e4(%rsp)
jne 0x356f1
jmp 0x36039
cmpl $0x0, 0x2e0(%rsp)
jne 0x35700
jmp 0x36039
movq 0x320(%rsp), %rdi
addq $0x18, %rdi
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
je 0x3571f
jmp 0x36039
movq 0x320(%rsp), %rdi
addq $0x18, %rdi
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
je 0x3573e
jmp 0x36039
movq 0x320(%rsp), %rdi
callq 0x36360
movq 0x320(%rsp), %rax
cmpl $0x0, 0x770(%rax)
jne 0x35761
jmp 0x36039
movq 0x320(%rsp), %rax
movl 0x770(%rax), %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0x2a4b0
movl $0xde1, %edi            # imm = 0xDE1
callq 0x29a50
movl $0xb50, %edi            # imm = 0xB50
callq 0x2a130
movl $0x1, %edx
movl %edx, %edi
movl %edx, %esi
callq 0x39820
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0xd0, %rdi
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0x1a0, %rdi            # imm = 0x1A0
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0xd0, %rdi
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0x1a0, %rdi            # imm = 0x1A0
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0xd0, %rdi
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0x1a0, %rdi            # imm = 0x1A0
callq 0x39d90
cmpl 0x2e4(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0xd0, %rdi
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0x1a0, %rdi            # imm = 0x1A0
callq 0x39db0
cmpl 0x2e0(%rsp), %eax
jne 0x35c8c
xorl %edi, %edi
callq 0x38d90
movl $0x0, 0x2dc(%rsp)
movl 0x2dc(%rsp), %eax
cmpl 0x2e4(%rsp), %eax
jge 0x35c82
movl $0x0, 0x2d8(%rsp)
movl 0x2d8(%rsp), %eax
cmpl 0x2e0(%rsp), %eax
jge 0x35c6a
movq 0x320(%rsp), %rdi
addq $0x18, %rdi
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x2d0(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x2d0(%rsp), %xmm0
jae 0x359f3
movsd 0x2d0(%rsp), %xmm0
movsd 0x23070d(%rip), %xmm1   # 0x2660f8
ucomisd %xmm1, %xmm0
jne 0x359f8
jp 0x359f8
jmp 0x35c54
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x2c8(%rsp)
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0xd0, %rdi
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x2c0(%rsp)
movq 0x320(%rsp), %rdi
addq $0x4f8, %rdi            # imm = 0x4F8
addq $0x1a0, %rdi            # imm = 0x1A0
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x2b8(%rsp)
movsd 0x2c8(%rsp), %xmm0
movsd 0x2c0(%rsp), %xmm1
movsd 0x2b8(%rsp), %xmm2
leaq 0x2a0(%rsp), %rdi
callq 0x180ef0
leaq 0x2a0(%rsp), %rdi
callq 0x39e10
cmpl $0x0, %eax
je 0x35ac6
jmp 0x35c54
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x298(%rsp)
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0xd0, %rdi
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x290(%rsp)
movq 0x320(%rsp), %rdi
addq $0x288, %rdi            # imm = 0x288
addq $0x1a0, %rdi            # imm = 0x1A0
movl 0x2dc(%rsp), %esi
movl 0x2d8(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0x288(%rsp)
movsd 0x298(%rsp), %xmm0
movsd 0x290(%rsp), %xmm1
movsd 0x288(%rsp), %xmm2
leaq 0x270(%rsp), %rdi
callq 0x17fd90
movsd 0x2d0(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movq 0x310(%rsp), %rsi
leaq 0x2a0(%rsp), %rdi
callq 0x181500
movaps %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x268(%rsp)
movsd 0x268(%rsp), %xmm0
leaq 0x238(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x38f20
leaq 0x250(%rsp), %rdi
leaq 0x270(%rsp), %rsi
leaq 0x238(%rsp), %rdx
callq 0x180350
cvtsi2sdl 0x2dc(%rsp), %xmm0
cvtsi2sdl 0x2e4(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x230(%rsp)
cvtsi2sdl 0x2d8(%rsp), %xmm0
cvtsi2sdl 0x2e0(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x228(%rsp)
movsd 0x230(%rsp), %xmm0
movsd 0x228(%rsp), %xmm1
callq 0x39e80
leaq 0x250(%rsp), %rdi
callq 0x38e20
movl 0x2d8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2d8(%rsp)
jmp 0x35990
jmp 0x35c6c
movl 0x2dc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2dc(%rsp)
jmp 0x35971
callq 0x38e40
jmp 0x3602f
movq 0x308(%rsp), %rsi
leaq 0x1e0(%rsp), %rdi
movsd 0x23040c(%rip), %xmm0   # 0x2660b0
callq 0x38f20
movsd 0x2e8(%rsp), %xmm0
leaq 0x1f8(%rsp), %rdi
leaq 0x1e0(%rsp), %rsi
callq 0x181dc0
movsd 0x2f8(%rsp), %xmm0
callq 0x299c0
leaq 0x210(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x181dc0
movq 0x300(%rsp), %rsi
leaq 0x198(%rsp), %rdi
movsd 0x2303ae(%rip), %xmm0   # 0x2660b0
callq 0x38f20
movsd 0x2e8(%rsp), %xmm0
leaq 0x1b0(%rsp), %rdi
leaq 0x198(%rsp), %rsi
callq 0x181dc0
movsd 0x2f0(%rsp), %xmm0
callq 0x299c0
leaq 0x1c8(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x181dc0
movq 0x318(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x310(%rsp), %rsi
movsd 0x2e8(%rsp), %xmm0
leaq 0x168(%rsp), %rdi
callq 0x181dc0
movq 0x10(%rsp), %rsi
leaq 0x180(%rsp), %rdi
leaq 0x168(%rsp), %rdx
callq 0x180350
leaq 0x120(%rsp), %rdi
movsd 0x2302b3(%rip), %xmm0   # 0x266050
leaq 0x210(%rsp), %rsi
callq 0x38f20
leaq 0x138(%rsp), %rdi
leaq 0x180(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0x180cf0
leaq 0x108(%rsp), %rdi
movsd 0x230279(%rip), %xmm0   # 0x266050
leaq 0x1c8(%rsp), %rsi
callq 0x38f20
leaq 0x150(%rsp), %rdi
leaq 0x138(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x180cf0
xorl %edi, %edi
callq 0x38d90
movl $0x0, 0x104(%rsp)
movl 0x104(%rsp), %eax
cmpl 0x2e4(%rsp), %eax
jge 0x3602a
movl $0x0, 0x100(%rsp)
movl 0x100(%rsp), %eax
cmpl 0x2e0(%rsp), %eax
jge 0x36012
movq 0x320(%rsp), %rdi
addq $0x18, %rdi
movl 0x104(%rsp), %esi
movl 0x100(%rsp), %edx
callq 0x39dd0
movsd %xmm0, 0xf8(%rsp)
xorps %xmm0, %xmm0
ucomisd 0xf8(%rsp), %xmm0
jae 0x35e95
movsd 0xf8(%rsp), %xmm0
movsd 0x23026b(%rip), %xmm1   # 0x2660f8
ucomisd %xmm1, %xmm0
jne 0x35e9a
jp 0x35e9a
jmp 0x35ffc
cvtsi2sdl 0x104(%rsp), %xmm0
cvtsi2sdl 0x2e4(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xf0(%rsp)
cvtsi2sdl 0x100(%rsp), %xmm0
cvtsi2sdl 0x2e0(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0xf0(%rsp), %xmm0
leaq 0xa0(%rsp), %rdi
leaq 0x210(%rsp), %rsi
callq 0x38f20
leaq 0xb8(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x180350
movsd 0xe8(%rsp), %xmm0
leaq 0x88(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x38f20
leaq 0xd0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
leaq 0x88(%rsp), %rdx
callq 0x180350
movq 0x318(%rsp), %rdx
leaq 0x70(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x1800f0
movq 0x310(%rsp), %rsi
leaq 0x70(%rsp), %rdi
callq 0x181500
movsd %xmm0, 0x68(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x68(%rsp), %xmm0
jb 0x35f8d
jmp 0x35ffc
movq 0x318(%rsp), %rax
movq %rax, 0x8(%rsp)
movsd 0xf8(%rsp), %xmm0
leaq 0x20(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x181dc0
movsd 0x68(%rsp), %xmm0
leaq 0x38(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x182430
movq 0x8(%rsp), %rsi
leaq 0x50(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x180350
movsd 0xf0(%rsp), %xmm0
movsd 0xe8(%rsp), %xmm1
callq 0x39e80
leaq 0x50(%rsp), %rdi
callq 0x38e20
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0x35e32
jmp 0x36014
movl 0x104(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x104(%rsp)
jmp 0x35e13
callq 0x38e40
movl $0xde1, %edi            # imm = 0xDE1
callq 0x2a130
addq $0x328, %rsp            # imm = 0x328
retq
nopw %cs:(%rax,%rax)