// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::RenderGridTriangle(gaps::R2Point const&, gaps::R2Point const&, gaps::R2Point const&, double, double, double, double, double, double, gaps::R2Grid&)
void R2Grid::
RenderGridTriangle(
   const R2Point& pointA, const R2Point& pointB, const R2Point& pointC,
   RNScalar valueA, RNScalar valueB, RNScalar valueC,
   RNScalar depthA, RNScalar depthB, RNScalar depthC,
   R2Grid& depth_grid)
{
  // Check values
  if (valueA == R2_GRID_UNKNOWN_VALUE) return;
  if (valueB == R2_GRID_UNKNOWN_VALUE) return;
  if (valueC == R2_GRID_UNKNOWN_VALUE) return;

  // Check depths
  if (depthA == R2_GRID_UNKNOWN_VALUE) return;
  if (depthB == R2_GRID_UNKNOWN_VALUE) return;
  if (depthC == R2_GRID_UNKNOWN_VALUE) return;

  // Get convenient variables
  R2Point points[3] = { pointA, pointB, pointC };
  RNScalar values[3] = { valueA, valueB, valueC };
  RNScalar depths[3] = { depthA, depthB, depthC };

  // Sort vertex indices by Y coordinate
  int iv0, iv1, iv2;
  if (points[0].Y() < points[1].Y()) {
    if (points[0].Y() < points[2].Y()) { 
      if (points[1].Y() < points[2].Y()) { iv0 = 0; iv1 = 1; iv2 = 2; }
      else { iv0 = 0; iv1 = 2; iv2 = 1; }
    }
    else { iv0 = 2; iv1 = 0; iv2 = 1; }
  }
  else {
    if (points[1].Y() < points[2].Y()) { 
      if (points[0].Y() < points[2].Y()) { iv0 = 1; iv1 = 0; iv2 = 2; }
      else { iv0 = 1; iv1 = 2; iv2 = 0; }
    }
    else { iv0 = 2; iv1 = 1; iv2 = 0; }
  }
  
  // Sort vertex coordinates
  double dy = points[iv2].Y() - points[iv0].Y();
  double t1 = (dy > 0) ? (points[iv1].Y() - points[iv0].Y()) / dy : 0;
  double y0 = points[iv0].Y();
  double y1 = points[iv1].Y();
  double y2 = points[iv2].Y();
  double x0 = points[iv0].X();
  double x2 = points[iv2].X();
  double x1a = points[iv1].X();
  double x1b = (1-t1)*x0 + t1*x2;
  double value0 = values[iv0];
  double value2 = values[iv2];
  double value1a = values[iv1];
  double value1b = (1-t1)*value0 + t1*value2;
  double depth0 = depths[iv0];
  double depth2 = depths[iv2];
  double depth1a = depths[iv1];
  double depth1b = (1-t1)*depth0 + t1*depth2;
  if (x1a > x1b) { 
    double swap;
    swap = x1a; x1a = x1b; x1b = swap; 
    swap = value1a; value1a = value1b; value1b = swap; 
    swap = depth1a; depth1a = depth1b; depth1b = swap; 
  }

  // Rasterize lower half of triangle
  int iy0 = (int) (y0 + 0.5);
  int iy1 = (int) (y1 + 0.5);
  int nysteps = iy1 - iy0;
  double xa_step = (nysteps > 0) ? (x1a - x0) / nysteps : 0;
  double xb_step = (nysteps > 0) ? (x1b - x0) / nysteps : 0;
  double valuea_step = (nysteps > 0) ? (value1a  - value0) / nysteps : 0;
  double valueb_step = (nysteps > 0) ? (value1b  - value0) / nysteps : 0;
  double deptha_step = (nysteps > 0) ? (depth1a  - depth0) / nysteps : 0;
  double depthb_step = (nysteps > 0) ? (depth1b  - depth0) / nysteps : 0;
  double xa = x0;
  double xb = x0;
  double valuea = value0;
  double valueb = value0;
  double deptha = depth0;
  double depthb = depth0;
  for (int iy = iy0; iy <= iy1; iy++) {
    int ixa = (int) (xa + 0.5);
    int ixb = (int) (xb + 0.5);
    int nxsteps = ixb - ixa;
    double value_step = (nxsteps > 0) ? (valueb - valuea) / nxsteps : 0;
    double depth_step = (nxsteps > 0) ? (depthb - deptha) / nxsteps : 0;
    double value = valuea;
    double depth = deptha;
    for (int ix = ixa; ix <= ixb; ix++) {
      RNScalar old_depth = depth_grid.GridValue(ix, iy);
      if ((old_depth == R2_GRID_UNKNOWN_VALUE) || (depth < old_depth)) {
        SetGridValue(ix, iy, value);
        depth_grid.SetGridValue(ix, iy, depth);
      }
      value += value_step;
      depth += depth_step;
    }
    valuea += valuea_step;
    valueb += valueb_step;
    deptha += deptha_step;
    depthb += depthb_step;
    xa += xa_step;
    xb += xb_step;
  }
  
  // Rasterize upper half of triangle
  int iy2 = (int) (y2 + 0.5);
  nysteps = iy2 - iy1;
  xa_step = (nysteps > 0) ? (x2 - x1a) / nysteps : 0;
  xb_step = (nysteps > 0) ? (x2 - x1b) / nysteps : 0;
  valuea_step = (nysteps > 0) ? (value2  - value1a) / nysteps : 0;
  valueb_step = (nysteps > 0) ? (value2  - value1b) / nysteps : 0;
  deptha_step = (nysteps > 0) ? (depth2  - depth1a) / nysteps : 0;
  depthb_step = (nysteps > 0) ? (depth2  - depth1b) / nysteps : 0;
  xa = x1a;
  xb = x1b;
  valuea = value1a;
  valueb = value1b;
  deptha = depth1a;
  depthb = depth1b;
  for (int iy = iy1; iy <= iy2; iy++) {
    int ixa = (int) (xa + 0.5);
    int ixb = (int) (xb + 0.5);
    int nxsteps = ixb - ixa;
    double value_step = (nxsteps > 0) ? (valueb - valuea) / nxsteps : 0;
    double depth_step = (nxsteps > 0) ? (depthb - deptha) / nxsteps : 0;
    double value = valuea;
    double depth = deptha;
    for (int ix = ixa; ix <= ixb; ix++) {
      RNScalar old_depth = depth_grid.GridValue(ix, iy);
      if ((old_depth == R2_GRID_UNKNOWN_VALUE) || (depth < old_depth)) {
        SetGridValue(ix, iy, value);
        depth_grid.SetGridValue(ix, iy, depth);
      }
      value += value_step;
      depth += depth_step;
    }
    valuea += valuea_step;
    valueb += valueb_step;
    deptha += deptha_step;
    depthb += depthb_step;
    xa += xa_step;
    xb += xb_step;
  }
}

// Assembly:
ucomisd 0x3c7f8(%rip), %xmm0    # 0x93f68
jne 0x57778
jnp 0x57ce7
ucomisd 0x3c7e8(%rip), %xmm1    # 0x93f68
jne 0x57788
jnp 0x57ce7
ucomisd 0x3c7d8(%rip), %xmm2    # 0x93f68
jne 0x57798
jnp 0x57ce7
ucomisd 0x3c7c8(%rip), %xmm3    # 0x93f68
jne 0x577a8
jnp 0x57ce7
ucomisd 0x3c7b8(%rip), %xmm4    # 0x93f68
jne 0x577b8
jnp 0x57ce7
ucomisd 0x3c7a8(%rip), %xmm5    # 0x93f68
jne 0x577c8
jnp 0x57ce7
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %r8, %rbx
movq %rcx, %r13
movq %rdx, %r12
movq %rdi, %r14
leaq 0xa0(%rsp), %r15
leaq 0x90(%rsp), %rbp
leaq 0x80(%rsp), %rdi
movsd %xmm5, 0x10(%rsp)
movsd %xmm4, 0x8(%rsp)
movsd %xmm3, 0x38(%rsp)
movsd %xmm2, 0x30(%rsp)
movsd %xmm1, 0x28(%rsp)
movsd %xmm0, 0x20(%rsp)
callq 0x5f596
movq %rbp, %rdi
movq %r12, %rsi
callq 0x5f596
movq %r15, %rdi
movq %r13, %rsi
callq 0x5f596
leaq 0x80(%rsp), %rdx
leaq 0x70(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movsd 0x20(%rsp), %xmm0
movsd %xmm0, -0x10(%rdi)
movsd 0x28(%rsp), %xmm0
movsd %xmm0, -0x8(%rdi)
movsd 0x30(%rsp), %xmm0
movsd %xmm0, (%rdi)
movsd 0x38(%rsp), %xmm0
movsd %xmm0, -0x10(%rsi)
movsd 0x8(%rsp), %xmm0
movsd %xmm0, -0x8(%rsi)
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%rsi)
movsd 0x8(%rdx), %xmm1
movsd 0x18(%rdx), %xmm2
ucomisd %xmm1, %xmm2
movsd 0x28(%rdx), %xmm0
jbe 0x578ca
ucomisd %xmm1, %xmm0
jbe 0x578f6
xorl %ecx, %ecx
ucomisd %xmm2, %xmm0
seta %cl
pushq $0x2
popq %rax
subq %rcx, %rax
incq %rcx
leaq 0x60(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %rdx, %r15
jmp 0x57902
ucomisd %xmm2, %xmm0
jbe 0x578fd
leaq 0x48(%rsp), %rsi
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd %xmm1, %xmm0
setbe %al
seta %cl
leaq 0x68(%rsp), %rdi
addl %ecx, %ecx
addl %eax, %eax
leaq 0x90(%rsp), %r15
jmp 0x57902
pushq $0x1
popq %rcx
xorl %eax, %eax
jmp 0x57902
pushq $0x1
popq %rax
xorl %ecx, %ecx
movl %ecx, %edx
shll $0x4, %edx
movsd 0x80(%rsp,%rdx), %xmm11
movsd 0x88(%rsp,%rdx), %xmm0
movsd (%r15), %xmm8
movsd 0x8(%r15), %xmm5
movsd %xmm0, 0x8(%rsp)
subsd %xmm5, %xmm0
movl %eax, %edx
shll $0x4, %edx
movsd 0x80(%rsp,%rdx), %xmm1
movsd 0x88(%rsp,%rdx), %xmm6
movapd %xmm6, %xmm2
subsd %xmm5, %xmm2
divsd %xmm0, %xmm2
xorpd %xmm4, %xmm4
cmpltsd %xmm0, %xmm4
andpd %xmm2, %xmm4
movsd 0x3b6a1(%rip), %xmm2    # 0x93008
subsd %xmm4, %xmm2
movapd %xmm4, %xmm0
mulsd %xmm11, %xmm0
movapd %xmm2, %xmm10
mulsd %xmm8, %xmm10
addsd %xmm0, %xmm10
shll $0x3, %ecx
shll $0x3, %eax
unpcklpd %xmm4, %xmm4            # xmm4 = xmm4[0,0]
movsd 0x60(%rsp,%rcx), %xmm3
movhpd 0x40(%rsp,%rcx), %xmm3  # xmm3 = xmm3[0],mem[0]
mulpd %xmm3, %xmm4
movsd (%rdi), %xmm7
movhpd (%rsi), %xmm7           # xmm7 = xmm7[0],mem[0]
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
mulpd %xmm7, %xmm2
ucomisd %xmm10, %xmm1
addpd %xmm4, %xmm2
movsd 0x60(%rsp,%rax), %xmm9
movhpd 0x40(%rsp,%rax), %xmm9  # xmm9 = xmm9[0],mem[0]
movapd %xmm11, 0x10(%rsp)
ja 0x579e2
unpcklpd %xmm1, %xmm10           # xmm10 = xmm10[0],xmm1[0]
movapd %xmm2, %xmm4
movapd %xmm9, %xmm2
movapd %xmm10, %xmm1
jmp 0x579ec
unpcklpd %xmm10, %xmm1           # xmm1 = xmm1[0],xmm10[0]
movapd %xmm9, %xmm4
unpcklpd %xmm5, %xmm6            # xmm6 = xmm6[0],xmm5[0]
addpd 0x3b648(%rip), %xmm6    # 0x93040
cvttpd2dq %xmm6, %xmm0
shufpd $0x1, %xmm1, %xmm1      # xmm1 = xmm1[1,0]
movd %xmm0, %eax
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, %ecx
movl %eax, %edx
subl %ecx, %edx
xorl %esi, %esi
testl %edx, %edx
setg %sil
cvtsi2sd %edx, %xmm0
unpcklpd %xmm8, %xmm8            # xmm8 = xmm8[0,0]
movapd %xmm1, %xmm10
subpd %xmm8, %xmm10
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
divpd %xmm0, %xmm10
movd %esi, %xmm5
pshufd $0x0, %xmm5, %xmm5      # xmm5 = xmm5[0,0,0,0]
pslld $0x1f, %xmm5
psrad $0x1f, %xmm5
andpd %xmm5, %xmm10
movapd %xmm2, %xmm11
subpd %xmm7, %xmm11
divpd %xmm0, %xmm11
movapd %xmm4, %xmm12
subpd %xmm7, %xmm12
divpd %xmm0, %xmm12
andpd %xmm5, %xmm11
andpd %xmm5, %xmm12
movapd 0x3b5c2(%rip), %xmm5    # 0x93040
movsd 0x3c4e2(%rip), %xmm6    # 0x93f68
movapd %xmm7, %xmm9
cmpl %eax, %ecx
jg 0x57b78
movapd %xmm8, %xmm0
addpd %xmm5, %xmm0
cvttpd2dq %xmm0, %xmm0
movd %xmm0, %esi
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, %edi
movslq %edi, %rdx
subl %esi, %edi
xorl %r8d, %r8d
testl %edi, %edi
setg %r8b
movapd %xmm7, %xmm0
subpd %xmm9, %xmm0
cvtsi2sd %edi, %xmm13
unpcklpd %xmm13, %xmm13          # xmm13 = xmm13[0,0]
divpd %xmm13, %xmm0
movd %r8d, %xmm13
pshufd $0x0, %xmm13, %xmm14    # xmm14 = xmm13[0,0,0,0]
pslld $0x1f, %xmm14
psrad $0x1f, %xmm14
pand %xmm0, %xmm14
movl 0xc8(%r14), %edi
imull %ecx, %edi
movslq %edi, %rdi
shlq $0x3, %rdi
addq 0xb8(%r14), %rdi
movslq %esi, %rsi
movl 0xc8(%rbx), %r8d
imull %ecx, %r8d
movslq %r8d, %r8
shlq $0x3, %r8
addq 0xb8(%rbx), %r8
movapd %xmm9, %xmm13
cmpq %rdx, %rsi
jg 0x57b62
movsd (%r8,%rsi,8), %xmm0
ucomisd %xmm6, %xmm0
movapd %xmm13, %xmm15
unpckhpd %xmm13, %xmm15          # xmm15 = xmm15[1],xmm13[1]
jne 0x57b45
jnp 0x57b4c
ucomisd %xmm15, %xmm0
jbe 0x57b58
movlpd %xmm13, (%rdi,%rsi,8)
movsd %xmm15, (%r8,%rsi,8)
addpd %xmm14, %xmm13
incq %rsi
jmp 0x57b28
addpd %xmm11, %xmm9
addpd %xmm12, %xmm7
addpd %xmm10, %xmm8
incl %ecx
jmp 0x57a8b
movsd 0x8(%rsp), %xmm0
addsd 0x3b48a(%rip), %xmm0    # 0x93010
cvttsd2si %xmm0, %ecx
movl %ecx, %edx
subl %eax, %edx
xorl %esi, %esi
testl %edx, %edx
setg %sil
movapd 0x10(%rsp), %xmm11
unpcklpd %xmm11, %xmm11          # xmm11 = xmm11[0,0]
subpd %xmm1, %xmm11
cvtsi2sd %edx, %xmm0
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
divpd %xmm0, %xmm11
movd %esi, %xmm7
pshufd $0x0, %xmm7, %xmm8      # xmm8 = xmm7[0,0,0,0]
pslld $0x1f, %xmm8
psrad $0x1f, %xmm8
andpd %xmm8, %xmm11
movapd %xmm3, %xmm7
subpd %xmm2, %xmm7
subpd %xmm4, %xmm3
divpd %xmm0, %xmm7
divpd %xmm0, %xmm3
andpd %xmm8, %xmm7
andpd %xmm8, %xmm3
cmpl %ecx, %eax
jg 0x57cd6
movapd %xmm1, %xmm0
addpd %xmm5, %xmm0
cvttpd2dq %xmm0, %xmm0
movd %xmm0, %esi
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, %edi
movslq %edi, %rdx
subl %esi, %edi
xorl %r8d, %r8d
testl %edi, %edi
setg %r8b
movapd %xmm4, %xmm0
subpd %xmm2, %xmm0
cvtsi2sd %edi, %xmm8
unpcklpd %xmm8, %xmm8            # xmm8 = xmm8[0,0]
divpd %xmm8, %xmm0
movd %r8d, %xmm8
pshufd $0x0, %xmm8, %xmm8      # xmm8 = xmm8[0,0,0,0]
pslld $0x1f, %xmm8
psrad $0x1f, %xmm8
pand %xmm0, %xmm8
movl 0xc8(%r14), %edi
imull %eax, %edi
movslq %edi, %rdi
shlq $0x3, %rdi
addq 0xb8(%r14), %rdi
movslq %esi, %rsi
movl 0xc8(%rbx), %r8d
imull %eax, %r8d
movslq %r8d, %r8
shlq $0x3, %r8
addq 0xb8(%rbx), %r8
movapd %xmm2, %xmm9
cmpq %rdx, %rsi
jg 0x57cc2
movsd (%r8,%rsi,8), %xmm0
ucomisd %xmm6, %xmm0
movapd %xmm9, %xmm10
unpckhpd %xmm9, %xmm10           # xmm10 = xmm10[1],xmm9[1]
jne 0x57ca5
jnp 0x57cac
ucomisd %xmm10, %xmm0
jbe 0x57cb8
movlpd %xmm9, (%rdi,%rsi,8)
movsd %xmm10, (%r8,%rsi,8)
addpd %xmm8, %xmm9
incq %rsi
jmp 0x57c88
addpd %xmm7, %xmm2
addpd %xmm3, %xmm4
addpd %xmm11, %xmm1
incl %eax
jmp 0x57bed
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq