// File: /workspace/github_cpp_makefile_star2_O1/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 %rsi, %r15
testq %rdi, %rdi
sete %al
testq %rsi, %rsi
sete %sil
orb %al, %sil
jne 0x371c6
movq %rdi, %r13
movq %rcx, 0x10(%rsp)
testq %rdx, %rdx
jne 0x36d2b
movq (%r15), %rdx
movq %rdx, 0x70(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x886bc
cmpl $0x0, 0x24(%r13)
movq %r13, 0x8(%rsp)
jle 0x36d98
leaq 0x18(%r15), %rbx
xorl %r12d, %r12d
leaq 0x60(%rsp), %r14
movq 0x18(%r13), %rax
movq (%rax,%r12,8), %rdi
callq 0x431a8
movq %rax, %r13
movq %r15, 0x8(%rax)
movl 0x24(%r15), %edx
movl %edx, 0x10(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0x88752
movl 0x6c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x88752
incq %r12
movq 0x8(%rsp), %r13
movslq 0x24(%r13), %rax
cmpq %rax, %r12
jl 0x36d52
leaq 0x50(%rsp), %rdi
callq 0x886bc
cmpl $0x0, 0x54(%r13)
jle 0x36e0e
leaq 0x48(%r15), %rbx
xorl %r12d, %r12d
leaq 0x50(%rsp), %r14
movq 0x48(%r13), %rax
movq (%rax,%r12,8), %rbp
movl $0x50, %edi
callq 0x218c0
movq %rax, %r13
movq %rax, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x44f56
movl 0x5c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x88752
movq %r15, (%r13)
movl 0x54(%r15), %edx
movl %edx, 0x8(%r13)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x88752
incq %r12
movq 0x8(%rsp), %r13
movslq 0x54(%r13), %rax
cmpq %rax, %r12
jl 0x36db5
leaq 0x40(%rsp), %rdi
callq 0x886bc
cmpl $0x0, 0x44(%r13)
jle 0x36e84
leaq 0x38(%r15), %rbx
xorl %r12d, %r12d
leaq 0x40(%rsp), %r14
movq 0x38(%r13), %rax
movq (%rax,%r12,8), %rbp
movl $0xb8, %edi
callq 0x218c0
movq %rax, %r13
movq %rax, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x443d8
movl 0x4c(%rsp), %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x88752
movq %r15, 0x8(%r13)
movl 0x44(%r15), %edx
movl %edx, 0x10(%r13)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x88752
incq %r12
movq 0x8(%rsp), %r13
movslq 0x44(%r13), %rax
cmpq %rax, %r12
jl 0x36e2b
leaq 0x20(%rsp), %rdi
callq 0x886bc
cmpl $0x0, 0x34(%r13)
movq 0x10(%rsp), %rcx
jle 0x36f6a
leaq 0x28(%r15), %rax
movq %rax, 0x18(%rsp)
xorl %r13d, %r13d
movslq 0xc(%rcx), %rax
cmpq %rax, %r13
jge 0x36ebc
movq (%rcx), %rax
movq (%rax,%r13,8), %r14
jmp 0x36ebf
xorl %r14d, %r14d
testq %r14, %r14
jne 0x36f3f
movq 0x8(%rsp), %rax
movq 0x28(%rax), %rax
movq (%rax,%r13,8), %r12
movq 0x18(%r12), %rax
testq %rax, %rax
je 0x36eea
movslq 0x10(%rax), %rax
movq 0x40(%rsp), %rcx
movq (%rcx,%rax,8), %rbp
jmp 0x36eec
xorl %ebp, %ebp
movq 0x20(%r12), %rax
testq %rax, %rax
je 0x36f05
movslq 0x8(%rax), %rax
movq 0x50(%rsp), %rcx
movq (%rcx,%rax,8), %rbx
jmp 0x36f07
xorl %ebx, %ebx
movl $0x30, %edi
callq 0x218c0
movq %rax, %r14
movq 0x10(%r12), %rcx
movq %rax, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x44174
movq %r15, (%r14)
movl 0x34(%r15), %edx
movl %edx, 0x8(%r14)
movq 0x18(%rsp), %rdi
movq %r14, %rsi
callq 0x88752
movl 0x2c(%rsp), %edx
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
callq 0x88752
incq %r13
movq 0x8(%rsp), %rax
movslq 0x34(%rax), %rax
cmpq %rax, %r13
movq 0x10(%rsp), %rcx
jl 0x36eaa
leaq 0x30(%rsp), %rdi
callq 0x886bc
movq 0x8(%rsp), %rcx
cmpl $0x0, 0x14(%rcx)
jle 0x3714e
leaq 0x8(%r15), %rax
movq %rax, 0x78(%rsp)
leaq 0x28(%r15), %r13
xorl %ebx, %ebx
movq 0x8(%rcx), %rax
movq (%rax,%rbx,8), %r12
movl $0x1b0, %edi            # imm = 0x1B0
callq 0x218c0
movq %rax, %r14
movq %rax, %rdi
movq %r12, %rsi
callq 0x3bc4e
movq %r15, (%r14)
movl 0x14(%r15), %edx
movl %edx, 0x8(%r14)
movq 0x78(%rsp), %rdi
movq %r14, %rsi
callq 0x88752
movl 0x3c(%rsp), %edx
leaq 0x30(%rsp), %rdi
movq %r14, %rsi
callq 0x88752
movq %r14, 0x10(%rsp)
movq %rbx, 0x80(%rsp)
cmpl $0x0, 0x3c(%r12)
movq %r12, 0x18(%rsp)
jle 0x3708e
xorl %ebp, %ebp
movq 0x30(%r12), %rax
movq (%rax,%rbp,8), %r12
movq 0x8(%r12), %rax
testq %rax, %rax
je 0x3701d
movslq 0x8(%rax), %rax
movq 0x20(%rsp), %rcx
movq (%rcx,%rax,8), %rbx
jmp 0x3701f
xorl %ebx, %ebx
movl $0x60, %edi
callq 0x218c0
movq %rax, %r14
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3d9c4
movq 0x10(%rsp), %rdi
movq %r14, %rsi
callq 0x3ceca
cmpl $0x0, 0x1c(%r12)
jle 0x37078
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 0x3dc6c
incq %rbx
movslq 0x1c(%r12), %rax
cmpq %rax, %rbx
jl 0x3704e
incq %rbp
movq 0x18(%rsp), %r12
movslq 0x3c(%r12), %rax
cmpq %rax, %rbp
jl 0x36ffb
cmpl $0x0, 0x4c(%r12)
leaq 0x88(%rsp), %rbp
jle 0x37131
xorl %ebx, %ebx
movq 0x40(%r12), %rax
movq (%rax,%rbx,8), %r12
movq (%r12), %r14
movq %rbp, %rdi
callq 0x886bc
cmpl $0x0, 0x14(%r12)
jle 0x370f8
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 0x88752
incq %rbp
movslq 0x14(%r12), %rax
cmpq %rax, %rbp
jl 0x370c3
movq %r14, %rdi
movq %r15, %rsi
movq 0x10(%rsp), %rdx
leaq 0x88(%rsp), %rbp
movq %rbp, %rcx
callq 0x36cf1
movq %rbp, %rdi
callq 0x88726
incq %rbx
movq 0x18(%rsp), %r12
movslq 0x4c(%r12), %rax
cmpq %rax, %rbx
jl 0x370a4
movq 0x80(%rsp), %rbx
incq %rbx
movq 0x8(%rsp), %rcx
movslq 0x14(%rcx), %rax
cmpq %rax, %rbx
jl 0x36f92
cmpl $0x0, 0x14(%rcx)
movq 0x70(%rsp), %r14
jle 0x37194
movq %rcx, %r15
xorl %ebx, %ebx
movq 0x8(%r15), %rax
movq (%rax,%rbx,8), %rcx
movq 0x30(%rsp), %rax
movq 0x10(%rcx), %rcx
movq %r14, %rdi
testq %rcx, %rcx
je 0x3717f
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
movq (%rax,%rbx,8), %rsi
callq 0x3ce8e
incq %rbx
movslq 0x14(%r15), %rax
cmpq %rax, %rbx
jl 0x3715e
leaq 0x30(%rsp), %rdi
callq 0x88726
leaq 0x20(%rsp), %rdi
callq 0x88726
leaq 0x40(%rsp), %rdi
callq 0x88726
leaq 0x50(%rsp), %rdi
callq 0x88726
leaq 0x60(%rsp), %rdi
callq 0x88726
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x37200
jmp 0x3722b
jmp 0x37230
jmp 0x37235
movq %rax, %rbx
movl $0x30, %esi
movq %r14, %rdi
callq 0x218e0
jmp 0x37271
jmp 0x37200
movq %rax, %rbx
movl $0x1b0, %esi            # imm = 0x1B0
jmp 0x37246
jmp 0x37264
movq %rax, %rbx
jmp 0x37271
movq %rax, %rbx
movl $0xb8, %esi
movq %r13, %rdi
callq 0x218e0
jmp 0x3727b
movq %rax, %rbx
movl $0x50, %esi
movq %r13, %rdi
callq 0x218e0
jmp 0x37285
jmp 0x37264
movq %rax, %rbx
jmp 0x3727b
movq %rax, %rbx
jmp 0x37285
movq %rax, %rbx
jmp 0x3728f
jmp 0x37252
jmp 0x37264
movq %rax, %rbx
movl $0x60, %esi
movq %r14, %rdi
callq 0x218e0
jmp 0x37267
jmp 0x37264
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x88726
jmp 0x37267
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x88726
leaq 0x20(%rsp), %rdi
callq 0x88726
leaq 0x40(%rsp), %rdi
callq 0x88726
leaq 0x50(%rsp), %rdi
callq 0x88726
leaq 0x60(%rsp), %rdi
callq 0x88726
movq %rbx, %rdi
callq 0x220d0
nop