// File: Luthaf[P]zeopp/ray.cc
// Function: rayTraceInsideSphere(ATOM_NETWORK*, std::vector<Sphere, std::allocator<Sphere>>&, ray, hitdata&)
void rayTraceInsideSphere(ATOM_NETWORK *cell,vector<Sphere>& spheres,ray r, hitdata& hitobject)
{
  
#if DEBUG
  cout << "Current Ray Length: " << hitobject.dist << endl;
#endif
  
  if (hitobject.dist > MAXRAYDIST){
    return;
  }
  
  if (findSphereOfPoint(r.base,spheres,hitobject.id) == false) //This function also updates the id of the new sphere in hitsphere
    {
      return; //No sphere found that included point.
    }
  hitobject.object = &(spheres[hitobject.id]); //set the object*

  //If inside sphere this it should hit the sphere
  hitdata hitsphere; 
  spheres[hitobject.id].hitSphere(r,hitsphere);
  
  if (hitsphere.hit == false){
    //It is possible that point is an epsilon outside lets check
    if (fabs(calcEuclideanDistance(r.base,spheres[hitobject.id].center) - spheres[hitobject.id].radius) < threshold)
      {
	//It was round-off error so lets continue
	Sphere epsilon_sphere = spheres[hitobject.id];
	if (((r.base - spheres[hitobject.id].center) * r.vector) > 0)
	  { //vector is headed away from sphere
	    epsilon_sphere.radius += threshold;
	  }
	else
	  { // vector is headed into the sphere	    
	    epsilon_sphere.radius += -threshold;
	  }
	epsilon_sphere.hitSphere(r,hitsphere);
      }
    if (hitsphere.hit == false) //Epsilon Case has been covered so thid should not happen
      {
      	cerr << "Error: Ray did not hit a sphere. findSphereOfPoint said that one was within the radius. And it failed to be within an epsilon. Output in vmd style for easy visulization" << endl;
	cout << "draw sphere {" << spheres[hitobject.id].center << "} radius " << spheres[hitobject.id].radius << " resolution 10\n";
	Point p = r.base+r.vector.scale(10);
	cout << "draw line {" << r.base << "} {" << p << "}\n";
	abort();
      }
  }
  
  hitobject.hit = hitsphere.hit;
  hitobject.dist += hitsphere.dist; //Updates the distance traveled in spheres
  r.base = cell->shiftXYZInUC(hitsphere.hitpoint); //Move back to unit cell and set values
  hitobject.hitpoint = hitsphere.hitpoint;
  
  rayTraceInsideSphere(cell,spheres,r,hitobject);
  return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
leaq 0x10(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
movsd 0x20(%rax), %xmm0
movsd 0x16461d(%rip), %xmm1   # 0x1f2040
ucomisd %xmm1, %xmm0
jbe 0x8da2e
jmp 0x8dfea
movq -0x1f8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x30(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x28(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x28, %rsi
leaq -0x30(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x8d690
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8da89
jmp 0x8dfea
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
leaq -0x68(%rbp), %rdi
callq 0x91b70
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq -0x1f8(%rbp), %rsi
movq %rax, -0x200(%rbp)
leaq -0x98(%rbp), %rdi
movl $0x30, %edx
callq 0x5430
movq -0x200(%rbp), %rdi
movups -0x98(%rbp), %xmm0
movups -0x88(%rbp), %xmm1
movups -0x78(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x68(%rbp), %rsi
callq 0x8bdf0
movb -0x68(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8ded6
movq -0x1f8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0xb0(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xa8(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq (%rax), %rcx
movq %rcx, -0xc8(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xc0(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0xb8(%rbp)
leaq -0xb0(%rbp), %rcx
leaq -0xc8(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rcx
movq %rcx, 0x10(%rsp)
movq (%rax), %rcx
movq %rcx, 0x18(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
callq 0xebb80
movsd %xmm0, -0x208(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movsd -0x208(%rbp), %xmm1
subsd 0x18(%rax), %xmm1
movaps 0x164496(%rip), %xmm0   # 0x1f2080
pand %xmm0, %xmm1
movsd 0x1697a2(%rip), %xmm0   # 0x1f7398
ucomisd %xmm1, %xmm0
jbe 0x8dd7a
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq (%rax), %rcx
movq %rcx, -0xe8(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0xe0(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0xd8(%rbp)
movq 0x18(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq -0x1f8(%rbp), %rsi
movq (%rax), %rcx
movq %rcx, -0x118(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x110(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x108(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x118(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0xea360
movq -0x1f8(%rbp), %rax
movq 0x18(%rax), %rcx
movq %rcx, -0x130(%rbp)
movq 0x20(%rax), %rcx
movq %rcx, -0x128(%rbp)
movq 0x28(%rax), %rax
movq %rax, -0x120(%rbp)
leaq -0x100(%rbp), %rdi
leaq -0x130(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0xea4e0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x8dd17
movsd 0x169693(%rip), %xmm0   # 0x1f7398
addsd -0xd0(%rbp), %xmm0
movsd %xmm0, -0xd0(%rbp)
jmp 0x8dd2f
movsd 0x169681(%rip), %xmm0   # 0x1f73a0
addsd -0xd0(%rbp), %xmm0
movsd %xmm0, -0xd0(%rbp)
movq -0x1f8(%rbp), %rsi
leaq -0x160(%rbp), %rdi
movl $0x30, %edx
callq 0x5430
movups -0x160(%rbp), %xmm0
movups -0x150(%rbp), %xmm1
movups -0x140(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0xe8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x8bdf0
movb -0x68(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8ded4
movq 0x1e525e(%rip), %rdi    # 0x272ff0
leaq 0x1696cf(%rip), %rsi    # 0x1f7468
callq 0x5540
movq %rax, %rdi
movq 0x1e51f0(%rip), %rsi    # 0x272f98
callq 0x55b0
movq 0x1e520c(%rip), %rdi    # 0x272fc0
leaq 0x169756(%rip), %rsi    # 0x1f7511
callq 0x5540
movq %rax, -0x218(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq -0x218(%rbp), %rdi
movq %rax, %rsi
callq 0xea610
movq %rax, %rdi
leaq 0x1686f4(%rip), %rsi    # 0x1f64e5
callq 0x5540
movq %rax, -0x210(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movslq 0x28(%rax), %rsi
callq 0x91c10
movq -0x210(%rbp), %rdi
movsd 0x18(%rax), %xmm0
callq 0x5980
movq %rax, %rdi
leaq 0x1696f6(%rip), %rsi    # 0x1f751f
callq 0x5540
movq -0x1f8(%rbp), %rsi
addq $0x18, %rsi
leaq -0x190(%rbp), %rdi
movsd 0x1687d8(%rip), %xmm0   # 0x1f6620
callq 0xea000
movq -0x1f8(%rbp), %rsi
leaq -0x178(%rbp), %rdi
leaq -0x190(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0xea420
movq 0x1e5139(%rip), %rdi    # 0x272fc0
leaq 0x1696a1(%rip), %rsi    # 0x1f752f
callq 0x5540
movq -0x1f8(%rbp), %rsi
movq %rax, %rdi
callq 0xea610
movq %rax, %rdi
leaq 0x16968f(%rip), %rsi    # 0x1f753b
callq 0x5540
movq %rax, %rdi
leaq -0x178(%rbp), %rsi
callq 0xea610
movq %rax, %rdi
leaq 0x17c4cf(%rip), %rsi    # 0x20a399
callq 0x5540
callq 0x52b0
jmp 0x8ded6
movb -0x68(%rbp), %cl
movq -0x18(%rbp), %rax
andb $0x1, %cl
movb %cl, (%rax)
movsd -0x48(%rbp), %xmm0
movq -0x18(%rbp), %rax
addsd 0x20(%rax), %xmm0
movsd %xmm0, 0x20(%rax)
movq -0x8(%rbp), %rsi
movq -0x60(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x1b0(%rbp)
leaq -0x1a8(%rbp), %rdi
leaq -0x1c0(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0x97f20
movq -0x1f8(%rbp), %rsi
movq -0x1a8(%rbp), %rax
movq %rax, (%rsi)
movq -0x1a0(%rbp), %rax
movq %rax, 0x8(%rsi)
movq -0x198(%rbp), %rax
movq %rax, 0x10(%rsi)
movq -0x18(%rbp), %rax
movq -0x60(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x58(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0x50(%rbp), %rcx
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rax
movq %rax, -0x228(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq -0x1f0(%rbp), %rdi
movl $0x30, %edx
callq 0x5430
movq -0x228(%rbp), %rdi
movq -0x220(%rbp), %rsi
movq -0x18(%rbp), %rdx
movups -0x1f0(%rbp), %xmm0
movups -0x1e0(%rbp), %xmm1
movups -0x1d0(%rbp), %xmm2
movq %rsp, %rax
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0x8d9f0
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
nopw %cs:(%rax,%rax)