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


		#include "raytracer/raytracer_core.h"
		#include "core/geometry.h"

		using namespace GS;
		using namespace GS::Core;
		using namespace GS::Raytrace;


//------------------------------------------------------------------------------
Vector4				Raytracer::SampleGeometryAttribute(const Trace &trace, GeometryAttribute attr)
{
	Vector4	sample;

	switch (attr)
	{
		case GeometryVertexColor:
			if	(trace.g->rgb)
				sample = (	trace.g->rgb[trace.bi + 0] * trace.w +
							trace.g->rgb[trace.bi + trace.it + 1] * trace.u +
							trace.g->rgb[trace.bi + trace.it + 2] * trace.v	);
			else
				sample.Set(0.25f, 0.f, 0.f);
			break;

		case GeometryNormal:
		{
			if	(
					(trace.m->renderword & Material::Render_Smooth) ||
					(trace.m->renderword & Material::Render_NormalTangent)
				)
			{
				// Interpolated vertex normal.
				sample = (	trace.g->vtx_normal[trace.bi + 0] * trace.w +
							trace.g->vtx_normal[trace.bi + trace.it + 1] * trace.u +
							trace.g->vtx_normal[trace.bi + trace.it + 2] * trace.v	).Normalized();

				// Normal map support.
				if	(trace.m->GetChannelStage(Channel_Normal))
				{
					if	(trace.m->renderword & Material::Render_NormalTangent)
					{
						Vector4 T, B;

						if	(trace.g->vtx_tangent)
						{
							// Interpolated tangent basis.
							T =	(	trace.g->vtx_tangent[trace.bi + 0].T * trace.w +
									trace.g->vtx_tangent[trace.bi + trace.it + 1].T * trace.u +
									trace.g->vtx_tangent[trace.bi + trace.it + 2].T * trace.v	).Normalized();
							B =	(	trace.g->vtx_tangent[trace.bi + 0].B * trace.w +
									trace.g->vtx_tangent[trace.bi + trace.it + 1].B * trace.u +
									trace.g->vtx_tangent[trace.bi + trace.it + 2].B * trace.v	).Normalized();
						}
						else
						{
							T.Set(1, 0, 0);
							B.Set(0, 1, 0);
						}

						// Build tangent frame.
						Matrix3	tangent_matrix(T, B, sample);
						Vector4	normal_sample(SampleMaterialAttribute(trace, Channel_Normal)),
								tangent_normal(normal_sample.x * 2 - 1, normal_sample.y * 2 - 1, normal_sample.z * 2 - 1);

						sample = tangent_normal * tangent_matrix;
					}
					else
					{
						// World space.
						Vector4	normal_sample(SampleMaterialAttribute(trace, Channel_Normal)),
								tangent_normal(normal_sample.x * 2 - 1, normal_sample.z * 2 - 1, normal_sample.y * 2 - 1);
						sample = tangent_normal;
					}
				}
			}
			else
				sample = trace.g->pol_normal[trace.ip];
		}
		break;
	}
	return sample;
}
//------------------------------------------------------------------------------
