// File: tomfunkhouser[P]gaps/pkgs/RGBD/RGBDConfiguration.cpp
// Function: gaps::RGBDConfiguration::WriteObjFile(char const*) const
int RGBDConfiguration::
WriteObjFile(const char *filename) const
{
  // Write mtl file
  char mtl_filename[1024];
  strncpy(mtl_filename, filename, 1020);
  char *endp = strrchr(mtl_filename, '.');
  if (endp) { *endp = '\0'; strcat(mtl_filename, ".mtl"); }
  if (!WriteMtlFile(this, mtl_filename)) return 0;

  // Open obj file
  FILE *fp = fopen(filename, "w");
  if (!fp) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Write material library
  char *startp = strrchr(mtl_filename, '/');
  if (startp) startp++;
  else startp = mtl_filename;
  fprintf(fp, "mtllib %s\n", startp);

  // Write surfaces
  for (int s = 0; s < NSurfaces(); s++) {
    RGBDSurface *surface = Surface(s);
    int width = surface->NTexels(RN_X);
    int height = surface->NTexels(RN_Y);
    if ((width == 0) || (height == 0)) continue;
    
    // Write mesh
    R3Mesh *mesh = surface->mesh;
    if (mesh) {
      // Write material reference
      fprintf(fp, "g surface%d\n", s);
      fprintf(fp, "usemtl surface%d\n", s);

      // Write vertices
      for (int i = 0; i < mesh->NVertices(); i++) {
        R3MeshVertex *vertex = mesh->Vertex(i);
        const R3Point& p = mesh->VertexPosition(vertex);
        R2Point t, s = mesh->VertexTextureCoords(vertex);
        surface->TransformSurfaceToTexture(s, t);
        fprintf(fp, "vt %g %g\n", t.X() / width, t.Y() / height);
        fprintf(fp, "v %g %g %g\n", p.X(), p.Y(), p.Z());
      }

      // Write faces
      for (int i = 0; i < mesh->NFaces(); i++) {
        R3MeshFace *face = mesh->Face(i);
        R3MeshVertex *v0 = mesh->VertexOnFace(face, 0);
        R3MeshVertex *v1 = mesh->VertexOnFace(face, 1);
        R3MeshVertex *v2 = mesh->VertexOnFace(face, 2);
        int i0 = mesh->VertexID(v0) + 1;
        int i1 = mesh->VertexID(v1) + 1;
        int i2 = mesh->VertexID(v2) + 1;
        fprintf(fp, "f %d/%d %d/%d %d/%d\n", i0, i0, i1, i1, i2, i2);
      }
    }
  }
  
  // Close obj file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
subq $0x518, %rsp            # imm = 0x518
movq %rdi, 0x508(%rsp)
movq %rsi, 0x500(%rsp)
movq 0x508(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0x100(%rsp), %rdi
movq 0x500(%rsp), %rsi
movl $0x3fc, %edx            # imm = 0x3FC
callq 0x12350
leaq 0x100(%rsp), %rdi
movl $0x2e, %esi
callq 0x127a0
movq %rax, 0xf8(%rsp)
cmpq $0x0, 0xf8(%rsp)
je 0x20fe2
movq 0xf8(%rsp), %rax
movb $0x0, (%rax)
leaq 0x100(%rsp), %rdi
leaq 0x145da9(%rip), %rsi    # 0x166d86
callq 0x12c40
movq 0x50(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x214d0
cmpl $0x0, %eax
jne 0x21009
movl $0x0, 0x514(%rsp)
jmp 0x214b6
movq 0x500(%rsp), %rdi
leaq 0x147892(%rip), %rsi    # 0x1688aa
callq 0x12860
movq %rax, 0xf0(%rsp)
cmpq $0x0, 0xf0(%rsp)
jne 0x21056
movq 0x500(%rsp), %rsi
leaq 0x145d4c(%rip), %rdi    # 0x166d8b
movb $0x0, %al
callq 0xdf990
movl $0x0, 0x514(%rsp)
jmp 0x214b6
leaq 0x100(%rsp), %rdi
movl $0x2f, %esi
callq 0x127a0
movq %rax, 0xe8(%rsp)
cmpq $0x0, 0xe8(%rsp)
je 0x21091
movq 0xe8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xe8(%rsp)
jmp 0x210a1
leaq 0x100(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0xf0(%rsp), %rdi
movq 0xe8(%rsp), %rdx
leaq 0x145cea(%rip), %rsi    # 0x166da2
movb $0x0, %al
callq 0x12a30
movl $0x0, 0xe4(%rsp)
movq 0x50(%rsp), %rdi
movl 0xe4(%rsp), %eax
movl %eax, 0x4c(%rsp)
callq 0x19c60
movl %eax, %ecx
movl 0x4c(%rsp), %eax
cmpl %ecx, %eax
jge 0x2149e
movq 0x50(%rsp), %rdi
movl 0xe4(%rsp), %esi
callq 0x19f70
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rdi
xorl %esi, %esi
callq 0x19fd0
movl %eax, 0xd4(%rsp)
movq 0xd8(%rsp), %rdi
movl $0x1, %esi
callq 0x19fd0
movl %eax, 0xd0(%rsp)
cmpl $0x0, 0xd4(%rsp)
je 0x21149
cmpl $0x0, 0xd0(%rsp)
jne 0x2114e
jmp 0x21488
movq 0xd8(%rsp), %rax
movq 0x88(%rax), %rax
movq %rax, 0xc8(%rsp)
cmpq $0x0, 0xc8(%rsp)
je 0x21486
movq 0xf0(%rsp), %rdi
movl 0xe4(%rsp), %edx
leaq 0x145c23(%rip), %rsi    # 0x166dad
movb $0x0, %al
callq 0x12a30
movq 0xf0(%rsp), %rdi
movl 0xe4(%rsp), %edx
leaq 0x145c13(%rip), %rsi    # 0x166dba
movb $0x0, %al
callq 0x12a30
movl $0x0, 0xc4(%rsp)
movl 0xc4(%rsp), %eax
movl %eax, 0x48(%rsp)
movq 0xc8(%rsp), %rdi
callq 0x19f40
movl %eax, %ecx
movl 0x48(%rsp), %eax
cmpl %ecx, %eax
jge 0x21343
movq 0xc8(%rsp), %rdi
movl 0xc4(%rsp), %esi
callq 0x22b40
movq %rax, 0xb8(%rsp)
movq 0xc8(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0x22b70
movq %rax, 0xb0(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0xcfd70
movq 0xc8(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0x22b90
movq %rax, %rsi
leaq 0x90(%rsp), %rdi
callq 0xcfdb0
movq 0xd8(%rsp), %rdi
movq (%rdi), %rax
leaq 0x90(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq *0x40(%rax)
movq 0xf0(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x1af20
cvtsi2sdl 0xd4(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x1af70
movq 0x20(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x28(%rsp), %xmm0
cvtsi2sdl 0xd0(%rsp), %xmm2
divsd %xmm2, %xmm1
leaq 0x145b08(%rip), %rsi    # 0x166dcc
movb $0x2, %al
callq 0x12a30
movq 0xf0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x19ea0
movsd %xmm0, 0x40(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x19eb0
movsd %xmm0, 0x38(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x19ec0
movq 0x30(%rsp), %rdi
movsd 0x38(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x40(%rsp), %xmm0
leaq 0x145ab0(%rip), %rsi    # 0x166dd6
movb $0x3, %al
callq 0x12a30
movl 0xc4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc4(%rsp)
jmp 0x211b9
movl $0x0, 0x8c(%rsp)
movl 0x8c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0xc8(%rsp), %rdi
callq 0x19f00
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x21484
movq 0xc8(%rsp), %rdi
movl 0x8c(%rsp), %esi
callq 0x22bb0
movq %rax, 0x80(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x80(%rsp), %rsi
xorl %edx, %edx
callq 0x22be0
movq %rax, 0x78(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x80(%rsp), %rsi
movl $0x1, %edx
callq 0x22be0
movq %rax, 0x70(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x80(%rsp), %rsi
movl $0x2, %edx
callq 0x22be0
movq %rax, 0x68(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x22c00
addl $0x1, %eax
movl %eax, 0x64(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x22c00
addl $0x1, %eax
movl %eax, 0x60(%rsp)
movq 0xc8(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x22c00
addl $0x1, %eax
movl %eax, 0x5c(%rsp)
movq 0xf0(%rsp), %rdi
movl 0x64(%rsp), %edx
movl 0x64(%rsp), %ecx
movl 0x60(%rsp), %r8d
movl 0x60(%rsp), %r9d
movl 0x5c(%rsp), %r10d
movl 0x5c(%rsp), %eax
leaq 0x145983(%rip), %rsi    # 0x166de2
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x12a30
movl 0x8c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8c(%rsp)
jmp 0x2134e
jmp 0x21486
jmp 0x21488
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0x210ca
movq 0xf0(%rsp), %rdi
callq 0x126c0
movl $0x1, 0x514(%rsp)
movl 0x514(%rsp), %eax
addq $0x518, %rsp            # imm = 0x518
retq
nopw %cs:(%rax,%rax)