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


#ifndef	__NGEOTREE__
#define	__NGEOTREE__


		#include "core/graphic_resource_factory.h"
		#include "core/geometry.h"
		#include "math/vector.h"


namespace GS {
	namespace Core {

struct	GeometryTraceBase
{
		Geometry	*g;

		float		i_t;					///< Distance to intersection from ray's origin.
		bool		backface;				///< Hit is on the back face of the polygon.

		int			ip;						///< Polygon index.
		uint		it;						///< Triangle index in polygon.
		uint		bi;						///< Polygon binding start index.
		float		u, v, w;				///< Barycentric coordinates.

		Material	*m;
		ShaderTree	*st;
};

// Raytrace result.
struct	GeometryTrace : public GeometryTraceBase
{
		Vector4		s;						///< Ray origin.
		Vector4		d;						///< Ray direction.

		bool		want_closest;
		bool		has_i;					///< Do we have an intersection.

		uint		node_visited;			///< Number of nodes visited.
		uint		tri_test;				///< Number of triangle tested.

		GeometryTrace(bool closest = true)
		{
			want_closest = closest;
			has_i = false;

			node_visited = 0;
			tri_test = 0;
		}
};

/*!
	@short	Geometry abstract tree.
	@author	Emmanuel Julien (ejulien@gsworks.fr)
*/
class	IGeometryTree
{
protected:

		sGeometry		geometry;

public:

		Geometry		*GetGeometry() const { return geometry; }

		/*!
			@short	Specify a fixed ray origin.

			This function provides the tree implementation with an optimization
			opportunity by specifying a fixed ray origin.

			@note	Pass NULL to remove hint.
		*/
virtual	void			SetRayOriginHint(const Vector4 *) {}

/*!
	@name	Interface core functions.
	@{
*/
		/// Raytrace the geometry tree.
virtual	void			RaytraceGeometry(GeometryTrace &, const Vector4 &s, const Vector4 &d, float length = -1.f) = 0;
		/// Build tree from a geometry.
virtual	bool			BuildFromGeometry(ResourceFactory &, Geometry *) = 0;
		/// Free all internal structures.
virtual	void			Free() = 0;
/// @}

virtual	~IGeometryTree() {}
};

	} // Core
} // GS


#endif	// __NGEOTREE__
