// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/../../pkgs/R3Shapes/R3Kdtree.cpp
// Function: gaps::R3Kdtree<gaps::R3SurfelPoint*>::FindClosest(gaps::R3SurfelPoint*, double, double, int, int (*)(gaps::R3SurfelPoint*, gaps::R3SurfelPoint*, void*), void*, gaps::RNArray<gaps::R3SurfelPoint*>&, double*) const
int R3Kdtree<PtrType>::
FindClosest(PtrType query_point, 
  RNScalar min_distance, RNScalar max_distance, int max_points, 
  int (*IsCompatible)(PtrType, PtrType, void *), void *compatible_data, 
  RNArray<PtrType>& points, RNLength *distances) const
{
  // Check root
  if (!root) return 0;

  // Use squared distances for efficiency
  if (max_distance < 0) return 0;
  if (min_distance < 0) min_distance = 0;
  RNLength min_distance_squared = min_distance * min_distance;
  RNLength max_distance_squared = max_distance * max_distance;

  // Allocate temporary array of squared distances to max_points closest points
  RNLength *distances_squared = new RNLength [ max_points ];

  // Search nodes recursively
  FindClosest(root, bbox, 
    query_point, Position(query_point),
    min_distance_squared, max_distance_squared, max_points, 
    IsCompatible, compatible_data,
    points, distances_squared);

  // Update return distances
  if (distances) {
    for (int i = 0; i < points.NEntries(); i++) {
      distances[i] = sqrt(distances_squared[i]);
    }
  }

  // Delete temporary array of squared distances
  delete [] distances_squared;

  // Return number of points
  return points.NEntries();
}

// Assembly:
pushq %rbx
subq $0xd0, %rsp
movq 0xe0(%rsp), %rax
movq %rdi, 0xc0(%rsp)
movq %rsi, 0xb8(%rsp)
movsd %xmm0, 0xb0(%rsp)
movsd %xmm1, 0xa8(%rsp)
movl %edx, 0xa4(%rsp)
movq %rcx, 0x98(%rsp)
movq %r8, 0x90(%rsp)
movq %r9, 0x88(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x50(%rax)
jne 0x5c1e5
movl $0x0, 0xcc(%rsp)
jmp 0x5c3a3
xorps %xmm0, %xmm0
ucomisd 0xa8(%rsp), %xmm0
jbe 0x5c203
movl $0x0, 0xcc(%rsp)
jmp 0x5c3a3
xorps %xmm0, %xmm0
ucomisd 0xb0(%rsp), %xmm0
jbe 0x5c21d
xorps %xmm0, %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0xb0(%rsp), %xmm0
mulsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0xa8(%rsp), %xmm0
mulsd 0xa8(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
movslq 0xa4(%rsp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x13030
movq 0x48(%rsp), %rsi
movq %rax, 0x70(%rsp)
movq 0x50(%rsi), %rax
movq %rax, 0x38(%rsp)
movq 0xb8(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xb8(%rsp), %rdx
leaq 0x58(%rsp), %rdi
callq 0x5b800
movq 0x38(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq 0x40(%rsp), %rcx
movsd 0x80(%rsp), %xmm0
movsd 0x78(%rsp), %xmm1
movl 0xa4(%rsp), %r9d
movq 0x98(%rsp), %rbx
movq 0x90(%rsp), %r11
movq 0x88(%rsp), %r10
movq 0x70(%rsp), %rax
leaq 0x58(%rsp), %r8
movq %rdx, %rdi
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x5c3c0
cmpq $0x0, 0xe0(%rsp)
je 0x5c375
movl $0x0, 0x54(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x34(%rsp)
movq 0x88(%rsp), %rdi
callq 0x16d50
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0x5c373
movq 0x70(%rsp), %rax
movslq 0x54(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x13420
movq 0xe0(%rsp), %rax
movslq 0x54(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x54(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x54(%rsp)
jmp 0x5c321
jmp 0x5c375
movq 0x70(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x5c38f
movq 0x28(%rsp), %rdi
callq 0x13750
movq 0x88(%rsp), %rdi
callq 0x16d50
movl %eax, 0xcc(%rsp)
movl 0xcc(%rsp), %eax
addq $0xd0, %rsp
popq %rbx
retq
nopw %cs:(%rax,%rax)
nopl (%rax)