// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/GSV/GSVScan.cpp
// Function: gaps::GSVScan::Grid(int) const
R2Grid *GSVScan::
Grid(int channel) const
{
  // Check dimensions
  int nx = MaxSweepIndex() + 1;
  int ny = MaxBeamIndex() + 1;
  RNBoolean use_sweep_index = TRUE;
  if (nx <= 1) { use_sweep_index = FALSE; nx = NScanlines(); }
  if (nx * ny == 0) return NULL;
                     
  // Allocate image
  R2Grid *grid = new R2Grid(nx, ny);
  if (!grid) {
    RNFail("Unable to allocate grid");
    return NULL;
  }

  // Fill grid
  grid->Clear(R2_GRID_UNKNOWN_VALUE);
  for (int i = 0; i < NScanlines(); i++) {
    GSVScanline *scanline = Scanline(i);
    int ix = (use_sweep_index) ? scanline->SweepIndex() : i;
    const R3Point& sensor_position = scanline->Pose().Viewpoint();
    for (int j = 0; j < scanline->NPoints(); j++) {
      // Get point
      const GSVPoint& point = scanline->Point(j);

      // Compute value
      RNScalar value = R2_GRID_UNKNOWN_VALUE;
      switch (channel) {
      case GSV_POSITION_X_CHANNEL:
        value = point.Position().X();
        break;
      case GSV_POSITION_Y_CHANNEL:
        value = point.Position().Y();
        break;
      case GSV_POSITION_Z_CHANNEL:
        value = point.Position().Z();
        break;
      case GSV_NORMAL_X_CHANNEL:
        value = point.Normal().X();
        break;
      case GSV_NORMAL_Y_CHANNEL:
        value = point.Normal().Y();
        break;
      case GSV_NORMAL_Z_CHANNEL:
        value = point.Normal().Z();
        break;
      case GSV_TANGENT_X_CHANNEL:
        value = point.Tangent().X();
        break;
      case GSV_TANGENT_Y_CHANNEL:
        value = point.Tangent().Y();
        break;
      case GSV_TANGENT_Z_CHANNEL:
        value = point.Tangent().Z();
        break;
      case GSV_RADIUS_0_CHANNEL:
        value = point.Radius(0);
        break;
      case GSV_RADIUS_1_CHANNEL:
        value = point.Radius(1);
        break;
      case GSV_RED_CHANNEL:
        value = point.Color().R();
        break;
      case GSV_GREEN_CHANNEL:
        value = point.Color().G();
        break;
      case GSV_BLUE_CHANNEL:
        value = point.Color().B();
        break;
      case GSV_DISTANCE_CHANNEL:
        value = R3Distance(point.Position(), sensor_position);
        break;
      case GSV_REFLECTIVITY_CHANNEL:
        value = point.Reflectivity();
        break;
      case GSV_POINT_IDENTIFIER_CHANNEL:
        value = point.PointIdentifier();
        break;        
      case GSV_CLUSTER_IDENTIFIER_CHANNEL:
        value = point.ClusterIdentifier();
        break;        
      case GSV_CATEGORY_IDENTIFIER_CHANNEL:
        value = point.CategoryIdentifier();
        break;
      case GSV_CATEGORY_CONFIDENCE_CHANNEL:
        value = point.CategoryConfidence();
        break;
      case GSV_BEAM_INDEX_CHANNEL:
        value = point.BeamIndex();
        break;
      }        

      // Set value
      grid->SetGridValue(ix, point.BeamIndex(), value);
    }
  }
  
  // Return grid
  return grid;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %esi, %ebx
movq %rdi, %r14
callq 0x3cf5e
movl %eax, %r15d
movq %r14, %rdi
callq 0x3cf8a
movl %eax, %ebp
incl %ebp
testl %r15d, %r15d
jg 0x3d1ba
movl 0x34(%r14), %r13d
jmp 0x3d1be
leal 0x1(%r15), %r13d
movl %r13d, %eax
imull %ebp, %eax
testl %eax, %eax
je 0x3d3e5
movq %r15, 0x28(%rsp)
movl $0xd0, %edi
callq 0x27940
movq %rax, %r12
movq %rax, %rdi
movl %r13d, %esi
movl %ebp, %edx
callq 0xcb0b0
movsd 0xedf1d(%rip), %xmm0    # 0x12b110
movq %r12, %rdi
callq 0xcd000
xorl %ecx, %ecx
decl %ebx
movq %r14, 0x30(%rsp)
movslq 0x34(%r14), %rax
cmpq %rax, %rcx
jge 0x3d3e8
movq 0x28(%r14), %rax
movq (%rax,%rcx,8), %rbp
cmpl $0x0, 0x28(%rsp)
movq %rcx, 0x38(%rsp)
jle 0x3d231
movl 0x80(%rbp), %eax
movl %eax, 0x24(%rsp)
jmp 0x3d235
movl %ecx, 0x24(%rsp)
leaq 0x40(%rbp), %rax
movq %rax, 0x40(%rsp)
xorl %r13d, %r13d
xorl %r14d, %r14d
movslq 0x30(%rbp), %rax
cmpq %rax, %r14
jge 0x3d3d3
movq 0x28(%rbp), %r15
movsd 0xedeb3(%rip), %xmm0    # 0x12b110
cmpl $0x14, %ebx
ja 0x3d391
leaq (%r15,%r13), %rsi
leaq 0xeeee7(%rip), %rcx     # 0x12c158
movslq (%rcx,%rbx,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x8(%rsp), %rdi
callq 0x310c8
jmp 0x3d359
cvtsi2sdl 0x38(%r15,%r13), %xmm0
jmp 0x3d391
leaq 0x8(%rsp), %rdi
callq 0x310c8
leaq 0x8(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x8e602
jmp 0x3d391
leaq 0x8(%rsp), %rdi
callq 0x3108e
jmp 0x3d359
leaq 0x8(%rsp), %rdi
callq 0x310e4
jmp 0x3d31e
leaq 0x8(%rsp), %rdi
callq 0x3108e
jmp 0x3d31e
movzwl 0x40(%r15,%r13), %eax
jmp 0x3d373
leaq 0x8(%rsp), %rdi
callq 0x310c8
jmp 0x3d38b
movzbl 0x47(%r15,%r13), %eax
jmp 0x3d367
leaq 0x8(%rsp), %rdi
callq 0x310e4
jmp 0x3d359
leaq 0x8(%rsp), %rdi
callq 0x38d32
jmp 0x3d31e
leaq 0x8(%rsp), %rdi
callq 0x310c8
movsd 0x10(%rsp), %xmm0
jmp 0x3d391
cvtsi2sdl 0x3c(%r15,%r13), %xmm0
jmp 0x3d391
movzbl 0x46(%r15,%r13), %eax
jmp 0x3d367
leaq 0x8(%rsp), %rdi
callq 0x310e4
jmp 0x3d38b
leaq 0x8(%rsp), %rdi
callq 0x3108e
jmp 0x3d38b
leaq 0x8(%rsp), %rdi
callq 0x38d32
movsd 0x8(%rsp), %xmm0
jmp 0x3d391
movzbl 0x4b(%r15,%r13), %eax
cvtsi2sd %eax, %xmm0
jmp 0x3d391
movzwl 0x42(%r15,%r13), %eax
cvtsi2sd %eax, %xmm0
mulsd 0xeeb29(%rip), %xmm0    # 0x12bea8
jmp 0x3d391
leaq 0x8(%rsp), %rdi
callq 0x38d32
movsd 0x18(%rsp), %xmm0
movzbl 0x46(%r15,%r13), %eax
movq 0xb8(%r12), %rcx
imull 0xc8(%r12), %eax
addl 0x24(%rsp), %eax
cltq
movsd %xmm0, (%rcx,%rax,8)
incq %r14
addq $0x50, %r13
jmp 0x3d244
movzbl 0x4c(%r15,%r13), %eax
cvtsi2sd %eax, %xmm0
divsd 0xedcff(%rip), %xmm0    # 0x12b0d0
jmp 0x3d391
movq 0x38(%rsp), %rcx
incq %rcx
movq 0x30(%rsp), %r14
jmp 0x3d204
xorl %r12d, %r12d
movq %r12, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0xd0, %esi
movq %r12, %rdi
callq 0x27960
movq %rbx, %rdi
callq 0x28170