// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::CollapseEdge(gaps::R3MeshEdge*, gaps::R3Point const&)
R3MeshVertex *R3Mesh::
CollapseEdge(R3MeshEdge *edge, const R3Point& point)
{
  // Just to be safe
  if (NFaces() <= 4) return NULL;

  // Get vertices on edge
  R3MeshVertex *v[2];
  v[0] = edge->vertex[0];
  v[1] = edge->vertex[1];

  // Get faces on edge
  R3MeshFace *f[2];
  f[0] = edge->face[0];
  f[1] = edge->face[1];

#if 1
  // Get other edges and vertex on faces
  R3MeshEdge *ef[2][2] = { { NULL, NULL }, { NULL, NULL } };
  R3MeshFace *ff[2][2] = { { NULL, NULL }, { NULL, NULL } };
  R3MeshVertex *vf[2] = { NULL, NULL };
  if (f[0]) {
    ef[0][0] = EdgeAcrossVertex(v[0], edge, f[0]);
    ef[0][1] = EdgeAcrossVertex(v[1], edge, f[0]);
    vf[0] = VertexAcrossEdge(ef[0][1], v[1]);
    assert(vf[0] == VertexAcrossEdge(ef[0][0], v[0]));
    ff[0][0] = FaceAcrossEdge(ef[0][0], f[0]);
    ff[0][1] = FaceAcrossEdge(ef[0][1], f[0]);
  }
  if (f[1]) {
    ef[1][0] = EdgeAcrossVertex(v[0], edge, f[1]);
    ef[1][1] = EdgeAcrossVertex(v[1], edge, f[1]);
    vf[1] = VertexAcrossEdge(ef[1][1], v[1]);
    assert(vf[1] == VertexAcrossEdge(ef[1][0], v[0]));
    ff[1][0] = FaceAcrossEdge(ef[1][0], f[1]);
    ff[1][1] = FaceAcrossEdge(ef[1][1], f[1]);
  }

  // Check if will create a fin
  for (int i = 0; i < VertexValence(v[0]); i++) {
    R3MeshEdge *e0 = EdgeOnVertex(v[0], i);
    if ((e0 == ef[0][0]) || (e0 == ef[1][0])) continue;
    R3MeshVertex *ve0 = VertexAcrossEdge(e0, v[0]);
    for (int j = 0; j < VertexValence(v[1]); j++) {
      R3MeshEdge *e1 = EdgeOnVertex(v[1], j);
      if ((e1 == ef[0][1]) || (e1 == ef[1][1])) continue;
      R3MeshVertex *ve1 = VertexAcrossEdge(e1, v[1]);
      if (ve0 == ve1) return NULL;
    }
  }

  // Update vertex-edge relations
  v[0]->edges.Remove(edge);
  for (int i = 0; i < v[1]->edges.NEntries(); i++) {
    R3MeshEdge *ev1 = v[1]->edges[i];
    if (ev1 == edge) continue;
    if (ev1 == ef[0][1]) continue;
    if (ev1 == ef[1][1]) continue;
    v[0]->edges.Insert(ev1);
  }
  if (f[0]) {
    assert(vf[0] && ef[0][1]);
    vf[0]->edges.Remove(ef[0][1]);
  }
  if (f[1]) {
    assert(vf[1] && ef[1][1]);
    vf[1]->edges.Remove(ef[1][1]);
  }

  // Update edge-vertex relations (v[1]->v[0]) 
  for (int i = 0; i < v[1]->edges.NEntries(); i++) {
    R3MeshEdge *ev = v[1]->edges[i];
    for (int j = 0; j < 2; j++) {
      if (ev->vertex[j] == v[1]) ev->vertex[j] = v[0];
    }
  }
  
  // Update edge-face relations (ef[i][1]->ef[i][0])
  for (int i = 0; i < 2; i++) {
    if (!f[i]) continue;
    assert(ef[i][0]);
    for (int j = 0; j < 2; j++) {
      if (ef[i][0]->face[j] == f[i]) ef[i][0]->face[j] = ff[i][1];
    }
  }

  // Update face-vertex relations (v[1]->v[0])
  for (int i = 0; i < v[1]->edges.NEntries(); i++) {
    R3MeshEdge *ev = v[1]->edges[i];
    for (int j = 0; j < 2; j++) {
      R3MeshFace *fv = ev->face[j];
      if (fv) {
        for (int k = 0; k < 3; k++) {
          if (fv->vertex[k] == v[1]) fv->vertex[k] = v[0];
        }
      }
    }
  }
  
  // Update face-edge relations (ef[i][1]->ef[i][0])
  for (int i = 0; i < 2; i++) {
    if (!f[i]) continue;
    if (!ff[i][1]) continue;
    for (int j = 0; j < 3; j++) {
      if (ff[i][1]->edge[j] == ef[i][1]) {
        ff[i][1]->edge[j] = ef[i][0];
      }
    }
  }

  // Update vertex properties
  RNScalar d0 = R3Distance(point, VertexPosition(v[0]));
  RNScalar d1 = R3Distance(point, VertexPosition(v[1]));
  RNScalar dsum = d0 + d1;
  if (RNIsPositive(dsum)) {
    d0 /= dsum;  d1 /= dsum;
    SetVertexTextureCoords(v[0], d1*VertexTextureCoords(v[0]) + d0*VertexTextureCoords(v[1])); 
    SetVertexColor(v[0], d1*VertexColor(v[0]) + d0*VertexColor(v[1])); 
  }

  // Deallocate faces 
  if (f[0]) DeallocateFace(f[0]);
  if (f[1]) DeallocateFace(f[1]);

  // Deallocate edges
  if (f[0]) DeallocateEdge(ef[0][1]);
  if (f[1]) DeallocateEdge(ef[1][1]);
  DeallocateEdge(edge);

  // Deallocate vertex
  DeallocateVertex(v[1]);

  // Set position of remaining vertex
  SetVertexPosition(v[0], point);

  // Return remaining vertex
  return v[0];
#else
  // Set vertex position 
  SetVertexPosition(v[0], point);

  // Make arrays of everything attached to v[1]
  R3mesh_mark++;
  RNArray<R3MeshFace *> faces_to_remove;
  RNArray<R3MeshEdge *> edges_to_remove;
  RNArray<R3MeshVertex *> cw_vertices;
  RNArray<R3MeshVertex *> ccw_vertices;
  for (int i = 0; i < v[1]->edges.NEntries(); i++) {
    R3MeshEdge *v1_e = v[1]->edges[i];
    edges_to_remove.Insert(v1_e);
    R3MeshFace *v1_f = FaceOnEdge(v1_e, v[1], RN_CCW);
    if (v1_f) {
      faces_to_remove.Insert(v1_f);
      if ((v1_f != f[0]) && (v1_f != f[1])) {
        cw_vertices.Insert(VertexOnFace(v1_f, v[1], RN_CW));
        ccw_vertices.Insert(VertexOnFace(v1_f, v[1], RN_CCW));
      }
    }
  }

  // Remove everything attached to v1
  for (int i = 0; i < faces_to_remove.NEntries(); i++) 
    DeleteFace(faces_to_remove[i]);
  for (int i = 0; i < edges_to_remove.NEntries(); i++) 
    DeleteEdge(edges_to_remove[i]);
  DeleteVertex(v[1]);

  // Recreate everything by replacing v1 with v0
  for (int i = 0; i < cw_vertices.NEntries(); i++) {
    CreateFace(v[0], cw_vertices[i], ccw_vertices[i]);
  }

  // Return remaining vertex
  return v[0];
#endif
}

// Assembly:
subq $0x218, %rsp            # imm = 0x218
movq %rdi, 0x208(%rsp)
movq %rsi, 0x200(%rsp)
movq %rdx, 0x1f8(%rsp)
movq 0x208(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x135a0
cmpl $0x4, %eax
jg 0x1bfb7
movq $0x0, 0x210(%rsp)
jmp 0x1cbc4
movq 0x200(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x1e0(%rsp)
movq 0x200(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x1e8(%rsp)
movq 0x200(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x1d0(%rsp)
movq 0x200(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x1d8(%rsp)
leaq 0x1b0(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0xf280
leaq 0x190(%rsp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0xf280
leaq 0x180(%rsp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0xf280
cmpq $0x0, 0x1d0(%rsp)
je 0x1c10c
movq 0x60(%rsp), %rdi
movq 0x1e0(%rsp), %rsi
movq 0x200(%rsp), %rdx
movq 0x1d0(%rsp), %rcx
callq 0x18410
movq 0x60(%rsp), %rdi
movq %rax, 0x1b0(%rsp)
movq 0x1e8(%rsp), %rsi
movq 0x200(%rsp), %rdx
movq 0x1d0(%rsp), %rcx
callq 0x18410
movq 0x60(%rsp), %rdi
movq %rax, 0x1b8(%rsp)
movq 0x1b8(%rsp), %rsi
movq 0x1e8(%rsp), %rdx
callq 0x36f50
movq 0x60(%rsp), %rdi
movq %rax, 0x180(%rsp)
movq 0x1b0(%rsp), %rsi
movq 0x1d0(%rsp), %rdx
callq 0x373c0
movq 0x60(%rsp), %rdi
movq %rax, 0x190(%rsp)
movq 0x1b8(%rsp), %rsi
movq 0x1d0(%rsp), %rdx
callq 0x373c0
movq %rax, 0x198(%rsp)
cmpq $0x0, 0x1d8(%rsp)
je 0x1c1d5
movq 0x60(%rsp), %rdi
movq 0x1e0(%rsp), %rsi
movq 0x200(%rsp), %rdx
movq 0x1d8(%rsp), %rcx
callq 0x18410
movq 0x60(%rsp), %rdi
movq %rax, 0x1c0(%rsp)
movq 0x1e8(%rsp), %rsi
movq 0x200(%rsp), %rdx
movq 0x1d8(%rsp), %rcx
callq 0x18410
movq 0x60(%rsp), %rdi
movq %rax, 0x1c8(%rsp)
movq 0x1c8(%rsp), %rsi
movq 0x1e8(%rsp), %rdx
callq 0x36f50
movq 0x60(%rsp), %rdi
movq %rax, 0x188(%rsp)
movq 0x1c0(%rsp), %rsi
movq 0x1d8(%rsp), %rdx
callq 0x373c0
movq 0x60(%rsp), %rdi
movq %rax, 0x1a0(%rsp)
movq 0x1c8(%rsp), %rsi
movq 0x1d8(%rsp), %rdx
callq 0x373c0
movq %rax, 0x1a8(%rsp)
movl $0x0, 0x17c(%rsp)
movq 0x60(%rsp), %rdi
movl 0x17c(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0x1e0(%rsp), %rsi
callq 0x36b50
movl %eax, %ecx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1c369
movq 0x60(%rsp), %rdi
movq 0x1e0(%rsp), %rsi
movl 0x17c(%rsp), %edx
callq 0x36ec0
movq %rax, 0x170(%rsp)
movq 0x170(%rsp), %rax
cmpq 0x1b0(%rsp), %rax
je 0x1c250
movq 0x170(%rsp), %rax
cmpq 0x1c0(%rsp), %rax
jne 0x1c255
jmp 0x1c353
movq 0x60(%rsp), %rdi
movq 0x170(%rsp), %rsi
movq 0x1e0(%rsp), %rdx
callq 0x36f50
movq %rax, 0x168(%rsp)
movl $0x0, 0x164(%rsp)
movq 0x60(%rsp), %rdi
movl 0x164(%rsp), %eax
movl %eax, 0x58(%rsp)
movq 0x1e8(%rsp), %rsi
callq 0x36b50
movl %eax, %ecx
movl 0x58(%rsp), %eax
cmpl %ecx, %eax
jge 0x1c351
movq 0x60(%rsp), %rdi
movq 0x1e8(%rsp), %rsi
movl 0x164(%rsp), %edx
callq 0x36ec0
movq %rax, 0x158(%rsp)
movq 0x158(%rsp), %rax
cmpq 0x1b8(%rsp), %rax
je 0x1c2f2
movq 0x158(%rsp), %rax
cmpq 0x1c8(%rsp), %rax
jne 0x1c2f4
jmp 0x1c33b
movq 0x60(%rsp), %rdi
movq 0x158(%rsp), %rsi
movq 0x1e8(%rsp), %rdx
callq 0x36f50
movq %rax, 0x150(%rsp)
movq 0x168(%rsp), %rax
cmpq 0x150(%rsp), %rax
jne 0x1c339
movq $0x0, 0x210(%rsp)
jmp 0x1cbc4
jmp 0x1c33b
movl 0x164(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x164(%rsp)
jmp 0x1c282
jmp 0x1c353
movl 0x17c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x17c(%rsp)
jmp 0x1c1e0
movq 0x1e0(%rsp), %rdi
addq $0x8, %rdi
movq 0x200(%rsp), %rsi
callq 0x377b0
movl $0x0, 0x14c(%rsp)
movl 0x14c(%rsp), %eax
movl %eax, 0x54(%rsp)
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
callq 0x13600
movl %eax, %ecx
movl 0x54(%rsp), %eax
cmpl %ecx, %eax
jge 0x1c445
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
movl 0x14c(%rsp), %esi
callq 0x372f0
movq (%rax), %rax
movq %rax, 0x140(%rsp)
movq 0x140(%rsp), %rax
cmpq 0x200(%rsp), %rax
jne 0x1c3ee
jmp 0x1c42f
movq 0x140(%rsp), %rax
cmpq 0x1b8(%rsp), %rax
jne 0x1c402
jmp 0x1c42f
movq 0x140(%rsp), %rax
cmpq 0x1c8(%rsp), %rax
jne 0x1c416
jmp 0x1c42f
movq 0x1e0(%rsp), %rdi
addq $0x8, %rdi
movq 0x140(%rsp), %rsi
callq 0x376d0
movl 0x14c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14c(%rsp)
jmp 0x1c38d
cmpq $0x0, 0x1d0(%rsp)
je 0x1c469
movq 0x180(%rsp), %rdi
addq $0x8, %rdi
movq 0x1b8(%rsp), %rsi
callq 0x377b0
cmpq $0x0, 0x1d8(%rsp)
je 0x1c48d
movq 0x188(%rsp), %rdi
addq $0x8, %rdi
movq 0x1c8(%rsp), %rsi
callq 0x377b0
movl $0x0, 0x13c(%rsp)
movl 0x13c(%rsp), %eax
movl %eax, 0x50(%rsp)
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
callq 0x13600
movl %eax, %ecx
movl 0x50(%rsp), %eax
cmpl %ecx, %eax
jge 0x1c563
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
movl 0x13c(%rsp), %esi
callq 0x372f0
movq (%rax), %rax
movq %rax, 0x130(%rsp)
movl $0x0, 0x12c(%rsp)
cmpl $0x2, 0x12c(%rsp)
jge 0x1c54b
movq 0x130(%rsp), %rax
movslq 0x12c(%rsp), %rcx
movq 0x8(%rax,%rcx,8), %rax
cmpq 0x1e8(%rsp), %rax
jne 0x1c536
movq 0x1e0(%rsp), %rdx
movq 0x130(%rsp), %rax
movslq 0x12c(%rsp), %rcx
movq %rdx, 0x8(%rax,%rcx,8)
jmp 0x1c538
movl 0x12c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rsp)
jmp 0x1c4f0
jmp 0x1c54d
movl 0x13c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x13c(%rsp)
jmp 0x1c498
movl $0x0, 0x128(%rsp)
cmpl $0x2, 0x128(%rsp)
jge 0x1c658
movslq 0x128(%rsp), %rax
cmpq $0x0, 0x1d0(%rsp,%rax,8)
jne 0x1c594
jmp 0x1c642
movl $0x0, 0x124(%rsp)
cmpl $0x2, 0x124(%rsp)
jge 0x1c640
movslq 0x128(%rsp), %rcx
leaq 0x1b0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq 0x124(%rsp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movslq 0x128(%rsp), %rcx
cmpq 0x1d0(%rsp,%rcx,8), %rax
jne 0x1c628
movslq 0x128(%rsp), %rcx
leaq 0x190(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdx
movslq 0x128(%rsp), %rcx
leaq 0x1b0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq 0x124(%rsp), %rcx
movq %rdx, 0x18(%rax,%rcx,8)
jmp 0x1c62a
movl 0x124(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x124(%rsp)
jmp 0x1c59f
jmp 0x1c642
movl 0x128(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x128(%rsp)
jmp 0x1c56e
movl $0x0, 0x120(%rsp)
movl 0x120(%rsp), %eax
movl %eax, 0x4c(%rsp)
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
callq 0x13600
movl %eax, %ecx
movl 0x4c(%rsp), %eax
cmpl %ecx, %eax
jge 0x1c789
movq 0x1e8(%rsp), %rdi
addq $0x8, %rdi
movl 0x120(%rsp), %esi
callq 0x372f0
movq (%rax), %rax
movq %rax, 0x118(%rsp)
movl $0x0, 0x114(%rsp)
cmpl $0x2, 0x114(%rsp)
jge 0x1c771
movq 0x118(%rsp), %rax
movslq 0x114(%rsp), %rcx
movq 0x18(%rax,%rcx,8), %rax
movq %rax, 0x108(%rsp)
cmpq $0x0, 0x108(%rsp)
je 0x1c759
movl $0x0, 0x104(%rsp)
cmpl $0x3, 0x104(%rsp)
jge 0x1c757
movq 0x108(%rsp), %rax
movslq 0x104(%rsp), %rcx
movq 0x8(%rax,%rcx,8), %rax
cmpq 0x1e8(%rsp), %rax
jne 0x1c742
movq 0x1e0(%rsp), %rdx
movq 0x108(%rsp), %rax
movslq 0x104(%rsp), %rcx
movq %rdx, 0x8(%rax,%rcx,8)
jmp 0x1c744
movl 0x104(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x104(%rsp)
jmp 0x1c6fc
jmp 0x1c759
jmp 0x1c75b
movl 0x114(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x114(%rsp)
jmp 0x1c6bb
jmp 0x1c773
movl 0x120(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x120(%rsp)
jmp 0x1c663
movl $0x0, 0x100(%rsp)
cmpl $0x2, 0x100(%rsp)
jge 0x1c8ad
movslq 0x100(%rsp), %rax
cmpq $0x0, 0x1d0(%rsp,%rax,8)
jne 0x1c7ba
jmp 0x1c897
movslq 0x100(%rsp), %rcx
leaq 0x190(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
cmpq $0x0, 0x8(%rax)
jne 0x1c7dd
jmp 0x1c897
movl $0x0, 0xfc(%rsp)
cmpl $0x3, 0xfc(%rsp)
jge 0x1c895
movslq 0x100(%rsp), %rcx
leaq 0x190(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movslq 0xfc(%rsp), %rcx
movq 0x20(%rax,%rcx,8), %rax
movslq 0x100(%rsp), %rdx
leaq 0x1b0(%rsp), %rcx
shlq $0x4, %rdx
addq %rdx, %rcx
cmpq 0x8(%rcx), %rax
jne 0x1c87d
movslq 0x100(%rsp), %rcx
leaq 0x1b0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdx
movslq 0x100(%rsp), %rcx
leaq 0x190(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movslq 0xfc(%rsp), %rcx
movq %rdx, 0x20(%rax,%rcx,8)
jmp 0x1c87f
movl 0xfc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xfc(%rsp)
jmp 0x1c7e8
jmp 0x1c897
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0x1c794
movq 0x60(%rsp), %rdi
movq 0x1f8(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x1e0(%rsp), %rsi
callq 0x13660
movq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0x86c40
movq 0x60(%rsp), %rdi
movsd %xmm0, 0xf0(%rsp)
movq 0x1f8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x1e8(%rsp), %rsi
callq 0x13660
movq 0x40(%rsp), %rdi
movq %rax, %rsi
callq 0x86c40
movsd %xmm0, 0xe8(%rsp)
movsd 0xf0(%rsp), %xmm0
addsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0xe0(%rsp)
movsd 0xe0(%rsp), %xmm0
leaq 0x15bb9e(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x1caea
movq 0x60(%rsp), %rdi
movsd 0xe0(%rsp), %xmm1
movsd 0xf0(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0xf0(%rsp)
movsd 0xe0(%rsp), %xmm1
movsd 0xe8(%rsp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0xe8(%rsp)
movq 0x1e0(%rsp), %rax
movq %rax, 0x18(%rsp)
movsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movq 0x1e0(%rsp), %rsi
callq 0x368f0
movsd 0x8(%rsp), %xmm0
movq %rax, %rsi
leaq 0xc0(%rsp), %rdi
callq 0x37910
movq 0x60(%rsp), %rdi
movsd 0xf0(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x1e8(%rsp), %rsi
callq 0x368f0
movsd 0x10(%rsp), %xmm0
movq %rax, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x37910
leaq 0xd0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
leaq 0xb0(%rsp), %rdx
callq 0xc3750
movq 0x18(%rsp), %rsi
movq 0x60(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
callq 0x376a0
movq 0x60(%rsp), %rdi
movq 0x1e0(%rsp), %rax
movq %rax, 0x30(%rsp)
movsd 0xe8(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x1e0(%rsp), %rsi
callq 0x368d0
movsd 0x20(%rsp), %xmm0
movq %rax, %rsi
leaq 0x80(%rsp), %rdi
callq 0x37950
movq 0x60(%rsp), %rdi
movsd 0xf0(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movq 0x1e8(%rsp), %rsi
callq 0x368d0
movsd 0x28(%rsp), %xmm0
movq %rax, %rsi
leaq 0x68(%rsp), %rdi
callq 0x37950
leaq 0x98(%rsp), %rdi
leaq 0x80(%rsp), %rsi
leaq 0x68(%rsp), %rdx
callq 0x37200
movq 0x60(%rsp), %rdi
movq 0x30(%rsp), %rsi
leaq 0x98(%rsp), %rdx
callq 0x37670
cmpq $0x0, 0x1d0(%rsp)
je 0x1cb0b
movq 0x60(%rsp), %rdi
movq 0x1d0(%rsp), %rsi
movq (%rdi), %rax
callq *0x2a8(%rax)
cmpq $0x0, 0x1d8(%rsp)
je 0x1cb2c
movq 0x60(%rsp), %rdi
movq 0x1d8(%rsp), %rsi
movq (%rdi), %rax
callq *0x2a8(%rax)
cmpq $0x0, 0x1d0(%rsp)
je 0x1cb4d
movq 0x60(%rsp), %rdi
movq 0x1b8(%rsp), %rsi
movq (%rdi), %rax
callq *0x2a0(%rax)
cmpq $0x0, 0x1d8(%rsp)
je 0x1cb6e
movq 0x60(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
movq (%rdi), %rax
callq *0x2a0(%rax)
movq 0x60(%rsp), %rdi
movq 0x200(%rsp), %rsi
movq (%rdi), %rax
callq *0x2a0(%rax)
movq 0x60(%rsp), %rdi
movq 0x1e8(%rsp), %rsi
movq (%rdi), %rax
callq *0x298(%rax)
movq 0x60(%rsp), %rdi
movq 0x1e0(%rsp), %rsi
movq 0x1f8(%rsp), %rdx
callq 0x18060
movq 0x1e0(%rsp), %rax
movq %rax, 0x210(%rsp)
movq 0x210(%rsp), %rax
addq $0x218, %rsp            # imm = 0x218
retq
nopw %cs:(%rax,%rax)