#ifndef		__FASTTUNNELBLOBS_H_
#define		__FASTTUNNELBLOBS_H_

#pragma pack(4)
struct FASTBLOBVERTEX
{
	he3d_CVector	v;
	he3d_CVector	n;	
};
#pragma pack()

#define FASTBLOBFVF	D3DFVF_XYZ | D3DFVF_NORMAL

class CSimpleBlob3D
{
public:

	// blob center position
	he3d_CVector	m_vPos;
	
	FLOAT			m_fDensity;
	FLOAT			m_fRadius;	

	// calculate density at given point
	FLOAT BlobFunction( he3d_CVector& pos );
	FLOAT CalcEffectiveRadius();

	// constructor
	CSimpleBlob3D() : m_vPos(), m_fDensity(1.0f), m_fRadius(1.0f)
	{
	}	
};

class CSimpleBlobSystem
{
private:

	class CNode
	{
	public:

		CSimpleBlob3D*	blob;
		CNode*			next;
		CNode*			prev;
	};

	// grid... one dimensional for easier allocation
	FLOAT*					m_pfGrid;
	LPWORD					m_pRow;
	LPWORD					m_pPlane;
	// grid properties
	DWORD					m_dwGridDensity;

	he3d_CVector			m_vSize;
	he3d_CVector			m_vCenter;		
	
	DWORD					m_bAutoResize;

	DWORD					m_dwBlobCount;
	CNode*					root;

	DWORD					m_dwVerticesCount;	
	DWORD					m_dwFacesCount;
	PDIRECT3DVERTEXBUFFER8	m_pvbVertices;
	PDIRECT3DINDEXBUFFER8	m_pibIndices;	
	
	VOID Normals( DWORD dwVertsCount, FASTBLOBVERTEX* pVertTable );	
	VOID ResizeToFit();

public:

	CSimpleBlobSystem( DWORD dwDensity = 32 );
	~CSimpleBlobSystem();	

	VOID Initialize( PDIRECT3DDEVICE8 pDevice );

	VOID SetGridDensity( DWORD density );		
	VOID SetGridCenter( he3d_CVector& center );		

	DWORD GetGridDensity();		

	VOID AddBlob( CSimpleBlob3D* blob );
	VOID RemoveBlob( CSimpleBlob3D* blob );
	VOID RemoveBlob( DWORD index );
	CSimpleBlob3D* GetBlob( DWORD index );	
	DWORD GetBlobCount();

	// just recalculate blobs primitive and call render
	VOID CalculateDensity();	
	VOID Triangulate( PDIRECT3DVERTEXBUFFER8 vb, PDIRECT3DINDEXBUFFER8 ib, DWORD& dwVertsCount, DWORD& dwFacesCount );			
	VOID Render( PDIRECT3DDEVICE8 pDevice );
};

#endif