// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::R3Scene::WritePrincetonFile(char const*) const
int R3Scene::
WritePrincetonFile(const char *filename) const
{
  // Open file
  FILE *fp;
  if (!(fp = fopen(filename, "w"))) {
    RNFail("Unable to open file %s", filename);
    return 0;
  }

  // Determine output directory
  const char *output_directory = ".";

  // Determine if need to remove references
  RNBoolean remove_references = FALSE;
  for (int i = 0; i < NReferencedScenes(); i++) {
    R3Scene *referenced_scene = ReferencedScene(i);
    if (referenced_scene->Filename()) continue;
    remove_references = TRUE; break;
  }

  // Remove references if necessary (this will change the scene structure :( )
  if (remove_references) ((R3Scene *) this)->RemoveReferences();

  // Write color and camera 
  fprintf(fp, "background %g %g %g\n", Background().R(), Background().G(), Background().B());
  fprintf(fp, "ambient %g %g %g\n", Ambient().R(), Ambient().G(), Ambient().B());
  fprintf(fp, "camera %g %g %g  %g %g %g  %g %g %g  %g   %g %g  \n",
    Camera().Origin().X(), Camera().Origin().Y(), Camera().Origin().Z(),
    Camera().Towards().X(), Camera().Towards().Y(), Camera().Towards().Z(),
    Camera().Up().X(), Camera().Up().Y(), Camera().Up().Z(),
    Camera().XFOV(), Camera().Near(), Camera().Far());

  // Create textures files
  for (int i = 0; i < NTextures(); i++) {
    R2Texture *texture = Texture(i);
    if (!CreateTextureFile(this, texture, output_directory)) return 0;
  }

  // Write lights
  fprintf(fp, "\n");
  for (int i = 0; i < NLights(); i++) {
    R3Light *light = Light(i);
    if (!WritePrincetonLight(this, light, fp)) return 0;
  }

  // Write materials
  fprintf(fp, "\n");
  for (int i = 0; i < NMaterials(); i++) {
    R3Material *material = Material(i);
    if (!WritePrincetonMaterial(this, material, fp)) return 0;
  }

  // Write nodes recursively
  int status = WritePrincetonNode(this, root, R3identity_affine, fp, "");
  
  // Close file
  fclose(fp);

  // Return status
  return status;
}

// Assembly:
subq $0x188, %rsp            # imm = 0x188
movq %rdi, 0x178(%rsp)
movq %rsi, 0x170(%rsp)
movq 0x178(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x170(%rsp), %rdi
leaq 0x157424(%rip), %rsi    # 0x19157a
callq 0x22c10
movq %rax, 0x168(%rsp)
cmpq $0x0, %rax
jne 0x3a18f
movq 0x170(%rsp), %rsi
leaq 0x154556(%rip), %rdi    # 0x18e6ce
movb $0x0, %al
callq 0xf3b00
movl $0x0, 0x184(%rsp)
jmp 0x3a7c3
leaq 0x16377a(%rip), %rax    # 0x19d910
movq %rax, 0x160(%rsp)
movl $0x0, 0x15c(%rsp)
movl $0x0, 0x158(%rsp)
movq 0xc8(%rsp), %rdi
movl 0x158(%rsp), %eax
movl %eax, 0xc4(%rsp)
callq 0x2c080
movl %eax, %ecx
movl 0xc4(%rsp), %eax
cmpl %ecx, %eax
jge 0x3a22d
movq 0xc8(%rsp), %rdi
movl 0x158(%rsp), %esi
callq 0x482f0
movq %rax, 0x150(%rsp)
movq 0x150(%rsp), %rdi
callq 0x49420
cmpq $0x0, %rax
je 0x3a20d
jmp 0x3a21a
movl $0x1, 0x15c(%rsp)
jmp 0x3a22d
movl 0x158(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x158(%rsp)
jmp 0x3a1b4
cmpl $0x0, 0x15c(%rsp)
je 0x3a244
movq 0xc8(%rsp), %rdi
callq 0x2d290
movq 0xc8(%rsp), %rdi
movq 0x168(%rsp), %rax
movq %rax, 0x30(%rsp)
callq 0x49440
movq %rax, %rdi
callq 0x2b4a0
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x40(%rsp)
callq 0x49440
movq %rax, %rdi
callq 0x2b4b0
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x38(%rsp)
callq 0x49440
movq %rax, %rdi
callq 0x2b4c0
movq 0x30(%rsp), %rdi
movsd 0x38(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x40(%rsp), %xmm0
leaq 0x154b8f(%rip), %rsi    # 0x18ee46
movb $0x3, %al
callq 0x22f30
movq 0xc8(%rsp), %rdi
movq 0x168(%rsp), %rax
movq %rax, 0x48(%rsp)
callq 0x2be80
movq %rax, %rdi
callq 0x2b4a0
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x58(%rsp)
callq 0x2be80
movq %rax, %rdi
callq 0x2b4b0
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x50(%rsp)
callq 0x2be80
movq %rax, %rdi
callq 0x2b4c0
movq 0x48(%rsp), %rdi
movsd 0x50(%rsp), %xmm1
movaps %xmm0, %xmm2
movsd 0x58(%rsp), %xmm0
leaq 0x154b2a(%rip), %rsi    # 0x18ee5b
movb $0x3, %al
callq 0x22f30
movq 0xc8(%rsp), %rdi
movq 0x168(%rsp), %rax
movq %rax, 0x60(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b820
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0xb8(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b830
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x68(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b900
movq %rax, %rdi
callq 0x2b840
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x70(%rsp)
callq 0x2b8e0
movq %rax, %rsi
leaq 0x138(%rsp), %rdi
callq 0x2b770
leaq 0x138(%rsp), %rdi
callq 0x2b910
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x78(%rsp)
callq 0x2b8e0
movq %rax, %rsi
leaq 0x120(%rsp), %rdi
callq 0x2b770
leaq 0x120(%rsp), %rdi
callq 0x2b920
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x80(%rsp)
callq 0x2b8e0
movq %rax, %rsi
leaq 0x108(%rsp), %rdi
callq 0x2b770
leaq 0x108(%rsp), %rdi
callq 0x2b930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x88(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b910
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x90(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b920
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0x98(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b890
movq %rax, %rdi
callq 0x2b930
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0xa0(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x2b940
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0xa8(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x49460
movq 0xc8(%rsp), %rdi
movsd %xmm0, 0xb0(%rsp)
callq 0x2b8e0
movq %rax, %rdi
callq 0x49470
movq 0x60(%rsp), %rdi
movsd 0x68(%rsp), %xmm1
movsd 0x70(%rsp), %xmm2
movsd 0x78(%rsp), %xmm3
movsd 0x80(%rsp), %xmm4
movsd 0x88(%rsp), %xmm5
movsd 0x90(%rsp), %xmm6
movsd 0x98(%rsp), %xmm7
movsd 0xa0(%rsp), %xmm11
movsd 0xa8(%rsp), %xmm10
movsd 0xb0(%rsp), %xmm9
movaps %xmm0, %xmm8
movsd 0xb8(%rsp), %xmm0
leaq 0x1548f6(%rip), %rsi    # 0x18ee6d
movsd %xmm11, (%rsp)
movsd %xmm10, 0x8(%rsp)
movsd %xmm9, 0x10(%rsp)
movsd %xmm8, 0x18(%rsp)
movb $0x8, %al
callq 0x22f30
movl $0x0, 0x104(%rsp)
movq 0xc8(%rsp), %rdi
movl 0x104(%rsp), %eax
movl %eax, 0x2c(%rsp)
callq 0x2c060
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x3a62c
movq 0xc8(%rsp), %rdi
movl 0x104(%rsp), %esi
callq 0x482b0
movq 0xc8(%rsp), %rdi
movq %rax, 0xf8(%rsp)
movq 0xf8(%rsp), %rsi
movq 0x160(%rsp), %rdx
callq 0x3d140
cmpl $0x0, %eax
jne 0x3a614
movl $0x0, 0x184(%rsp)
jmp 0x3a7c3
jmp 0x3a616
movl 0x104(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x104(%rsp)
jmp 0x3a5a4
movq 0x168(%rsp), %rdi
leaq 0x15b007(%rip), %rsi    # 0x195642
movb $0x0, %al
callq 0x22f30
movl $0x0, 0xf4(%rsp)
movq 0xc8(%rsp), %rdi
movl 0xf4(%rsp), %eax
movl %eax, 0x28(%rsp)
callq 0x2b9f0
movl %eax, %ecx
movl 0x28(%rsp), %eax
cmpl %ecx, %eax
jge 0x3a6d5
movq 0xc8(%rsp), %rdi
movl 0xf4(%rsp), %esi
callq 0x2ba10
movq 0xc8(%rsp), %rdi
movq %rax, 0xe8(%rsp)
movq 0xe8(%rsp), %rsi
movq 0x168(%rsp), %rdx
callq 0x3d160
cmpl $0x0, %eax
jne 0x3a6bd
movl $0x0, 0x184(%rsp)
jmp 0x3a7c3
jmp 0x3a6bf
movl 0xf4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf4(%rsp)
jmp 0x3a64d
movq 0x168(%rsp), %rdi
leaq 0x15af5e(%rip), %rsi    # 0x195642
movb $0x0, %al
callq 0x22f30
movl $0x0, 0xe4(%rsp)
movq 0xc8(%rsp), %rdi
movl 0xe4(%rsp), %eax
movl %eax, 0x24(%rsp)
callq 0x2c020
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x3a77b
movq 0xc8(%rsp), %rdi
movl 0xe4(%rsp), %esi
callq 0x48220
movq 0xc8(%rsp), %rdi
movq %rax, 0xd8(%rsp)
movq 0xd8(%rsp), %rsi
movq 0x168(%rsp), %rdx
callq 0x3d8d0
cmpl $0x0, %eax
jne 0x3a763
movl $0x0, 0x184(%rsp)
jmp 0x3a7c3
jmp 0x3a765
movl 0xe4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xe4(%rsp)
jmp 0x3a6f6
movq 0xc8(%rsp), %rdi
movq (%rdi), %rsi
movq 0x168(%rsp), %rcx
leaq 0x1c423b(%rip), %rdx    # 0x1fe9d0
leaq 0x154808(%rip), %r8     # 0x18efa4
callq 0x3dd50
movl %eax, 0xd4(%rsp)
movq 0x168(%rsp), %rdi
callq 0x229d0
movl 0xd4(%rsp), %eax
movl %eax, 0x184(%rsp)
movl 0x184(%rsp), %eax
addq $0x188, %rsp            # imm = 0x188
retq
nopw %cs:(%rax,%rax)