// File: tomfunkhouser[P]gaps/apps/sflprocess/sflprocess.cpp
// Function: LoadSurfelsFromMesh(gaps::R3SurfelScene*, char const*, char const*, char const*, double)
static int
LoadSurfelsFromMesh(R3SurfelScene *scene, const char *mesh_filename, 
  const char *parent_object_name, const char *parent_node_name,
  RNLength surfel_spacing = 0.01)
{
  // Start statistics
  RNTime start_time;
  start_time.Read();
  int surfel_count = 0;
  int node_count = 0;

  // Get surfel tree
  R3SurfelTree *tree = scene->Tree();
  if (!tree) {
    RNFail("Scene has no tree\n");
    return 0;
  }    

  // Get surfel database
  R3SurfelDatabase *database = tree->Database();
  if (!database) {
    RNFail("Scene has no database\n");
    return 0;
  }    

  // Find parent object
  R3SurfelObject *parent_object = scene->FindObjectByName(parent_object_name);
  if (!parent_object) {
    RNFail("Unable to find parent object with name %s\n", parent_object_name);
    return 0;
  }

  // Find parent node
  R3SurfelNode *parent_node = tree->FindNodeByName(parent_node_name);
  if (!parent_node) {
    RNFail("Unable to find parent node with name %s\n", parent_node_name);
    return 0;
  }

  // Read mesh file
  R3Mesh mesh;
  if (!mesh.ReadFile(mesh_filename)) {
    RNFail("Unable to read mesh from %s\n", mesh_filename);
    return 0;
  }

  // Create surfels for every mesh segment
  RNSeedRandomScalar();
  RNArray<R3SurfelLabel *> labels;
  RNArray<RNArray<R3Surfel *> *> surfels;
  R3Point mesh_centroid = mesh.Centroid();
  for (int i = 0; i < mesh.NFaces(); i++) {
    R3MeshFace *face = mesh.Face(i);
    int segment_index = mesh.FaceSegment(face);
    if (segment_index < 0) segment_index = mesh.FaceMaterial(face);
    if (segment_index < 0) segment_index = 0;

    // Get label
    int label_index = mesh.FaceCategory(face);
    if ((label_index >= 0) && (label_index < scene->NLabels())) {
      R3SurfelLabel *label = scene->Label(label_index);
      labels[segment_index] = label;
    }

    // Get/create array of surfels for segment
    while (labels.NEntries() <= segment_index) labels.Insert(NULL);
    while (surfels.NEntries() <= segment_index) surfels.Insert(NULL);
    RNArray<R3Surfel *> *segment_surfels = surfels[segment_index];
    if (!segment_surfels) {
      segment_surfels = new RNArray<R3Surfel *>();
      surfels[segment_index] = segment_surfels;
    }

    // Get vertex positions
    R3MeshVertex *v0 = mesh.VertexOnFace(face, 0);
    R3MeshVertex *v1 = mesh.VertexOnFace(face, 1);
    R3MeshVertex *v2 = mesh.VertexOnFace(face, 2);
    R3Point p0 = mesh.VertexPosition(v0);
    R3Point p1 = mesh.VertexPosition(v1);
    R3Point p2 = mesh.VertexPosition(v2);
    // const R3Vector& n0 = mesh.VertexNormal(v0);
    // const R3Vector& n1 = mesh.VertexNormal(v1);
    // const R3Vector& n2 = mesh.VertexNormal(v2);
    const RNRgb& c0 = mesh.VertexColor(v0);
    const RNRgb& c1 = mesh.VertexColor(v1);
    const RNRgb& c2 = mesh.VertexColor(v2);

    // Translate vertices by mesh centroid
    p0 -= mesh_centroid.Vector();
    p1 -= mesh_centroid.Vector();
    p2 -= mesh_centroid.Vector();

    // Determine number of surfels for face
    RNScalar surfels_per_area = 4.0 / (RN_PI * surfel_spacing * surfel_spacing);
    RNScalar ideal_face_nsurfels = surfels_per_area * mesh.FaceArea(face);
    int face_nsurfels = (int) ideal_face_nsurfels;
    RNScalar remainder = ideal_face_nsurfels - face_nsurfels;
    if (remainder > RNRandomScalar()) face_nsurfels++;

    // Get normal, tangent, etc.
    R3Vector normal = mesh.FaceNormal(face);
    R3MeshEdge *edge = mesh.LongestEdgeOnFace(face);
    R3Vector tangent = mesh.EdgeVector(edge); tangent.Normalize();
    RNLength radius = surfel_spacing;
    
    // Generate random surfels on face
    for (int j = 0; j < face_nsurfels; j++) {
      RNScalar r1 = sqrt(RNRandomScalar());
      RNScalar r2 = RNRandomScalar();
      RNScalar t0 = (1.0 - r1);
      RNScalar t1 = r1 * (1.0 - r2);
      RNScalar t2 = r1 * r2;
      R3Point position = t0*p0 + t1*p1 + t2*p2;
      RNRgb color = t0*c0 + t1*c1 + t2*c2;
      int category = label_index;
      if (category < 0) category = 0;
      if (category > 255) category = 255;
      double elevation = position.Z() - mesh.BBox().ZMin();
      int encoded_elevation = 400 * elevation + 32768;
      if (encoded_elevation < 0) encoded_elevation = 0;
      if (encoded_elevation > 65535) encoded_elevation = 65535;
      unsigned int attribute = category | (encoded_elevation << 16);
      R3Surfel *surfel = new R3Surfel();
      surfel->SetPosition(position.X(), position.Y(), position.Z());
      surfel->SetColor(255*color.R(), 255*color.G(), 255*color.B());
      surfel->SetNormal(normal.X(), normal.Y(), normal.Z());
      surfel->SetTangent(tangent.X(), tangent.Y(), tangent.Z());
      surfel->SetRadius(radius);
      surfel->SetIdentifier(surfel_count+1);
      surfel->SetAttribute(attribute);
      surfel->SetAerial(FALSE);
      segment_surfels->Insert(surfel);
      surfel_count++;
    }
  }

  // Create surfel blocks/nodes
  for (int i = 0; i < surfels.NEntries(); i++) {
    R3SurfelLabel *label = labels.Kth(i);
    RNArray<R3Surfel *> *segment_surfels = surfels.Kth(i);
    if (!segment_surfels) continue;

    // Compute segment name
    char segment_name[1024];
    sprintf(segment_name, "MESH_SEGMENT_%d", i);

    // Create object
    R3SurfelObject *object = new R3SurfelObject(segment_name);
     if (!object) {
      RNFail("Unable to allocate object\n");
      return 0;
    }
   
    // Insert object into scene
    scene->InsertObject(object, parent_object);

    // Create node
    R3SurfelNode *node = new R3SurfelNode(segment_name);
    if (!node) {
      RNFail("Unable to allocate node\n");
      return 0;
    }
            
    // Insert node into tree
    tree->InsertNode(node, parent_node);
          
    // Insert node into object
    object->InsertNode(node);

    // Create block
    RNArray<const R3Surfel *>& tmp = *((RNArray<const R3Surfel *> *) segment_surfels);
    R3SurfelBlock *block = new R3SurfelBlock(tmp, mesh_centroid);
    if (!block) {
      RNFail("Unable to allocate block\n");
      return 0;
    }
    
    // Update block properties
    block->UpdateProperties();
          
    // Insert block into database
    database->InsertBlock(block);
            
    // Insert block into node
    node->InsertBlock(block);
          
    // Update node properties
    node->UpdateProperties();
          
    // Update object properties
    object->UpdateProperties();

    // Create label assignment
    if (label) {
      int originator = R3_SURFEL_HUMAN_ORIGINATOR;
      R3SurfelLabelAssignment *assignment = new R3SurfelLabelAssignment(object, label, 1.0, originator);
      scene->InsertLabelAssignment(assignment);
    }

    // Release block
    database->ReleaseBlock(block);

    // Delete segment surfel arrays    
    for (int j = 0; j < segment_surfels->NEntries(); j++)
      delete segment_surfels->Kth(j);
    delete segment_surfels;

    // Increment statistics
    node_count++;
  }
  
  // Print statistics
  if (print_verbose) {
    printf("Loaded surfels from mesh %s ...\n", mesh_filename);
    printf("  Time = %.2f seconds\n", start_time.Elapsed());
    printf("  # Objects = %d\n", node_count);
    printf("  # Surfels = %d\n", surfel_count);
    fflush(stdout);
  }

  // Return success
  return 1;
}

// Assembly:
subq $0xad8, %rsp            # imm = 0xAD8
movq %rdi, 0xac8(%rsp)
movq %rsi, 0xac0(%rsp)
movq %rdx, 0xab8(%rsp)
movq %rcx, 0xab0(%rsp)
movsd %xmm0, 0xaa8(%rsp)
leaq 0xa98(%rsp), %rdi
callq 0x16dd30
leaq 0xa98(%rsp), %rdi
callq 0x263f0
movl $0x0, 0xa94(%rsp)
movl $0x0, 0xa90(%rsp)
movq 0xac8(%rsp), %rdi
callq 0x26780
movq %rax, 0xa88(%rsp)
cmpq $0x0, 0xa88(%rsp)
jne 0x1fd5e
leaq 0x1d89ab(%rip), %rdi    # 0x1f86f2
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xad4(%rsp)
jmp 0x212ce
movq 0xa88(%rsp), %rdi
callq 0x26790
movq %rax, 0xa80(%rsp)
cmpq $0x0, 0xa80(%rsp)
jne 0x1fd9c
leaq 0x1d8a59(%rip), %rdi    # 0x1f87de
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xad4(%rsp)
jmp 0x212ce
movq 0xac8(%rsp), %rdi
movq 0xab8(%rsp), %rsi
callq 0x70d50
movq %rax, 0xa78(%rsp)
cmpq $0x0, 0xa78(%rsp)
jne 0x1fdea
movq 0xab8(%rsp), %rsi
leaq 0x1d8974(%rip), %rdi    # 0x1f8747
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xad4(%rsp)
jmp 0x212ce
movq 0xa88(%rsp), %rdi
movq 0xab0(%rsp), %rsi
callq 0x60280
movq %rax, 0xa70(%rsp)
cmpq $0x0, 0xa70(%rsp)
jne 0x1fe38
movq 0xab0(%rsp), %rsi
leaq 0x1d88e4(%rip), %rdi    # 0x1f8705
movb $0x0, %al
callq 0x172cb0
movl $0x0, 0xad4(%rsp)
jmp 0x212ce
leaq 0x938(%rsp), %rdi
movq %rdi, 0x210(%rsp)
callq 0xc5450
movq 0x210(%rsp), %rdi
movq 0xac0(%rsp), %rsi
callq 0xdd4b0
movl %eax, 0x218(%rsp)
jmp 0x1fe6b
movl 0x218(%rsp), %eax
cmpl $0x0, %eax
jne 0x1fec3
movq 0xac0(%rsp), %rsi
leaq 0x1d8c16(%rip), %rdi    # 0x1f8a9c
xorl %eax, %eax
callq 0x172cb0
jmp 0x1fe8f
movl $0x0, 0xad4(%rsp)
movl $0x1, 0x928(%rsp)
jmp 0x212b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
jmp 0x212bf
xorps %xmm0, %xmm0
callq 0x1716d0
jmp 0x1fecd
leaq 0x918(%rsp), %rdi
callq 0x26a20
jmp 0x1fedc
leaq 0x908(%rsp), %rdi
callq 0x26a30
jmp 0x1feeb
leaq 0x8f0(%rsp), %rdi
leaq 0x938(%rsp), %rsi
callq 0xc63f0
jmp 0x1ff02
movl $0x0, 0x8ec(%rsp)
movl 0x8ec(%rsp), %eax
movl %eax, 0x208(%rsp)
leaq 0x938(%rsp), %rdi
callq 0x26a40
movl %eax, 0x20c(%rsp)
jmp 0x1ff31
movl 0x208(%rsp), %eax
movl 0x20c(%rsp), %ecx
cmpl %ecx, %eax
jge 0x20d12
movl 0x8ec(%rsp), %esi
leaq 0x938(%rsp), %rdi
callq 0x26a60
movq %rax, 0x200(%rsp)
jmp 0x1ff65
movq 0x200(%rsp), %rax
movq %rax, 0x8e0(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26a90
movl %eax, 0x1fc(%rsp)
jmp 0x1ff93
movl 0x1fc(%rsp), %eax
movl %eax, 0x8dc(%rsp)
cmpl $0x0, 0x8dc(%rsp)
jge 0x2000b
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26ab0
movl %eax, 0x1f8(%rsp)
jmp 0x1ffc9
movl 0x1f8(%rsp), %eax
movl %eax, 0x8dc(%rsp)
jmp 0x2000b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
jmp 0x212a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
jmp 0x21294
cmpl $0x0, 0x8dc(%rsp)
jge 0x20020
movl $0x0, 0x8dc(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26ad0
movl %eax, 0x1f4(%rsp)
jmp 0x2003e
movl 0x1f4(%rsp), %eax
movl %eax, 0x8d8(%rsp)
cmpl $0x0, 0x8d8(%rsp)
jl 0x200f1
movl 0x8d8(%rsp), %eax
movl %eax, 0x1f0(%rsp)
movq 0xac8(%rsp), %rdi
callq 0x266e0
movl %eax, %ecx
movl 0x1f0(%rsp), %eax
cmpl %ecx, %eax
jge 0x200f1
movq 0xac8(%rsp), %rdi
movl 0x8d8(%rsp), %esi
callq 0x26af0
movq %rax, 0x1e8(%rsp)
jmp 0x200a0
movq 0x1e8(%rsp), %rax
movq %rax, 0x8d0(%rsp)
movq 0x8d0(%rsp), %rax
movq %rax, 0x1d8(%rsp)
movl 0x8dc(%rsp), %esi
leaq 0x918(%rsp), %rdi
callq 0x26b20
movq %rax, 0x1e0(%rsp)
jmp 0x200de
movq 0x1e0(%rsp), %rax
movq 0x1d8(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x200f3
leaq 0x918(%rsp), %rdi
callq 0x26490
cmpl 0x8dc(%rsp), %eax
jg 0x2011e
xorl %eax, %eax
movl %eax, %esi
leaq 0x918(%rsp), %rdi
callq 0x26b40
jmp 0x2011c
jmp 0x200f3
jmp 0x20120
leaq 0x908(%rsp), %rdi
callq 0x26490
cmpl 0x8dc(%rsp), %eax
jg 0x2014b
xorl %eax, %eax
movl %eax, %esi
leaq 0x908(%rsp), %rdi
callq 0x26b70
jmp 0x20149
jmp 0x20120
movl 0x8dc(%rsp), %esi
leaq 0x908(%rsp), %rdi
callq 0x26ba0
movq %rax, 0x1d0(%rsp)
jmp 0x20169
movq 0x1d0(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8c8(%rsp)
cmpq $0x0, 0x8c8(%rsp)
jne 0x2022c
movl $0x10, %edi
callq 0x16740
movq %rax, 0x1c8(%rsp)
jmp 0x2019f
movq 0x1c8(%rsp), %rdi
callq 0x26bc0
jmp 0x201ae
movq 0x1c8(%rsp), %rax
movq %rax, 0x8c8(%rsp)
movq 0x8c8(%rsp), %rax
movq %rax, 0x1b8(%rsp)
movl 0x8dc(%rsp), %esi
leaq 0x908(%rsp), %rdi
callq 0x26ba0
movq %rax, 0x1c0(%rsp)
jmp 0x201ec
movq 0x1c0(%rsp), %rax
movq 0x1b8(%rsp), %rcx
movq %rcx, (%rax)
jmp 0x2022c
movq 0x1c8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0x10, %esi
callq 0x16750
jmp 0x21294
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
xorl %edx, %edx
callq 0x26bd0
movq %rax, 0x1b0(%rsp)
jmp 0x2024d
movq 0x1b0(%rsp), %rax
movq %rax, 0x8c0(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
movl $0x1, %edx
callq 0x26bd0
movq %rax, 0x1a8(%rsp)
jmp 0x20281
movq 0x1a8(%rsp), %rax
movq %rax, 0x8b8(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
movl $0x2, %edx
callq 0x26bd0
movq %rax, 0x1a0(%rsp)
jmp 0x202b5
movq 0x1a0(%rsp), %rax
movq %rax, 0x8b0(%rsp)
movq 0x8c0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26bf0
movq %rax, 0x198(%rsp)
jmp 0x202e4
movq 0x198(%rsp), %rsi
leaq 0x898(%rsp), %rdi
callq 0x126090
jmp 0x202fb
movq 0x8b8(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26bf0
movq %rax, 0x190(%rsp)
jmp 0x2031a
movq 0x190(%rsp), %rsi
leaq 0x880(%rsp), %rdi
callq 0x126090
jmp 0x20331
movq 0x8b0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26bf0
movq %rax, 0x188(%rsp)
jmp 0x20350
movq 0x188(%rsp), %rsi
leaq 0x868(%rsp), %rdi
callq 0x126090
jmp 0x20367
movq 0x8c0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26c10
movq %rax, 0x180(%rsp)
jmp 0x20386
movq 0x180(%rsp), %rax
movq %rax, 0x860(%rsp)
movq 0x8b8(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26c10
movq %rax, 0x178(%rsp)
jmp 0x203b5
movq 0x178(%rsp), %rax
movq %rax, 0x858(%rsp)
movq 0x8b0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26c10
movq %rax, 0x170(%rsp)
jmp 0x203e4
movq 0x170(%rsp), %rax
movq %rax, 0x850(%rsp)
leaq 0x838(%rsp), %rdi
leaq 0x8f0(%rsp), %rsi
callq 0x26c30
jmp 0x2040b
leaq 0x898(%rsp), %rdi
leaq 0x838(%rsp), %rsi
callq 0x126d90
jmp 0x20422
leaq 0x820(%rsp), %rdi
leaq 0x8f0(%rsp), %rsi
callq 0x26c30
jmp 0x20439
leaq 0x880(%rsp), %rdi
leaq 0x820(%rsp), %rsi
callq 0x126d90
jmp 0x20450
leaq 0x808(%rsp), %rdi
leaq 0x8f0(%rsp), %rsi
callq 0x26c30
jmp 0x20467
leaq 0x868(%rsp), %rdi
leaq 0x808(%rsp), %rsi
callq 0x126d90
jmp 0x2047e
leaq 0x1de6cb(%rip), %rax    # 0x1feb50
movsd (%rax), %xmm1
movsd 0xaa8(%rsp), %xmm0
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movsd 0x1d7b9e(%rip), %xmm0   # 0x1f8040
divsd %xmm1, %xmm0
movsd %xmm0, 0x800(%rsp)
movsd 0x800(%rsp), %xmm0
movsd %xmm0, 0x160(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26c70
movsd %xmm0, 0x168(%rsp)
jmp 0x204e1
movsd 0x168(%rsp), %xmm1
movsd 0x160(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x7f8(%rsp)
cvttsd2si 0x7f8(%rsp), %eax
movl %eax, 0x7f4(%rsp)
movsd 0x7f8(%rsp), %xmm0
cvtsi2sdl 0x7f4(%rsp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, 0x7e8(%rsp)
movsd 0x7e8(%rsp), %xmm0
movsd %xmm0, 0x150(%rsp)
callq 0x171730
movsd %xmm0, 0x158(%rsp)
jmp 0x20551
movsd 0x150(%rsp), %xmm0
movsd 0x158(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2057a
movl 0x7f4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7f4(%rsp)
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0x26ce0
movq %rax, 0x148(%rsp)
jmp 0x20599
movq 0x148(%rsp), %rsi
leaq 0x7d0(%rsp), %rdi
callq 0x1271f0
jmp 0x205b0
movq 0x8e0(%rsp), %rsi
leaq 0x938(%rsp), %rdi
callq 0xca0a0
movq %rax, 0x140(%rsp)
jmp 0x205cf
movq 0x140(%rsp), %rax
movq %rax, 0x7c8(%rsp)
movq 0x7c8(%rsp), %rdx
leaq 0x7b0(%rsp), %rdi
leaq 0x938(%rsp), %rsi
callq 0x26d10
jmp 0x205fe
leaq 0x7b0(%rsp), %rdi
callq 0x127910
jmp 0x2060d
movsd 0xaa8(%rsp), %xmm0
movsd %xmm0, 0x7a8(%rsp)
movl $0x0, 0x7a4(%rsp)
movl 0x7a4(%rsp), %eax
cmpl 0x7f4(%rsp), %eax
jge 0x20cfa
callq 0x171730
movsd %xmm0, 0x138(%rsp)
jmp 0x2064e
movsd 0x138(%rsp), %xmm0
callq 0x165a0
movsd %xmm0, 0x798(%rsp)
callq 0x171730
movsd %xmm0, 0x130(%rsp)
jmp 0x20675
movsd 0x130(%rsp), %xmm0
movsd %xmm0, 0x790(%rsp)
movsd 0x798(%rsp), %xmm2
movsd 0x1d7998(%rip), %xmm1   # 0x1f8030
movaps %xmm1, %xmm0
subsd %xmm2, %xmm0
movsd %xmm0, 0x788(%rsp)
movsd 0x798(%rsp), %xmm0
movsd 0x790(%rsp), %xmm2
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x780(%rsp)
movsd 0x798(%rsp), %xmm0
movsd 0x790(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x778(%rsp)
movsd 0x788(%rsp), %xmm0
leaq 0x730(%rsp), %rdi
leaq 0x898(%rsp), %rsi
callq 0x26d60
jmp 0x2070a
movsd 0x780(%rsp), %xmm0
leaq 0x718(%rsp), %rdi
leaq 0x880(%rsp), %rsi
callq 0x26d60
jmp 0x2072a
leaq 0x748(%rsp), %rdi
leaq 0x730(%rsp), %rsi
leaq 0x718(%rsp), %rdx
callq 0x126f40
jmp 0x20749
movsd 0x778(%rsp), %xmm0
leaq 0x700(%rsp), %rdi
leaq 0x868(%rsp), %rsi
callq 0x26d60
jmp 0x20769
leaq 0x760(%rsp), %rdi
leaq 0x748(%rsp), %rsi
leaq 0x700(%rsp), %rdx
callq 0x126f40
jmp 0x20788
movsd 0x788(%rsp), %xmm0
movq 0x860(%rsp), %rsi
leaq 0x6b8(%rsp), %rdi
callq 0x26e10
jmp 0x207a8
movsd 0x780(%rsp), %xmm0
movq 0x858(%rsp), %rsi
leaq 0x6a0(%rsp), %rdi
callq 0x26e10
jmp 0x207c8
leaq 0x6d0(%rsp), %rdi
leaq 0x6b8(%rsp), %rsi
leaq 0x6a0(%rsp), %rdx
callq 0x26da0
jmp 0x207e7
movsd 0x778(%rsp), %xmm0
movq 0x850(%rsp), %rsi
leaq 0x688(%rsp), %rdi
callq 0x26e10
jmp 0x20807
leaq 0x6e8(%rsp), %rdi
leaq 0x6d0(%rsp), %rsi
leaq 0x688(%rsp), %rdx
callq 0x26da0
jmp 0x20826
movl 0x8d8(%rsp), %eax
movl %eax, 0x684(%rsp)
cmpl $0x0, 0x684(%rsp)
jge 0x20849
movl $0x0, 0x684(%rsp)
cmpl $0xff, 0x684(%rsp)
jle 0x20861
movl $0xff, 0x684(%rsp)
leaq 0x760(%rsp), %rdi
callq 0x26e50
movsd %xmm0, 0x128(%rsp)
jmp 0x20879
leaq 0x938(%rsp), %rdi
callq 0x26e60
movq %rax, 0x120(%rsp)
jmp 0x20890
movq 0x120(%rsp), %rdi
callq 0x26e80
movsd %xmm0, 0x118(%rsp)
jmp 0x208a8
movsd 0x118(%rsp), %xmm1
movsd 0x128(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x678(%rsp)
movsd 0x678(%rsp), %xmm0
movsd 0x1d7770(%rip), %xmm1   # 0x1f8048
mulsd %xmm1, %xmm0
movsd 0x1d776c(%rip), %xmm1   # 0x1f8050
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0x674(%rsp)
cmpl $0x0, 0x674(%rsp)
jge 0x20908
movl $0x0, 0x674(%rsp)
cmpl $0xffff, 0x674(%rsp) # imm = 0xFFFF
jle 0x20920
movl $0xffff, 0x674(%rsp) # imm = 0xFFFF
movl 0x684(%rsp), %eax
movl 0x674(%rsp), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movl %eax, 0x670(%rsp)
movl $0x30, %edi
callq 0x16740
movq %rax, 0x110(%rsp)
jmp 0x2094e
movq 0x110(%rsp), %rdi
callq 0x46640
jmp 0x2095d
movq 0x110(%rsp), %rax
movq %rax, 0x668(%rsp)
movq 0x668(%rsp), %rax
movq %rax, 0x100(%rsp)
leaq 0x760(%rsp), %rdi
callq 0x26ee0
movsd %xmm0, 0x108(%rsp)
jmp 0x20995
movsd 0x108(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xf4(%rsp)
leaq 0x760(%rsp), %rdi
callq 0x26ef0
movsd %xmm0, 0xf8(%rsp)
jmp 0x209c3
movsd 0xf8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xe4(%rsp)
leaq 0x760(%rsp), %rdi
callq 0x26e50
movsd %xmm0, 0xe8(%rsp)
jmp 0x209f1
movss 0xe4(%rsp), %xmm1
movss 0xf4(%rsp), %xmm0
movq 0x100(%rsp), %rdi
movsd 0xe8(%rsp), %xmm2
cvtsd2ss %xmm2, %xmm2
callq 0x26ea0
jmp 0x20a1f
movq 0x668(%rsp), %rax
movq %rax, 0xd0(%rsp)
leaq 0x6e8(%rsp), %rdi
callq 0x26f40
movsd %xmm0, 0xd8(%rsp)
jmp 0x20a47
movsd 0xd8(%rsp), %xmm0
movsd 0x1d75e0(%rip), %xmm1   # 0x1f8038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movb %al, 0xc7(%rsp)
leaq 0x6e8(%rsp), %rdi
callq 0x26f50
movsd %xmm0, 0xc8(%rsp)
jmp 0x20a7f
movsd 0xc8(%rsp), %xmm0
movsd 0x1d75a8(%rip), %xmm1   # 0x1f8038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movb %al, 0xb7(%rsp)
leaq 0x6e8(%rsp), %rdi
callq 0x26f60
movsd %xmm0, 0xb8(%rsp)
jmp 0x20ab7
movq 0xd0(%rsp), %rdi
movb 0xb7(%rsp), %al
movb 0xc7(%rsp), %dl
movsd 0xb8(%rsp), %xmm0
movsd 0x1d755a(%rip), %xmm1   # 0x1f8038
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movzbl %cl, %ecx
movzbl %dl, %esi
movzbl %al, %edx
callq 0x26f00
jmp 0x20af6
movq 0x668(%rsp), %rax
movq %rax, 0xa0(%rsp)
leaq 0x7d0(%rsp), %rdi
callq 0x27040
movsd %xmm0, 0xa8(%rsp)
jmp 0x20b1e
movsd 0xa8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x94(%rsp)
leaq 0x7d0(%rsp), %rdi
callq 0x27050
movsd %xmm0, 0x98(%rsp)
jmp 0x20b4c
movsd 0x98(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x84(%rsp)
leaq 0x7d0(%rsp), %rdi
callq 0x27060
movsd %xmm0, 0x88(%rsp)
jmp 0x20b7a
movss 0x84(%rsp), %xmm1
movss 0x94(%rsp), %xmm0
movq 0xa0(%rsp), %rdi
movsd 0x88(%rsp), %xmm2
cvtsd2ss %xmm2, %xmm2
callq 0x26f70
jmp 0x20ba8
movq 0x668(%rsp), %rax
movq %rax, 0x70(%rsp)
leaq 0x7b0(%rsp), %rdi
callq 0x27040
movsd %xmm0, 0x78(%rsp)
jmp 0x20bca
movsd 0x78(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x64(%rsp)
leaq 0x7b0(%rsp), %rdi
callq 0x27050
movsd %xmm0, 0x68(%rsp)
jmp 0x20bef
movsd 0x68(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x54(%rsp)
leaq 0x7b0(%rsp), %rdi
callq 0x27060
movsd %xmm0, 0x58(%rsp)
jmp 0x20c14
movss 0x54(%rsp), %xmm1
movss 0x64(%rsp), %xmm0
movq 0x70(%rsp), %rdi
movsd 0x58(%rsp), %xmm2
cvtsd2ss %xmm2, %xmm2
callq 0x27070
jmp 0x20c36
movq 0x668(%rsp), %rdi
movsd 0x7a8(%rsp), %xmm0
cvtsd2ss %xmm0, %xmm0
callq 0x27140
jmp 0x20c52
movq 0x668(%rsp), %rdi
movl 0xa94(%rsp), %esi
incl %esi
callq 0x271c0
jmp 0x20c6a
movq 0x668(%rsp), %rdi
movl 0x670(%rsp), %esi
callq 0x271e0
jmp 0x20c80
movq 0x668(%rsp), %rdi
xorl %esi, %esi
callq 0x27200
jmp 0x20c91
movq 0x8c8(%rsp), %rdi
movq 0x668(%rsp), %rsi
callq 0x27240
jmp 0x20ca8
movl 0xa94(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa94(%rsp)
movl 0x7a4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7a4(%rsp)
jmp 0x2062a
movq 0x110(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0x30, %esi
callq 0x16750
jmp 0x21294
jmp 0x20cfc
movl 0x8ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8ec(%rsp)
jmp 0x1ff0d
movl $0x0, 0x664(%rsp)
movl 0x664(%rsp), %eax
movl %eax, 0x50(%rsp)
leaq 0x908(%rsp), %rdi
callq 0x26490
movl %eax, %ecx
movl 0x50(%rsp), %eax
cmpl %ecx, %eax
jge 0x211d3
movl 0x664(%rsp), %esi
leaq 0x918(%rsp), %rdi
callq 0x27270
movq %rax, 0x48(%rsp)
jmp 0x20d5e
movq 0x48(%rsp), %rax
movq %rax, 0x658(%rsp)
movl 0x664(%rsp), %esi
leaq 0x908(%rsp), %rdi
callq 0x27290
movq %rax, 0x40(%rsp)
jmp 0x20d86
movq 0x40(%rsp), %rax
movq %rax, 0x650(%rsp)
cmpq $0x0, 0x650(%rsp)
jne 0x20da3
jmp 0x211bd
movl 0x664(%rsp), %edx
leaq 0x1d7d08(%rip), %rsi    # 0x1f8ab9
xorl %eax, %eax
leaq 0x250(%rsp), %rdi
callq 0x16130
movl $0xf8, %edi
callq 0x16740
movq %rax, 0x38(%rsp)
jmp 0x20dd1
movq 0x38(%rsp), %rdi
leaq 0x250(%rsp), %rsi
callq 0x6ae00
jmp 0x20de5
movq 0x38(%rsp), %rax
movq %rax, 0x248(%rsp)
cmpq $0x0, 0x248(%rsp)
jne 0x20e50
leaq 0x1d797d(%rip), %rdi    # 0x1f8781
xorl %eax, %eax
callq 0x172cb0
jmp 0x20e0d
movl $0x0, 0xad4(%rsp)
movl $0x1, 0x928(%rsp)
jmp 0x21278
movq 0x38(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0xf8, %esi
callq 0x16750
jmp 0x21294
movq 0xac8(%rsp), %rdi
movq 0x248(%rsp), %rsi
movq 0xa78(%rsp), %rdx
movq (%rdi), %rax
movq 0x18(%rax), %rax
callq *%rax
jmp 0x20e73
movl $0xd0, %edi
callq 0x16740
movq %rax, 0x30(%rsp)
jmp 0x20e84
movq 0x30(%rsp), %rdi
leaq 0x250(%rsp), %rsi
callq 0x5c600
jmp 0x20e98
movq 0x30(%rsp), %rax
movq %rax, 0x240(%rsp)
cmpq $0x0, 0x240(%rsp)
jne 0x20f03
leaq 0x1d7877(%rip), %rdi    # 0x1f872e
xorl %eax, %eax
callq 0x172cb0
jmp 0x20ec0
movl $0x0, 0xad4(%rsp)
movl $0x1, 0x928(%rsp)
jmp 0x21278
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0xd0, %esi
callq 0x16750
jmp 0x21294
movq 0xa88(%rsp), %rdi
movq 0x240(%rsp), %rsi
movq 0xa70(%rsp), %rdx
callq 0x60080
jmp 0x20f22
movq 0x248(%rsp), %rdi
movq 0x240(%rsp), %rsi
callq 0x6d020
jmp 0x20f39
movq 0x650(%rsp), %rax
movq %rax, 0x238(%rsp)
movl $0xc8, %edi
callq 0x16740
movq %rax, 0x28(%rsp)
jmp 0x20f5a
movq 0x28(%rsp), %rdi
movq 0x238(%rsp), %rsi
leaq 0x8f0(%rsp), %rdx
xorps %xmm0, %xmm0
callq 0x48650
jmp 0x20f79
movq 0x28(%rsp), %rax
movq %rax, 0x230(%rsp)
cmpq $0x0, 0x230(%rsp)
jne 0x20fe4
leaq 0x1d7b31(%rip), %rdi    # 0x1f8ac9
xorl %eax, %eax
callq 0x172cb0
jmp 0x20fa1
movl $0x0, 0xad4(%rsp)
movl $0x1, 0x928(%rsp)
jmp 0x21278
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0xc8, %esi
callq 0x16750
jmp 0x21294
movq 0x230(%rsp), %rdi
callq 0x4b450
jmp 0x20ff3
movq 0xa80(%rsp), %rdi
movq 0x230(%rsp), %rsi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
jmp 0x2100e
movq 0x240(%rsp), %rdi
movq 0x230(%rsp), %rsi
movq (%rdi), %rax
movq 0x28(%rax), %rax
callq *%rax
jmp 0x21029
movq 0x240(%rsp), %rdi
callq 0x5e580
jmp 0x21038
movq 0x248(%rsp), %rdi
callq 0x6dc90
jmp 0x21047
cmpq $0x0, 0x658(%rsp)
je 0x210f2
movl $0x0, 0x22c(%rsp)
movl $0x50, %edi
callq 0x16740
movq %rax, 0x20(%rsp)
jmp 0x21072
movq 0x20(%rsp), %rdi
movq 0x248(%rsp), %rsi
movq 0x658(%rsp), %rdx
movl 0x22c(%rsp), %ecx
movsd 0x1d6f9a(%rip), %xmm0   # 0x1f8030
callq 0x6fbd0
jmp 0x2109d
movq 0x20(%rsp), %rax
movq %rax, 0x220(%rsp)
movq 0xac8(%rsp), %rdi
movq 0x220(%rsp), %rsi
movq (%rdi), %rax
movq 0x80(%rax), %rax
callq *%rax
jmp 0x210c8
jmp 0x210f2
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x930(%rsp)
movl %eax, 0x92c(%rsp)
movl $0x50, %esi
callq 0x16750
jmp 0x21294
movq 0xa80(%rsp), %rdi
movq 0x230(%rsp), %rsi
callq 0x26820
jmp 0x21109
movl $0x0, 0x21c(%rsp)
movl 0x21c(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x650(%rsp), %rdi
callq 0x26490
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0x21180
movq 0x650(%rsp), %rdi
movl 0x21c(%rsp), %esi
callq 0x272b0
movq %rax, 0x10(%rsp)
jmp 0x21151
movq 0x10(%rsp), %rax
cmpq $0x0, %rax
je 0x2116b
movq 0x10(%rsp), %rdi
movl $0x30, %esi
callq 0x16750
jmp 0x2116d
movl 0x21c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x21c(%rsp)
jmp 0x21114
movq 0x650(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x211ac
movq 0x8(%rsp), %rdi
callq 0x272d0
movq 0x8(%rsp), %rdi
movl $0x10, %esi
callq 0x16750
movl 0xa90(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xa90(%rsp)
movl 0x664(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x664(%rsp)
jmp 0x20d1d
cmpl $0x0, 0x2435e6(%rip)    # 0x2647c0
je 0x21262
movq 0xac0(%rsp), %rsi
leaq 0x1d78f4(%rip), %rdi    # 0x1f8ae3
xorl %eax, %eax
callq 0x16090
jmp 0x211f8
leaq 0xa98(%rsp), %rdi
callq 0x16ddf0
movsd %xmm0, (%rsp)
jmp 0x2120c
movsd (%rsp), %xmm0
leaq 0x1d7367(%rip), %rdi    # 0x1f857f
movb $0x1, %al
callq 0x16090
jmp 0x21221
movl 0xa90(%rsp), %esi
leaq 0x1d7421(%rip), %rdi    # 0x1f8650
xorl %eax, %eax
callq 0x16090
jmp 0x21238
movl 0xa94(%rsp), %esi
leaq 0x1d78be(%rip), %rdi    # 0x1f8b04
xorl %eax, %eax
callq 0x16090
jmp 0x2124f
movq 0x239d3a(%rip), %rax    # 0x25af90
movq (%rax), %rdi
callq 0x168c0
jmp 0x21260
jmp 0x21262
movl $0x1, 0xad4(%rsp)
movl $0x1, 0x928(%rsp)
leaq 0x908(%rsp), %rdi
callq 0x272e0
leaq 0x918(%rsp), %rdi
callq 0x272f0
jmp 0x212b0
leaq 0x908(%rsp), %rdi
callq 0x272e0
leaq 0x918(%rsp), %rdi
callq 0x272f0
jmp 0x212bf
leaq 0x938(%rsp), %rdi
callq 0xc6350
jmp 0x212ce
leaq 0x938(%rsp), %rdi
callq 0xc6350
jmp 0x212dd
movl 0xad4(%rsp), %eax
addq $0xad8, %rsp            # imm = 0xAD8
retq
movq 0x930(%rsp), %rdi
callq 0x16ca0
nopw (%rax,%rax)