// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::R3Scene::WriteObj(gaps::R3SceneNode*, char const*) const
int R3Scene::
WriteObj(R3SceneNode *node, const char *filename) const
{
  // Determine directory name (for texture image files)
  char *dirname = NULL;
  char buffer[1024];
  strncpy(buffer, filename, 1023);
  char *endp = strrchr(buffer, '/');
  if (!endp) endp = strrchr(buffer, '\\');
  if (!endp) strcpy(buffer, ".");
  else { *endp = '\0'; dirname = buffer; }

  // Determine material filename
  char mtl_filename[1024];
  const char *startp = strrchr(filename, '/');
  startp = (startp) ? startp+1 : filename;
  strncpy(mtl_filename, startp, 1023);
  int slen = strlen(mtl_filename);
  if (slen > 4) mtl_filename[slen-4] = '\0';
  strncat(mtl_filename, ".mtl", 1024-strlen(mtl_filename));

  // Create directory
  if (dirname) {
    char mkdir_cmd[1064];
    sprintf(mkdir_cmd, "mkdir -p %s", dirname);
    system(mkdir_cmd);
  }

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

  // Write material file
  fprintf(fp, "mtllib %s\n", mtl_filename);
  if (!WriteObjMtlFile(dirname, mtl_filename)) {
    RNFail("Unable to write OBJ material file %s\n", mtl_filename);
    fclose(fp);
    return 0;
  }

  // Write nodes 
  int ngroups = 0;
  int nvertices = 0;
  int nnormals = 0;
  int ntexture_coords = 0;
  if (!WriteObj(node, node->Transformation(), ngroups, nvertices, nnormals, ntexture_coords, fp)) {
    RNFail("Unable to write OBJ file %s\n", filename);
    fclose(fp);
    return 0;
  }

  // Close file
  fclose(fp);

  // Return success
  return 1;
}

// Assembly:
subq $0xcc8, %rsp            # imm = 0xCC8
movq %rdi, 0xcb8(%rsp)
movq %rsi, 0xcb0(%rsp)
movq %rdx, 0xca8(%rsp)
movq 0xcb8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq $0x0, 0xca0(%rsp)
leaq 0x8a0(%rsp), %rdi
movq 0xca8(%rsp), %rsi
movl $0x3ff, %edx            # imm = 0x3FF
callq 0x224b0
leaq 0x8a0(%rsp), %rdi
movl $0x2f, %esi
callq 0x22b10
movq %rax, 0x898(%rsp)
cmpq $0x0, 0x898(%rsp)
jne 0x3c4a1
leaq 0x8a0(%rsp), %rdi
movl $0x5c, %esi
callq 0x22b10
movq %rax, 0x898(%rsp)
cmpq $0x0, 0x898(%rsp)
jne 0x3c4c2
leaq 0x8a0(%rsp), %rdi
leaq 0x161455(%rip), %rsi    # 0x19d910
callq 0x22900
jmp 0x3c4dd
movq 0x898(%rsp), %rax
movb $0x0, (%rax)
leaq 0x8a0(%rsp), %rax
movq %rax, 0xca0(%rsp)
movq 0xca8(%rsp), %rdi
movl $0x2f, %esi
callq 0x22b10
movq %rax, 0x488(%rsp)
cmpq $0x0, 0x488(%rsp)
je 0x3c515
movq 0x488(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0x3c522
movq 0xca8(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x488(%rsp)
leaq 0x490(%rsp), %rdi
movq 0x488(%rsp), %rsi
movl $0x3ff, %edx            # imm = 0x3FF
callq 0x224b0
leaq 0x490(%rsp), %rdi
callq 0x223d0
movl %eax, 0x484(%rsp)
cmpl $0x4, 0x484(%rsp)
jle 0x3c57b
movl 0x484(%rsp), %eax
subl $0x4, %eax
cltq
movb $0x0, 0x490(%rsp,%rax)
leaq 0x490(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0x490(%rsp), %rdi
callq 0x223d0
movq 0x20(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
subq %rax, %rdx
leaq 0x15228f(%rip), %rsi    # 0x18e838
callq 0x226b0
cmpq $0x0, 0xca0(%rsp)
je 0x3c5de
leaq 0x50(%rsp), %rdi
movq 0xca0(%rsp), %rdx
leaq 0x152270(%rip), %rsi    # 0x18e83d
movb $0x0, %al
callq 0x22160
leaq 0x50(%rsp), %rdi
callq 0x22860
movq 0xca8(%rsp), %rdi
leaq 0x154f8d(%rip), %rsi    # 0x19157a
callq 0x22c10
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x48(%rsp)
jne 0x3c625
movq 0xca8(%rsp), %rsi
leaq 0x1520c0(%rip), %rdi    # 0x18e6ce
movb $0x0, %al
callq 0xf3b00
movl $0x0, 0xcc4(%rsp)
jmp 0x3c744
movq 0x48(%rsp), %rdi
leaq 0x490(%rsp), %rdx
leaq 0x152210(%rip), %rsi    # 0x18e849
movb $0x0, %al
callq 0x22f30
movq 0x30(%rsp), %rdi
movq 0xca0(%rsp), %rsi
leaq 0x490(%rsp), %rdx
callq 0x3ab50
cmpl $0x0, %eax
jne 0x3c68f
leaq 0x490(%rsp), %rsi
leaq 0x1521e6(%rip), %rdi    # 0x18e854
movb $0x0, %al
callq 0xf3b00
movq 0x48(%rsp), %rdi
callq 0x229d0
movl $0x0, 0xcc4(%rsp)
jmp 0x3c744
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
movl $0x0, 0x3c(%rsp)
movl $0x0, 0x38(%rsp)
movq 0xcb0(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0xcb0(%rsp), %rdi
callq 0x2bae0
movq 0x30(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq %rax, %rdx
movq 0x48(%rsp), %rax
leaq 0x44(%rsp), %rcx
leaq 0x40(%rsp), %r8
leaq 0x3c(%rsp), %r9
leaq 0x38(%rsp), %r10
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x3b3e0
cmpl $0x0, %eax
jne 0x3c72f
movq 0xca8(%rsp), %rsi
leaq 0x152169(%rip), %rdi    # 0x18e87a
movb $0x0, %al
callq 0xf3b00
movq 0x48(%rsp), %rdi
callq 0x229d0
movl $0x0, 0xcc4(%rsp)
jmp 0x3c744
movq 0x48(%rsp), %rdi
callq 0x229d0
movl $0x1, 0xcc4(%rsp)
movl 0xcc4(%rsp), %eax
addq $0xcc8, %rsp            # imm = 0xCC8
retq
nopw %cs:(%rax,%rax)