////////////////////////////////////////////////////////////////////////////////////////////////////
// Grobal values
////////////////////////////////////////////////////////////////////////////////////////////////////

#if MIX_SM_HIGH

	/****************************************
		Reserved : b0
	****************************************/
	
	//

	/****************************************
		General : b1
	****************************************/

	cbuffer cbGeneral : register( b1 )
	{
		float4x4 g_ViewMat;      // View matrix
		float4x4 g_ViewProjMat;  // View * Projection matrix
		float4x4 g_LightMat;     // Light matrix (ProjectionShadow)
		float4x4 g_LightBiasMat; // Light * Bias matrix (ProjectionCamera)
	};

	/****************************************
		Transform : b2
	****************************************/

	cbuffer cbTransform : register( b2 )
	{
		float4x4 g_WorldMat[20]; // World matrix ( skining )
	};

	/****************************************
		LocalLight : b3
	****************************************/
	
	//

	/****************************************
		Material : b4
	****************************************/
	
	//
	
#else //MIX_SM_HIGH

	/****************************************
		Reserved : c0 - c15
	****************************************/
	
	//

	/****************************************
		General : c16 - c111
	****************************************/

	float4x4 g_ViewMat      : register( c16 ); // View matrix
	float4x4 g_ViewProjMat  : register( c20 ); // View * Projection matrix
	float4x4 g_LightMat     : register( c24 ); // Light matrix (ProjectionShadow)
	float4x4 g_LightBiasMat : register( c28 ); // Light * Bias matrix (ProjectionCamera)

	float4x4 g_WorldMat[20] : register( c32 ); // World matrix ( skining )

	/****************************************
		LocalLight : c112 - c131
	****************************************/
	
	//

	/****************************************
		Material : c132 - ?
	****************************************/
	
	//

#endif //MIX_SM_HIGH

////////////////////////////////////////////////////////////////////////////////////////////////////
// Macros : Global values
////////////////////////////////////////////////////////////////////////////////////////////////////

#define VIEW_MAT_3x3 ( float3x3 )g_ViewMat
#define VIEW_PROJ_MAT_4x4 g_ViewProjMat

#define LIGHT_MAT_4x4 g_LightMat
#define LIGHT_BIAS_MAT_4x4 g_LightBiasMat

#define WORLD_MAT_4x4 g_WorldMat[0]
#define WORLD_MAT_3x3 ( float3x3 )g_WorldMat[0]
#define WORLD_MAT_4x4_ARRAY( index ) g_WorldMat[index]
#define WORLD_MAT_3x3_ARRAY( index ) ( float3x3 )g_WorldMat[index]

////////////////////////////////////////////////////////////////////////////////////////////////////
// Functions
////////////////////////////////////////////////////////////////////////////////////////////////////

// Skining //

#if ENABLE_SKINNING

	// World transform position
	float4 BoneTransformPosition( float4 pos, uint4 indices, float4 weights )
	{
		float4 ret =	( mul( pos, WORLD_MAT_4x4_ARRAY( indices.x ) ) * weights.x ) +
						( mul( pos, WORLD_MAT_4x4_ARRAY( indices.y ) ) * weights.y ) +
						( mul( pos, WORLD_MAT_4x4_ARRAY( indices.z ) ) * weights.z ) +
						( mul( pos, WORLD_MAT_4x4_ARRAY( indices.w ) ) * weights.w );

		return float4( ret.xyz, 1.0 );
	}

	// World transform normal
	float3 BoneTransformNormal( float3 norm, uint4 indices, float4 weights )
	{
		float3 ret =	( mul( norm, WORLD_MAT_3x3_ARRAY( indices.x ) ) * weights.x ) +
						( mul( norm, WORLD_MAT_3x3_ARRAY( indices.y ) ) * weights.y ) +
						( mul( norm, WORLD_MAT_3x3_ARRAY( indices.z ) ) * weights.z ) +
						( mul( norm, WORLD_MAT_3x3_ARRAY( indices.w ) ) * weights.w );

		return ret;
	}

#endif //ENABLE_SKINNING
