/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "raytracer/raytracer_job.h"
		#include "core/geometry.h"
		#include "rand/rand.h"

		using namespace GS::Raytrace;


//------------------------------------------------------------------------------
void				RaytraceJob::Execute(uint)
{
	Vector4	pt_s = pt_l + dt_l * (float)start_height;

	for (int v = start_height; v < end_height; ++v)
	{
		Vector4	dt_s = ((pt_r + dt_r * (float)start_height) - (pt_l + dt_l * (float)start_height)) / (float)pitch;
		for	(int u = start_width; u < end_width; ++u)
		{
			Vector4	d = (pt_s + dt_s * (float)u - s).Normalized();
			core->PrimaryRay(RayGrid(s, d), hdr[v * pitch + u]);
		}
		pt_s += dt_l;
	}
}
void				AntialiasJob::Execute(uint)
{
	Configuration &config = core->GetConfiguration();

	float aa_v_k = config.interlaced_trace_half_frame ? 0.5f : 1.f,
		  aa_threshold = config.aa_threshold,
		  aa_jitter = config.aa_jitter;

	int	aa_sample = config.aa_sample;

	// When rendering half frame halve the AA kernel vertically.
	for (int v = start_height; v < end_height; ++v)
		for	(int u = start_width; u < end_width; ++u)
		{
			Color *o_hdr = &hdr[v * pitch + u];

			// Check threshold.
			if	(
					(Vector4::Dist2(o_hdr[0], o_hdr[-1]) < aa_threshold) &&
					(Vector4::Dist2(o_hdr[0], o_hdr[-pitch]) < aa_threshold) &&
					(Vector4::Dist2(o_hdr[0], o_hdr[1]) < aa_threshold) &&
					(Vector4::Dist2(o_hdr[0], o_hdr[pitch]) < aa_threshold)
				)
				continue;

			// Multi-sample.
			o_hdr[0].Set(0, 0, 0);

			for (int ms_v = 0; ms_v < aa_sample; ++ms_v)
			{
				// TODO pre-calculate jittered/non-jittered grids.
				float ms_v_o = v + ((float)ms_v * aa_v_k) / aa_sample + (aa_jitter ? Random::FRand(0.125f / aa_sample) : 0);

				Vector4	dt_s = ((pt_r + dt_r * ms_v_o) - (pt_l + dt_l * ms_v_o)) / (float)pitch,
						pt_s = pt_l + dt_l * ms_v_o;

				for (int ms_u = 0; ms_u < aa_sample; ++ms_u)
				{
					float ms_u_o = u + (float)ms_u / aa_sample + (aa_jitter ? Random::FRand(0.125f / aa_sample) : 0);
					Vector4 d = (pt_s + dt_s * ms_u_o - s).Normalized();

					Color out;
					core->PrimaryRay(RayGrid(s, d), out);
					o_hdr[0] += out.Clamped(0, 1);
				}
			}
			o_hdr[0] /= (float)(aa_sample * aa_sample);
		}
}
//------------------------------------------------------------------------------
