// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Distance(gaps::R3Mesh*, gaps::R3MeshEdge*, gaps::R3Point const&, gaps::R3MeshIntersection*)
RNLength 
R3Distance(R3Mesh *mesh, R3MeshEdge *edge, const R3Point& point, R3MeshIntersection* closest_point)
{
  // Compute distance from edge to point
  R3Span edge_span = mesh->EdgeSpan(edge);
  RNScalar distance = R3Distance(point, edge_span);

  // Fill in closest point info
  if (closest_point) {
    closest_point->edge = edge;
    closest_point->face = NULL;
    closest_point->t = distance; 
    RNScalar edge_t = edge_span.T(point);
    if (RNIsEqual(edge_t, 0)) {
      R3MeshVertex *vertex = mesh->VertexOnEdge(edge, 0);
      closest_point->type = R3_MESH_VERTEX_TYPE;
      closest_point->vertex = vertex;
      closest_point->point = mesh->VertexPosition(vertex);
    }
    else if (RNIsEqual(edge_t, edge_span.Length())) {
      R3MeshVertex *vertex = mesh->VertexOnEdge(edge, 1);
      closest_point->type = R3_MESH_VERTEX_TYPE;
      closest_point->vertex = vertex;
      closest_point->point = mesh->VertexPosition(vertex);
    }
    else {
      closest_point->type = R3_MESH_EDGE_TYPE;
      closest_point->vertex = NULL;
      closest_point->point = edge_span.Point(edge_t);
    }
  }

  // Return squared distance
  return distance;
}

// Assembly:
subq $0xb8, %rsp
movq %rdi, 0xb0(%rsp)
movq %rsi, 0xa8(%rsp)
movq %rdx, 0xa0(%rsp)
movq %rcx, 0x98(%rsp)
movq 0xb0(%rsp), %rsi
movq 0xa8(%rsp), %rdx
leaq 0x48(%rsp), %rdi
callq 0x37a00
movq 0xa0(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x86d80
movsd %xmm0, 0x40(%rsp)
cmpq $0x0, 0x98(%rsp)
je 0x360c2
movq 0xa8(%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0x98(%rsp), %rax
movq $0x0, 0x18(%rax)
movsd 0x40(%rsp), %xmm0
movq 0x98(%rsp), %rax
movsd %xmm0, 0x38(%rax)
movq 0xa0(%rsp), %rsi
leaq 0x48(%rsp), %rdi
callq 0x6d920
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
leaq 0x14257c(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm2
xorps %xmm1, %xmm1
callq 0x37170
cmpl $0x0, %eax
je 0x35fdb
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
xorl %edx, %edx
callq 0x36960
movq %rax, 0x30(%rsp)
movq 0x98(%rsp), %rax
movl $0x1, (%rax)
movq 0x30(%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0xb0(%rsp), %rdi
movq 0x30(%rsp), %rsi
callq 0x13660
movq %rax, %rsi
movq 0x98(%rsp), %rdi
addq $0x20, %rdi
callq 0x6f1e0
jmp 0x360c0
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x37a50
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
leaq 0x1424df(%rip), %rax    # 0x1784e0
movsd (%rax), %xmm2
callq 0x37170
cmpl $0x0, %eax
je 0x36075
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
movl $0x1, %edx
callq 0x36960
movq %rax, 0x28(%rsp)
movq 0x98(%rsp), %rax
movl $0x1, (%rax)
movq 0x28(%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0xb0(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x13660
movq %rax, %rsi
movq 0x98(%rsp), %rdi
addq $0x20, %rdi
callq 0x6f1e0
jmp 0x360be
movq 0x98(%rsp), %rax
movl $0x2, (%rax)
movq 0x98(%rsp), %rax
movq $0x0, 0x8(%rax)
movsd 0x38(%rsp), %xmm0
leaq 0x10(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x6d710
movq 0x98(%rsp), %rdi
addq $0x20, %rdi
leaq 0x10(%rsp), %rsi
callq 0x6f1e0
jmp 0x360c0
jmp 0x360c2
movsd 0x40(%rsp), %xmm0
addq $0xb8, %rsp
retq