// File: /workspace/github_cpp_makefile_star2_O2/tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Grid.cpp
// Function: gaps::R2Grid::RasterizeGridTriangle(int const*, int const*, int const*, double, double, double, int)
void R2Grid::
RasterizeGridTriangle(const int p1[2], const int p2[2], const int p3[2], RNScalar value1, RNScalar value2, RNScalar value3, int operation)
{
  // Resolve values
  if (value1 == R2_GRID_UNKNOWN_VALUE) return;
  if (value2 == R2_GRID_UNKNOWN_VALUE) return;
  if (value3 == R2_GRID_UNKNOWN_VALUE) return;

  // Get convenient point variables
  R2Point points[3];
  points[0][0] = p1[0];
  points[0][1] = p1[1];
  points[1][0] = p2[0];
  points[1][1] = p2[1];
  points[2][0] = p3[0];
  points[2][1] = p3[1];

  // Get convenient value variables
  RNScalar values[3];
  values[0] = value1;
  values[1] = value2;
  values[2] = value3;

  // 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 val0 = values[iv0];
  double val2 = values[iv2];
  double val1a = values[iv1];
  double val1b = (1-t1)*val0 + t1*val2;
  if (x1a > x1b) { 
    double swap;
    swap = x1a; x1a = x1b; x1b = swap; 
    swap = val1a; val1a = val1b; val1b = swap; 
  }

  // Rasterize lower half of triangle
  int iy0 = (int) (y0 + 0.5);
  int iy1 = (int) (y1 + 0.5);
  int nysteps = (iy1 - iy0) + 1;
  double xa_step = (x1a - x0) / nysteps;
  double xb_step = (x1b - x0) / nysteps;
  double vala_step = (val1a  - val0) / nysteps;
  double valb_step = (val1b  - val0) / nysteps;
  double xa = x0;
  double xb = x0;
  double vala = val0;
  double valb = val0;
  for (int iy = iy0; iy <= iy1; iy++) {
    int ixa = (int) (xa + 0.5);
    int ixb = (int) (xb + 0.5);
    int nxsteps = (ixb - ixa) + 1;
    double val_step = (valb - vala) / nxsteps;
    double val = vala;
    for (int ix = ixa; ix <= ixb; ix++) {
      RasterizeGridValue(ix, iy, val, operation);
      val += val_step;
    }
    vala += vala_step;
    valb += valb_step;
    xa += xa_step;
    xb += xb_step;
  }
  
  // Rasterize upper half of triangle
  int iy2 = (int) (y2 + 0.5);
  nysteps = (iy2 - iy1) + 1;
  xa_step = (x2 - x1a) / nysteps;
  xb_step = (x2 - x1b) / nysteps;
  vala_step = (val2  - val1a) / nysteps;
  valb_step = (val2  - val1b) / nysteps;
  xa = x1a;
  xb = x1b;
  vala = val1a;
  valb = val1b;
  for (int iy = iy1; iy <= iy2; iy++) {
    int ixa = (int) (xa + 0.5);
    int ixb = (int) (xb + 0.5);
    int nxsteps = (ixb - ixa) + 1;
    double val_step = (valb - vala) / nxsteps;
    double val = vala;
    for (int ix = ixa; ix <= ixb; ix++) {
      RasterizeGridValue(ix, iy, val, operation);
      val += val_step;
    }
    vala += vala_step;
    valb += valb_step;
    xa += xa_step;
    xb += xb_step;
  }
}

// Assembly:
ucomisd 0x3d052(%rip), %xmm0    # 0x93f68
jne 0x56f1e
jnp 0x57358
ucomisd 0x3d042(%rip), %xmm1    # 0x93f68
jne 0x56f2e
jnp 0x57358
ucomisd 0x3d032(%rip), %xmm2    # 0x93f68
jne 0x56f3e
jnp 0x57358
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movl %r8d, %ebx
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r13
movq %rdi, %r14
movsd %xmm0, (%rsp)
movsd %xmm1, 0x10(%rsp)
movsd %xmm2, 0x20(%rsp)
xorl %ebp, %ebp
leaq (%rsp,%rbp), %rdi
addq $0x80, %rdi
callq 0x5f58a
addq $0x10, %rbp
cmpq $0x30, %rbp
jne 0x56f71
cvtdq2pd (%r13), %xmm1
movapd %xmm1, 0x80(%rsp)
cvtdq2pd (%r12), %xmm2
movapd %xmm2, 0x90(%rsp)
cvtdq2pd (%r15), %xmm0
movapd %xmm0, 0xa0(%rsp)
movsd (%rsp), %xmm3
movsd %xmm3, 0x30(%rsp)
movsd 0x10(%rsp), %xmm3
movsd %xmm3, 0x38(%rsp)
movsd 0x20(%rsp), %xmm3
movsd %xmm3, 0x40(%rsp)
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
ucomisd %xmm1, %xmm2
jbe 0x57013
ucomisd %xmm1, %xmm0
jbe 0x5703a
xorl %ecx, %ecx
ucomisd %xmm2, %xmm0
seta %cl
pushq $0x2
popq %rax
subq %rcx, %rax
incq %rcx
leaq 0x80(%rsp), %r8
leaq 0x30(%rsp), %rdi
jmp 0x57053
ucomisd %xmm2, %xmm0
jbe 0x57041
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd %xmm1, %xmm0
setbe %al
seta %cl
addl %ecx, %ecx
addl %eax, %eax
leaq 0x38(%rsp), %rdi
leaq 0x90(%rsp), %r8
jmp 0x57053
pushq $0x1
popq %rcx
xorl %eax, %eax
jmp 0x57046
pushq $0x1
popq %rax
xorl %ecx, %ecx
leaq 0x40(%rsp), %rdi
leaq 0xa0(%rsp), %r8
movl %ecx, %edx
shll $0x4, %edx
movsd 0x88(%rsp,%rdx), %xmm2
movsd 0x8(%r8), %xmm0
movsd %xmm2, 0xb8(%rsp)
subsd %xmm0, %xmm2
movl %eax, %esi
shll $0x4, %esi
movsd 0x80(%rsp,%rsi), %xmm5
movsd 0x88(%rsp,%rsi), %xmm1
movapd %xmm1, %xmm3
subsd %xmm0, %xmm3
divsd %xmm2, %xmm3
xorpd %xmm4, %xmm4
cmpltsd %xmm2, %xmm4
andpd %xmm3, %xmm4
movsd 0x3bf5c(%rip), %xmm3    # 0x93008
subsd %xmm4, %xmm3
unpcklpd %xmm4, %xmm4            # xmm4 = xmm4[0,0]
movsd 0x80(%rsp,%rdx), %xmm2
movhpd 0x30(%rsp,%rcx,8), %xmm2 # xmm2 = xmm2[0],mem[0]
movapd %xmm2, 0x50(%rsp)
mulpd %xmm2, %xmm4
unpcklpd %xmm3, %xmm3            # xmm3 = xmm3[0,0]
movsd (%rdi), %xmm7
movsd (%r8), %xmm2
movapd %xmm2, %xmm8
movapd %xmm7, %xmm6
unpcklpd %xmm7, %xmm2            # xmm2 = xmm2[0],xmm7[0]
mulpd %xmm3, %xmm2
addpd %xmm4, %xmm2
ucomisd %xmm2, %xmm5
movhpd 0x30(%rsp,%rax,8), %xmm5 # xmm5 = xmm5[0],mem[0]
ja 0x57101
movapd %xmm2, %xmm3
jmp 0x57109
movapd %xmm5, %xmm3
movapd %xmm2, %xmm5
unpcklpd %xmm0, %xmm1            # xmm1 = xmm1[0],xmm0[0]
addpd 0x3bf2b(%rip), %xmm1    # 0x93040
cvttpd2dq %xmm1, %xmm0
movd %xmm0, %ebp
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, %r15d
movl %ebp, %eax
subl %r15d, %eax
incl %eax
cvtsi2sd %eax, %xmm0
movapd %xmm5, %xmm2
unpcklpd %xmm3, %xmm2            # xmm2 = xmm2[0],xmm3[0]
movapd %xmm3, 0x60(%rsp)
movapd %xmm5, 0x70(%rsp)
unpckhpd %xmm5, %xmm3            # xmm3 = xmm3[1],xmm5[1]
unpcklpd %xmm6, %xmm6            # xmm6 = xmm6[0,0]
movapd %xmm8, %xmm1
unpcklpd %xmm8, %xmm1            # xmm1 = xmm1[0],xmm8[0]
subpd %xmm1, %xmm2
movapd %xmm6, (%rsp)
subpd %xmm6, %xmm3
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
divpd %xmm0, %xmm3
movapd %xmm3, 0xc0(%rsp)
divpd %xmm0, %xmm2
movapd %xmm2, 0xd0(%rsp)
cmpl %ebp, %r15d
jg 0x57243
movapd %xmm1, %xmm0
movapd %xmm1, %xmm2
movsd 0x3be74(%rip), %xmm1    # 0x93010
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %r12d
movapd %xmm2, 0xe0(%rsp)
movapd %xmm2, %xmm0
unpckhpd %xmm2, %xmm0            # xmm0 = xmm0[1],xmm2[1]
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %r13d
movl %r13d, %eax
subl %r12d, %eax
incl %eax
movapd (%rsp), %xmm1
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
movapd %xmm1, %xmm2
subsd %xmm0, %xmm2
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm2
movapd %xmm2, 0x10(%rsp)
cmpl %r13d, %r12d
jg 0x57216
movq %r14, %rdi
movl %r12d, %esi
movl %r15d, %edx
movl %ebx, %ecx
movapd %xmm0, 0x20(%rsp)
callq 0x569e8
movapd 0x20(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
incl %r12d
jmp 0x571ea
movapd 0xe0(%rsp), %xmm1
addpd 0xd0(%rsp), %xmm1
movapd (%rsp), %xmm0
addpd 0xc0(%rsp), %xmm0
movapd %xmm0, (%rsp)
incl %r15d
jmp 0x57183
movsd 0xb8(%rsp), %xmm0
addsd 0x3bdbc(%rip), %xmm0    # 0x93010
cvttsd2si %xmm0, %r12d
movl %r12d, %eax
subl %ebp, %eax
incl %eax
movapd 0x50(%rsp), %xmm2
movapd %xmm2, %xmm4
movapd 0x70(%rsp), %xmm1
subpd %xmm1, %xmm4
cvtsi2sd %eax, %xmm0
movapd 0x60(%rsp), %xmm3
subpd %xmm3, %xmm2
unpcklpd %xmm0, %xmm0            # xmm0 = xmm0[0,0]
divpd %xmm0, %xmm4
movapd %xmm4, (%rsp)
divpd %xmm0, %xmm2
movapd %xmm3, %xmm0
movapd %xmm2, 0x50(%rsp)
cmpl %r12d, %ebp
jg 0x57347
movapd %xmm0, %xmm2
movapd %xmm1, %xmm0
movsd 0x3bd5a(%rip), %xmm3    # 0x93010
addsd %xmm3, %xmm0
cvttsd2si %xmm0, %r15d
movapd %xmm2, %xmm0
addsd %xmm3, %xmm0
cvttsd2si %xmm0, %r13d
movl %r13d, %eax
subl %r15d, %eax
incl %eax
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
movapd %xmm2, 0x60(%rsp)
movapd %xmm1, 0x70(%rsp)
subpd %xmm1, %xmm2
unpckhpd %xmm2, %xmm2            # xmm2 = xmm2[1,1]
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm2
movapd %xmm2, 0x10(%rsp)
cmpl %r13d, %r15d
jg 0x57329
movq %r14, %rdi
movl %r15d, %esi
movl %ebp, %edx
movl %ebx, %ecx
movapd %xmm0, 0x20(%rsp)
callq 0x569e8
movapd 0x20(%rsp), %xmm0
addsd 0x10(%rsp), %xmm0
incl %r15d
jmp 0x572fe
movapd 0x70(%rsp), %xmm1
addpd (%rsp), %xmm1
movapd 0x60(%rsp), %xmm0
addpd 0x50(%rsp), %xmm0
incl %ebp
jmp 0x5729d
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop