// File: tomfunkhouser[P]gaps/apps/msh2df/../../pkgs/R3Shapes/R3Kdtree.cpp
// Function: gaps::R3Kdtree<Point*>::InsertPoints(gaps::R3KdtreeNode<Point*>*, gaps::R3Box const&, Point**, int)
void R3Kdtree<PtrType>::
InsertPoints(R3KdtreeNode<PtrType> *node, const R3Box& node_box, PtrType *points, int npoints) 
{
  // Make sure node is an empty leaf
  assert(node);
  assert(node->children[0] == NULL);
  assert(node->children[1] == NULL);
  assert(node->npoints == 0);

  // Check number of points
  if (npoints < R3kdtree_max_points_per_node) {
    // Insert new points into leaf node and return
    for (int i = 0; i < npoints; i++) {
      node->points[node->npoints++] = points[i];
    }
  }
  else {
    // Find dimension to split along
    node->split_dimension = node_box.LongestAxis();
    
    // Partition points according to coordinates in split_dimension
    int split_index = PartitionPoints(points, npoints, node->split_dimension, 0, npoints-1);
    assert((split_index >= 0) && (split_index < npoints));

    // Determine split coordinate
    node->split_coordinate = Position(points[split_index])[node->split_dimension];
    assert(node->split_coordinate >= node_box[RN_LO][node->split_dimension]);
    assert(node->split_coordinate <= node_box[RN_HI][node->split_dimension]);

    // Construct children node boxes
    R3Box node0_box(node_box);
    R3Box node1_box(node_box);
    node0_box[RN_HI][node->split_dimension] = node->split_coordinate;
    node1_box[RN_LO][node->split_dimension] = node->split_coordinate;

    // Create children
    node->children[0] = new R3KdtreeNode<PtrType>(node);
    node->children[1] = new R3KdtreeNode<PtrType>(node);

    // Insert points into children
    InsertPoints(node->children[0], node0_box, points, split_index);
    InsertPoints(node->children[1], node1_box, &points[split_index], npoints - split_index);

    // Increment number of nodes
    nnodes += 2;
  }
}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq %rdx, 0xe0(%rsp)
movq %rcx, 0xd8(%rsp)
movl %r8d, 0xd4(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpl $0x20, 0xd4(%rsp)
jge 0x18d36
movl $0x0, 0xd0(%rsp)
movl 0xd0(%rsp), %eax
cmpl 0xd4(%rsp), %eax
jge 0x18d31
movq 0xd8(%rsp), %rax
movslq 0xd0(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
movq 0xe8(%rsp), %rax
movq 0xe8(%rsp), %rsi
movl 0x128(%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, 0x128(%rsi)
movslq %ecx, %rcx
movq %rdx, 0x28(%rax,%rcx,8)
movl 0xd0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xd0(%rsp)
jmp 0x18cd1
jmp 0x18fdb
movq 0xe0(%rsp), %rdi
callq 0x68390
movq 0x28(%rsp), %rdi
movl %eax, %ecx
movq 0xe8(%rsp), %rax
movl %ecx, 0x20(%rax)
movq 0xd8(%rsp), %rsi
movl 0xd4(%rsp), %edx
movq 0xe8(%rsp), %rax
movl 0x20(%rax), %ecx
movl %edx, %r9d
decl %r9d
xorl %r8d, %r8d
callq 0x18ff0
movq 0x28(%rsp), %rsi
movl %eax, 0xcc(%rsp)
movq 0xd8(%rsp), %rax
movslq 0xcc(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
leaq 0xb0(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x18bc0
movq 0x20(%rsp), %rdi
movq 0xe8(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x17e60
movq 0xe8(%rsp), %rax
movsd %xmm0, 0x18(%rax)
movq 0xe0(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x67100
movq 0xe0(%rsp), %rsi
leaq 0x40(%rsp), %rdi
callq 0x67100
jmp 0x18df7
movq 0xe8(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x78(%rsp), %rdi
movl $0x1, %esi
callq 0x17820
movq %rax, %rdi
movq 0xe8(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x17800
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rax)
movq 0xe8(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x40(%rsp), %rdi
xorl %esi, %esi
callq 0x17820
movq %rax, %rdi
movq 0xe8(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x17800
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rax)
movl $0x130, %edi            # imm = 0x130
callq 0xf4c0
movq %rax, 0x18(%rsp)
jmp 0x18e83
movq 0x18(%rsp), %rdi
movq 0xe8(%rsp), %rsi
callq 0x18b70
jmp 0x18e97
movq 0x18(%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x8(%rax)
movl $0x130, %edi            # imm = 0x130
callq 0xf4c0
movq %rax, (%rsp)
jmp 0x18eb8
movq (%rsp), %rdi
movq 0xe8(%rsp), %rsi
callq 0x18b70
jmp 0x18ecb
movq 0x28(%rsp), %rdi
movq (%rsp), %rcx
movq 0xe8(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xe8(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0xd8(%rsp), %rcx
movl 0xcc(%rsp), %r8d
leaq 0x78(%rsp), %rdx
callq 0x18c80
jmp 0x18f08
movq 0x28(%rsp), %rdi
movq 0xe8(%rsp), %rax
movq 0x10(%rax), %rsi
movq 0xd8(%rsp), %rcx
movslq 0xcc(%rsp), %rdx
movl %edx, %eax
leaq (%rcx,%rdx,8), %rcx
movl 0xd4(%rsp), %r8d
subl %eax, %r8d
leaq 0x40(%rsp), %rdx
callq 0x18c80
jmp 0x18f46
movq 0x28(%rsp), %rax
movl 0x5c(%rax), %ecx
addl $0x2, %ecx
movl %ecx, 0x5c(%rax)
leaq 0x40(%rsp), %rdi
callq 0x17670
leaq 0x78(%rsp), %rdi
callq 0x17670
jmp 0x18fdb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
jmp 0x18fcf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
jmp 0x18fc5
movq 0x18(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
movl $0x130, %esi            # imm = 0x130
callq 0xf4d0
jmp 0x18fc5
movq (%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
movl $0x130, %esi            # imm = 0x130
callq 0xf4d0
leaq 0x40(%rsp), %rdi
callq 0x17670
leaq 0x78(%rsp), %rdi
callq 0x17670
jmp 0x18fe3
addq $0xf8, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0xf890
nopl (%rax)