// File: 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
subq $0x3b0, %rsp            # imm = 0x3B0
movq %rdi, -0x358(%rbp)
movq %rdi, -0x350(%rbp)
movq %rsi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq -0x8(%rbp), %rsi
movq %rsi, -0x348(%rbp)
movq -0x10(%rbp), %rdx
leaq -0x30(%rbp), %rdi
leaq -0x20(%rbp), %rcx
callq 0xeb40
leaq -0x30(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xed40
testb $0x1, %al
jne 0xe183
jmp 0xe1ae
movq -0x358(%rbp), %rdi
callq 0x4a70
jmp 0xe191
movl $0x1, -0x40(%rbp)
jmp 0xe8dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0xe8f5
movq -0x10(%rbp), %rsi
movsd -0x20(%rbp), %xmm0
leaq -0x58(%rbp), %rdi
callq 0xed70
jmp 0xe1c2
leaq -0x30(%rbp), %rdi
callq 0xee00
movq %rax, %rsi
movq (%rsi), %rax
movq 0x28(%rax), %rax
leaq -0x70(%rbp), %rdi
leaq -0x58(%rbp), %rdx
callq *%rax
jmp 0xe1e1
movq -0x358(%rbp), %rdi
callq 0x4a70
jmp 0xe1ef
leaq -0x78(%rbp), %rdi
callq 0xa990
movq -0x348(%rbp), %rdi
callq 0xa9b0
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x348(%rbp), %rdi
callq 0xaa20
movq %rax, -0x88(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xa9e0
testb $0x1, %al
jne 0xe23c
jmp 0xe4a1
leaq -0x78(%rbp), %rdi
callq 0xaa80
movq %rax, %rsi
leaq -0x98(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x6090
movq -0x360(%rbp), %rdi
callq 0xee50
movq %rax, %rdi
callq 0x9f20
movq %rax, %rsi
leaq -0xb0(%rbp), %rdi
leaq -0x58(%rbp), %rdx
callq 0x53a0
jmp 0xe284
leaq -0xc8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x5420
jmp 0xe299
movq -0xb8(%rbp), %rax
movq %rax, -0xa0(%rbp)
movups -0xc8(%rbp), %xmm0
movaps %xmm0, -0xb0(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movq %rsi, -0x368(%rbp)
callq 0x7ea0
movq -0x368(%rbp), %rsi
movsd %xmm0, -0xd0(%rbp)
leaq -0x100(%rbp), %rdi
movsd 0x1d66(%rip), %xmm0     # 0x10050
callq 0x8990
jmp 0xe2f1
leaq -0xe8(%rbp), %rdi
leaq -0x58(%rbp), %rsi
leaq -0x100(%rbp), %rdx
callq 0x8910
jmp 0xe30a
leaq -0x130(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
movl $0x1, %ecx
callq 0x8870
jmp 0xe32b
movq -0x348(%rbp), %rax
movb 0x48(%rax), %cl
movb $0x0, -0x149(%rbp)
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x369(%rbp)
je 0xe389
movq -0x348(%rbp), %rsi
leaq -0x148(%rbp), %rdi
leaq -0x130(%rbp), %rdx
leaq -0x138(%rbp), %rcx
callq 0xeb40
jmp 0xe36c
movb $0x1, -0x149(%rbp)
leaq -0x148(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xc9c0
movb %al, -0x369(%rbp)
movb -0x369(%rbp), %al
movb %al, -0x36a(%rbp)
testb $0x1, -0x149(%rbp)
jne 0xe3a0
jmp 0xe3ac
leaq -0x148(%rbp), %rdi
callq 0x4ef0
movb -0x36a(%rbp), %al
testb $0x1, %al
jne 0xe3b8
jmp 0xe3e1
movl $0x4, -0x40(%rbp)
jmp 0xe471
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x5300
jmp 0xe8f5
movsd -0xd0(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xe46a
leaq -0x98(%rbp), %rdi
callq 0xee50
movq %rax, %rdi
callq 0x8830
movq %rax, -0x378(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xee00
movq %rax, %rdi
callq 0x8830
movq -0x378(%rbp), %rsi
movq %rax, %rdx
leaq -0x180(%rbp), %rdi
callq 0xef10
jmp 0xe436
movsd -0xd0(%rbp), %xmm0
leaq -0x168(%rbp), %rdi
leaq -0x180(%rbp), %rsi
callq 0xeea0
jmp 0xe453
movq -0x358(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0xef80
jmp 0xe468
jmp 0xe46a
movl $0x0, -0x40(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x5300
movl -0x40(%rbp), %eax
testl %eax, %eax
je 0xe488
jmp 0xe486
jmp 0xe48a
jmp 0xe48a
leaq -0x78(%rbp), %rdi
xorl %esi, %esi
callq 0xaaf0
movq %rax, -0x188(%rbp)
jmp 0xe210
leaq -0x190(%rbp), %rdi
callq 0xeff0
movq -0x348(%rbp), %rdi
addq $0x18, %rdi
callq 0xf010
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rax
movq %rax, -0x190(%rbp)
movq -0x348(%rbp), %rdi
addq $0x18, %rdi
callq 0xf080
movq %rax, -0x1a0(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0xf040
testb $0x1, %al
jne 0xe505
jmp 0xe82a
leaq -0x190(%rbp), %rdi
callq 0xf0b0
movq %rax, %rsi
leaq -0x1b0(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x61c0
movq -0x380(%rbp), %rdi
callq 0xf0d0
movq %rax, %rdi
callq 0x9f20
movq %rax, %rsi
leaq -0x1d0(%rbp), %rdi
leaq -0x58(%rbp), %rdx
callq 0x53a0
jmp 0xe550
leaq -0x1e8(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x5420
jmp 0xe565
movq -0x1d8(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movups -0x1e8(%rbp), %xmm0
movaps %xmm0, -0x1d0(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0xf0d0
movq %rax, %rdi
callq 0xf120
movq %rax, -0x388(%rbp)
jmp 0xe59e
movq -0x388(%rbp), %rsi
leaq -0x208(%rbp), %rdi
callq 0x5420
jmp 0xe5b3
leaq -0x220(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0xf140
jmp 0xe5c8
leaq -0x208(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x7ea0
callq 0x3220
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x1ec(%rbp)
movss -0x1ec(%rbp), %xmm0
movss %xmm0, -0x390(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0xf0d0
movq %rax, %rdi
callq 0xf1b0
movss %xmm0, -0x38c(%rbp)
jmp 0xe61a
movss -0x390(%rbp), %xmm0
movss -0x38c(%rbp), %xmm1
ucomiss %xmm1, %xmm0
jbe 0xe658
movl $0x7, -0x40(%rbp)
jmp 0xe7f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x55f0
jmp 0xe8f5
leaq -0x1d0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movq %rsi, -0x398(%rbp)
callq 0x7ea0
movq -0x398(%rbp), %rsi
movsd %xmm0, -0x228(%rbp)
leaq -0x258(%rbp), %rdi
movsd 0x19c3(%rip), %xmm0     # 0x10050
callq 0x8990
jmp 0xe694
leaq -0x240(%rbp), %rdi
leaq -0x58(%rbp), %rsi
leaq -0x258(%rbp), %rdx
callq 0x8910
jmp 0xe6ad
leaq -0x288(%rbp), %rdi
leaq -0x240(%rbp), %rsi
leaq -0x1d0(%rbp), %rdx
movl $0x1, %ecx
callq 0x8870
jmp 0xe6ce
movq -0x348(%rbp), %rax
movb 0x48(%rax), %cl
movb $0x0, -0x2a1(%rbp)
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x399(%rbp)
je 0xe72c
movq -0x348(%rbp), %rsi
leaq -0x2a0(%rbp), %rdi
leaq -0x288(%rbp), %rdx
leaq -0x290(%rbp), %rcx
callq 0xeb40
jmp 0xe70f
movb $0x1, -0x2a1(%rbp)
leaq -0x2a0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0xc9c0
movb %al, -0x399(%rbp)
movb -0x399(%rbp), %al
movb %al, -0x39a(%rbp)
testb $0x1, -0x2a1(%rbp)
jne 0xe743
jmp 0xe74f
leaq -0x2a0(%rbp), %rdi
callq 0x4ef0
movb -0x39a(%rbp), %al
testb $0x1, %al
jne 0xe75b
jmp 0xe767
movl $0x7, -0x40(%rbp)
jmp 0xe7f7
movsd -0x228(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xe7f0
leaq -0x1b0(%rbp), %rdi
callq 0xf0d0
movq %rax, %rdi
callq 0x8830
movq %rax, -0x3a8(%rbp)
leaq -0x30(%rbp), %rdi
callq 0xee00
movq %rax, %rdi
callq 0x8830
movq -0x3a8(%rbp), %rsi
movq %rax, %rdx
leaq -0x2d8(%rbp), %rdi
callq 0xef10
jmp 0xe7bc
movsd -0x228(%rbp), %xmm0
leaq -0x2c0(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0xeea0
jmp 0xe7d9
movq -0x358(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0xef80
jmp 0xe7ee
jmp 0xe7f0
movl $0x0, -0x40(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x55f0
movl -0x40(%rbp), %eax
testl %eax, %eax
je 0xe80e
jmp 0xe80c
jmp 0xe810
jmp 0xe810
leaq -0x190(%rbp), %rdi
xorl %esi, %esi
callq 0xf1d0
movq %rax, -0x2e0(%rbp)
jmp 0xe4d2
leaq -0x30(%rbp), %rdi
callq 0xee00
movq %rax, %rdi
callq 0x8850
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jbe 0xe8d5
cmpl $0xa, -0x14(%rbp)
jge 0xe8d5
movq -0x10(%rbp), %rsi
leaq -0x310(%rbp), %rdi
leaq -0x58(%rbp), %rdx
leaq -0x70(%rbp), %rcx
movsd 0x17dc(%rip), %xmm0     # 0x10048
callq 0xf210
jmp 0xe873
movq -0x348(%rbp), %rsi
movl -0x14(%rbp), %ecx
incl %ecx
leaq -0x328(%rbp), %rdi
leaq -0x310(%rbp), %rdx
callq 0xe130
jmp 0xe894
leaq -0x30(%rbp), %rdi
callq 0xee00
movq %rax, %rdi
callq 0x8850
cvtss2sd %xmm0, %xmm0
leaq -0x340(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0xf310
jmp 0xe8be
movq -0x358(%rbp), %rdi
leaq -0x340(%rbp), %rsi
callq 0xef80
jmp 0xe8d3
jmp 0xe8d5
movl $0x1, -0x40(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x4ef0
movq -0x350(%rbp), %rax
addq $0x3b0, %rsp            # imm = 0x3B0
popq %rbp
retq
leaq -0x30(%rbp), %rdi
callq 0x4ef0
movq -0x38(%rbp), %rdi
callq 0x3380
nopw (%rax,%rax)