// File: tomfunkhouser[P]gaps/pkgs/R3Surfels/R3SurfelNode.cpp
// Function: gaps::R3SurfelNode::DrawResidentAncestor(gaps::RNFlags) const
int R3SurfelNode::
DrawResidentAncestor(RNFlags draw_flags) const
{
#if 1
  // Draw K*K*K points in bounding box
  int K = 3;
  RNGrfxBegin(RN_GRFX_POINTS);
  for (int i = 0; i < K; i++) {
    double x = bbox.XMin() + bbox.XLength() * (i+0.5)/K;
    for (int j = 0; j < K; j++) {
      double y = bbox.YMin() + bbox.YLength() * (j+0.5)/K;
      for (int k = 0; k < K; k++) {
        double z = bbox.ZMin() + bbox.ZLength() * (k+0.5)/K;
        R3LoadPoint(x, y, z);
      }
    }
  }
  RNGrfxEnd();
#else
  // Find closest ancestor that is resident 
  const R3SurfelNode *ancestor = this;
  while (ancestor) {
    if (ancestor->AreBlocksResident()) break;
    ancestor = ancestor->Parent();
  }
      
  // Check ancestor
  if (!ancestor) return 0;

  // Set clip planes
  if (ancestor != this) {
    // Set up clip plane normals
    static GLdouble lowx_plane[4] =  {  1,  0,  0,  0 };
    static GLdouble lowy_plane[4] =  {  0,  1,  0,  0 };
    static GLdouble lowz_plane[4] =  {  0,  0,  1,  0 };
    static GLdouble highx_plane[4] = { -1,  0,  0,  0 };
    static GLdouble highy_plane[4] = {  0, -1,  0,  0 };
    static GLdouble highz_plane[4] = {  0,  0, -1,  0 };
        
    // Set up clip plane coordinates based on node bounding box
    const R3Box &b = BBox();
    lowx_plane[3] = -b.XMin();
    lowy_plane[3] = -b.YMin();
    lowz_plane[3] = -b.ZMin();
    highx_plane[3] = b.XMax();
    highy_plane[3] = b.YMax();
    highz_plane[3] = b.ZMax();
        
    // Send clip planes to OpenGL
    glClipPlane(GL_CLIP_PLANE0, lowx_plane);
    glClipPlane(GL_CLIP_PLANE1, lowy_plane);
    glClipPlane(GL_CLIP_PLANE2, lowz_plane);
    glClipPlane(GL_CLIP_PLANE3, highx_plane);
    glClipPlane(GL_CLIP_PLANE4, highy_plane);
    glClipPlane(GL_CLIP_PLANE5, highz_plane);
        
    // Enable clip planes
    glEnable(GL_CLIP_PLANE0);
    glEnable(GL_CLIP_PLANE1);
    glEnable(GL_CLIP_PLANE2);
    glEnable(GL_CLIP_PLANE3);
    glEnable(GL_CLIP_PLANE4);
    glEnable(GL_CLIP_PLANE5);
  }
      
  // Draw ancestor node
  ancestor->Draw(draw_flags);

  // Disable clip planes
  if (ancestor != this) {
    glDisable(GL_CLIP_PLANE0);
    glDisable(GL_CLIP_PLANE1);
    glDisable(GL_CLIP_PLANE2);
    glDisable(GL_CLIP_PLANE3);
    glDisable(GL_CLIP_PLANE4);
    glDisable(GL_CLIP_PLANE5);
  }
#endif

  // Return success
  return 1;
}

// Assembly:
subq $0x68, %rsp
movq %rsi, 0x60(%rsp)
movq %rdi, 0x58(%rsp)
movq 0x58(%rsp), %rax
movq %rax, 0x20(%rsp)
movl $0x3, 0x54(%rsp)
xorl %edi, %edi
callq 0x4ff50
movl $0x0, 0x50(%rsp)
movl 0x50(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x6057f
movq 0x20(%rsp), %rdi
addq $0x60, %rdi
callq 0x446e0
movq 0x20(%rsp), %rdi
movsd %xmm0, 0x18(%rsp)
addq $0x60, %rdi
callq 0x44130
movaps %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
cvtsi2sdl 0x50(%rsp), %xmm2
movsd 0x143d12(%rip), %xmm3   # 0x1a4158
addsd %xmm3, %xmm2
mulsd %xmm2, %xmm1
cvtsi2sdl 0x54(%rsp), %xmm2
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x6056d
movq 0x20(%rsp), %rdi
addq $0x60, %rdi
callq 0x44700
movq 0x20(%rsp), %rdi
movsd %xmm0, 0x10(%rsp)
addq $0x60, %rdi
callq 0x44150
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
cvtsi2sdl 0x44(%rsp), %xmm2
movsd 0x143ca7(%rip), %xmm3   # 0x1a4158
addsd %xmm3, %xmm2
mulsd %xmm2, %xmm1
cvtsi2sdl 0x54(%rsp), %xmm2
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x54(%rsp), %eax
jge 0x6055b
movq 0x20(%rsp), %rdi
addq $0x60, %rdi
callq 0x435e0
movq 0x20(%rsp), %rdi
movsd %xmm0, 0x8(%rsp)
addq $0x60, %rdi
callq 0x44170
movaps %xmm0, %xmm1
movsd 0x8(%rsp), %xmm0
cvtsi2sdl 0x34(%rsp), %xmm2
movsd 0x143c40(%rip), %xmm3   # 0x1a4158
addsd %xmm3, %xmm2
mulsd %xmm2, %xmm1
cvtsi2sdl 0x54(%rsp), %xmm2
divsd %xmm2, %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movsd 0x28(%rsp), %xmm2
callq 0x61080
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x604d5
jmp 0x6055d
movl 0x44(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44(%rsp)
jmp 0x6046a
jmp 0x6056f
movl 0x50(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x50(%rsp)
jmp 0x603ff
callq 0x50070
movl $0x1, %eax
addq $0x68, %rsp
retq
nop