user: Translate the below assembly code into C programming language:

```asm
<glmClosestPointOnTriangle3f>:
  endbr64
  push   %r15
  push   %r14
  mov    %rdx,%r14
  push   %r13
  mov    %rcx,%r13
  push   %r12
  mov    %rsi,%r12
  push   %rbp
  mov    %r8,%rbp
  push   %rbx
  sub    $0x78,%rsp
  mov    %rdi,(%rsp)
  lea    0x38(%rsp),%rbx
  lea    0x2c(%rsp),%r15
  mov    %rbx,%rdi
  mov    %fs:0x28,%rax
  mov    %rax,0x68(%rsp)
  xor    %eax,%eax
  call   <glmComputeTriangleNormalf@plt>
  mov    %rbp,%rcx
  mov    %rbx,%rdx
  mov    %r12,%rsi
  mov    %r15,%rdi
  call   <glmClosestPointOnPlane3f@plt>
  mov    %r13,%rcx
  mov    %r14,%rdx
  mov    %r12,%rsi
  mov    %rbp,%rdi
  call   <glmIsPointInTriangle3f@plt>
  test   %rax,%rax
  jne    L86
  lea    0x44(%rsp),%r9
  mov    %r14,%rdx
  mov    %r15,%rcx
  mov    %r12,%rsi
  mov    %r9,%rdi
  lea    0x50(%rsp),%rbx
  mov    %r9,0x8(%rsp)
  call   <glmClosestPointOnLineSegment3f@plt>
  mov    %r14,%rsi
  mov    %r15,%rcx
  mov    %r13,%rdx
  mov    %rbx,%rdi
  lea    0x5c(%rsp),%r14
  call   <glmClosestPointOnLineSegment3f@plt>
  mov    %r12,%rdx
  mov    %r15,%rcx
  mov    %r13,%rsi
  mov    %r14,%rdi
  call   <glmClosestPointOnLineSegment3f@plt>
  mov    0x8(%rsp),%r9
  mov    %rbp,%rsi
  mov    %r9,%rdi
  mov    %r9,0x18(%rsp)
  call   <glmComputeDistance3f@plt>
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  movss  %xmm0,0x14(%rsp)
  call   <glmComputeDistance3f@plt>
  mov    %rbp,%rsi
  mov    %r14,%rdi
  movss  %xmm0,0x8(%rsp)
  call   <glmComputeDistance3f@plt>
  movss  0x14(%rsp),%xmm3
  movss  0x8(%rsp),%xmm1
  xor    %edi,%edi
  movaps %xmm0,%xmm2
  mov    $0x2,%edx
  mov    $0x1,%esi
  movaps %xmm3,%xmm0
  call   <glmMinIndex3f@plt>
  cmp    $0x1,%eax
  je     L60
  cmp    $0x2,%eax
  je     L43
  test   %eax,%eax
  mov    0x18(%rsp),%r9
  je     L1
L24:
  mov    0x68(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L58
  add    $0x78,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L86:
  mov    (%rsp),%rsi
  mov    %rbp,%rdi
  call   <glmCopyVector3f@plt>
  jmp    L24
  cs nopw 0x0(%rax,%rax,1)
L1:
  mov    (%rsp),%rsi
  mov    %r9,%rdi
  call   <glmCopyVector3f@plt>
  jmp    L24
  xchg   %ax,%ax
L43:
  mov    (%rsp),%rsi
  mov    %r14,%rdi
  call   <glmCopyVector3f@plt>
  jmp    L24
  xchg   %ax,%ax
L60:
  mov    (%rsp),%rsi
  mov    %rbx,%rdi
  call   <glmCopyVector3f@plt>
  jmp    L24
L58:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void glmClosestPointOnTriangle3f(float result[3], const float v1[3], const float v2[3], const float v3[3], const float p[3]) {
  float temp[3];
  float normal[3];
  float d1, d2, d3;
  float t1[3], t2[3], t3[3];
  glmComputeTriangleNormalf(normal, v1, v2, v3);
  glmClosestPointOnPlane3f(temp, v1, normal, p);
  if (glmIsPointInTriangle3f(p, v1, v2, v3)) {
    glmCopyVector3f(p, result);
    return;
  }
  glmClosestPointOnLineSegment3f(t1, v1, v2, temp);
  glmClosestPointOnLineSegment3f(t2, v2, v3, temp);
  glmClosestPointOnLineSegment3f(t3, v3, v1, temp);
  d1 = glmComputeDistance3f(t1, p);
  d2 = glmComputeDistance3f(t2, p);
  d3 = glmComputeDistance3f(t3, p);
  switch (glmMinIndex3f(d1, d2, d3, 0, 1, 2)) {
  case 0:
    glmCopyVector3f(t1, result);
    return;
    break;
  case 1:
    glmCopyVector3f(t2, result);
    return;
    break;
  case 2:
    glmCopyVector3f(t3, result);
    return;
    break;
  }
}
```