//////////////////////////////////////////////////////////////////////
//
//	Crytek SuperFramework Source code
//	
//	File:PolyBump.h
//
//	History: 	
//    * July 16,2001: Created by Marco Corbetta
//    * 2/15/2002:    modified by Martin Mittring, integrated in a 3D Studio Plugin
//		- 2/21/2002 modified to work in 3DStudio max as a thread
//
//////////////////////////////////////////////////////////////////////

#ifndef POLYBUMP_H
#define POLYBUMP_H

#if _MSC_VER > 1000
# pragma once
#endif

#include "types.h"																		// uint32
#include "PbTri.h"																		// CPbTri
#include "EveryObjectOnlyOnce.h"											// CEveryObjectOnlyOnce

#include "TGA.h"																			// PIX_LoadTGA32
#include "RasterCube.h"																// CRasterCube


#define USE_MEMORY_BLOCKS

#ifdef USE_MEMORY_BLOCKS
	#define MAX_MEMORY_BLOCK 4*1024*1024
#endif

class CSimpleIndexedMesh;
class CPolyBumpWorkerThread;





class CPbLowMesh
{
public:

	//! constructor
	CPbLowMesh() :m_pMesh(0), m_nNumTris(0) {}
		
	//! destructor
	~CPbLowMesh()
	{
		if(m_pMesh)
		{
			delete [] m_pMesh;
			m_pMesh=NULL;
		}    
	}

	//! copy the data, doesn´t build a accelerator data structure
	//! /param mesh pointer to the input mesh
  void GetNormalsAndClearBaseVectors( CSimpleIndexedMesh *mesh );

	//! for object and tangentspace
	//! copy the data, doesn´t build a accelerator data structure (classes BuildNormalsAndClearBaseVectors)
	//! /param mesh pointer to the input mesh
	void BuildNormalsAndBaseVectors( CSimpleIndexedMesh *mesh );

	//! this methor builds the internal data structured for speedup the raycasting
	//! /param inbDebug debug output is generated
	//! /return status information that could be shown later (is terminated with '\n')
	std::string BuildRayAccelerator( const bool inbDebug );

	//! calculate the size of the bounding sphere (needed for BuildRayAccelerator())
	//! /return outMin minimum x,y,z of the bounding box
	//! /return outMin maximum x,y,z of the bounding box
	//! /return diameter size
	float CalcBoundingVolume( Vec3 &outMin, Vec3 &outMax );

	//! needed for low and high poly
	//! raytracing, gather unsorted hits
	//! call ClearListBefore and GetHitList afterwards
	//! /param inStart start vector in worldspace
	//! /param inDirection end vector of the ray
	//! /param outIntersections reference to the intersection list (make sure the list is empty)
	void GatherRayHits( const Vec3 invStart, const Vec3 invEnd, CIntInfoLowList &outIntersections, const CPbLowTri *inpIgnoreObject );
	
	// -------------------------------------------------------------------------------------------

	uint32													m_nNumTris;								//!< number of triangles in the mesh
  CPbLowTri *											m_pMesh;									//!< pointer to the triangle data

	CRasterCube<CPbLowTri *>				m_Raster;									//!< triangle intersetcion accelerator data structure
};




class CPbHighMesh
{
public:

	//! constructor
	CPbHighMesh();
	//! destructor
	~CPbHighMesh();

	//! raytracing, test if there is a hit or not
	//! /param inStart start vector in worldspace
	//! /param inDirection end vector of the ray
	//! /return true: ray has a intersection, false: otherwise
	bool CalcIntersection( const Vec3 invStart, const Vec3 invEnd, const CPbHighTri *inpIgnoreObject );

	//! copy the data, doesn´t build a accelerator data structure
	//! /param mesh pointer to the input mesh
  void GetNormalsAndClearBaseVectors( CSimpleIndexedMesh *mesh );

	//! this methor builds the internal data structured for speedup the raycasting
	//! /param inbDebug debug output is generated
	//! /return status information that could be shown later (is terminated with '\n')
	std::string BuildRayAccelerator( const bool inbDebug );

	//! calculate the size of the bounding sphere (needed for BuildRayAccelerator())
	//! /return outMin minimum x,y,z of the bounding box
	//! /return outMin maximum x,y,z of the bounding box
	//! /return diameter size
	float CalcBoundingVolume( Vec3 &outMin, Vec3 &outMax );

	//! needed for low and high poly
	//! raytracing, gather unsorted hits
	//! call ClearListBefore and GetHitList afterwards
	//! /param inStart start vector in worldspace
	//! /param inDirection end vector of the ray
	//! /param outIntersections reference to the intersection list (make sure the list is empty)
	void GatherRayHits( const Vec3 invStart, const Vec3 invEnd, CIntInfoHighList &outIntersections, const CPbHighTri *inpIgnoreObject );

	
	// -------------------------------------------------------------------------------------------


	uint32													m_nNumTris;								//!< number of triangles in the mesh
#ifdef USE_MEMORY_BLOCKS
	unsigned long										m_nBlockCnt, m_nObjPerBlock;
  CPbHighTri **										m_pMesh;
#else
  CPbHighTri *										m_pMesh;									//!< pointer to the triangle data
#endif //USE_MEMORY_BLOCKS

	CRasterCube<CPbHighTri *>				m_Raster;									//!< triangle intersetcion accelerator data structure
};



	


bool CreateBumpMap( CPolyBumpWorkerThread *inpData );

#endif


