// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3TriangleArray.cpp
// Function: gaps::R3TriangleArray::Subdivide(double)
void R3TriangleArray::
Subdivide(RNLength max_edge_length) 
{
  // Get convenient variables
  RNLength max_edge_length_squared = max_edge_length * max_edge_length;
  
  // Subdivide triangles with edges that are too long
  RNArray<R3Triangle *> stack = triangles;
  while (!stack.IsEmpty()) {
    // Get triangle from stack
    R3Triangle *triangle = stack.Tail();
    stack.RemoveTail();

    // Get vertices
    R3TriangleVertex *v0 = triangle->V0();
    R3TriangleVertex *v1 = triangle->V1();
    R3TriangleVertex *v2 = triangle->V2();
    const R3Point& p0 = v0->Position();
    const R3Point& p1 = v1->Position();
    const R3Point& p2 = v2->Position();
    RNLength dd01 = R3SquaredDistance(p0, p1);
    RNLength dd12 = R3SquaredDistance(p1, p2);
    RNLength dd20 = R3SquaredDistance(p2, p0);

    // Check if edge is too long
    if ((dd01 > max_edge_length_squared) && (dd01 >= dd12) && (dd01 >= dd20)) {
      // Create new vertex at midpoint of edge between v0 and v1
      R3Point position = 0.5*(p0 + p1);
      R3Vector normal = 0.5*(v0->Normal() + v1->Normal()); normal.Normalize();
      R3TriangleVertex *v = new R3TriangleVertex(position, normal);
      if (v0->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG] && v1->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG])
        v->SetTextureCoords(0.5*(v0->TextureCoords() + v1->TextureCoords()));
      vertices.Insert(v);

      // Adjust existing triangle
      triangle->Reset(v0, v, v2);
      stack.Insert(triangle);

      // Create new triangle
      R3Triangle *t = new R3Triangle(v1, v2, v);
      triangles.Insert(t);
      stack.Insert(t);
    }
    else if ((dd12 > max_edge_length_squared) && (dd12 >= dd01) && (dd12 >= dd20)) {
      // Create new vertex at midpoint of edge between v1 and v2
      R3Point position = 0.5*(p1 + p2);
      R3Vector normal = 0.5*(v1->Normal() + v2->Normal()); normal.Normalize();
      R3TriangleVertex *v = new R3TriangleVertex(position, normal);
      if (v1->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG] && v2->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG])
        v->SetTextureCoords(0.5*(v1->TextureCoords() + v2->TextureCoords()));
      vertices.Insert(v);

      // Adjust existing triangle
      triangle->Reset(v1, v, v0);
      stack.Insert(triangle);

      // Create new triangle
      R3Triangle *t = new R3Triangle(v2, v0, v);
      triangles.Insert(t);
      stack.Insert(t);
    }
    else if ((dd20 > max_edge_length_squared) && (dd20 >= dd01) && (dd20 >= dd12)) {
      // Create new vertex at midpoint of edge between v2 and v0
      R3Point position = 0.5*(p2 + p0);
      R3Vector normal = 0.5*(v2->Normal() + v0->Normal()); normal.Normalize();
      R3TriangleVertex *v = new R3TriangleVertex(position, normal);
      if (v2->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG] && v0->flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG])
        v->SetTextureCoords(0.5*(v2->TextureCoords() + v0->TextureCoords()));
      vertices.Insert(v);

      // Adjust existing triangle
      triangle->Reset(v2, v, v1);
      stack.Insert(triangle);

      // Create new triangle
      R3Triangle *t = new R3Triangle(v0, v1, v);
      triangles.Insert(t);
      stack.Insert(t);
    }
  }

  // Update
  Update();
}

// Assembly:
subq $0x3d8, %rsp            # imm = 0x3D8
movq %rdi, 0x3d0(%rsp)
movsd %xmm0, 0x3c8(%rsp)
movq 0x3d0(%rsp), %rsi
movq %rsi, 0x168(%rsp)
movsd 0x3c8(%rsp), %xmm0
mulsd 0x3c8(%rsp), %xmm0
movsd %xmm0, 0x3c0(%rsp)
addq $0x18, %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a3a0
leaq 0x3b0(%rsp), %rdi
callq 0x36e30
movl %eax, 0x164(%rsp)
jmp 0x97ada
movl 0x164(%rsp), %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x97af2
jmp 0x9878f
leaq 0x3b0(%rsp), %rdi
callq 0x9a430
movq %rax, 0x158(%rsp)
jmp 0x97b09
movq 0x158(%rsp), %rax
movq %rax, 0x398(%rsp)
leaq 0x3b0(%rsp), %rdi
callq 0x36e60
jmp 0x97b28
movq 0x398(%rsp), %rdi
callq 0x86a00
movq %rax, 0x150(%rsp)
jmp 0x97b3f
movq 0x150(%rsp), %rax
movq %rax, 0x390(%rsp)
movq 0x398(%rsp), %rdi
callq 0x86a10
movq %rax, 0x148(%rsp)
jmp 0x97b66
movq 0x148(%rsp), %rax
movq %rax, 0x388(%rsp)
movq 0x398(%rsp), %rdi
callq 0x86a20
movq %rax, 0x140(%rsp)
jmp 0x97b8d
movq 0x140(%rsp), %rax
movq %rax, 0x380(%rsp)
movq 0x390(%rsp), %rdi
callq 0x78950
movq %rax, 0x138(%rsp)
jmp 0x97bb4
movq 0x138(%rsp), %rax
movq %rax, 0x378(%rsp)
movq 0x388(%rsp), %rdi
callq 0x78950
movq %rax, 0x130(%rsp)
jmp 0x97bdb
movq 0x130(%rsp), %rax
movq %rax, 0x370(%rsp)
movq 0x380(%rsp), %rdi
callq 0x78950
movq %rax, 0x128(%rsp)
jmp 0x97c02
movq 0x128(%rsp), %rax
movq %rax, 0x368(%rsp)
movq 0x378(%rsp), %rdi
movq 0x370(%rsp), %rsi
callq 0x86c10
movsd %xmm0, 0x120(%rsp)
jmp 0x97c32
movsd 0x120(%rsp), %xmm0
movsd %xmm0, 0x360(%rsp)
movq 0x370(%rsp), %rdi
movq 0x368(%rsp), %rsi
callq 0x86c10
movsd %xmm0, 0x118(%rsp)
jmp 0x97c64
movsd 0x118(%rsp), %xmm0
movsd %xmm0, 0x358(%rsp)
movq 0x368(%rsp), %rdi
movq 0x378(%rsp), %rsi
callq 0x86c10
movsd %xmm0, 0x110(%rsp)
jmp 0x97c96
movsd 0x110(%rsp), %xmm0
movsd %xmm0, 0x350(%rsp)
movsd 0x360(%rsp), %xmm0
ucomisd 0x3c0(%rsp), %xmm0
jbe 0x9807e
movsd 0x360(%rsp), %xmm0
ucomisd 0x358(%rsp), %xmm0
jb 0x9807e
movsd 0x360(%rsp), %xmm0
ucomisd 0x350(%rsp), %xmm0
jb 0x9807e
movq 0x378(%rsp), %rsi
movq 0x370(%rsp), %rdx
leaq 0x320(%rsp), %rdi
callq 0x6fa40
jmp 0x97d0f
leaq 0x338(%rsp), %rdi
movsd 0x9b2f1(%rip), %xmm0    # 0x133010
leaq 0x320(%rsp), %rsi
callq 0x36b10
jmp 0x97d2e
movq 0x390(%rsp), %rdi
callq 0x789e0
movq %rax, 0x108(%rsp)
jmp 0x97d45
movq 0x388(%rsp), %rdi
callq 0x789e0
movq %rax, 0x100(%rsp)
jmp 0x97d5c
movq 0x100(%rsp), %rdx
movq 0x108(%rsp), %rsi
leaq 0x2f0(%rsp), %rdi
callq 0x71030
jmp 0x97d7b
leaq 0x308(%rsp), %rdi
movsd 0x9b285(%rip), %xmm0    # 0x133010
leaq 0x2f0(%rsp), %rsi
callq 0x13800
jmp 0x97d9a
leaq 0x308(%rsp), %rdi
callq 0x70410
jmp 0x97da9
movl $0x68, %edi
callq 0xf4c0
movq %rax, 0xf8(%rsp)
jmp 0x97dbd
movq 0xf8(%rsp), %rdi
leaq 0x338(%rsp), %rsi
leaq 0x308(%rsp), %rdx
callq 0x9a960
jmp 0x97ddc
movq 0xf8(%rsp), %rax
movq %rax, 0x2e8(%rsp)
movq 0x390(%rsp), %rax
addq $0x58, %rax
movq %rax, 0xf0(%rsp)
leaq 0x2e0(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x97e14
movq 0xf0(%rsp), %rdi
movq 0x2e0(%rsp), %rsi
callq 0x13d50
movl %eax, 0xec(%rsp)
jmp 0x97e32
movl 0xec(%rsp), %eax
cmpl $0x0, %eax
je 0x97f71
movq 0x388(%rsp), %rax
addq $0x58, %rax
movq %rax, 0xe0(%rsp)
leaq 0x2d8(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x97e6a
movq 0xe0(%rsp), %rdi
movq 0x2d8(%rsp), %rsi
callq 0x13d50
movl %eax, 0xdc(%rsp)
jmp 0x97e88
movl 0xdc(%rsp), %eax
cmpl $0x0, %eax
je 0x97f71
movq 0x2e8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x390(%rsp), %rdi
callq 0x78a10
movq %rax, 0xd0(%rsp)
jmp 0x97ebf
movq 0x388(%rsp), %rdi
callq 0x78a10
movq %rax, 0xc0(%rsp)
jmp 0x97ed6
movq 0xc0(%rsp), %rdx
movq 0xd0(%rsp), %rsi
leaq 0x2b8(%rsp), %rdi
callq 0xc3750
jmp 0x97ef5
leaq 0x2c8(%rsp), %rdi
movsd 0x9b10b(%rip), %xmm0    # 0x133010
leaq 0x2b8(%rsp), %rsi
callq 0x37910
jmp 0x97f14
movq 0xc8(%rsp), %rdi
leaq 0x2c8(%rsp), %rsi
callq 0x9a440
jmp 0x97f2b
jmp 0x97f71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
jmp 0x987ba
movq 0xf8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x68, %esi
callq 0xf4d0
jmp 0x987ba
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movq 0x2e8(%rsp), %rsi
callq 0x9a280
jmp 0x97f8c
movq 0x398(%rsp), %rdi
movq 0x390(%rsp), %rsi
movq 0x2e8(%rsp), %rdx
movq 0x380(%rsp), %rcx
movq (%rdi), %rax
movq 0x230(%rax), %rax
callq *%rax
jmp 0x97fba
movq 0x398(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x97fd1
movl $0x88, %edi
callq 0xf4c0
movq %rax, 0xb8(%rsp)
jmp 0x97fe5
movq 0xb8(%rsp), %rdi
movq 0x388(%rsp), %rsi
movq 0x380(%rsp), %rdx
movq 0x2e8(%rsp), %rcx
callq 0x9b320
jmp 0x9800c
movq 0x168(%rsp), %rdi
movq 0xb8(%rsp), %rax
movq %rax, 0x2b0(%rsp)
addq $0x18, %rdi
movq 0x2b0(%rsp), %rsi
callq 0x9a340
jmp 0x98037
movq 0x2b0(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x9804e
jmp 0x9878a
movq 0xb8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x88, %esi
callq 0xf4d0
jmp 0x987ba
movsd 0x358(%rsp), %xmm0
ucomisd 0x3c0(%rsp), %xmm0
jbe 0x9841d
movsd 0x358(%rsp), %xmm0
ucomisd 0x360(%rsp), %xmm0
jb 0x9841d
movsd 0x358(%rsp), %xmm0
ucomisd 0x350(%rsp), %xmm0
jb 0x9841d
movq 0x370(%rsp), %rsi
movq 0x368(%rsp), %rdx
leaq 0x280(%rsp), %rdi
callq 0x6fa40
jmp 0x980e5
leaq 0x298(%rsp), %rdi
movsd 0x9af1b(%rip), %xmm0    # 0x133010
leaq 0x280(%rsp), %rsi
callq 0x36b10
jmp 0x98104
movq 0x388(%rsp), %rdi
callq 0x789e0
movq %rax, 0xb0(%rsp)
jmp 0x9811b
movq 0x380(%rsp), %rdi
callq 0x789e0
movq %rax, 0xa8(%rsp)
jmp 0x98132
movq 0xa8(%rsp), %rdx
movq 0xb0(%rsp), %rsi
leaq 0x250(%rsp), %rdi
callq 0x71030
jmp 0x98151
leaq 0x268(%rsp), %rdi
movsd 0x9aeaf(%rip), %xmm0    # 0x133010
leaq 0x250(%rsp), %rsi
callq 0x13800
jmp 0x98170
leaq 0x268(%rsp), %rdi
callq 0x70410
jmp 0x9817f
movl $0x68, %edi
callq 0xf4c0
movq %rax, 0xa0(%rsp)
jmp 0x98193
movq 0xa0(%rsp), %rdi
leaq 0x298(%rsp), %rsi
leaq 0x268(%rsp), %rdx
callq 0x9a960
jmp 0x981b2
movq 0xa0(%rsp), %rax
movq %rax, 0x248(%rsp)
movq 0x388(%rsp), %rax
addq $0x58, %rax
movq %rax, 0x98(%rsp)
leaq 0x240(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x981ea
movq 0x98(%rsp), %rdi
movq 0x240(%rsp), %rsi
callq 0x13d50
movl %eax, 0x94(%rsp)
jmp 0x98208
movl 0x94(%rsp), %eax
cmpl $0x0, %eax
je 0x9831c
movq 0x380(%rsp), %rax
addq $0x58, %rax
movq %rax, 0x88(%rsp)
leaq 0x238(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x98240
movq 0x88(%rsp), %rdi
movq 0x238(%rsp), %rsi
callq 0x13d50
movl %eax, 0x84(%rsp)
jmp 0x9825e
movl 0x84(%rsp), %eax
cmpl $0x0, %eax
je 0x9831c
movq 0x248(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x388(%rsp), %rdi
callq 0x78a10
movq %rax, 0x78(%rsp)
jmp 0x9828f
movq 0x380(%rsp), %rdi
callq 0x78a10
movq %rax, 0x68(%rsp)
jmp 0x982a3
movq 0x68(%rsp), %rdx
movq 0x78(%rsp), %rsi
leaq 0x218(%rsp), %rdi
callq 0xc3750
jmp 0x982bc
leaq 0x228(%rsp), %rdi
movsd 0x9ad44(%rip), %xmm0    # 0x133010
leaq 0x218(%rsp), %rsi
callq 0x37910
jmp 0x982db
movq 0x70(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0x9a440
jmp 0x982ef
jmp 0x9831c
movq 0xa0(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x68, %esi
callq 0xf4d0
jmp 0x987ba
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movq 0x248(%rsp), %rsi
callq 0x9a280
jmp 0x98337
movq 0x398(%rsp), %rdi
movq 0x388(%rsp), %rsi
movq 0x248(%rsp), %rdx
movq 0x390(%rsp), %rcx
movq (%rdi), %rax
movq 0x230(%rax), %rax
callq *%rax
jmp 0x98365
movq 0x398(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x9837c
movl $0x88, %edi
callq 0xf4c0
movq %rax, 0x60(%rsp)
jmp 0x9838d
movq 0x60(%rsp), %rdi
movq 0x380(%rsp), %rsi
movq 0x390(%rsp), %rdx
movq 0x248(%rsp), %rcx
callq 0x9b320
jmp 0x983b1
movq 0x168(%rsp), %rdi
movq 0x60(%rsp), %rax
movq %rax, 0x210(%rsp)
addq $0x18, %rdi
movq 0x210(%rsp), %rsi
callq 0x9a340
jmp 0x983d9
movq 0x210(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x983f0
jmp 0x98788
movq 0x60(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x88, %esi
callq 0xf4d0
jmp 0x987ba
movsd 0x350(%rsp), %xmm0
ucomisd 0x3c0(%rsp), %xmm0
jbe 0x98786
movsd 0x350(%rsp), %xmm0
ucomisd 0x360(%rsp), %xmm0
jb 0x98786
movsd 0x350(%rsp), %xmm0
ucomisd 0x358(%rsp), %xmm0
jb 0x98786
movq 0x368(%rsp), %rsi
movq 0x378(%rsp), %rdx
leaq 0x1e0(%rsp), %rdi
callq 0x6fa40
jmp 0x98484
leaq 0x1f8(%rsp), %rdi
movsd 0x9ab7c(%rip), %xmm0    # 0x133010
leaq 0x1e0(%rsp), %rsi
callq 0x36b10
jmp 0x984a3
movq 0x380(%rsp), %rdi
callq 0x789e0
movq %rax, 0x58(%rsp)
jmp 0x984b7
movq 0x390(%rsp), %rdi
callq 0x789e0
movq %rax, 0x50(%rsp)
jmp 0x984cb
movq 0x50(%rsp), %rdx
movq 0x58(%rsp), %rsi
leaq 0x1b0(%rsp), %rdi
callq 0x71030
jmp 0x984e4
leaq 0x1c8(%rsp), %rdi
movsd 0x9ab1c(%rip), %xmm0    # 0x133010
leaq 0x1b0(%rsp), %rsi
callq 0x13800
jmp 0x98503
leaq 0x1c8(%rsp), %rdi
callq 0x70410
jmp 0x98512
movl $0x68, %edi
callq 0xf4c0
movq %rax, 0x48(%rsp)
jmp 0x98523
movq 0x48(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
leaq 0x1c8(%rsp), %rdx
callq 0x9a960
jmp 0x9853f
movq 0x48(%rsp), %rax
movq %rax, 0x1a8(%rsp)
movq 0x380(%rsp), %rax
addq $0x58, %rax
movq %rax, 0x40(%rsp)
leaq 0x1a0(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x98571
movq 0x40(%rsp), %rdi
movq 0x1a0(%rsp), %rsi
callq 0x13d50
movl %eax, 0x3c(%rsp)
jmp 0x98589
movl 0x3c(%rsp), %eax
cmpl $0x0, %eax
je 0x9868b
movq 0x390(%rsp), %rax
addq $0x58, %rax
movq %rax, 0x30(%rsp)
leaq 0x198(%rsp), %rdi
movl $0x200, %esi            # imm = 0x200
callq 0x13d80
jmp 0x985bb
movq 0x30(%rsp), %rdi
movq 0x198(%rsp), %rsi
callq 0x13d50
movl %eax, 0x2c(%rsp)
jmp 0x985d3
movl 0x2c(%rsp), %eax
cmpl $0x0, %eax
je 0x9868b
movq 0x1a8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x380(%rsp), %rdi
callq 0x78a10
movq %rax, 0x20(%rsp)
jmp 0x98601
movq 0x390(%rsp), %rdi
callq 0x78a10
movq %rax, 0x10(%rsp)
jmp 0x98615
movq 0x10(%rsp), %rdx
movq 0x20(%rsp), %rsi
leaq 0x178(%rsp), %rdi
callq 0xc3750
jmp 0x9862e
leaq 0x188(%rsp), %rdi
movsd 0x9a9d2(%rip), %xmm0    # 0x133010
leaq 0x178(%rsp), %rsi
callq 0x37910
jmp 0x9864d
movq 0x18(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x9a440
jmp 0x98661
jmp 0x9868b
movq 0x48(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x68, %esi
callq 0xf4d0
jmp 0x987ba
movq 0x168(%rsp), %rdi
addq $0x8, %rdi
movq 0x1a8(%rsp), %rsi
callq 0x9a280
jmp 0x986a6
movq 0x398(%rsp), %rdi
movq 0x380(%rsp), %rsi
movq 0x1a8(%rsp), %rdx
movq 0x388(%rsp), %rcx
movq (%rdi), %rax
movq 0x230(%rax), %rax
callq *%rax
jmp 0x986d4
movq 0x398(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x986eb
movl $0x88, %edi
callq 0xf4c0
movq %rax, 0x8(%rsp)
jmp 0x986fc
movq 0x8(%rsp), %rdi
movq 0x390(%rsp), %rsi
movq 0x388(%rsp), %rdx
movq 0x1a8(%rsp), %rcx
callq 0x9b320
jmp 0x98720
movq 0x168(%rsp), %rdi
movq 0x8(%rsp), %rax
movq %rax, 0x170(%rsp)
addq $0x18, %rdi
movq 0x170(%rsp), %rsi
callq 0x9a340
jmp 0x98748
movq 0x170(%rsp), %rsi
leaq 0x3b0(%rsp), %rdi
callq 0x9a340
jmp 0x9875f
jmp 0x98786
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x3a8(%rsp)
movl %eax, 0x3a4(%rsp)
movl $0x88, %esi
callq 0xf4d0
jmp 0x987ba
jmp 0x98788
jmp 0x9878a
jmp 0x97ac4
movq 0x168(%rsp), %rdi
movq (%rdi), %rax
movq 0x248(%rax), %rax
callq *%rax
jmp 0x987a5
leaq 0x3b0(%rsp), %rdi
callq 0x9a240
addq $0x3d8, %rsp            # imm = 0x3D8
retq
leaq 0x3b0(%rsp), %rdi
callq 0x9a240
movq 0x3a8(%rsp), %rdi
callq 0xf890
nopw %cs:(%rax,%rax)