// File: /workspace/github_cpp_makefile_star2_O2/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 0xc224a(%rip), %xmm0    # 0xfc040
ja 0x3a022
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 0x39bd3
testb %al, %al
je 0x3a022
movslq 0x28(%r15), %rax
shlq $0x5, %rax
addq (%r14), %rax
movq %rax, 0x30(%r15)
leaq 0x38(%rsp), %rbp
movq %rbp, %rdi
callq 0x3cc56
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 0x38c00
cmpb $0x0, (%rbp)
jne 0x39f9d
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 0x64959
movslq (%r13), %rcx
movq (%r14), %rax
shlq $0x5, %rcx
subsd 0x18(%rax,%rcx), %xmm0
andpd 0xc21c6(%rip), %xmm0    # 0xfc0a0
movsd 0xc7306(%rip), %xmm1    # 0x1011e8
ucomisd %xmm0, %xmm1
jbe 0x39f92
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 0x63e4e
movq 0x28(%rbx), %rax
movq %rax, 0x10(%rsp)
movupd 0x18(%rbx), %xmm0
movupd %xmm0, (%rsp)
leaq 0x98(%rsp), %rdi
callq 0x63e92
xorpd %xmm1, %xmm1
xorl %eax, %eax
ucomisd %xmm1, %xmm0
seta %al
movsd 0x18(%rbp), %xmm0
leaq 0xc72c2(%rip), %rcx     # 0x101220
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 0x38c00
cmpb $0x0, 0x38(%rsp)
je 0x3a034
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 0x3f9c2
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 0x39dd8
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x115fb5(%rip), %rdi    # 0x14fff0
leaq 0xc7286(%rip), %rsi     # 0x1012c8
callq 0x4480
movq %rax, %rdi
callq 0x4230
movq 0x115f6a(%rip), %r15    # 0x14ffc0
leaq 0xc7314(%rip), %rsi     # 0x101371
movq %r15, %rdi
callq 0x4480
movslq (%r13), %rsi
shlq $0x5, %rsi
addq (%r14), %rsi
movq %rax, %rdi
callq 0x63f0d
leaq 0xc63de(%rip), %rsi     # 0x10045d
movq %rax, %rdi
callq 0x4480
movslq (%r13), %rcx
movq (%r14), %rdx
shlq $0x5, %rcx
movsd 0x18(%rdx,%rcx), %xmm0
movq %rax, %rdi
callq 0x47f0
leaq 0xc72d8(%rip), %rsi     # 0x10137f
movq %rax, %rdi
callq 0x4480
leaq 0x18(%rbx), %rsi
leaq 0xb0(%rsp), %r14
movsd 0xc712d(%rip), %xmm0    # 0x1011f0
movq %r14, %rdi
callq 0x63d70
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 0x63e70
leaq 0xc729c(%rip), %rsi     # 0x10138f
movq %r15, %rdi
callq 0x4480
movq %rax, %rdi
movq %rbx, %rsi
callq 0x63f0d
leaq 0xc728e(%rip), %rsi     # 0x10139b
movq %rax, %rdi
callq 0x4480
movq %rax, %rdi
movq %r14, %rsi
callq 0x63f0d
leaq 0xd50d6(%rip), %rsi     # 0x10f1fd
movq %rax, %rdi
callq 0x4480
callq 0x4290