// File: tomfunkhouser[P]gaps/pkgs/R3Graphics/R3Scene.cpp
// Function: gaps::R3SceneSubdivideTriangles(gaps::R3Scene*, gaps::R3SceneNode*, double)
static void
R3SceneSubdivideTriangles(R3Scene *scene, R3SceneNode *node, RNLength max_edge_length)
{
  // Check max edge length
  if (RNIsNegativeOrZero(max_edge_length)) return;

  // Transform max_edge_length
  RNScalar scale = node->Transformation().ScaleFactor();
  if (RNIsNotZero(scale)) max_edge_length /= scale;

  // Subdivide triangles in elements
  for (int i = 0; i < node->NElements(); i++) {
    R3SceneElement *element = node->Element(i);
    for (int j = 0; j < element->NShapes(); j++) {
      R3Shape *shape = element->Shape(j);
      if (shape->ClassID() == R3TriangleArray::CLASS_ID()) {
        R3TriangleArray *triangles = (R3TriangleArray *) shape;
        triangles->Subdivide(max_edge_length);
      }
    }
  }

  // Subdivide triangles in references
  for (int i = 0; i < node->NReferences(); i++) {
    R3SceneReference *reference = node->Reference(i);
    R3Scene *referenced_scene = reference->ReferencedScene();
    R3SceneSubdivideTriangles(referenced_scene, referenced_scene->Root(), max_edge_length);
  }

  // Recurse to children
  for (int i = 0; i < node->NChildren(); i++) {
    R3SceneNode *child = node->Child(i);
    R3SceneSubdivideTriangles(scene, child, max_edge_length);
  }
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movsd %xmm0, 0x80(%rsp)
movsd 0x80(%rsp), %xmm0
leaq 0x1c89c8(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x49e40
cmpl $0x0, %eax
je 0x2d8f3
jmp 0x2db0c
movq 0x88(%rsp), %rdi
callq 0x2bae0
movq %rax, %rdi
movq (%rdi), %rax
callq *0xc0(%rax)
movsd %xmm0, 0x78(%rsp)
movsd 0x78(%rsp), %xmm0
leaq 0x1c8989(%rip), %rax    # 0x1f62a8
movsd (%rax), %xmm1
callq 0x48a80
cmpl $0x0, %eax
je 0x2d949
movsd 0x78(%rsp), %xmm1
movsd 0x80(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0x24(%rsp)
movq 0x88(%rsp), %rdi
callq 0x2bba0
movl %eax, %ecx
movl 0x24(%rsp), %eax
cmpl %ecx, %eax
jge 0x2da24
movq 0x88(%rsp), %rdi
movl 0x74(%rsp), %esi
callq 0x2bbc0
movq %rax, 0x68(%rsp)
movl $0x0, 0x64(%rsp)
movl 0x64(%rsp), %eax
movl %eax, 0x20(%rsp)
movq 0x68(%rsp), %rdi
callq 0x2bbf0
movl %eax, %ecx
movl 0x20(%rsp), %eax
cmpl %ecx, %eax
jge 0x2da12
movq 0x68(%rsp), %rdi
movl 0x64(%rsp), %esi
callq 0x2bc10
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rdi
movq (%rdi), %rax
callq *0xb8(%rax)
movl %eax, 0x1c(%rsp)
callq 0xac600
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jne 0x2da03
movq 0x58(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rdi
movsd 0x80(%rsp), %xmm0
movq (%rdi), %rax
callq *0x228(%rax)
jmp 0x2da05
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x2d992
jmp 0x2da14
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x2d951
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x18(%rsp)
movq 0x88(%rsp), %rdi
callq 0x2bb40
movl %eax, %ecx
movl 0x18(%rsp), %eax
cmpl %ecx, %eax
jge 0x2daa7
movq 0x88(%rsp), %rdi
movl 0x4c(%rsp), %esi
callq 0x2bb60
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rdi
callq 0x2bb90
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rdi
callq 0x2b510
movq 0x10(%rsp), %rdi
movq %rax, %rsi
movsd 0x80(%rsp), %xmm0
callq 0x2d8b0
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x2da2c
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x88(%rsp), %rdi
callq 0x2baf0
movl %eax, %ecx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x2db0c
movq 0x88(%rsp), %rdi
movl 0x34(%rsp), %esi
callq 0x2bb10
movq %rax, 0x28(%rsp)
movq 0x90(%rsp), %rdi
movq 0x28(%rsp), %rsi
movsd 0x80(%rsp), %xmm0
callq 0x2d8b0
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x2daaf
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)