#include "stdafx.h"										// precompiled headers
#include <assert.h>										// assert()
#include "pbclonemap.h"								// CPBCloneMap
//#include "vector.h"										// Vec3
#include "TGA.h"											// PIX_LoadTGA,PIX_SaveTGA
#include "SimpleTriangleRasterizer.h"	// CSimpleTriangleRasterizer
#include "RGBPackedBase.h"						// CRGBPackedBase Base orthogonal base stored in 3 Bytes


// constructor
CPBCloneMap::CPBCloneMap( void )
{
	assert(6*g_dwCMSideLength*g_dwCMSideLength*g_dwCMAngleLength<=0xffffff);

	m_pBitmap=0;
	m_dwBitmapWidth=0;
	m_dwBitmapHeight=0;
}



// destructor
CPBCloneMap::~CPBCloneMap( void )
{
	FreeData();
}







void CPBCloneMap::FreeData( void )
{
	if(m_pBitmap)delete[] m_pBitmap;m_pBitmap=0;

	m_dwBitmapWidth=0;m_dwBitmapHeight=0;
}



//
bool CPBCloneMap::Create( const DWORD indwWidth, const DWORD indwHeight )
{
	FreeData();

	if(indwWidth==0)return(false);
	if(indwHeight==0)return(false);

	m_pBitmap=new DWORD[indwWidth*indwHeight];

	if(m_pBitmap)
	{
		DWORD *pPtr=m_pBitmap;

		for(DWORD i=0;i<indwWidth*indwHeight;i++)
			*pPtr++=0;

		m_dwBitmapWidth=indwWidth;
		m_dwBitmapHeight=indwHeight;
		return(true);
	}

	else return(false);
}




// set the base for a UV triangle definition
bool CPBCloneMap::Set( float infU[3], float infV[3], Vec3 invBase[3] )
{
	if(!m_pBitmap)return(false);

	float fU[3],fV[3];

	for(int i=0;i<3;i++)
	{
		fU[i]=(float)(infU[i]*(float)m_dwBitmapWidth);
		fV[i]=(float)(infV[i]*(float)m_dwBitmapHeight);
	}

	CRGBPackedBase pack;

	pack.SetBase(invBase[0],invBase[1],invBase[2]);

	DWORD dwColor=pack.GetRGB();

	// triangle
	{
		CSimpleTriangleRasterizer Raster(m_dwBitmapWidth,m_dwBitmapHeight);

		CSimpleTriangleRasterizer::ShrinkTriangle(fU,fV,1.0f);

		Raster.DWORDFlatFill(m_pBitmap,m_dwBitmapWidth,fU,fV,g_dwCMStartBaseColor+dwColor,false);
	}

	// midpoint
	{
		float fU=(infU[0]+infU[1]+infU[2])/3.0f;
		float fV=(infV[0]+infV[1]+infV[2])/3.0f;

		DWORD dwX=(DWORD)(fU*m_dwBitmapWidth);		dwX=dwX%m_dwBitmapWidth;
		DWORD dwY=(DWORD)(fV*m_dwBitmapHeight);		dwY=dwY%m_dwBitmapHeight;

		m_pBitmap[dwX+dwY*m_dwBitmapWidth]=g_dwCMStartBaseColor+dwColor;
	}

	return(true);
}


// save the clonemap (same directory and filename (except extension) as objectspace bumpmap is recommended)
bool CPBCloneMap::SaveCloneMap( const char *inszFileName )
{
	if(!m_pBitmap)return(false);
		
	return(PIX_SaveTGA32(inszFileName,(unsigned char *)m_pBitmap,m_dwBitmapWidth,m_dwBitmapHeight,false,true));
}
