//!HLS


// -----------------------------------------------------------------------------
// definitions and functions for doing skinning
// -----------------------------------------------------------------------------
#ifndef WEIGHT_COUNT					
	#define WEIGHT_COUNT				4
#endif

#define FLOAT_TO_INT_HACK_CONST		765.01f // 255 * 3 + 0.01

#ifndef MAX_PALETTE_SIZE
// We manually add a VS_PROFILE define just before compiling in createVertexShader_HLSL() so we can size the palette appropriately
	  
	#if (VS_PROFILE == vs_2_a)
		#define MAX_PALETTE_SIZE		60 // allow 60 bones  = 180 vectors (magic #, needs to be < 256 though)
	#else
		#define MAX_PALETTE_SIZE		28 // allow 28 bones  = 84 vectors ( seems reasonable for vs_1_1)
	#endif 
#endif

// convert the indices from floats to int and do some magic fixups
// because of the way alchemy exports these
//
int4 getIntIndices(float4 vBoneIndices)
{
	int4 vIntIndices;

	// alchemy exports the indices already pre-multiplied to index into an array
	// of floats, not matrices
	// The hacked constant and inexplicable swizzling comes straight out of the alchemy
	// gpuSkinning example shader
	vIntIndices = vBoneIndices.zyxw * FLOAT_TO_INT_HACK_CONST;
//	vIntIndices /= 3;	// This is not needed.	We used to divide by 3 here and then multiply by 3 below.

	return vIntIndices;
}

// do the actual bone weighting
//
float4 getBlendedPosition(float4 vPosition, int4 vIndices, float4 vBoneWeights, float4 Bones[MAX_PALETTE_SIZE * 3])
{
#ifndef PBS
	// FxComposer 1.8 does not support bone palettes
	return vPosition;
#else
	float4 vBlendedPosition = float4(0,0,0,1);

	for(int i = 0; i < WEIGHT_COUNT; ++i)
	{
		float3 vTempPosition;
		float iBoneIndex;

		iBoneIndex = vIndices[i];

		vTempPosition.x = dot(vPosition, Bones[iBoneIndex+0]);
		vTempPosition.y = dot(vPosition, Bones[iBoneIndex+1]);
		vTempPosition.z = dot(vPosition, Bones[iBoneIndex+2]);

		vBlendedPosition.xyz += vTempPosition * vBoneWeights[i];
	}

	return vBlendedPosition;
#endif	
}


// combine the base texture, mask texture, primary and secondary colors
float4 computeBlendedColor(float2 vUV, sampler2D baseTexture, sampler2D maskTexture,
						   float4 vPrimaryColor, float4 vSecondaryColor, float4 vSkinColor)
{
	float4 vBaseColor = tex2D( baseTexture, vUV);
	float4 vMask = tex2D( maskTexture, vUV);

	float4 vFinalColor;
	float4 vBlendColor;
	// the base color modulates with the primary/secondary/skin colors, and the
	// mask values determine the blend between the base and the modulated values
	vBlendColor=  vPrimaryColor * vMask.x + vSecondaryColor * vMask.y;
	vFinalColor = lerp( vBaseColor, vBlendColor * vBaseColor, vMask.x + vMask.y );
	vFinalColor = lerp(vFinalColor, vFinalColor * vSkinColor, vMask.z);	 

	vFinalColor.w = vBaseColor.w;
	return vFinalColor;
}


