////////////////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////////////////

#include "../../../types.txt"
#include "../common.vs.txt"

#include "types.txt"
#include "common.vs.txt"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function : ColorModel
////////////////////////////////////////////////////////////////////////////////////////////////////

VS_COLOR_MODEL_OUTPUT mainColorModel( VS_MODEL_INPUT input )
{
	VS_COLOR_MODEL_OUTPUT output = ( VS_COLOR_MODEL_OUTPUT )0;

	//////////////////////////////////////////////////
	// World transform position
	//////////////////////////////////////////////////

#if ENABLE_SKINNING
	float4 pos = BoneTransformPosition( float4( input.pos, 1.0 ), input.indices, input.weights );
#else //ENABLE_SKINNING
	float4 pos = mul( float4( input.pos, 1.0f ), WORLD_MAT_4x4 );
#endif //ENABLE_SKINNING

	//////////////////////////////////////////////////
	// Output position(WVP)
	//////////////////////////////////////////////////

	output.pos = mul( pos, VIEW_PROJ_MAT_4x4 );

	//////////////////////////////////////////////////
	// Output color
	//////////////////////////////////////////////////

	output.color = input.color;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Output position(W)
	////////////////////////////////////////////////////////////////////////////////////////////////////

	output.worldPos = pos;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Output position(P)
	////////////////////////////////////////////////////////////////////////////////////////////////////

	output.projPos = output.pos;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Output tangentSpace and normal
	////////////////////////////////////////////////////////////////////////////////////////////////////

#if ENABLE_LIGHTING

	#if ENABLE_SKINNING

		#if ENABLE_BUMP
			output.tangent  = BoneTransformNormal( input.tangent,  input.indices, input.weights );
			output.binormal = BoneTransformNormal( input.binormal, input.indices, input.weights );
		#endif //ENABLE_BUMP

		output.normal = BoneTransformNormal( input.normal, input.indices, input.weights );

	#else //ENABLE_SKINNING

		#if ENABLE_BUMP
			output.tangent  = mul( input.tangent, WORLD_MAT_3x3 );
			output.binormal = mul( input.binormal, WORLD_MAT_3x3 );
		#endif //ENABLE_BUMP

		output.normal = mul( input.normal, WORLD_MAT_3x3 );

	#endif //ENABLE_SKINNING

	#if ENABLE_BUMP
		output.tangent = normalize( output.tangent );
		output.binormal = normalize( output.binormal );
	#endif //ENABLE_BUMP

	output.normal = normalize( output.normal );

	#if ENABLE_SSAO
		output.viewNormal = mul( output.normal, VIEW_MAT_3x3 );
	#endif //ENABLE_SSAO

#endif //ENABLE_LIGHTING

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Output texture
	////////////////////////////////////////////////////////////////////////////////////////////////////

#if ENABLE_TEXTURE
	output.tex = input.tex;
#endif //ENABLE_TEXTURE

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Output shadow
	////////////////////////////////////////////////////////////////////////////////////////////////////

#if ENABLE_SHADOW_RECEIVE
	output.shadowDepth = mul( pos, LIGHT_MAT_4x4 );
	output.shadowTex   = mul( pos, LIGHT_BIAS_MAT_4x4 );
#endif //ENABLE_SHADOW_RECEIVE

	return output;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function : MaskModel
////////////////////////////////////////////////////////////////////////////////////////////////////

VS_MASK_MODEL_OUTPUT mainMaskModel( VS_MODEL_INPUT input )
{
	VS_MASK_MODEL_OUTPUT output = ( VS_MASK_MODEL_OUTPUT )0;

#if ENABLE_SKINNING
	output.pos = BoneTransformPosition( float4( input.pos, 1.0 ), input.indices, input.weights );
#else //ENABLE_SKINNING
	output.pos = mul( float4( input.pos, 1.0f ), WORLD_MAT_4x4 );
#endif //ENABLE_SKINNING

	output.pos = mul( output.pos, VIEW_PROJ_MAT_4x4 );

	output.projPos = output.pos;

	return output;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function : ShadowModel
////////////////////////////////////////////////////////////////////////////////////////////////////

VS_SHADOW_MODEL_OUTPUT mainShadowModel( VS_MODEL_INPUT input )
{
	VS_SHADOW_MODEL_OUTPUT output;

#if ENABLE_SKINNING
	output.pos = BoneTransformPosition( float4( input.pos, 1.0 ), input.indices, input.weights );
#else //ENABLE_SKINNING
	output.pos = mul( float4( input.pos, 1.0f ), WORLD_MAT_4x4 );
#endif //ENABLE_SKINNING

	output.pos = mul( output.pos, LIGHT_MAT_4x4 );

	output.color = input.color;

#if ENABLE_TEXTURE
	output.tex = input.tex;
#endif //ENABLE_TEXTURE

	output.depth = output.pos;

	return output;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function : SelectModel
////////////////////////////////////////////////////////////////////////////////////////////////////

VS_SELECT_MODEL_OUTPUT mainSelectModel( VS_MODEL_INPUT input )
{
	VS_SELECT_MODEL_OUTPUT output = (VS_SELECT_MODEL_OUTPUT)0;

#if ENABLE_SKINNING
	output.pos = BoneTransformPosition( float4( input.pos, 1.0 ), input.indices, input.weights );
#else //ENABLE_SKINNING
	output.pos = mul( float4( input.pos, 1.0f ), WORLD_MAT_4x4 );
#endif //ENABLE_SKINNING

	output.pos = mul( output.pos, VIEW_PROJ_MAT_4x4 );

	return output;
}
