// File: dmarto[P]crrs-xlib/main.cpp
// Function: Trace(Ray const&, Sphere const&, std::vector<Sphere*, std::allocator<Sphere*>> const&)
Vec3 Trace(const Ray &ray, const Sphere &light, const std::vector<Sphere *> &objects)
{
	Colors color;
	Vec3 pixclr = color.black;

	for (auto &sphere : objects)
	{
		double t;
		double lightIntensity = 0.62;

		if (sphere->Intersects(ray, t))
		{
			const Vec3 pointOfIntersection = ray.origin + ray.destination * t;
			const Vec3 len = light.center - pointOfIntersection;
			const Vec3 normal = sphere->GetNormal(pointOfIntersection);
			const double dotProduct = dot(len.Normalize(), normal.Normalize());

			pixclr = (sphere->clr + light.clr / 2 * dotProduct) * lightIntensity;

			if (sphere->name != "world")
				Reflection(objects, pointOfIntersection, normal, pixclr);
			Shadow(objects, pointOfIntersection, normal, pixclr, light);

			ColorBoundary(pixclr);
		}
	}

	return pixclr;
}

// Assembly:
subq $0x1f8, %rsp            # imm = 0x1F8
movq %rdi, 0x20(%rsp)
movq %rdi, 0x18(%rsp)
movq %rsi, 0x1f0(%rsp)
movq %rdx, 0x1e8(%rsp)
movq %rcx, 0x1e0(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x3bd0
movq 0x20(%rsp), %rdi
movq 0x180(%rsp), %rax
movq %rax, (%rdi)
movq 0x188(%rsp), %rax
movq %rax, 0x8(%rdi)
movq 0x190(%rsp), %rax
movq %rax, 0x10(%rdi)
movq 0x1e0(%rsp), %rax
movq %rax, 0x148(%rsp)
movq 0x148(%rsp), %rdi
callq 0x3ca0
movq %rax, 0x140(%rsp)
movq 0x148(%rsp), %rdi
callq 0x3cd0
movq %rax, 0x138(%rsp)
leaq 0x140(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x3d00
testb $0x1, %al
jne 0x2c06
jmp 0x2e46
leaq 0x140(%rsp), %rdi
callq 0x3d40
movq %rax, 0x130(%rsp)
movsd 0x343d(%rip), %xmm0     # 0x6060
movsd %xmm0, 0x120(%rsp)
movq 0x130(%rsp), %rax
movq (%rax), %rdi
movq 0x1f0(%rsp), %rsi
leaq 0x128(%rsp), %rdx
callq 0x3df0
testb $0x1, %al
jne 0x2c55
jmp 0x2e32
movq 0x1f0(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x1f0(%rsp), %rsi
addq $0x18, %rsi
movsd 0x128(%rsp), %xmm0
leaq 0xf0(%rsp), %rdi
callq 0x3d50
movq 0x8(%rsp), %rsi
leaq 0x108(%rsp), %rdi
leaq 0xf0(%rsp), %rdx
callq 0x3fc0
movq 0x1e8(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
leaq 0x108(%rsp), %rdx
callq 0x4020
movq 0x130(%rsp), %rax
movq (%rax), %rsi
leaq 0xc0(%rsp), %rdi
leaq 0x108(%rsp), %rdx
callq 0x4080
leaq 0xa0(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x4130
leaq 0x88(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0x4130
leaq 0xa0(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x40e0
movsd %xmm0, 0xb8(%rsp)
movq 0x130(%rsp), %rax
movq (%rax), %rax
addq $0x20, %rax
movq %rax, 0x10(%rsp)
movq 0x1e8(%rsp), %rsi
addq $0x20, %rsi
leaq 0x28(%rsp), %rdi
movsd 0x32f0(%rip), %xmm0     # 0x6040
callq 0x41e0
movsd 0xb8(%rsp), %xmm0
leaq 0x40(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x3d50
movq 0x10(%rsp), %rsi
leaq 0x58(%rsp), %rdi
leaq 0x40(%rsp), %rdx
callq 0x3fc0
movsd 0x120(%rsp), %xmm0
leaq 0x70(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x3d50
movq 0x20(%rsp), %rax
movq 0x70(%rsp), %rcx
movq %rcx, (%rax)
movq 0x78(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq 0x80(%rsp), %rcx
movq %rcx, 0x10(%rax)
movq 0x130(%rsp), %rax
movq (%rax), %rdi
addq $0x38, %rdi
leaq 0x3357(%rip), %rsi      # 0x6128
callq 0x4300
testb $0x1, %al
jne 0x2ddc
jmp 0x2dfe
movq 0x20(%rsp), %rcx
movq 0x1e0(%rsp), %rdi
leaq 0x108(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x2530
movq 0x20(%rsp), %rcx
movq 0x1e0(%rsp), %rdi
movq 0x1e8(%rsp), %r8
leaq 0x108(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x2830
movq 0x20(%rsp), %rdi
callq 0x23e0
jmp 0x2e34
leaq 0x140(%rsp), %rdi
callq 0x4230
jmp 0x2be8
movq 0x18(%rsp), %rax
addq $0x1f8, %rsp            # imm = 0x1F8
retq
nopw %cs:(%rax,%rax)