// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Utils/R3SurfelViewer.cpp
// Function: gaps::R3SurfelViewer::MouseButton(int, int, int, int, int, int, int, int)
int R3SurfelViewer::
MouseButton(int x, int y, int button, int state, int shift, int ctrl, int alt, int update_center_point)
{
  // Initialize
  int redraw = 0;

  // Process mouse button event
  if (state == 1) {
    // Button is going down
    mouse_drag_distance_squared = 0;

    // Remember mouse down position 
    mouse_down_position[0] = x;
    mouse_down_position[1] = y;

    // Process thumbwheel
    if ((button == 3) || (button == 4)) {
      R3Point viewing_center_point = center_point;
      const R3Camera& camera = viewer.Camera();
      R3Plane camera_plane(camera.Origin(), camera.Towards());
      RNScalar signed_distance = R3SignedDistance(camera_plane, viewing_center_point);
      if (signed_distance < 0) viewing_center_point -= (signed_distance - 1) * camera.Towards();
      if (button == 3) viewer.ScaleWorld(viewing_center_point, 1.1);
      else if (button == 4) viewer.ScaleWorld(viewing_center_point, 0.9);
      redraw = TRUE;
    }
  }
  else {
    // Check for drag
    RNBoolean drag = (mouse_drag_distance_squared > 10 * 10);

    // Check for double click
    static RNBoolean double_click = FALSE;
    static RNTime last_mouse_down_time;
    double_click = !drag && !double_click && (last_mouse_down_time.Elapsed() < 0.4);
    last_mouse_down_time.Read();

    // Select stuff on left click 
    if (!drag && update_center_point) {
      // Select image
      R3Point pick_position;
      R3SurfelImage *picked_image = PickImage(x, y, &pick_position);
      if (picked_image) {
        if (button == 0) SelectImage(picked_image, FALSE, FALSE);
        SetCenterPoint(pick_position);
        redraw = TRUE;
      }
      else {
        // Select point
        int picked_surfel_index = -1;
        R3SurfelBlock *picked_block = NULL;
        if (PickNode(x, y, &pick_position, &picked_block, &picked_surfel_index)) {
          // Hit
          if ((button == 0) && (picked_surfel_index >= 0)) {
            SelectPoint(picked_block, picked_surfel_index);
            if (selected_point && !image_plane_visibility) {
              R3SurfelImage *image = scene->FindImageByBestView(selected_point->Position(), selected_point->Normal());
              SelectImage(image, FALSE, FALSE);
            }
          }
          SetCenterPoint(pick_position);
          redraw = TRUE;
        }
        else {
          // Miss
          SelectPoint(NULL, -1);
          redraw = TRUE;
        }
      }
    }

    // Redraw if was subsampling
    if (subsampling_multiplier_when_mouse_down > 1) redraw = TRUE;
  }

  // Remember mouse position 
  mouse_position[0] = x;
  mouse_position[1] = y;

  // Remember button state 
  mouse_button[button] = state;
  
  // Remember modifiers 
  shift_down = shift;
  ctrl_down = ctrl;
  alt_down = alt;

  // Return whether need redraw
  return redraw;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl %r9d, %r13d
movl %r8d, %ebp
movl %ecx, %r12d
movq %rdi, %r14
cmpl $0x1, %r8d
jne 0x30628
movl $0x0, 0x4b8(%r14)
movl %esi, 0x4b0(%r14)
movl %edx, 0x4b4(%r14)
leal -0x3(%r12), %ecx
xorl %eax, %eax
cmpl $0x1, %ecx
ja 0x30816
movl %ebp, 0x14(%rsp)
movl %esi, 0x18(%rsp)
movl %edx, 0x1c(%rsp)
movq %r12, 0x20(%rsp)
movl %r13d, 0x28(%rsp)
leaq 0x2b0(%r14), %rsi
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
callq 0xc3d42
leaq 0x78(%r14), %rax
movq %rax, 0x38(%rsp)
leaq 0x80(%r14), %r12
leaq 0xc8(%r14), %rbx
leaq 0x90(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0xc5400
leaq 0x58(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
movq %r13, %rdx
callq 0xc28b2
movq %r15, %rdi
movq %rbp, %rsi
callq 0x8bd3b
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x305e4
addsd 0x107a90(%rip), %xmm0   # 0x138038
movsd %xmm0, 0x30(%rsp)
leaq 0x78(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0xc5400
leaq 0x90(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movsd 0x30(%rsp), %xmm0
callq 0xc5162
leaq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0xc469a
xorl %eax, %eax
movq 0x20(%rsp), %r12
cmpl $0x3, %r12d
sete %al
leaq 0x107ea7(%rip), %rcx    # 0x1384a0
movsd (%rcx,%rax,8), %xmm0
leaq 0x40(%rsp), %rsi
movq 0x38(%rsp), %rdi
callq 0x78788
movl $0x1, %eax
movl 0x28(%rsp), %r13d
movl 0x1c(%rsp), %edx
movl 0x18(%rsp), %esi
movl 0x14(%rsp), %ebp
jmp 0x30816
movl %esi, 0x18(%rsp)
movl %edx, 0x1c(%rsp)
movq %r12, 0x20(%rsp)
movl 0x4b8(%r14), %ebx
movb 0x1913a6(%rip), %al     # 0x1c19e8
testb %al, %al
je 0x3087c
movl 0xf0(%rsp), %r12d
xorl %r15d, %r15d
movl $0x0, %eax
cmpl $0x64, %ebx
jg 0x30685
cmpl $0x0, 0x19136a(%rip)    # 0x1c19d0
jne 0x30685
leaq 0x191369(%rip), %rdi    # 0x1c19d8
callq 0xe514a
movsd 0x1079a4(%rip), %xmm1   # 0x138020
xorl %eax, %eax
ucomisd %xmm0, %xmm1
seta %al
cmpl $0x65, %ebx
setge %bl
movl %eax, 0x19133f(%rip)    # 0x1c19d0
leaq 0x191340(%rip), %rdi    # 0x1c19d8
xorl %esi, %esi
callq 0x28020
testl %r12d, %r12d
sete %al
orb %bl, %al
movq 0x20(%rsp), %r12
jne 0x307fd
movl %ebp, 0x14(%rsp)
leaq 0x58(%rsp), %rbx
movq %rbx, %rdi
callq 0xc3d30
movq (%r14), %rax
movq %r14, %rdi
movl 0x18(%rsp), %ebp
movl %ebp, %esi
movl 0x1c(%rsp), %r15d
movl %r15d, %edx
movq %rbx, %rcx
callq *0x1e8(%rax)
testq %rax, %rax
je 0x30718
testl %r12d, %r12d
jne 0x306fe
movq (%r14), %r8
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *0x1c0(%r8)
movq (%r14), %rax
leaq 0x58(%rsp), %rsi
movq %r14, %rdi
callq *0x80(%rax)
movl 0x14(%rsp), %ebp
jmp 0x307f7
leaq 0x2c(%rsp), %r9
movl $0xffffffff, (%r9)      # imm = 0xFFFFFFFF
leaq 0x78(%rsp), %r8
movq $0x0, (%r8)
movq (%r14), %rax
movl $0x0, (%rsp)
leaq 0x58(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
movl %r15d, %edx
callq *0x1f8(%rax)
testq %rax, %rax
je 0x30864
testl %r12d, %r12d
sete %al
movl 0x2c(%rsp), %edx
testl %edx, %edx
setns %cl
andb %al, %cl
cmpb $0x1, %cl
movl 0x14(%rsp), %ebp
jne 0x307e6
movq 0x78(%rsp), %rsi
movq (%r14), %rax
movq %r14, %rdi
callq *0x1b8(%rax)
movq 0x2c8(%r14), %rsi
testq %rsi, %rsi
je 0x307e6
cmpl $0x0, 0x328(%r14)
jne 0x307e6
movq 0x8(%r14), %rbx
leaq 0x40(%rsp), %r15
movq %r15, %rdi
callq 0x344fc
movq 0x2c8(%r14), %rsi
leaq 0x90(%rsp), %r12
movq %r12, %rdi
callq 0x3452e
movq %rbx, %rdi
movq %r15, %rsi
movq %r12, %rdx
movq 0x20(%rsp), %r12
callq 0x48c8a
movq (%r14), %r8
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq *0x1c0(%r8)
movq (%r14), %rax
leaq 0x58(%rsp), %rsi
movq %r14, %rdi
callq *0x80(%rax)
movl $0x1, %r15d
cmpl $0x2, 0x490(%r14)
movl $0x1, %eax
cmovll %r15d, %eax
movl 0x1c(%rsp), %edx
movl 0x18(%rsp), %esi
movl 0xe8(%rsp), %ecx
movl 0xe0(%rsp), %edi
movl %esi, 0x4a8(%r14)
movl %edx, 0x4ac(%r14)
movslq %r12d, %rsi
movl %ebp, 0x49c(%r14,%rsi,4)
movl %r13d, 0x4bc(%r14)
movl %edi, 0x4c0(%r14)
movl %ecx, 0x4c4(%r14)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r14), %rax
movq %r14, %rdi
xorl %esi, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq *0x1b8(%rax)
jmp 0x3070f
leaq 0x191165(%rip), %rdi    # 0x1c19e8
callq 0x28190
testl %eax, %eax
je 0x3064a
leaq 0x191141(%rip), %rdi    # 0x1c19d8
callq 0xe50e8
leaq 0x191145(%rip), %rdi    # 0x1c19e8
callq 0x275f0
jmp 0x3064a
movq %rax, %rbx
leaq 0x191131(%rip), %rdi    # 0x1c19e8
callq 0x275d0
movq %rbx, %rdi
callq 0x28120