// File: /workspace/github_cpp_makefile_star2_O2/hamikm[P]Raytracer/src/scene.hh
// Function: scene<double, double, double, 3>::traceRay(ray<double, double, 3> const&, int) const
rgbcolor<color_T> traceRay(
			const ray<vec_T, time_T, dim> &r, int depth = 0) const {
		time_T tIntersect; // out parameter
		sp_shape intersectedObjPtr =
				findClosestShape(r, tIntersect);
		if(intersectedObjPtr == 0) {
			return DEFAULT_BKCOLOR;
		}

		mvector<vec_T, dim> intersectionPt = r.getPointAtT(tIntersect);
		mvector<vec_T, dim> N = intersectedObjPtr->surfaceNorm(intersectionPt);

		// Loop over all the point lights, summing the color contributions from
		// each one
		rgbcolor<color_T> finalColor;
		typename std::vector<sp_light>::const_iterator iter;
		for (iter = pointlights.begin(); iter < pointlights.end(); iter++) {
			sp_light currLightPtr = *iter;
			mvector<vec_T, dim> L = currLightPtr->getPos() - intersectionPt;
			L = L.norm();
			vec_T LdotN = L * N;

			// A hack to make sure an object doesn't intersect itself...
			// make the "to light" ray start a little outside an object itself
			// by adding a tiny scalar multiple of a normal line to the
			// starting point
			mvector<vec_T, dim> intersectionPtWithDelta =
					intersectionPt + N * DELTA;

			// shoot a ray to this light. if it hits anything on the way,
			// skip the light (if shadows are on)
			ray<vec_T, time_T, dim> rayToLight(
					intersectionPtWithDelta, L);
			time_T t;
			if (useShadows && findClosestShape(rayToLight, t) != 0) {
				continue;
			}

			// add in the color contribution of the light
			if(LdotN > 0) {
				finalColor += (currLightPtr->getColor() *
						intersectedObjPtr->getColor() * LdotN);
			}
		}

		// Loop over all the spotlights, summing the color contributions from
		// each one. Skip the spotlight if the angle between the ray and the
		// spotlight's direction vector is > the cone angle.
		typename std::vector<sp_spotlight>::const_iterator iter2;
		for (iter2 = spotlights.begin(); iter2 < spotlights.end(); iter2++) {
			sp_spotlight currLightPtr = *iter2;
			mvector<vec_T, dim> L = currLightPtr->getPos() - intersectionPt;
			L = L.norm();

			// skip this light if it's outside the spotlight cone
			float ray_spotlight_angle =
					acos(currLightPtr->getDir().norm() * -L);
			if (ray_spotlight_angle > currLightPtr->getAngle()) {
				continue;
			}

			vec_T LdotN = L * N;

			// A hack to make sure an object doesn't intersect itself...
			// make the "to light" ray start a little outside an object itself
			// by adding a tiny scalar multiple of a normal line to the
			// starting point
			mvector<vec_T, dim> intersectionPtWithDelta =
					intersectionPt + N * DELTA;

			// shoot a ray to this light. if it hits anything on the way,
			// skip the light (if shadows are on)
			ray<vec_T, time_T, dim> rayToLight(
					intersectionPtWithDelta, L);
			time_T t;
			if (useShadows && findClosestShape(rayToLight, t) != 0) {
				continue;
			}

			// add in the color contribution of the light
			if(LdotN > 0) {
				finalColor += (currLightPtr->getColor() *
						intersectedObjPtr->getColor() * LdotN);
			}
		}

		// handle reflections
		if (intersectedObjPtr->getReflectivity() > 0 && depth < MAX_REFLECT) {
			// R_r is the direction of the reflected vector
			ray<vec_T, time_T, dim> R_r = r.reflect(intersectionPt, N);
			// col_r is the reflection color
			rgbcolor<color_T> col_r = traceRay(R_r, depth + 1);
			finalColor +=
					((color_T) intersectedObjPtr->getReflectivity()) * col_r;
		}

		return finalColor;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movl %ecx, %r12d
movq %rdx, %r13
movq %rdi, %r14
leaq -0x98(%rbp), %rbx
leaq -0xd0(%rbp), %rcx
movq %rbx, %rdi
movq %rsi, -0x30(%rbp)
callq 0x8066
cmpq $0x0, (%rbx)
je 0x7f13
movsd -0xd0(%rbp), %xmm0
leaq -0xc8(%rbp), %rdi
movq %r13, %rsi
callq 0x8172
movq %r13, -0xa8(%rbp)
movl %r12d, -0x9c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x81d8
movq (%rax), %rcx
leaq -0x130(%rbp), %rdi
leaq -0xc8(%rbp), %rdx
movq %rax, %rsi
callq *0x28(%rcx)
xorpd %xmm0, %xmm0
andq $0x0, 0x10(%r14)
movq %r14, -0x88(%rbp)
movupd %xmm0, (%r14)
movq -0x30(%rbp), %rax
movq (%rax), %rcx
leaq -0x80(%rbp), %r12
leaq -0xc8(%rbp), %r14
movq -0x30(%rbp), %rax
cmpq 0x8(%rax), %rcx
jae 0x7c53
movq (%rcx), %rax
movq %rax, -0x48(%rbp)
movq %rcx, -0x38(%rbp)
movq 0x8(%rcx), %rax
movq %rax, -0x40(%rbp)
testq %rax, %rax
je 0x7aea
lock
incl 0x8(%rax)
leaq -0x48(%rbp), %rdi
callq 0x8204
leaq 0x20(%rax), %rsi
movq %r12, %rdi
movq %r14, %rdx
callq 0x46c8
leaq -0x100(%rbp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x4722
movq -0xf0(%rbp), %rax
movq %rax, -0x70(%rbp)
movups -0x100(%rbp), %xmm0
movaps %xmm0, -0x80(%rbp)
movq %r12, %r13
movq %r12, %rdi
leaq -0x130(%rbp), %r12
movq %r12, %rsi
callq 0x58c4
movsd %xmm0, -0x50(%rbp)
movq %r15, %rdi
movq %r12, %rsi
movsd 0x150e(%rip), %xmm0     # 0x9060
callq 0x5ea9
leaq -0x118(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x5e50
movq %r14, %r12
movq %r15, %rdi
movq %rbx, %rsi
movq %r13, %rdx
pushq $0x1
popq %rcx
callq 0x5dd8
movb $0x1, %r14b
movq -0x30(%rbp), %rax
cmpb $0x1, 0x48(%rax)
jne 0x7bba
leaq -0x68(%rbp), %rdi
movq -0x30(%rbp), %rsi
leaq -0x100(%rbp), %rdx
leaq -0xb0(%rbp), %rcx
callq 0x8066
cmpq $0x0, -0x68(%rbp)
sete %r14b
leaq -0x60(%rbp), %rdi
callq 0x5092
movsd -0x50(%rbp), %xmm0
ucomisd 0x1481(%rip), %xmm0     # 0x9048
jbe 0x7c37
testb %r14b, %r14b
je 0x7c37
leaq -0x48(%rbp), %rdi
callq 0x8204
movq %rax, %r14
leaq -0x98(%rbp), %rdi
callq 0x81d8
movsd 0x8(%r14), %xmm0
movsd 0x10(%r14), %xmm1
movsd 0x18(%r14), %xmm2
mulsd 0x8(%rax), %xmm0
mulsd 0x10(%rax), %xmm1
mulsd 0x18(%rax), %xmm2
movsd -0x50(%rbp), %xmm3
mulsd %xmm3, %xmm0
mulsd %xmm3, %xmm1
mulsd %xmm3, %xmm2
movsd %xmm0, -0x68(%rbp)
movsd %xmm1, -0x60(%rbp)
movsd %xmm2, -0x58(%rbp)
movq -0x88(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x8230
leaq -0x40(%rbp), %rdi
callq 0x5092
movq -0x38(%rbp), %rcx
addq $0x10, %rcx
movq %r12, %r14
movq %r13, %r12
jmp 0x7ac0
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
leaq -0x40(%rbp), %r13
leaq -0x80(%rbp), %r14
leaq -0x100(%rbp), %rbx
leaq -0x118(%rbp), %r12
movq -0x30(%rbp), %r15
movq -0x30(%rbp), %rax
cmpq 0x20(%rax), %rcx
jae 0x7e58
movq (%rcx), %rax
movq %rax, -0x48(%rbp)
movq %rcx, -0x50(%rbp)
movq 0x8(%rcx), %rax
movq %rax, -0x40(%rbp)
testq %rax, %rax
je 0x7c9f
lock
incl 0x8(%rax)
leaq -0x48(%rbp), %rdi
callq 0x8264
leaq 0x20(%rax), %rsi
movq %r14, %rdi
leaq -0xc8(%rbp), %rdx
callq 0x46c8
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4722
movq -0xf0(%rbp), %rax
movq %rax, -0x70(%rbp)
movupd -0x100(%rbp), %xmm0
movapd %xmm0, -0x80(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x8264
leaq 0x38(%rax), %rsi
movq %rbx, %rdi
callq 0x4722
movq %r12, %rdi
movq %r14, %rsi
callq 0x8290
movq %rbx, %rdi
movq %r12, %rsi
callq 0x58c4
callq 0x31c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x38(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x8264
movss -0x38(%rbp), %xmm0
ucomiss 0x50(%rax), %xmm0
ja 0x7e43
movq %r14, %rdi
leaq -0x130(%rbp), %r14
movq %r14, %rsi
callq 0x58c4
movsd %xmm0, -0x38(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
movsd 0x130c(%rip), %xmm0     # 0x9060
callq 0x5ea9
movq %r12, %rdi
leaq -0xc8(%rbp), %rsi
movq %rbx, %rdx
callq 0x5e50
movq %r13, %r14
movq %r12, %rsi
movq %rbx, %r12
movq %rbx, %rdi
leaq -0x80(%rbp), %rdx
pushq $0x1
popq %rcx
callq 0x5dd8
movb $0x1, %r13b
cmpb $0x1, 0x48(%r15)
jne 0x7db5
leaq -0x68(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
leaq -0xb0(%rbp), %rcx
callq 0x8066
cmpq $0x0, -0x68(%rbp)
sete %r13b
leaq -0x60(%rbp), %rdi
callq 0x5092
movsd -0x38(%rbp), %xmm0
ucomisd 0x1286(%rip), %xmm0     # 0x9048
jbe 0x7e32
testb %r13b, %r13b
je 0x7e32
leaq -0x48(%rbp), %rdi
callq 0x8264
movq %rax, %r13
leaq -0x98(%rbp), %rdi
callq 0x81d8
movsd 0x8(%r13), %xmm0
movsd 0x10(%r13), %xmm1
movsd 0x18(%r13), %xmm2
mulsd 0x8(%rax), %xmm0
mulsd 0x10(%rax), %xmm1
mulsd 0x18(%rax), %xmm2
movsd -0x38(%rbp), %xmm3
mulsd %xmm3, %xmm0
mulsd %xmm3, %xmm1
mulsd %xmm3, %xmm2
movsd %xmm0, -0x68(%rbp)
movsd %xmm1, -0x60(%rbp)
movsd %xmm2, -0x58(%rbp)
movq -0x88(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x8230
movq %r14, %r13
leaq -0x80(%rbp), %r14
movq %r12, %rbx
leaq -0x118(%rbp), %r12
movq %r13, %rdi
callq 0x5092
movq -0x50(%rbp), %rcx
addq $0x10, %rcx
jmp 0x7c75
leaq -0x98(%rbp), %rdi
callq 0x81d8
movl -0x9c(%rbp), %ebx
cmpl $0x9, %ebx
movq -0x88(%rbp), %r14
jg 0x7f21
movss 0x20(%rax), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0x7f21
leaq -0x100(%rbp), %rdi
leaq -0xc8(%rbp), %rdx
leaq -0x130(%rbp), %rcx
movsd 0x11b0(%rip), %xmm0     # 0x9058
movq -0xa8(%rbp), %rsi
callq 0x82ce
incl %ebx
leaq -0x80(%rbp), %rdi
leaq -0x100(%rbp), %rdx
movq -0x30(%rbp), %rsi
movl %ebx, %ecx
callq 0x7a10
leaq -0x98(%rbp), %rdi
callq 0x81d8
cvtss2sd 0x20(%rax), %xmm0
movsd -0x80(%rbp), %xmm1
mulsd %xmm0, %xmm1
movsd -0x78(%rbp), %xmm2
mulsd %xmm0, %xmm2
mulsd -0x70(%rbp), %xmm0
leaq -0x118(%rbp), %rsi
movsd %xmm1, (%rsi)
movsd %xmm2, 0x8(%rsi)
movsd %xmm0, 0x10(%rsi)
movq %r14, %rdi
callq 0x8230
jmp 0x7f21
xorpd %xmm0, %xmm0
movupd %xmm0, (%r14)
andq $0x0, 0x10(%r14)
leaq -0x90(%rbp), %rdi
callq 0x5092
movq %r14, %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x7f4a
jmp 0x7f4a
jmp 0x7f4a
jmp 0x7f4a
movq %rax, %rbx
jmp 0x7f84
jmp 0x7f5e
jmp 0x7f5e
jmp 0x7f5e
jmp 0x7f78
jmp 0x7f78
jmp 0x7f6a
movq %r13, %r14
movq %rax, %rbx
movq %r14, %r13
jmp 0x7f6d
jmp 0x7f6a
jmp 0x7f6a
movq %rax, %rbx
movq %r13, %rdi
jmp 0x7f7f
jmp 0x7f78
jmp 0x7f78
jmp 0x7f78
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x5092
leaq -0x90(%rbp), %rdi
callq 0x5092
movq %rbx, %rdi
callq 0x32d0