// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rcx, %rbx
movq %rdx, %r12
movq %rsi, %r14
movq %rdi, %r15
cmpq $0x0, 0x8(%rsi)
je 0x15103
leaq 0x50(%rsp), %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1502a
movslq 0x20(%r14), %rax
movsd 0x50(%rsp,%rax,8), %xmm0
subsd 0x18(%r14), %xmm0
xorpd %xmm1, %xmm1
leaq 0x8(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
ucomisd %xmm0, %xmm1
jae 0x15124
callq 0x3a0e6
movsd 0x18(%r14), %xmm0
movslq 0x20(%r14), %rax
movsd %xmm0, 0x10(%rsp,%rax,8)
movq 0x10(%r14), %rsi
movq %r15, %rdi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1507e
jmp 0x15289
movslq 0x128(%r14), %rax
cmpq $0x1f, %rax
jg 0x15150
leal 0x1(%rax), %ecx
movl %ecx, 0x128(%r14)
movq %rbx, 0x28(%r14,%rax,8)
jmp 0x15293
callq 0x3a0e6
movsd 0x18(%r14), %xmm0
movslq 0x20(%r14), %rax
movsd %xmm0, 0x28(%rsp,%rax,8)
movq 0x8(%r14), %rsi
movq %r15, %rdi
movq %r13, %rdx
movq %rbx, %rcx
callq 0x1507e
jmp 0x15289
movq %r12, %rdi
callq 0x3a66e
movl %eax, 0x20(%r14)
leaq 0x28(%r14), %rsi
movl 0x128(%r14), %edx
leal -0x1(%rdx), %r9d
movq %r15, %rdi
movq %rsi, 0x48(%rsp)
movl %eax, %ecx
xorl %r8d, %r8d
callq 0x152ce
movl %eax, %ebp
cltq
movq %rax, 0x40(%rsp)
movq 0x28(%r14,%rax,8), %rdx
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x1502a
movslq 0x20(%r14), %rax
movsd 0x8(%rsp,%rax,8), %xmm0
movsd %xmm0, 0x18(%r14)
leaq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0x3a0e6
leaq 0x50(%rsp), %rdi
movq %r12, %rsi
callq 0x3a0e6
movsd 0x18(%r14), %xmm0
movslq 0x20(%r14), %rax
movsd %xmm0, 0x28(%rsp,%rax,8)
movsd %xmm0, 0x58(%rsp,%rax,8)
movl $0x130, %edi            # imm = 0x130
callq 0xe460
movq %rax, %r13
movq %r14, (%rax)
andl $0x0, 0x128(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rax, 0x8(%r14)
movl $0x130, %edi            # imm = 0x130
callq 0xe460
movq %r14, (%rax)
andl $0x0, 0x128(%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movups %xmm0, 0x14(%rax)
movq %rax, 0x10(%r14)
leaq 0x8(%rsp), %rdx
movq %r15, %rdi
movq %r13, %rsi
movq 0x48(%rsp), %rcx
movl %ebp, %r8d
callq 0x154aa
movq 0x40(%rsp), %rax
leaq (%r14,%rax,8), %rcx
addq $0x28, %rcx
movq 0x10(%r14), %rsi
movl 0x128(%r14), %r8d
subl %ebp, %r8d
leaq 0x50(%rsp), %rdx
movq %r15, %rdi
callq 0x154aa
andl $0x0, 0x128(%r14)
addl $0x2, 0x5c(%r15)
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
movq %rbx, %rcx
callq 0x1507e
leaq 0x50(%rsp), %rdi
callq 0x3ad9e
leaq 0x8(%rsp), %rdi
callq 0x3ad9e
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x152a9
jmp 0x152a9
movq %rax, %rbx
jmp 0x152bb
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x3ad9e
leaq 0x8(%rsp), %rdi
callq 0x3ad9e
movq %rbx, %rdi
callq 0xe820
nop