// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/apps/conf2img/conf2img.cpp
// Function: RenderMesh(gaps::R3Mesh const&, int, gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&)
static void
RenderMesh(const R3Mesh& mesh, int rendering_scheme,
  const R3Point& viewpoint, const R3Vector& towards, const R3Vector& up)
{
  // Clear window
  glViewport(0, 0, width, height);
  glClearColor(0, 0, 0, 0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glEnable(GL_DEPTH_TEST);
  RNLoadRgb(1.0, 1.0, 1.0);

  // Get world to camera matrix
  R3CoordSystem cs(viewpoint, R3Triad(towards, up));
  R4Matrix world_to_camera = cs.InverseMatrix();

  // Draw mesh
  RNGrfxBegin(RN_GRFX_TRIANGLES);
  for (int i = 0; i < mesh.NFaces(); i++) {
    R3MeshFace *face = mesh.Face(i);
    if (skip_removed_faces) {
      // This is a hack to skip faces marked for removal in the matterport dataset
      int category_index = mesh.FaceCategory(face);
      if (category_index == 9) continue;
      if (category_index == 64) continue;
    }
    if ((rendering_scheme >= CAMERA_PX_RENDERING) && (rendering_scheme <= WORLD_PZ_RENDERING)) {
      // Set color per vertex
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        RNScalar position_coordinate = 0;
        const R3Point& world_position = mesh.VertexPosition(vertex);
        R3Point camera_position = world_to_camera * world_position;
        if (rendering_scheme == CAMERA_PX_RENDERING) position_coordinate = camera_position.X();
        else if (rendering_scheme == CAMERA_PY_RENDERING) position_coordinate = camera_position.Y();
        else if (rendering_scheme == CAMERA_PZ_RENDERING) position_coordinate = camera_position.Z();
        else if (rendering_scheme == WORLD_PX_RENDERING) position_coordinate = world_position.X() - viewpoint.X();
        else if (rendering_scheme == WORLD_PY_RENDERING) position_coordinate = world_position.Y() - viewpoint.Y();
        else if (rendering_scheme == WORLD_PZ_RENDERING) position_coordinate = world_position.Z() - viewpoint.Z();
        int position_value = png_distance_scale * position_coordinate + 32768;
        if (position_value < 0) position_value = 0;
        else if (position_value > 65535) position_value = 65535;
        LoadInteger(position_value);
        R3LoadPoint(world_position);
      }
    }
    else if (((rendering_scheme >= CAMERA_NX_RENDERING) && (rendering_scheme <= CAMERA_NZ_RENDERING)) ||
             ((rendering_scheme >= WORLD_NX_RENDERING) && (rendering_scheme <= WORLD_NZ_RENDERING))) {
      // Set color per face based on normal
      RNScalar normal_coordinate = 0;
      R3Vector world_normal = mesh.FaceNormal(face);
      R3Vector camera_normal = world_to_camera * world_normal; camera_normal.Normalize();
      if (rendering_scheme == CAMERA_NX_RENDERING) normal_coordinate = camera_normal.X();
      else if (rendering_scheme == CAMERA_NY_RENDERING) normal_coordinate = camera_normal.Y();
      else if (rendering_scheme == CAMERA_NZ_RENDERING) normal_coordinate = camera_normal.Z();
      else if (rendering_scheme == WORLD_NX_RENDERING) normal_coordinate = world_normal.X();
      else if (rendering_scheme == WORLD_NY_RENDERING) normal_coordinate = world_normal.Y();
      else if (rendering_scheme == WORLD_NZ_RENDERING) normal_coordinate = world_normal.Z();
      int normal_value = 32768 * (normal_coordinate + 1.0);
      if (normal_value < 0) normal_value = 0;
      else if (normal_value > 65535) normal_value = 65535;
      LoadInteger(normal_value);
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& position = mesh.VertexPosition(vertex);
        R3LoadPoint(position);
      }
    }
    else if ((rendering_scheme == CAMERA_ND_RENDERING) || (rendering_scheme == WORLD_ND_RENDERING)) {
      RNScalar offset_coordinate = 0;
      R3Vector world_normal = mesh.FaceNormal(face);
      R3Point world_position = mesh.FaceCentroid(face);
      if (rendering_scheme == CAMERA_ND_RENDERING) {
        R3Point camera_position = world_to_camera * world_position;
        R3Vector camera_normal = world_to_camera * world_normal; camera_normal.Normalize();
        offset_coordinate = -camera_position.X()*camera_normal.X() - camera_position.Y()*camera_normal.Y() - camera_position.Z()*camera_normal.Z();
      }
      else if (rendering_scheme == WORLD_ND_RENDERING) {
        offset_coordinate = -world_position.X()*world_normal.X() - world_position.Y()*world_normal.Y() - world_position.Z()*world_normal.Z();
      }
      int offset_value = png_distance_scale * offset_coordinate + 32768;
      if (offset_value < 0) offset_value = 0;
      else if (offset_value > 65535) offset_value = 65535;
      LoadInteger(offset_value);
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& position = mesh.VertexPosition(vertex);
        R3LoadPoint(position);
      }
    }
    else if (rendering_scheme == NDOTV_RENDERING) {
      // Set color per vertex
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& world_position = mesh.VertexPosition(vertex);
        R3Vector n = mesh.FaceNormal(face);
        R3Vector v = viewpoint - world_position; v.Normalize();
        RNScalar ndotv = n.Dot(v);
        int ndotv_value = 32768 * (ndotv + 1.0);
        if (ndotv_value < 0) ndotv_value = 0;
        else if (ndotv_value > 65535) ndotv_value = 65535;
        LoadInteger(ndotv_value);
        R3LoadPoint(world_position);
      }
    }
    else if ((rendering_scheme >= FACE_INDEX_RENDERING) && (rendering_scheme <= FACE_CATEGORY_RENDERING)) {
      // Set color per face based on face attributes
      if (rendering_scheme == FACE_INDEX_RENDERING) LoadInteger(mesh.FaceID(face)+1);
      else if (rendering_scheme == FACE_MATERIAL_RENDERING) LoadInteger((mesh.FaceMaterial(face)+1) % 65536);
      else if (rendering_scheme == FACE_SEGMENT_RENDERING) LoadInteger((mesh.FaceSegment(face)+1) % 65536);
      else if (rendering_scheme == FACE_CATEGORY_RENDERING) LoadInteger((mesh.FaceCategory(face)+1) % 65536);
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& position = mesh.VertexPosition(vertex);
        R3LoadPoint(position);
      }
    }
    else if (rendering_scheme >= COLOR_RENDERING){
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& position = mesh.VertexPosition(vertex);
        const RNRgb& color = mesh.VertexColor(vertex);
        RNLoadRgb(color);
        R3LoadPoint(position);
      }
    }
    else {
      LoadInteger(0);
      for (int j = 0; j < 3; j++) {
        R3MeshVertex *vertex = mesh.VertexOnFace(face, j);
        const R3Point& position = mesh.VertexPosition(vertex);
        R3LoadPoint(position);
      }
    }
  }
  RNGrfxEnd();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %r12
movq %rdi, 0x58(%rsp)
movl 0x14ee66(%rip), %edx    # 0x179a60
movl 0x14ee64(%rip), %ecx    # 0x179a64
xorl %edi, %edi
xorl %esi, %esi
callq 0x231f0
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
xorps %xmm2, %xmm2
xorps %xmm3, %xmm3
callq 0x23e30
movl $0x4100, %edi           # imm = 0x4100
callq 0x231d0
movl $0xb71, %edi            # imm = 0xB71
callq 0x23820
movsd 0xda3f2(%rip), %xmm0    # 0x105028
movapd %xmm0, %xmm1
movapd %xmm0, %xmm2
callq 0x23e80
leaq 0x88(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x8e31a
leaq 0x108(%rsp), %rbx
movq %rbx, %rdi
movq %r12, 0x30(%rsp)
movq %r12, %rsi
movq %r15, %rdx
callq 0x8de1c
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x8deca
movl $0x4, %edi
callq 0x23180
cmpl $0x0, 0x14ec8f(%rip)    # 0x179924
jle 0x2b236
movq 0x58(%rsp), %rax
leal -0x6(%rax), %r12d
addl $-0x2, %eax
movl %eax, 0x54(%rsp)
leaq 0xda40a(%rip), %r15     # 0x1050bc
xorl %ecx, %ecx
movq 0x14ec5d(%rip), %rax    # 0x179918
movq %rcx, 0x68(%rsp)
movq (%rax,%rcx,8), %rbp
cmpb $0x1, 0x14ed8d(%rip)    # 0x179a58
jne 0x2ace5
movl 0xa0(%rbp), %eax
cmpl $0x9, %eax
je 0x2b151
cmpl $0x40, %eax
je 0x2b151
cmpl $0x5, %r12d
ja 0x2adc9
movl $0x1, %ebx
movq (%rbp,%rbx,8), %r13
leaq 0x18(%r13), %r14
movq %rsp, %rdi
leaq 0x88(%rsp), %rsi
movq %r14, %rdx
callq 0x91aae
cmpl $0x5, %r12d
ja 0x2ad6a
movslq (%r15,%r12,4), %rax
addq %r15, %rax
jmpq *%rax
movsd (%rsp), %xmm0
jmp 0x2ad6e
movsd 0x20(%r13), %xmm0
movq 0x30(%rsp), %rax
subsd 0x8(%rax), %xmm0
jmp 0x2ad6e
movsd 0x10(%rsp), %xmm0
jmp 0x2ad6e
movsd (%r14), %xmm0
movq 0x30(%rsp), %rax
subsd (%rax), %xmm0
jmp 0x2ad6e
movsd 0x8(%rsp), %xmm0
jmp 0x2ad6e
movsd 0x28(%r13), %xmm0
movq 0x30(%rsp), %rax
subsd 0x10(%rax), %xmm0
jmp 0x2ad6e
xorpd %xmm0, %xmm0
mulsd 0x149c2a(%rip), %xmm0   # 0x1749a0
addsd 0xda2b2(%rip), %xmm0    # 0x105030
cvttsd2si %xmm0, %eax
movl $0xffff, %ecx           # imm = 0xFFFF
cmpl %ecx, %eax
jl 0x2ad90
movl $0xffff, %eax           # imm = 0xFFFF
testl %eax, %eax
jg 0x2ad96
xorl %eax, %eax
movw $0x0, 0x38(%rsp)
movb %ah, 0x3a(%rsp)
movb %al, 0x3b(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x233f0
movq %r14, %rdi
callq 0x231a0
incq %rbx
cmpq $0x4, %rbx
jne 0x2acf4
jmp 0x2b151
movq 0x58(%rsp), %rbx
cmpl $0x14, %ebx
ja 0x2b007
movl $0x77000, %eax          # imm = 0x77000
btl %ebx, %eax
jae 0x2ae5b
testb $0x4, 0xa8(%rbp)
jne 0x2ae01
movq 0x14eaff(%rip), %rax    # 0x1798f0
leaq 0x14eaf8(%rip), %rdi    # 0x1798f0
movq %rbp, %rsi
callq *0x2c8(%rax)
leaq 0x38(%rbp), %rsi
movq %rsp, %r14
movq %r14, %rdi
callq 0x93b5a
leaq 0x38(%rsp), %r13
movq %r13, %rdi
leaq 0x88(%rsp), %rsi
movq %r14, %rdx
callq 0x91a36
movq %r13, %rdi
callq 0x93e60
xorpd %xmm0, %xmm0
leal -0xc(%rbx), %eax
cmpl $0x6, %eax
ja 0x2b05f
leaq 0xda259(%rip), %rcx     # 0x1050a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movsd 0x38(%rsp), %xmm0
jmp 0x2b05f
movl $0x88000, %eax          # imm = 0x88000
btl %ebx, %eax
jae 0x2af2c
testb $0x4, 0xa8(%rbp)
jne 0x2ae89
movq 0x14ea77(%rip), %rax    # 0x1798f0
leaq 0x14ea70(%rip), %rdi    # 0x1798f0
movq %rbp, %rsi
callq *0x2c8(%rax)
leaq 0x38(%rbp), %rsi
movq %rsp, %rdi
callq 0x93b5a
leaq 0x38(%rsp), %rdi
leaq 0x14ea4f(%rip), %rsi    # 0x1798f0
movq %rbp, %rdx
callq 0x6f23a
cmpl $0x13, %ebx
je 0x2b0c1
xorpd %xmm0, %xmm0
cmpl $0xf, %ebx
jne 0x2b0f4
leaq 0x18(%rsp), %rdi
leaq 0x88(%rsp), %rbx
movq %rbx, %rsi
leaq 0x38(%rsp), %rdx
callq 0x91aae
leaq 0x70(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %rsp, %rdx
callq 0x91a36
movq %r14, %rdi
callq 0x93e60
movsd 0x18(%rsp), %xmm0
movsd 0x78(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm1
xorpd 0xda172(%rip), %xmm0    # 0x105080
mulsd 0x70(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd 0x28(%rsp), %xmm1
mulsd 0x80(%rsp), %xmm1
jmp 0x2b0f0
cmpl $0x14, %ebx
jne 0x2b007
leaq 0x38(%rbp), %rax
movq %rax, 0x60(%rsp)
movl $0x1, %r14d
movq (%rbp,%r14,8), %rbx
testb $0x4, 0xa8(%rbp)
jne 0x2af69
movq 0x14e997(%rip), %rax    # 0x1798f0
leaq 0x14e990(%rip), %rdi    # 0x1798f0
movq %rbp, %rsi
callq *0x2c8(%rax)
addq $0x18, %rbx
movq %rsp, %r13
movq %r13, %rdi
movq 0x60(%rsp), %rsi
callq 0x93b5a
leaq 0x38(%rsp), %r15
movq %r15, %rdi
movq 0x30(%rsp), %rsi
movq %rbx, %rdx
callq 0x93312
movq %r15, %rdi
callq 0x93e60
movq %r13, %rdi
movq %r15, %rsi
callq 0x93dd6
addsd 0xda07b(%rip), %xmm0    # 0x105028
mulsd 0xda07b(%rip), %xmm0    # 0x105030
cvttsd2si %xmm0, %eax
movl $0xffff, %ecx           # imm = 0xFFFF
cmpl %ecx, %eax
cmovgel %ecx, %eax
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
movw $0x0, 0x18(%rsp)
movb %ah, 0x1a(%rsp)
movb %al, 0x1b(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x233f0
movq %rbx, %rdi
callq 0x231a0
incq %r14
cmpq $0x4, %r14
leaq 0xda0c0(%rip), %r15     # 0x1050bc
jne 0x2af44
jmp 0x2b151
cmpl $0x3, 0x54(%rsp)
ja 0x2b16e
cmpl $0x4, %ebx
je 0x2b1e0
cmpl $0x3, %ebx
je 0x2b1d8
cmpl $0x2, %ebx
jne 0x2b1e8
movl 0xa4(%rbp), %eax
incl %eax
jmp 0x2b208
movsd 0x48(%rsp), %xmm0
jmp 0x2b05f
movsd 0x10(%rsp), %xmm0
jmp 0x2b05f
movsd 0x40(%rsp), %xmm0
jmp 0x2b05f
movsd (%rsp), %xmm0
jmp 0x2b05f
movsd 0x8(%rsp), %xmm0
addsd 0xd9fc1(%rip), %xmm0    # 0x105028
mulsd 0xd9fc1(%rip), %xmm0    # 0x105030
cvttsd2si %xmm0, %eax
movl $0xffff, %ecx           # imm = 0xFFFF
cmpl %ecx, %eax
cmovgel %ecx, %eax
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
movw $0x0, 0x18(%rsp)
movb %ah, 0x1a(%rsp)
movb %al, 0x1b(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x233f0
movl $0x1, %ebx
movq (%rbp,%rbx,8), %rdi
addq $0x18, %rdi
callq 0x231a0
incq %rbx
cmpq $0x4, %rbx
jne 0x2b0a5
jmp 0x2b151
movsd 0x38(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
mulsd 0x40(%rsp), %xmm1
xorpd 0xd9fa5(%rip), %xmm0    # 0x105080
mulsd (%rsp), %xmm0
subsd %xmm1, %xmm0
movsd 0x48(%rsp), %xmm1
mulsd 0x10(%rsp), %xmm1
subsd %xmm1, %xmm0
mulsd 0x1498a4(%rip), %xmm0   # 0x1749a0
addsd 0xd9f2c(%rip), %xmm0    # 0x105030
cvttsd2si %xmm0, %eax
movl $0xffff, %ecx           # imm = 0xFFFF
cmpl %ecx, %eax
cmovgel %ecx, %eax
testl %eax, %eax
movl $0x0, %ecx
cmovlel %ecx, %eax
movw $0x0, 0x18(%rsp)
movb %ah, 0x1a(%rsp)
movb %al, 0x1b(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x233f0
movl $0x1, %ebx
movq (%rbp,%rbx,8), %rdi
addq $0x18, %rdi
callq 0x231a0
incq %rbx
cmpq $0x4, %rbx
jne 0x2b13a
movq 0x68(%rsp), %rcx
incq %rcx
movslq 0x14e7c4(%rip), %rax    # 0x179924
cmpq %rax, %rcx
jl 0x2acb4
jmp 0x2b236
testl %ebx, %ebx
jle 0x2b1a8
movl $0x1, %r14d
movq (%rbp,%r14,8), %rax
leaq 0x18(%rax), %rbx
movsd 0x58(%rax), %xmm0
movsd 0x60(%rax), %xmm1
movsd 0x68(%rax), %xmm2
callq 0x23e80
movq %rbx, %rdi
callq 0x231a0
incq %r14
cmpq $0x4, %r14
jne 0x2b178
jmp 0x2b151
movl $0x0, (%rsp)
movq %rsp, %rdi
callq 0x233f0
movl $0x1, %ebx
movq (%rbp,%rbx,8), %rdi
addq $0x18, %rdi
callq 0x231a0
incq %rbx
cmpq $0x4, %rbx
jne 0x2b1bc
jmp 0x2b151
movl 0x98(%rbp), %eax
jmp 0x2b1ee
movl 0x9c(%rbp), %eax
jmp 0x2b1ee
movl 0xa0(%rbp), %eax
leal 0x1(%rax), %ecx
leal 0x10000(%rax), %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
andl $0xffff0000, %edx       # imm = 0xFFFF0000
negl %edx
addl %edx, %eax
incl %eax
bswapl %eax
movl %eax, (%rsp)
movq %rsp, %rdi
callq 0x233f0
movl $0x1, %ebx
movq (%rbp,%rbx,8), %rdi
addq $0x18, %rdi
callq 0x231a0
incq %rbx
cmpq $0x4, %rbx
jne 0x2b21a
jmp 0x2b151
callq 0x23c60
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq