// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3CatmullRomSpline.cpp
// Function: gaps::R3CatmullRomSpline::PointDerivative(double) const
R3Vector R3CatmullRomSpline::
PointDerivative(RNScalar u) const
{
  // Return tangent vector at parametric value u

  // Get index variables
  int i = VertexIndex(u);
  double denom = VertexParameter(i+1) - VertexParameter(i);
  if (RNIsZero(denom)) return R3zero_vector;
  double t = (u - VertexParameter(i)) / denom;

  // Get control vertex_positions
  R3Point P0 = (i > 0) ? VertexPosition(i-1) : VertexPosition(0);
  R3Point P1 = VertexPosition(i);
  R3Point P2 = VertexPosition(i+1);
  R3Point P3 = (i < NVertices()-2) ? VertexPosition(i+2) : VertexPosition(NVertices()-1);

  // Compute derivative vector
  R3Vector v = R3zero_vector;
  v += BlendingWeightDerivative(t, -1) * P0.Vector();
  v += BlendingWeightDerivative(t,  0) * P1.Vector();
  v += BlendingWeightDerivative(t,  1) * P2.Vector();
  v += BlendingWeightDerivative(t,  2) * P3.Vector();

  // Return derivative vector
  return v;
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, 0x38(%rsp)
movq %rdi, %rax
movq %rax, 0x40(%rsp)
movq %rdi, 0x1a0(%rsp)
movq %rsi, 0x198(%rsp)
movsd %xmm0, 0x190(%rsp)
movq 0x198(%rsp), %rdi
movq %rdi, 0x48(%rsp)
movsd 0x190(%rsp), %xmm0
movq (%rdi), %rax
callq *0x268(%rax)
movq 0x48(%rsp), %rdi
movl %eax, 0x18c(%rsp)
movl 0x18c(%rsp), %esi
addl $0x1, %esi
callq 0x919f0
movq 0x48(%rsp), %rdi
movsd %xmm0, 0x50(%rsp)
movl 0x18c(%rsp), %esi
callq 0x919f0
movaps %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x180(%rsp)
movsd 0x180(%rsp), %xmm0
leaq 0xe71fc(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0x91308
movq 0x38(%rsp), %rdi
leaq 0x4e82a2(%rip), %rsi    # 0x5795a0
callq 0x6fcf0
jmp 0x9159b
movq 0x48(%rsp), %rdi
movsd 0x190(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movl 0x18c(%rsp), %esi
callq 0x919f0
movaps %xmm0, %xmm1
movsd 0x30(%rsp), %xmm0
subsd %xmm1, %xmm0
divsd 0x180(%rsp), %xmm0
movsd %xmm0, 0x178(%rsp)
cmpl $0x0, 0x18c(%rsp)
jle 0x9136f
movq 0x48(%rsp), %rsi
movl 0x18c(%rsp), %edx
subl $0x1, %edx
leaq 0x160(%rsp), %rdi
callq 0x919b0
jmp 0x91383
movq 0x48(%rsp), %rsi
leaq 0x160(%rsp), %rdi
xorl %edx, %edx
callq 0x919b0
movq 0x48(%rsp), %rsi
movl 0x18c(%rsp), %edx
leaq 0x148(%rsp), %rdi
callq 0x919b0
movq 0x48(%rsp), %rsi
movl 0x18c(%rsp), %edx
addl $0x1, %edx
leaq 0x130(%rsp), %rdi
callq 0x919b0
movq 0x48(%rsp), %rdi
movl 0x18c(%rsp), %eax
movl %eax, 0x2c(%rsp)
callq 0x91990
movl %eax, %ecx
movl 0x2c(%rsp), %eax
subl $0x2, %ecx
cmpl %ecx, %eax
jge 0x913f8
movq 0x48(%rsp), %rsi
movl 0x18c(%rsp), %edx
addl $0x2, %edx
leaq 0x118(%rsp), %rdi
callq 0x919b0
jmp 0x91419
movq 0x48(%rsp), %rdi
callq 0x91990
movq 0x48(%rsp), %rsi
movl %eax, %edx
subl $0x1, %edx
leaq 0x118(%rsp), %rdi
callq 0x919b0
movq 0x38(%rsp), %rdi
leaq 0x4e817b(%rip), %rsi    # 0x5795a0
callq 0x6fcf0
movq 0x48(%rsp), %rdi
movsd 0x178(%rsp), %xmm0
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x915b0
movsd %xmm0, 0x8(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0x160(%rsp), %rsi
callq 0x36d10
movsd 0x8(%rsp), %xmm0
leaq 0x100(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x13800
movq 0x38(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x70be0
movq 0x48(%rsp), %rdi
movsd 0x178(%rsp), %xmm0
xorl %esi, %esi
callq 0x915b0
movsd %xmm0, 0x10(%rsp)
leaq 0xb8(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x36d10
movsd 0x10(%rsp), %xmm0
leaq 0xd0(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x13800
movq 0x38(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
callq 0x70be0
movq 0x48(%rsp), %rdi
movsd 0x178(%rsp), %xmm0
movl $0x1, %esi
callq 0x915b0
movsd %xmm0, 0x18(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x130(%rsp), %rsi
callq 0x36d10
movsd 0x18(%rsp), %xmm0
leaq 0xa0(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x13800
movq 0x38(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x70be0
movq 0x48(%rsp), %rdi
movsd 0x178(%rsp), %xmm0
movl $0x2, %esi
callq 0x915b0
movsd %xmm0, 0x20(%rsp)
leaq 0x58(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x36d10
movsd 0x20(%rsp), %xmm0
leaq 0x70(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x13800
movq 0x38(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x70be0
movq 0x40(%rsp), %rax
addq $0x1a8, %rsp            # imm = 0x1A8
retq
nopl (%rax,%rax)