#ifndef __BVH_BOTTOM_H__
#define __BVH_BOTTOM_H__

#include "AbstractBVH.h"
#include <algorithm>

namespace VRUT
{

	/// BVH data structure.
	class BVHBottom : public AbstractBVH
	{

	public:

		struct TriangleCol
		{
			Vector3 v1;
			Vector3 e21;
			Vector3 e13;
			Vector3 e21x13;
		};

		struct TriangleNorm
		{
			Vector3 n1;
			Vector3 n2;
			Vector3 n3;
		};

		struct TriangleTex
		{
			Vector2 texCoord1;
			Vector2 texCoord2;
			Vector2 texCoord3;
		};

	private:

		/// Vector of triangles.
		std::vector<TriangleData> * triangles;
		std::vector<TriangleCol> triangleCols;
		std::vector<TriangleNorm> triangleNorms;
		std::vector<TriangleTex> triangleTexs;

		/// Returns cost of subtree with a given root index.
		float GetSubtreeCost(int index) const;

	public:

		/// Constructor, Nmax is suggested number of triangles in leaf.
		BVHBottom(void) : triangles(NULL) {}

		/// Destructor, free all used resources.
		~BVHBottom(void) {}

		const std::vector<BVHBottom::TriangleCol>& GetTriangleCols(void) const
		{
			return triangleCols;
		}

		void GetVerticesAt(const int index, Vector3 & v1, Vector3 & v2, Vector3 & v3) const;
		void GetTextureCoordsAt(const int index, Vector2 *& texCoords1, Vector2 *& texCoords2, Vector2 *& texCoords3) const;
		void GetNormalAtUnnormalized(const int index, const float u, const float v, Vector3 & normal) const;

		friend class BVHOptimizer;
		friend class BVHBuilder;
		friend class BVHBinnedBuilder;
		friend class BVHSAHBuilder;
		friend class MBVHTransformer;
		friend class RayCaster;
	};
}

#endif /* __BVH_BOTTOM_H__ */
