// File: /workspace/github_cpp_makefile_star2_O1/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 0x151dc5(%rip), %edx    # 0x17ca60
movl 0x151dc3(%rip), %ecx    # 0x17ca64
xorl %edi, %edi
xorl %esi, %esi
callq 0x231f0
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
xorps %xmm2, %xmm2
xorps %xmm3, %xmm3
callq 0x23e40
movl $0x4100, %edi           # imm = 0x4100
callq 0x231d0
movl $0xb71, %edi            # imm = 0xB71
callq 0x23820
movsd 0xdd351(%rip), %xmm0    # 0x108028
movapd %xmm0, %xmm1
movapd %xmm0, %xmm2
callq 0x23e90
leaq 0x88(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x8f66a
leaq 0x108(%rsp), %rbx
movq %rbx, %rdi
movq %r12, 0x30(%rsp)
movq %r12, %rsi
movq %r15, %rdx
callq 0x8f16c
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x8f21a
movl $0x4, %edi
callq 0x23180
cmpl $0x0, 0x151bee(%rip)    # 0x17c924
jle 0x2b2d7
movq 0x58(%rsp), %rax
leal -0x6(%rax), %r12d
addl $-0x2, %eax
movl %eax, 0x54(%rsp)
leaq 0xdd369(%rip), %r15     # 0x1080bc
xorl %ecx, %ecx
movq 0x151bbc(%rip), %rax    # 0x17c918
movq %rcx, 0x68(%rsp)
movq (%rax,%rcx,8), %rbp
cmpb $0x1, 0x151cec(%rip)    # 0x17ca58
jne 0x2ad86
movl 0xa0(%rbp), %eax
cmpl $0x9, %eax
je 0x2b1f2
cmpl $0x40, %eax
je 0x2b1f2
cmpl $0x5, %r12d
ja 0x2ae6a
movl $0x1, %ebx
movq (%rbp,%rbx,8), %r13
leaq 0x18(%r13), %r14
movq %rsp, %rdi
leaq 0x88(%rsp), %rsi
movq %r14, %rdx
callq 0x92eb2
cmpl $0x5, %r12d
ja 0x2ae0b
movslq (%r15,%r12,4), %rax
addq %r15, %rax
jmpq *%rax
movsd (%rsp), %xmm0
jmp 0x2ae0f
movsd 0x20(%r13), %xmm0
movq 0x30(%rsp), %rax
subsd 0x8(%rax), %xmm0
jmp 0x2ae0f
movsd 0x10(%rsp), %xmm0
jmp 0x2ae0f
movsd (%r14), %xmm0
movq 0x30(%rsp), %rax
subsd (%rax), %xmm0
jmp 0x2ae0f
movsd 0x8(%rsp), %xmm0
jmp 0x2ae0f
movsd 0x28(%r13), %xmm0
movq 0x30(%rsp), %rax
subsd 0x10(%rax), %xmm0
jmp 0x2ae0f
xorpd %xmm0, %xmm0
mulsd 0x14cb89(%rip), %xmm0   # 0x1779a0
addsd 0xdd211(%rip), %xmm0    # 0x108030
cvttsd2si %xmm0, %eax
movl $0xffff, %ecx           # imm = 0xFFFF
cmpl %ecx, %eax
jl 0x2ae31
movl $0xffff, %eax           # imm = 0xFFFF
testl %eax, %eax
jg 0x2ae37
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 0x2ad95
jmp 0x2b1f2
movq 0x58(%rsp), %rbx
cmpl $0x14, %ebx
ja 0x2b0a8
movl $0x77000, %eax          # imm = 0x77000
btl %ebx, %eax
jae 0x2aefc
testb $0x4, 0xa8(%rbp)
jne 0x2aea2
movq 0x151a5e(%rip), %rax    # 0x17c8f0
leaq 0x151a57(%rip), %rdi    # 0x17c8f0
movq %rbp, %rsi
callq *0x2c8(%rax)
leaq 0x38(%rbp), %rsi
movq %rsp, %r14
movq %r14, %rdi
callq 0x94f62
leaq 0x38(%rsp), %r13
movq %r13, %rdi
leaq 0x88(%rsp), %rsi
movq %r14, %rdx
callq 0x92e3a
movq %r13, %rdi
callq 0x95274
xorpd %xmm0, %xmm0
leal -0xc(%rbx), %eax
cmpl $0x6, %eax
ja 0x2b100
leaq 0xdd1b8(%rip), %rcx     # 0x1080a0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movsd 0x38(%rsp), %xmm0
jmp 0x2b100
movl $0x88000, %eax          # imm = 0x88000
btl %ebx, %eax
jae 0x2afcd
testb $0x4, 0xa8(%rbp)
jne 0x2af2a
movq 0x1519d6(%rip), %rax    # 0x17c8f0
leaq 0x1519cf(%rip), %rdi    # 0x17c8f0
movq %rbp, %rsi
callq *0x2c8(%rax)
leaq 0x38(%rbp), %rsi
movq %rsp, %rdi
callq 0x94f62
leaq 0x38(%rsp), %rdi
leaq 0x1519ae(%rip), %rsi    # 0x17c8f0
movq %rbp, %rdx
callq 0x7039c
cmpl $0x13, %ebx
je 0x2b162
xorpd %xmm0, %xmm0
cmpl $0xf, %ebx
jne 0x2b195
leaq 0x18(%rsp), %rdi
leaq 0x88(%rsp), %rbx
movq %rbx, %rsi
leaq 0x38(%rsp), %rdx
callq 0x92eb2
leaq 0x70(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
movq %rsp, %rdx
callq 0x92e3a
movq %r14, %rdi
callq 0x95274
movsd 0x18(%rsp), %xmm0
movsd 0x78(%rsp), %xmm1
mulsd 0x20(%rsp), %xmm1
xorpd 0xdd0d1(%rip), %xmm0    # 0x108080
mulsd 0x70(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd 0x28(%rsp), %xmm1
mulsd 0x80(%rsp), %xmm1
jmp 0x2b191
cmpl $0x14, %ebx
jne 0x2b0a8
leaq 0x38(%rbp), %rax
movq %rax, 0x60(%rsp)
movl $0x1, %r14d
movq (%rbp,%r14,8), %rbx
testb $0x4, 0xa8(%rbp)
jne 0x2b00a
movq 0x1518f6(%rip), %rax    # 0x17c8f0
leaq 0x1518ef(%rip), %rdi    # 0x17c8f0
movq %rbp, %rsi
callq *0x2c8(%rax)
addq $0x18, %rbx
movq %rsp, %r13
movq %r13, %rdi
movq 0x60(%rsp), %rsi
callq 0x94f62
leaq 0x38(%rsp), %r15
movq %r15, %rdi
movq 0x30(%rsp), %rsi
movq %rbx, %rdx
callq 0x9471c
movq %r15, %rdi
callq 0x95274
movq %r13, %rdi
movq %r15, %rsi
callq 0x951ea
addsd 0xdcfda(%rip), %xmm0    # 0x108028
mulsd 0xdcfda(%rip), %xmm0    # 0x108030
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 0xdd01f(%rip), %r15     # 0x1080bc
jne 0x2afe5
jmp 0x2b1f2
cmpl $0x3, 0x54(%rsp)
ja 0x2b20f
cmpl $0x4, %ebx
je 0x2b281
cmpl $0x3, %ebx
je 0x2b279
cmpl $0x2, %ebx
jne 0x2b289
movl 0xa4(%rbp), %eax
incl %eax
jmp 0x2b2a9
movsd 0x48(%rsp), %xmm0
jmp 0x2b100
movsd 0x10(%rsp), %xmm0
jmp 0x2b100
movsd 0x40(%rsp), %xmm0
jmp 0x2b100
movsd (%rsp), %xmm0
jmp 0x2b100
movsd 0x8(%rsp), %xmm0
addsd 0xdcf20(%rip), %xmm0    # 0x108028
mulsd 0xdcf20(%rip), %xmm0    # 0x108030
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 0x2b146
jmp 0x2b1f2
movsd 0x38(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
mulsd 0x40(%rsp), %xmm1
xorpd 0xdcf04(%rip), %xmm0    # 0x108080
mulsd (%rsp), %xmm0
subsd %xmm1, %xmm0
movsd 0x48(%rsp), %xmm1
mulsd 0x10(%rsp), %xmm1
subsd %xmm1, %xmm0
mulsd 0x14c803(%rip), %xmm0   # 0x1779a0
addsd 0xdce8b(%rip), %xmm0    # 0x108030
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 0x2b1db
movq 0x68(%rsp), %rcx
incq %rcx
movslq 0x151723(%rip), %rax    # 0x17c924
cmpq %rax, %rcx
jl 0x2ad55
jmp 0x2b2d7
testl %ebx, %ebx
jle 0x2b249
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 0x23e90
movq %rbx, %rdi
callq 0x231a0
incq %r14
cmpq $0x4, %r14
jne 0x2b219
jmp 0x2b1f2
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 0x2b25d
jmp 0x2b1f2
movl 0x98(%rbp), %eax
jmp 0x2b28f
movl 0x9c(%rbp), %eax
jmp 0x2b28f
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 0x2b2bb
jmp 0x2b1f2
callq 0x23c70
addq $0x168, %rsp            # imm = 0x168
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq