// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::CopyScene(gaps::R3Scene*, gaps::R3Scene*, gaps::R3SceneNode*, gaps::RNArray<gaps::R3Material*> const*)
static void
CopyScene(R3Scene *src_scene, R3Scene *dst_scene,
  R3SceneNode *dst_root_node = NULL, const RNArray<R3Material *> *materials = NULL)
{
  // Get/check inputs
  if (!src_scene || !dst_scene) return;
  if (!dst_root_node) dst_root_node = dst_scene->Root();
  
  // Copy lights
  RNArray<R3Light *> dst_lights;
  for (int i = 0; i < src_scene->NLights(); i++) {
    R3Light *src_light = src_scene->Light(i);
    R3Light *dst_light = src_light->Copy();
    dst_scene->InsertLight(dst_light);
    dst_lights.Insert(dst_light);
  }

  // Copy textures
  RNArray<R2Texture *> dst_textures;
  for (int i = 0; i < src_scene->NTextures(); i++) {
    R2Texture *src_texture = src_scene->Texture(i);
    R2Texture *dst_texture = new R2Texture(*src_texture);
    dst_textures.Insert(dst_texture);
    dst_scene->InsertTexture(dst_texture);
  }

  // Copy brdfs
  RNArray<R3Brdf *> dst_brdfs;
  for (int i = 0; i < src_scene->NBrdfs(); i++) {
    R3Brdf *src_brdf = src_scene->Brdf(i);
    R3Brdf *dst_brdf = new R3Brdf(*src_brdf);
    dst_brdfs.Insert(dst_brdf);
    dst_scene->InsertBrdf(dst_brdf);
  }

  // Copy materials
  RNArray<R3Material *> dst_materials;
  for (int i = 0; i < src_scene->NMaterials(); i++) {
    R3Material *dst_material = (i < materials->NEntries()) ? materials->Kth(i) : NULL;
    if (!dst_material) {
      R3Material *src_material = src_scene->Material(i);
      R3Brdf *dst_brdf = (src_material->Brdf()) ? dst_brdfs[src_material->Brdf()->SceneIndex()] : NULL;
      R2Texture *dst_texture = (src_material->Texture()) ? dst_textures[src_material->Texture()->SceneIndex()] : NULL;
      dst_material = new R3Material(dst_brdf, dst_texture, src_material->Name());
      dst_scene->InsertMaterial(dst_material);
    }
    dst_materials.Insert(dst_material);
  }

  // Copy nodes 
  RNArray<R3SceneNode *> dst_nodes;
  for (int i = 0; i < src_scene->NNodes(); i++) {
    R3SceneNode *src_node = src_scene->Node(i);
    R3SceneNode *dst_node = new R3SceneNode(*src_node);
    dst_scene->InsertNode(dst_node);
    dst_nodes.Insert(dst_node);

    // Copy elements
    for (int i = 0; i < src_node->NElements(); i++) {
      R3SceneElement *src_element = src_node->Element(i);
      R3Material *src_material = src_element->Material();
      R3Material *dst_material = (src_material) ? dst_materials[src_material->SceneIndex()] : NULL;
      R3SceneElement *dst_element = new R3SceneElement(dst_material);
      dst_node->InsertElement(dst_element);
      for (int j = 0; j < src_element->NShapes(); j++) {
        R3Shape *src_shape = src_element->Shape(j);
        R3Shape *dst_shape = src_shape->Copy();
        dst_element->InsertShape(dst_shape);
      }
    }

    // Copy references
    for (int i = 0; i < src_node->NReferences(); i++) {
      R3SceneReference *src_reference = src_node->Reference(i);
      R3Scene *src_referenced_scene = src_reference->ReferencedScene();
      RNArray<R3Material *> dst_reference_materials;
      for (int j = 0; j < src_reference->NMaterials(); j++) {
        R3Material *src_material = src_reference->Material(j);
        R3Material *dst_material = dst_materials[src_material->SceneIndex()];
        dst_scene->InsertMaterial(dst_material);
      }
      CopyScene(src_referenced_scene, dst_scene, dst_node, &dst_reference_materials);
    }
  }
  
  // Copy node hierarchy
  for (int i = 0; i < src_scene->NNodes(); i++) {
    R3SceneNode *src_node = src_scene->Node(i);
    R3SceneNode *dst_node = dst_nodes.Kth(i);
    R3SceneNode *src_parent = src_node->Parent();
    R3SceneNode *dst_parent = (src_parent) ? dst_nodes[src_parent->SceneIndex()] : dst_root_node;
    dst_parent->InsertChild(dst_node);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rcx, 0x10(%rsp)
testq %rdi, %rdi
sete %al
testq %rsi, %rsi
sete %cl
orb %al, %cl
jne 0x36db1
movq %rsi, %r15
movq %rdi, %rbx
testq %rdx, %rdx
jne 0x36916
movq (%r15), %rdx
movq %rdx, 0x70(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x8758c
cmpl $0x0, 0x24(%rbx)
movq %rbx, 0x8(%rsp)
jle 0x36985
movq %rbx, %rcx
leaq 0x18(%r15), %rbx
xorl %r12d, %r12d
leaq 0x60(%rsp), %r14
movq 0x18(%rcx), %rax
movq (%rax,%r12,8), %rdi
callq 0x42c90
movq %rax, %r13
movq %r15, 0x8(%rax)
movl 0x24(%r15), %edx
movl %edx, 0x10(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0x87622
movl 0x6c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x87622
incq %r12
movq 0x8(%rsp), %rcx
movslq 0x24(%rcx), %rax
cmpq %rax, %r12
jl 0x3693f
leaq 0x50(%rsp), %rdi
callq 0x8758c
movq 0x8(%rsp), %rcx
cmpl $0x0, 0x54(%rcx)
jle 0x369ff
leaq 0x48(%r15), %rbx
xorl %r12d, %r12d
leaq 0x50(%rsp), %r14
movq 0x48(%rcx), %rax
movq (%rax,%r12,8), %rbp
movl $0x50, %edi
callq 0x218c0
movq %rax, %r13
movq %rax, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x4497a
movl 0x5c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x87622
movq %r15, (%r13)
movl 0x54(%r15), %edx
movl %edx, 0x8(%r13)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x87622
incq %r12
movq 0x8(%rsp), %rcx
movslq 0x54(%rcx), %rax
cmpq %rax, %r12
jl 0x369a6
leaq 0x40(%rsp), %rdi
callq 0x8758c
movq 0x8(%rsp), %rcx
cmpl $0x0, 0x44(%rcx)
jle 0x36a79
leaq 0x38(%r15), %rbx
xorl %r12d, %r12d
leaq 0x40(%rsp), %r14
movq 0x38(%rcx), %rax
movq (%rax,%r12,8), %rbp
movl $0xb8, %edi
callq 0x218c0
movq %rax, %r13
movq %rax, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x43df4
movl 0x4c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x87622
movq %r15, 0x8(%r13)
movl 0x44(%r15), %edx
movl %edx, 0x10(%r13)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x87622
incq %r12
movq 0x8(%rsp), %rcx
movslq 0x44(%rcx), %rax
cmpq %rax, %r12
jl 0x36a20
leaq 0x20(%rsp), %rdi
callq 0x8758c
movq 0x8(%rsp), %rax
cmpl $0x0, 0x34(%rax)
jle 0x36b5c
leaq 0x28(%r15), %rax
movq %rax, 0x18(%rsp)
xorl %r12d, %r12d
movq 0x10(%rsp), %rax
movslq 0xc(%rax), %rax
cmpq %rax, %r12
jge 0x36abd
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r12,8), %r14
testq %r14, %r14
jne 0x36b36
movq 0x8(%rsp), %rax
movq 0x28(%rax), %rax
movq (%rax,%r12,8), %rbx
movq 0x18(%rbx), %rax
testq %rax, %rax
je 0x36ae2
movslq 0x10(%rax), %rax
movq 0x40(%rsp), %rcx
movq (%rcx,%rax,8), %rbp
jmp 0x36ae4
xorl %ebp, %ebp
movq 0x20(%rbx), %rax
testq %rax, %rax
je 0x36afc
movslq 0x8(%rax), %rax
movq 0x50(%rsp), %rcx
movq (%rcx,%rax,8), %r13
jmp 0x36aff
xorl %r13d, %r13d
movl $0x30, %edi
callq 0x218c0
movq %rax, %r14
movq 0x10(%rbx), %rcx
movq %rax, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0x43b4a
movq %r15, (%r14)
movl 0x34(%r15), %edx
movl %edx, 0x8(%r14)
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x87622
movl 0x2c(%rsp), %edx
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x87622
incq %r12
movq 0x8(%rsp), %rax
movslq 0x34(%rax), %rax
cmpq %rax, %r12
jl 0x36a9e
leaq 0x30(%rsp), %rdi
callq 0x8758c
movq 0x8(%rsp), %r14
cmpl $0x0, 0x14(%r14)
jle 0x36d7f
leaq 0x8(%r15), %rax
movq %rax, 0x78(%rsp)
leaq 0x28(%r15), %r13
xorl %ebx, %ebx
movq 0x8(%r14), %rax
movq (%rax,%rbx,8), %r12
movl $0x1b0, %edi            # imm = 0x1B0
callq 0x218c0
movq %rax, %r14
movq %rax, %rdi
movq %r12, %rsi
callq 0x3b6f0
movq %r15, (%r14)
movl 0x14(%r15), %edx
movl %edx, 0x8(%r14)
movq 0x78(%rsp), %rdi
movq %r14, %rsi
callq 0x87622
movl 0x3c(%rsp), %edx
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x87622
movq %r14, 0x10(%rsp)
movq %rbx, 0x80(%rsp)
cmpl $0x0, 0x3c(%r12)
movq %r12, 0x18(%rsp)
jle 0x36c81
xorl %ebp, %ebp
movq 0x30(%r12), %rax
movq (%rax,%rbp,8), %r12
movq 0x8(%r12), %rax
testq %rax, %rax
je 0x36c10
movslq 0x8(%rax), %rax
movq 0x20(%rsp), %rcx
movq (%rcx,%rax,8), %rbx
jmp 0x36c12
xorl %ebx, %ebx
movl $0x60, %edi
callq 0x218c0
movq %rax, %r14
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3d514
movq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x3c9ce
cmpl $0x0, 0x1c(%r12)
jle 0x36c6b
xorl %ebx, %ebx
movq 0x10(%r12), %rax
movq (%rax,%rbx,8), %rdi
movq (%rdi), %rax
callq *0x98(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x3d7bc
incq %rbx
movslq 0x1c(%r12), %rax
cmpq %rax, %rbx
jl 0x36c41
incq %rbp
movq 0x18(%rsp), %r12
movslq 0x3c(%r12), %rax
cmpq %rax, %rbp
jl 0x36bee
cmpl $0x0, 0x4c(%r12)
leaq 0x88(%rsp), %rbp
jle 0x36d24
xorl %ebx, %ebx
movq 0x40(%r12), %rax
movq (%rax,%rbx,8), %r12
movq (%r12), %r14
movq %rbp, %rdi
callq 0x8758c
cmpl $0x0, 0x14(%r12)
jle 0x36ceb
xorl %ebp, %ebp
movq 0x8(%r12), %rax
movq (%rax,%rbp,8), %rax
movslq 0x8(%rax), %rax
movq 0x20(%rsp), %rcx
movq (%rcx,%rax,8), %rsi
movq %r15, (%rsi)
movl 0x34(%r15), %edx
movl %edx, 0x8(%rsi)
movq %r13, %rdi
callq 0x87622
incq %rbp
movslq 0x14(%r12), %rax
cmpq %rax, %rbp
jl 0x36cb6
movq %r14, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %rdx
leaq 0x88(%rsp), %rbp
movq %rbp, %rcx
callq 0x368de
movq %rbp, %rdi
callq 0x875f6
incq %rbx
movq 0x18(%rsp), %r12
movslq 0x4c(%r12), %rax
cmpq %rax, %rbx
jl 0x36c97
movq 0x80(%rsp), %rbx
incq %rbx
movq 0x8(%rsp), %r14
movslq 0x14(%r14), %rax
cmpq %rax, %rbx
jl 0x36b85
testl %eax, %eax
jle 0x36d7f
xorl %ebx, %ebx
movq 0x8(%r14), %rax
movq (%rax,%rbx,8), %rcx
movq 0x30(%rsp), %rax
movq 0x10(%rcx), %rcx
movq 0x70(%rsp), %rdi
testq %rcx, %rcx
je 0x36d6a
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq (%rax,%rbx,8), %rsi
callq 0x3c97e
incq %rbx
movslq 0x14(%r14), %rax
cmpq %rax, %rbx
jl 0x36d47
leaq 0x30(%rsp), %rdi
callq 0x875f6
leaq 0x20(%rsp), %rdi
callq 0x875f6
leaq 0x40(%rsp), %rdi
callq 0x875f6
leaq 0x50(%rsp), %rdi
callq 0x875f6
leaq 0x60(%rsp), %rdi
callq 0x875f6
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x36e12
jmp 0x36e19
jmp 0x36e1e
jmp 0x36e23
jmp 0x36e52
movq %rax, %rbx
movl $0x30, %esi
movq %r14, %rdi
callq 0x218e0
jmp 0x36e5f
movq %rax, %rbx
movl $0x1b0, %esi            # imm = 0x1B0
jmp 0x36e34
jmp 0x36e12
movq %rax, %rbx
movl $0xb8, %esi
movq %r13, %rdi
callq 0x218e0
jmp 0x36e69
movq %rax, %rbx
movl $0x50, %esi
movq %r13, %rdi
callq 0x218e0
jmp 0x36e73
movq %rax, %rbx
jmp 0x36e5f
jmp 0x36e52
movq %rax, %rbx
jmp 0x36e69
movq %rax, %rbx
jmp 0x36e73
movq %rax, %rbx
jmp 0x36e7d
jmp 0x36e40
jmp 0x36e52
movq %rax, %rbx
movl $0x60, %esi
movq %r14, %rdi
callq 0x218e0
jmp 0x36e55
jmp 0x36e52
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x875f6
jmp 0x36e55
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x875f6
leaq 0x20(%rsp), %rdi
callq 0x875f6
leaq 0x40(%rsp), %rdi
callq 0x875f6
leaq 0x50(%rsp), %rdi
callq 0x875f6
leaq 0x60(%rsp), %rdi
callq 0x875f6
movq %rbx, %rdi
callq 0x220c0
nop