// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movsd 0x20(%rdx), %xmm0
ucomisd 0x1009e8(%rip), %xmm0   # 0x14d040
ja 0x4c884
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r12
leaq 0x100(%rsp), %rbx
leaq 0x28(%rdx), %r13
movq 0x10(%rbx), %rax
movq %rax, 0x10(%rsp)
movupd (%rbx), %xmm0
movupd %xmm0, (%rsp)
movq %rsi, %rdi
movq %r13, %rsi
callq 0x4c432
testb %al, %al
je 0x4c884
movslq 0x28(%r15), %rax
shlq $0x5, %rax
addq (%r14), %rax
movq %rax, 0x30(%r15)
leaq 0x38(%rsp), %rbp
movq %rbp, %rdi
callq 0x501a8
movslq 0x28(%r15), %rdi
shlq $0x5, %rdi
addq (%r14), %rdi
movupd (%rbx), %xmm0
movupd 0x10(%rbx), %xmm1
movups 0x20(%rbx), %xmm2
movups %xmm2, 0x20(%rsp)
movupd %xmm1, 0x10(%rsp)
movupd %xmm0, (%rsp)
movq %rbp, %rsi
callq 0x4af28
cmpb $0x0, (%rbp)
jne 0x4c7ff
movslq (%r13), %rax
movq (%r14), %rcx
shlq $0x5, %rax
movq 0x10(%rcx,%rax), %rdx
movq %rdx, 0x28(%rsp)
movups (%rcx,%rax), %xmm0
movups %xmm0, 0x18(%rsp)
movq 0x10(%rbx), %rax
movq %rax, 0x10(%rsp)
movupd (%rbx), %xmm0
movupd %xmm0, (%rsp)
callq 0x84ce3
movslq (%r13), %rcx
movq (%r14), %rax
shlq $0x5, %rcx
subsd 0x18(%rax,%rcx), %xmm0
andpd 0x100964(%rip), %xmm0   # 0x14d0a0
movsd 0x105b34(%rip), %xmm1   # 0x152278
ucomisd %xmm0, %xmm1
jbe 0x4c7f4
addq %rcx, %rax
movups (%rax), %xmm0
movupd 0x10(%rax), %xmm1
leaq 0x70(%rsp), %rbp
movapd %xmm1, 0x10(%rbp)
movaps %xmm0, (%rbp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movups (%rax), %xmm0
movups %xmm0, (%rsp)
leaq 0x98(%rsp), %rdi
movq %rbx, %rsi
callq 0x84174
movq 0x28(%rbx), %rax
movq %rax, 0x10(%rsp)
movupd 0x18(%rbx), %xmm0
movupd %xmm0, (%rsp)
leaq 0x98(%rsp), %rdi
callq 0x841b8
xorpd %xmm1, %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
seta %al
movsd 0x18(%rbp), %xmm0
leaq 0x105af0(%rip), %rcx    # 0x1522b0
addsd (%rcx,%rax,8), %xmm0
movsd %xmm0, 0x18(%rbp)
movupd (%rbx), %xmm0
movupd 0x10(%rbx), %xmm1
movups 0x20(%rbx), %xmm2
movups %xmm2, 0x20(%rsp)
movupd %xmm1, 0x10(%rsp)
movupd %xmm0, (%rsp)
leaq 0x38(%rsp), %rsi
movq %rbp, %rdi
callq 0x4af28
cmpb $0x0, 0x38(%rsp)
je 0x4c896
movb $0x1, (%r15)
movsd 0x58(%rsp), %xmm0
addsd 0x20(%r15), %xmm0
movsd %xmm0, 0x20(%r15)
movq 0x50(%rsp), %rax
movq %rax, 0x10(%rsp)
movups 0x40(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0x70(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x53b0e
movq 0x10(%r13), %rax
movq %rax, 0x10(%rbx)
movups (%r13), %xmm0
movups %xmm0, (%rbx)
movq 0x50(%rsp), %rax
movq %rax, 0x18(%r15)
movups 0x40(%rsp), %xmm0
movups %xmm0, 0x8(%r15)
movupd (%rbx), %xmm0
movups 0x10(%rbx), %xmm1
movups 0x20(%rbx), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movupd %xmm0, (%rsp)
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x4c63a
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x148753(%rip), %rdi    # 0x194ff0
leaq 0x105ab4(%rip), %rsi    # 0x152358
callq 0x4440
movq %rax, %rdi
callq 0x41f0
movq 0x148708(%rip), %r15    # 0x194fc0
leaq 0x105b42(%rip), %rsi    # 0x152401
movq %r15, %rdi
callq 0x4440
movslq (%r13), %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
movq %rax, %rdi
callq 0x84242
leaq 0x104bec(%rip), %rsi    # 0x1514cd
movq %rax, %rdi
callq 0x4440
movslq (%r13), %rcx
movq (%r14), %rdx
shlq $0x5, %rcx
movsd 0x18(%rdx,%rcx), %xmm0
movq %rax, %rdi
callq 0x4810
leaq 0x105b06(%rip), %rsi    # 0x15240f
movq %rax, %rdi
callq 0x4440
leaq 0x18(%rbx), %rsi
leaq 0xb0(%rsp), %r14
movsd 0x10595b(%rip), %xmm0   # 0x152280
movq %r14, %rdi
callq 0x84096
movq 0x10(%r14), %rax
movq %rax, 0x10(%rsp)
movups (%r14), %xmm0
movups %xmm0, (%rsp)
leaq 0x70(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x84196
leaq 0x105aca(%rip), %rsi    # 0x15241f
movq %r15, %rdi
callq 0x4440
movq %rax, %rdi
movq %rbx, %rsi
callq 0x84242
leaq 0x105abc(%rip), %rsi    # 0x15242b
movq %rax, %rdi
callq 0x4440
movq %rax, %rdi
movq %r14, %rsi
callq 0x84242
leaq 0x1119b4(%rip), %rsi    # 0x15e33d
movq %rax, %rdi
callq 0x4440
callq 0x4260