#ifndef __BVH_BUILDER_H__
#define __BVH_BUILDER_H__

#include "BVHBottom.h"

namespace VRUT
{

	class BVHBuilder
	{

	public:

		union Point
		{
			float v[4]; 
			__m128 _p;
		};

		struct TriangleAABB
		{
			VRUT_ALIGNED(16) Point min;
			VRUT_ALIGNED(16) Point max;
			VRUT_ALIGNED(16) Point centroid;
			unsigned int index;
			unsigned int bin;
		};

		/// structure to store information to build BVH
		struct BVHBuildNode
		{
			VRUT_ALIGNED(16) Point bMin; ///< minimum coordinate AABB of bounding box
			VRUT_ALIGNED(16) Point bMax; ///< maximum coordinate AABB of bounding box
			VRUT_ALIGNED(16) Point cMin; ///< minimum coordinate AABB of centroid
			VRUT_ALIGNED(16) Point cMax; ///< maximum coordinate AABB of centroid
			BVHBottom::BVHNode * node; ///< pointer to node
		};

	protected:

		VRUT_ALIGNED(16) Point sceneMin;
		VRUT_ALIGNED(16) Point sceneMax;
		VRUT_ALIGNED(16) Point centroidMin;
		VRUT_ALIGNED(16) Point centroidMax;

		unsigned int numberOfTriangles;
		TriangleAABB * aabbs;
		BVHBottom * bvh;

		void PreSetupTriangles(const smart_pointer<Geometry> & geometry);
		void PostSetupTriangles(const smart_pointer<Geometry> & geometry);
		void GenerateTrianglesFromText(const smart_pointer<Geometry>& text, std::vector<TriangleData>* triangles);
		void ComputeAABBs(void);

	public:

		BVHBuilder(void);
		virtual ~BVHBuilder(void);

		virtual BVHBottom * Build(const smart_pointer<Geometry> & geometry, unsigned int maxTrianglesPerLeaf) = 0;

	};

}

#endif /* __BVH_BUILDER_H__ */
