// File: tomfunkhouser[P]gaps/apps/gapsview/gapsview.cpp
// Function: DrawDotOnImageBillboard(ImageData*, gaps::R3Point const&, gaps::R3Vector const&, gaps::R3Vector const&, gaps::R3Vector const&, double, double, double, gaps::R2Point const&, double)
static void
DrawDotOnImageBillboard(ImageData *data, const R3Point& viewpoint,
  const R3Vector& towards, const R3Vector& right, const R3Vector& up,
  RNAngle xfov, RNAngle yfov, RNLength image_billboard_depth,
  const R2Point& image_position, RNLength radius)
{
  // Check if drawing image billboards
  if (!show_image_billboards) return;

  // Get convenient variables
  int w = data->image_width;
  int h = data->image_height;
  if ((w == 0) || (h == 0)) return;
  
  // Check 2D image_position
  if (image_position.X() < 0) return;
  if (image_position.Y() < 0) return;
  if (image_position.X() >= w) return;
  if (image_position.Y() >= h) return;

  // Compute 3D position
  RNScalar dx = 2.0 * (image_position.X() - 0.5 * w) / w;
  RNScalar dy = 2.0 * (image_position.Y() - 0.5 * h) / h;
  R3Point world_position = viewpoint + image_billboard_depth * towards;
  world_position += image_billboard_depth * dx * right * tan(xfov);
  world_position += image_billboard_depth * dy * up * tan(yfov);

  // Draw sphere
  RNLoadRgb(1, 0, 0);
  R3Sphere(world_position, radius).Draw();
}

// Assembly:
subq $0x178, %rsp            # imm = 0x178
movq %rdi, 0x170(%rsp)
movq %rsi, 0x168(%rsp)
movq %rdx, 0x160(%rsp)
movq %rcx, 0x158(%rsp)
movq %r8, 0x150(%rsp)
movsd %xmm0, 0x148(%rsp)
movsd %xmm1, 0x140(%rsp)
movsd %xmm2, 0x138(%rsp)
movq %r9, 0x130(%rsp)
movsd %xmm3, 0x128(%rsp)
cmpl $0x0, 0x2c9b6e(%rip)    # 0x2feef0
jne 0x35389
jmp 0x3562c
movq 0x170(%rsp), %rax
movl 0x768(%rax), %eax
movl %eax, 0x124(%rsp)
movq 0x170(%rsp), %rax
movl 0x76c(%rax), %eax
movl %eax, 0x120(%rsp)
cmpl $0x0, 0x124(%rsp)
je 0x353c7
cmpl $0x0, 0x120(%rsp)
jne 0x353cc
jmp 0x3562c
movq 0x130(%rsp), %rdi
callq 0x39990
movaps %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x353ea
jmp 0x3562c
movq 0x130(%rsp), %rdi
callq 0x399a0
movaps %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x35408
jmp 0x3562c
movq 0x130(%rsp), %rdi
callq 0x39990
cvtsi2sdl 0x124(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jb 0x35429
jmp 0x3562c
movq 0x130(%rsp), %rdi
callq 0x399a0
cvtsi2sdl 0x120(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jb 0x3544a
jmp 0x3562c
movq 0x130(%rsp), %rdi
callq 0x39990
movaps %xmm0, %xmm2
cvtsi2sdl 0x124(%rsp), %xmm1
movsd 0x230c6d(%rip), %xmm3   # 0x2660d8
movsd %xmm3, (%rsp)
movaps %xmm1, %xmm0
mulsd %xmm3, %xmm0
addsd %xmm2, %xmm0
addsd %xmm0, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x118(%rsp)
movq 0x130(%rsp), %rdi
callq 0x399a0
movsd (%rsp), %xmm3
movaps %xmm0, %xmm2
cvtsi2sdl 0x120(%rsp), %xmm1
movaps %xmm1, %xmm0
mulsd %xmm3, %xmm0
addsd %xmm2, %xmm0
addsd %xmm0, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x110(%rsp)
movq 0x168(%rsp), %rax
movq %rax, 0x8(%rsp)
movsd 0x138(%rsp), %xmm0
movq 0x160(%rsp), %rsi
leaq 0xe0(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x38f20
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
leaq 0xf8(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x180350
movsd 0x138(%rsp), %xmm0
movsd 0x118(%rsp), %xmm1
mulsd %xmm1, %xmm0
movq 0x158(%rsp), %rsi
leaq 0xb0(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x38f20
movsd 0x148(%rsp), %xmm0
callq 0x299c0
movq 0x18(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x181dc0
movq 0x20(%rsp), %rsi
movq 0x38(%rsp), %rdi
callq 0x1804d0
movsd 0x138(%rsp), %xmm0
movsd 0x110(%rsp), %xmm1
mulsd %xmm1, %xmm0
movq 0x150(%rsp), %rsi
leaq 0x80(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x38f20
movsd 0x140(%rsp), %xmm0
callq 0x299c0
movq 0x28(%rsp), %rsi
leaq 0x98(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x181dc0
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdi
callq 0x1804d0
movl $0x1, %edi
xorl %edx, %edx
movl %edx, %esi
callq 0x39820
movq 0x38(%rsp), %rsi
movsd 0x128(%rsp), %xmm0
leaq 0x58(%rsp), %rdi
callq 0x14d530
leaq 0x50(%rsp), %rdi
movl $0x772, %esi            # imm = 0x772
callq 0x38e50
jmp 0x35611
movq 0x50(%rsp), %rsi
leaq 0x58(%rsp), %rdi
callq 0xf8e00
jmp 0x35622
leaq 0x58(%rsp), %rdi
callq 0x398c0
addq $0x178, %rsp            # imm = 0x178
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
leaq 0x58(%rsp), %rdi
callq 0x398c0
movq 0x48(%rsp), %rdi
callq 0x29c10
nopw %cs:(%rax,%rax)