// File: tomfunkhouser[P]gaps/apps/msh2pts/../../pkgs/R3Shapes/R3Kdtree.cpp
// Function: gaps::R3Kdtree<Point*>::InsertPoint(gaps::R3KdtreeNode<Point*>*, gaps::R3Box const&, Point*)
void R3Kdtree<PtrType>::
InsertPoint(R3KdtreeNode<PtrType> *node, const R3Box& node_box, PtrType point) 
{
  // Check if interior node
  if (node->children[0]) {
    // Inserting point into an interior node
    assert(node->children[1]);

    // Get point position
    R3Point position = Position(point);

    // Determine side of split
    RNLength side = position[node->split_dimension] - node->split_coordinate;
    if (side <= 0) {
      // Insert into negative side
      R3Box child_box(node_box);
      child_box[RN_HI][node->split_dimension] = node->split_coordinate;
      InsertPoint(node->children[0], child_box, point);
    }
    else {
      // Insert into positive side
      R3Box child_box(node_box);
      child_box[RN_LO][node->split_dimension] = node->split_coordinate;
      InsertPoint(node->children[1], child_box, point);
    }
  }
  else {
    // Inserting point into a leaf
    assert(!node->children[1]);
    
    // Check number of points
    if (node->npoints < R3kdtree_max_points_per_node) {
      // Insert new point into leaf node and return
      node->points[node->npoints++] = point;
    }
    else {
      // Find dimension to split along
      node->split_dimension = node_box.LongestAxis();
    
      // Partition points according to coordinates in split_dimension
      int split_index = PartitionPoints(node->points, node->npoints, node->split_dimension, 0, node->npoints-1);
      assert((split_index >= 0) && (split_index < node->npoints));

      // Determine split coordinate
      node->split_coordinate = Position(node->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);

      // Move points into children
      InsertPoints(node->children[0], node0_box, node->points, split_index);
      InsertPoints(node->children[1], node1_box, &node->points[split_index], node->npoints - split_index);
      node->npoints = 0;
      
      // Increment number of nodes
      nnodes += 2;

      // Insert point into this node
      InsertPoint(node, node_box, point);
    }
  }
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, 0x1a0(%rsp)
movq %rsi, 0x198(%rsp)
movq %rdx, 0x190(%rsp)
movq %rcx, 0x188(%rsp)
movq 0x1a0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x198(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0x1d360
movq 0x50(%rsp), %rsi
movq 0x188(%rsp), %rdx
leaq 0x170(%rsp), %rdi
callq 0x1d040
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
leaq 0x170(%rsp), %rdi
callq 0x1b400
movsd (%rax), %xmm0
movq 0x198(%rsp), %rax
subsd 0x18(%rax), %xmm0
movsd %xmm0, 0x168(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x168(%rsp), %xmm0
jb 0x1d2ab
movq 0x190(%rsp), %rsi
leaq 0x130(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x70db0
movq 0x48(%rsp), %rdi
movq 0x198(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x40(%rsp)
movl $0x1, %esi
callq 0x1b3c0
movq %rax, %rdi
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x1b400
movsd 0x40(%rsp), %xmm0
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rdx
movsd %xmm0, (%rax)
movq 0x198(%rsp), %rax
movq 0x8(%rax), %rsi
movq 0x188(%rsp), %rcx
callq 0x1d150
jmp 0x1d273
leaq 0x130(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d35b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
leaq 0x130(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d6a8
movq 0x190(%rsp), %rsi
leaq 0xe8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x70db0
movq 0x38(%rsp), %rdi
movq 0x198(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
xorl %esi, %esi
callq 0x1b3c0
movq %rax, %rdi
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x1b400
movsd 0x30(%rsp), %xmm0
movq 0x50(%rsp), %rdi
movq 0x38(%rsp), %rdx
movsd %xmm0, (%rax)
movq 0x198(%rsp), %rax
movq 0x10(%rax), %rsi
movq 0x188(%rsp), %rcx
callq 0x1d150
jmp 0x1d326
leaq 0xe8(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d35b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d6a8
jmp 0x1d6a0
movq 0x198(%rsp), %rax
cmpl $0x20, 0x128(%rax)
jge 0x1d3a7
movq 0x188(%rsp), %rdx
movq 0x198(%rsp), %rax
movq 0x198(%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)
jmp 0x1d69e
movq 0x190(%rsp), %rdi
callq 0x72040
movq 0x50(%rsp), %rdi
movl %eax, %ecx
movq 0x198(%rsp), %rax
movl %ecx, 0x20(%rax)
movq 0x198(%rsp), %rax
movq %rax, %rsi
addq $0x28, %rsi
movl 0x20(%rax), %ecx
movl 0x128(%rax), %edx
movl %edx, %r9d
decl %r9d
xorl %r8d, %r8d
callq 0x1d6c0
movq 0x50(%rsp), %rsi
movl %eax, 0xe4(%rsp)
movq 0x198(%rsp), %rax
movslq 0xe4(%rsp), %rcx
movq 0x28(%rax,%rcx,8), %rdx
leaq 0xc8(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x1d040
movq 0x28(%rsp), %rdi
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x1c240
movq 0x198(%rsp), %rax
movsd %xmm0, 0x18(%rax)
movq 0x190(%rsp), %rsi
leaq 0x90(%rsp), %rdi
callq 0x70db0
movq 0x190(%rsp), %rsi
leaq 0x58(%rsp), %rdi
callq 0x70db0
jmp 0x1d46a
movq 0x198(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x90(%rsp), %rdi
movl $0x1, %esi
callq 0x1b3c0
movq %rax, %rdi
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x1b400
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rax)
movq 0x198(%rsp), %rax
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x58(%rsp), %rdi
xorl %esi, %esi
callq 0x1b3c0
movq %rax, %rdi
movq 0x198(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x1b400
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
movl $0x130, %edi            # imm = 0x130
callq 0xf4d0
movq %rax, 0x20(%rsp)
jmp 0x1d4f9
movq 0x20(%rsp), %rdi
movq 0x198(%rsp), %rsi
callq 0x1c260
jmp 0x1d50d
movq 0x20(%rsp), %rcx
movq 0x198(%rsp), %rax
movq %rcx, 0x8(%rax)
movl $0x130, %edi            # imm = 0x130
callq 0xf4d0
movq %rax, 0x8(%rsp)
jmp 0x1d52f
movq 0x8(%rsp), %rdi
movq 0x198(%rsp), %rsi
callq 0x1c260
jmp 0x1d543
movq 0x50(%rsp), %rdi
movq 0x8(%rsp), %rcx
movq 0x198(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x198(%rsp), %rcx
movq 0x8(%rcx), %rsi
addq $0x28, %rcx
movl 0xe4(%rsp), %r8d
leaq 0x90(%rsp), %rdx
callq 0x1dbe0
jmp 0x1d580
movq 0x50(%rsp), %rdi
movq 0x198(%rsp), %rdx
movq 0x10(%rdx), %rsi
movslq 0xe4(%rsp), %rcx
movl %ecx, %eax
leaq 0x28(%rdx,%rcx,8), %rcx
movl 0x128(%rdx), %r8d
subl %eax, %r8d
leaq 0x58(%rsp), %rdx
callq 0x1dbe0
jmp 0x1d5b6
movq 0x50(%rsp), %rdi
movq 0x198(%rsp), %rax
movl $0x0, 0x128(%rax)
movl 0x5c(%rdi), %eax
addl $0x2, %eax
movl %eax, 0x5c(%rdi)
movq 0x198(%rsp), %rsi
movq 0x190(%rsp), %rdx
movq 0x188(%rsp), %rcx
callq 0x1d150
jmp 0x1d5f5
leaq 0x58(%rsp), %rdi
callq 0x1b2c0
leaq 0x90(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d69e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
jmp 0x1d68f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
jmp 0x1d685
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
movl $0x130, %esi            # imm = 0x130
callq 0xf4e0
jmp 0x1d685
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x128(%rsp)
movl %eax, 0x124(%rsp)
movl $0x130, %esi            # imm = 0x130
callq 0xf4e0
leaq 0x58(%rsp), %rdi
callq 0x1b2c0
leaq 0x90(%rsp), %rdi
callq 0x1b2c0
jmp 0x1d6a8
jmp 0x1d6a0
addq $0x1a8, %rsp            # imm = 0x1A8
retq
movq 0x128(%rsp), %rdi
callq 0xf8a0
nopw %cs:(%rax,%rax)
nop