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


		#include <cmath>
		#include "raytracer/raytracer_spread.h"
		#include "math/matrix3.h"
		#include "rand/rand.h"
		#include "memory/memory.h"
		#include "log/log.h"

		using namespace GS::Raytrace;


//------------------------------------------------------------------------------
bool		Spread::Initialize(uint u_count, uint v_count, float max_spread)
{
	Free();

	if	(!spread.Allocate(u_count * v_count))
		__ERR__(__LOG_E__ << "failed to allocate vector spread.\n", false)

	float s_v = max_spread / (v_count + 2), a_v = s_v;

	uint count = 0;
	for	(uint v = 0; v < v_count; ++v)
	{
		float strat_v = a_v + Random::FRand(s_v);		// Stratified sampling.

		float s_u = Units::Deg(360.f) / u_count, a_u = Units::Deg(0.f);
		for	(uint u = 0; u < u_count; ++u)
		{
			float strat_u = a_u + Random::FRand(s_u);		// Stratified sampling.

			Vector4 tmp(sin(strat_v), 0, cos(strat_v));
			Matrix3 rtz(Matrix3::RotationMatrixZAxis(strat_u));
			rtz.Apply(&spread[count++], &tmp);

			a_u += s_u;
		}
		a_v += s_v;
	}
	return true;
}
void		Spread::Free()
{
	spread.Free();
}
//------------------------------------------------------------------------------
