
/************************************************************************************************

	Checker.cpp

	Copyright (c)1990 - 1999 MetaCreations. All rights reserved.

	Author: Jerome Bignon

	Date: 04/29/99

	Revision history

	when		who			what & why
	=========== =========== =====================================================================
	08/20/99	cph			Put in Extension3DInit() and Extension3DCleanup() methods
	04/29/99	Jerome		Finishing and comments
	04/28/99	Jerome		Creation

************************************************************************************************/

#include "math.h"
#include "Checker.h"


const MCGUID CLSID_Checker(R_CLSID_Checker);


void Extension3DInit(IMCUnknown* utilities)
{
	// Perform your dll initialization here
}

void Extension3DCleanup()
{
	// Perform any nec clean-up here
}

TBasicUnknown* MakeCOMObject(const MCCLSID& classId)	// This method instanciate
{														// the object Fog
	TBasicUnknown* res = NULL;

	if (classId == CLSID_Checker) res = new Checker;

	return res;
}


Checker::TPMap::TPMap()
{
	fNb[0] = fNb[1] = 4;	// Horizontal and Vertical checkers are equal
}


Checker::Checker()	// We just initialize the values
{
}

boolean Checker::IsEqualTo(I3DExShader* aShader)
{
	return ((fPMap.fNb[0]==((Checker*)aShader)->fPMap.fNb[0]) &&	(fPMap.fNb[1]==((Checker*)aShader)->fPMap.fNb[1]));
}

MCCOMErr Checker::GetShadingFlags(ShadingFlags& theFlags)
{
	theFlags.fNeedsUV = true;		// We need UV coordinates
	theFlags.fConstantChannelsMask = kNoChannel;
	return MC_S_OK;
}

EShaderOutput Checker::GetImplementedOutput()
{
	return kUsesGetValue;	// We use GetValue with shading Area
}

#define MyEven(xx)	(!(xx & 0x00000001))

MCCOMErr Checker::ExtensionDataChanged()
{
	MCCOMErr result1 = MC_S_OK;
	MCCOMErr result2 = MC_S_OK;

	fMul[0] = fPMap.fNb[0];
	fMul[1] = fPMap.fNb[1];
	if (fPMap.fShader[0])
		result1 = fPMap.fShader[0]->QueryInterface(IID_I3DShShader, (void**)&fShaders[0]);
	if (fPMap.fShader[1])
		result2 = fPMap.fShader[1]->QueryInterface(IID_I3DShShader, (void**)&fShaders[1]);

	if (result1 == MC_S_OK && result2 == MC_S_OK)
		return MC_S_OK;
	else
		return MC_S_FALSE;
}

real Checker::GetValue(real& result,boolean& fullArea,ShadingIn& shadingIn)
{
	real tempx = shadingIn.fUV[0] * fMul[0];
	real tempy = shadingIn.fUV[1] * fMul[1];
	if (MyEven(int32(RealFloor(tempx) + RealFloor(tempy))))
	{
		if (fShaders[0])
			fShaders[0]->GetValue(result, fullArea, shadingIn);
		else
			result = kRealZero;
	}
	else
	{
		if (fShaders[1])
			fShaders[1]->GetValue(result, fullArea, shadingIn);
		else
			result = kRealOne;
	}
	fullArea = true;

	return 1.0f;
}
