// File: tomfunkhouser[P]gaps/apps/gapsview/gapsview.cpp
// Function: DrawMesh(gaps::R3Mesh*, int, int)
static void
DrawMesh(R3Mesh *mesh,
  int model_index, int color_scheme)
{
  // Check if should draw mesh
  if (!show_meshes) return;

  // Draw faces
  if (show_surfaces) {
    if (color_scheme == SHADING_COLOR_SCHEME) glEnable(GL_LIGHTING);
    else glDisable(GL_LIGHTING);
    RNLoadRgb(0.8, 0.8, 0.8);
    if ((color_scheme == RGB_COLOR_SCHEME) || (color_scheme == SHADING_COLOR_SCHEME)) {
      RNFlags draw_flags = R3_DEFAULT_DRAW_FLAGS;
      if (color_scheme == RGB_COLOR_SCHEME) draw_flags.Add(R3_VERTEX_COLORS_DRAW_FLAG);
      mesh->Draw(draw_flags);
    }
    else {
      RNGrfxBegin(RN_GRFX_TRIANGLES);
      for (int i = 0; i < mesh->NFaces(); i++) {
        R3MeshFace *face = mesh->Face(i);
        if (color_scheme == PICK_COLOR_SCHEME)
          LoadColorIndex(model_index, MESH_FACE_ELEMENT_TYPE, i);
        else if (color_scheme == CATEGORY_COLOR_SCHEME)
          LoadColorIdentifier(1 + mesh->FaceCategory(face));
        else if (color_scheme == INSTANCE_COLOR_SCHEME)
          LoadColorIdentifier(1 + mesh->FaceSegment(face)); 
        if (color_scheme == SHADING_COLOR_SCHEME)
          R3LoadNormal(mesh->FaceNormal(face));
        for (int j = 0; j < 3; j++) {
          R3MeshVertex *vertex = mesh->VertexOnFace(face, j);
          if (color_scheme == RGB_COLOR_SCHEME)
            R3LoadRgb(mesh->VertexColor(vertex));
          R3LoadPoint(mesh->VertexPosition(vertex));
        }
      }
      RNGrfxEnd();
    }
  }

  // Draw edges
  if (show_edges) {
    if (color_scheme != PICK_COLOR_SCHEME) {
      glDisable(GL_LIGHTING);
      RNLoadRgb(1.0, 0.0, 0.0);
      mesh->DrawEdges(0);
    }
  }

  // Draw vertices
  if (show_points) {
    glDisable(GL_LIGHTING);
    RNLoadRgb(0.0, 0.0, 1.0);
    RNGrfxBegin(RN_GRFX_POINTS);
    for (int i = 0; i < mesh->NVertices(); i++) {
      R3MeshVertex *vertex = mesh->Vertex(i);
      if (color_scheme == PICK_COLOR_SCHEME)
        LoadColorIndex(model_index, MESH_VERTEX_ELEMENT_TYPE, i);
      else if (color_scheme == RGB_COLOR_SCHEME)
        R3LoadRgb(mesh->VertexColor(vertex));
      R3LoadPoint(mesh->VertexPosition(vertex));
    }
    RNGrfxEnd();
  }
  
  // Draw normals
  if (show_normals) {
    glDisable(GL_LIGHTING);
    RNLoadRgb(0.0, 1.0, 0.0); 
    RNGrfxBegin(RN_GRFX_LINES);
    RNScalar d = 0.0025 * world_bbox.DiagonalRadius();
    for (int i = 0; i < mesh->NVertices(); i++) {
      R3MeshVertex *vertex = mesh->Vertex(i);
      const R3Point& position = mesh->VertexPosition(vertex);
      const R3Vector& normal = mesh->VertexNormal(vertex);
      R3LoadPoint(position);
      R3LoadPoint(position + d * normal);
    }
    RNGrfxEnd();
  }
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xd0(%rsp)
movl %esi, 0xcc(%rsp)
movl %edx, 0xc8(%rsp)
cmpl $0x0, 0x2be47c(%rip)    # 0x2efb80
jne 0x3170b
jmp 0x31bfa
cmpl $0x0, 0x2cd5ba(%rip)    # 0x2feccc
je 0x3197c
cmpl $0x2, 0xc8(%rsp)
jne 0x3172e
movl $0xb50, %edi            # imm = 0xB50
callq 0x29a50
jmp 0x31738
movl $0xb50, %edi            # imm = 0xB50
callq 0x2a130
movsd 0x234950(%rip), %xmm2   # 0x266090
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0x38d60
cmpl $0x1, 0xc8(%rsp)
je 0x3175f
cmpl $0x2, 0xc8(%rsp)
jne 0x317d0
leaq 0xc0(%rsp), %rdi
movl $0x772, %esi            # imm = 0x772
callq 0x38e50
cmpl $0x1, 0xc8(%rsp)
jne 0x317a2
leaq 0xb8(%rsp), %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x38e50
movq 0xb8(%rsp), %rsi
leaq 0xc0(%rsp), %rdi
callq 0x38e70
movq 0xd0(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rsi
movq (%rdi), %rax
callq *0x120(%rax)
jmp 0x3197a
movl $0x4, %edi
callq 0x38d90
movl $0x0, 0xac(%rsp)
movl 0xac(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x39030
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x31975
movq 0xd0(%rsp), %rdi
movl 0xac(%rsp), %esi
callq 0x39050
movq %rax, 0xa0(%rsp)
cmpl $0x5, 0xc8(%rsp)
jne 0x3184b
movl 0xcc(%rsp), %edi
movl 0xac(%rsp), %edx
movl $0x4, %esi
callq 0x340b0
jmp 0x318a3
cmpl $0x3, 0xc8(%rsp)
jne 0x31876
movq 0xd0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x39080
movl %eax, %edi
addl $0x1, %edi
callq 0x34130
jmp 0x318a1
cmpl $0x4, 0xc8(%rsp)
jne 0x3189f
movq 0xd0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x390a0
movl %eax, %edi
addl $0x1, %edi
callq 0x34130
jmp 0x318a1
jmp 0x318a3
cmpl $0x2, 0xc8(%rsp)
jne 0x318ca
movq 0xd0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x390e0
movq %rax, %rdi
callq 0x390c0
movl $0x0, 0x9c(%rsp)
cmpl $0x3, 0x9c(%rsp)
jge 0x3195d
movq 0xd0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
movl 0x9c(%rsp), %edx
callq 0x39110
movq %rax, 0x90(%rsp)
cmpl $0x1, 0xc8(%rsp)
jne 0x3192a
movq 0xd0(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x39180
movq %rax, %rdi
callq 0x39130
movq 0xd0(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x391a0
movq %rax, %rdi
callq 0x38e20
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x318d5
jmp 0x3195f
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x317e5
callq 0x38e40
jmp 0x3197c
cmpl $0x0, 0x2cd34d(%rip)    # 0x2fecd0
je 0x319e2
cmpl $0x5, 0xc8(%rsp)
je 0x319e0
movl $0xb50, %edi            # imm = 0xB50
callq 0x2a130
movsd 0x23466f(%rip), %xmm0   # 0x266010
xorps %xmm2, %xmm2
movaps %xmm2, %xmm1
callq 0x38d60
movq 0xd0(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x88(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x38e50
movq 0x10(%rsp), %rdi
movq 0x88(%rsp), %rsi
movq (%rdi), %rax
callq *0x130(%rax)
jmp 0x319e2
cmpl $0x0, 0x2be18f(%rip)    # 0x2efb78
je 0x31adc
movl $0xb50, %edi            # imm = 0xB50
callq 0x2a130
xorps %xmm1, %xmm1
movsd 0x23460c(%rip), %xmm2   # 0x266010
movaps %xmm1, %xmm0
callq 0x38d60
xorl %edi, %edi
callq 0x38d90
movl $0x0, 0x84(%rsp)
movl 0x84(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x391c0
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x31ad7
movq 0xd0(%rsp), %rdi
movl 0x84(%rsp), %esi
callq 0x391e0
movq %rax, 0x78(%rsp)
cmpl $0x5, 0xc8(%rsp)
jne 0x31a81
movl 0xcc(%rsp), %edi
movl 0x84(%rsp), %edx
movl $0x2, %esi
callq 0x340b0
jmp 0x31aa7
cmpl $0x1, 0xc8(%rsp)
jne 0x31aa5
movq 0xd0(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x39180
movq %rax, %rdi
callq 0x39130
jmp 0x31aa7
movq 0xd0(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x391a0
movq %rax, %rdi
callq 0x38e20
movl 0x84(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x84(%rsp)
jmp 0x31a1e
callq 0x38e40
cmpl $0x0, 0x2cd1e5(%rip)    # 0x2fecc8
je 0x31bfa
movl $0xb50, %edi            # imm = 0xB50
callq 0x2a130
xorps %xmm2, %xmm2
movsd 0x234512(%rip), %xmm1   # 0x266010
movaps %xmm2, %xmm0
callq 0x38d60
movl $0x1, %edi
callq 0x38d90
leaq 0x2ccd21(%rip), %rdi    # 0x2fe838
callq 0x38be0
movaps %xmm0, %xmm1
movsd 0x234561(%rip), %xmm0   # 0x266088
mulsd %xmm1, %xmm0
movsd %xmm0, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x391c0
movl %eax, %ecx
movl 0x8(%rsp), %eax
cmpl %ecx, %eax
jge 0x31bf5
movq 0xd0(%rsp), %rdi
movl 0x6c(%rsp), %esi
callq 0x391e0
movq %rax, 0x60(%rsp)
movq 0xd0(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x391a0
movq %rax, 0x58(%rsp)
movq 0xd0(%rsp), %rdi
movq 0x60(%rsp), %rsi
callq 0x39210
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rdi
callq 0x38e20
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
movsd 0x70(%rsp), %xmm0
movq 0x50(%rsp), %rsi
leaq 0x20(%rsp), %rdi
callq 0x38f20
movq (%rsp), %rsi
leaq 0x38(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x180350
leaq 0x38(%rsp), %rdi
callq 0x38e20
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x31b39
callq 0x38e40
addq $0xd8, %rsp
retq
nopw %cs:(%rax,%rax)