// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Triangle.cpp
// Function: gaps::R3Triangle::ClosestPoint(gaps::R3Point const&) const
const R3Point R3Triangle::
ClosestPoint(const R3Point& point) const
{
    // Start with projection onto plane
    R3Point closest_point = point;
    closest_point.Project(Plane());

    // Project onto edge plane if point is on other side
    for (int i = 0; i < 3; i++) {
      R3TriangleVertex *v0 = v[i];
      R3TriangleVertex *v1 = v[(i+1)%3];
      R3Point p0 = v0->Position();
      R3Point p1 = v1->Position();
      R3Span span(p0, p1);
      if (RNIsZero(span.Length())) return Centroid();
      R3Vector n = span.Vector() % Normal();
      R3Plane edge_plane(p0, n);
      RNScalar d1 = R3SignedDistance(edge_plane, closest_point);
      if (RNIsPositive(d1)) {
        RNScalar t = span.T(closest_point);
        if (t < 0) t = 0;
        if (t > span.Length()) t = span.Length();
        closest_point = span.Point(t);
      }
    }
   
    // Return closest point;
    return closest_point;
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x18(%rsp)
movq %rdi, %rax
movq %rax, 0x20(%rsp)
movq %rdi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
movq %rdx, 0x140(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x140(%rsp), %rsi
leaq 0x128(%rsp), %rdi
callq 0x6eb90
movq 0x28(%rsp), %rdi
callq 0x81b30
movq %rax, %rsi
leaq 0x128(%rsp), %rdi
callq 0x6f220
movl $0x0, 0x124(%rsp)
cmpl $0x3, 0x124(%rsp)
jge 0x9c038
movq 0x28(%rsp), %rax
movslq 0x124(%rsp), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, 0x118(%rsp)
movl 0x124(%rsp), %eax
addl $0x1, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movq 0x28(%rsp), %rax
movslq %edx, %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, 0x110(%rsp)
movq 0x118(%rsp), %rdi
callq 0x78950
movq %rax, %rsi
leaq 0xf8(%rsp), %rdi
callq 0x6eb90
movq 0x110(%rsp), %rdi
callq 0x78950
movq %rax, %rsi
leaq 0xe0(%rsp), %rdi
callq 0x6eb90
leaq 0x90(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
leaq 0xe0(%rsp), %rdx
callq 0x6d550
leaq 0x90(%rsp), %rdi
callq 0x37a50
leaq 0xdc5f3(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x9bf10
movq 0x28(%rsp), %rsi
movq 0x18(%rsp), %rdi
movq (%rsi), %rax
callq *0x68(%rax)
jmp 0x9c04a
leaq 0x90(%rsp), %rdi
callq 0x392b0
movq 0x28(%rsp), %rdi
movq %rax, 0x10(%rsp)
callq 0x78960
movq 0x10(%rsp), %rsi
movq %rax, %rdx
leaq 0x78(%rsp), %rdi
callq 0x70af0
leaq 0x58(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
leaq 0x78(%rsp), %rdx
callq 0x6c260
leaq 0x58(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x86f90
movsd %xmm0, 0x50(%rsp)
movsd 0x50(%rsp), %xmm0
leaq 0xdc566(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36d50
cmpl $0x0, %eax
je 0x9c020
leaq 0x90(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x6d920
movsd %xmm0, 0x48(%rsp)
xorps %xmm0, %xmm0
ucomisd 0x48(%rsp), %xmm0
jbe 0x9bfbb
xorps %xmm0, %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x90(%rsp), %rdi
callq 0x37a50
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x9bff6
leaq 0x90(%rsp), %rdi
callq 0x37a50
movsd %xmm0, 0x48(%rsp)
movsd 0x48(%rsp), %xmm0
leaq 0x30(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x6d710
leaq 0x128(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x6f1e0
jmp 0x9c022
movl 0x124(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x124(%rsp)
jmp 0x9be33
movq 0x18(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x6eb90
movq 0x20(%rsp), %rax
addq $0x158, %rsp            # imm = 0x158
retq
nopw (%rax,%rax)