
void main(
           float4 position : POSITION ,
	   float4 texCoord : ATTR1,
	   float3 normal : ATTR2,
	   float3 tangent0 : ATTR3,
           float3 tangent1 : ATTR4,
           float4 color : ATTR5,
           uniform float4 lightOrigin,
	   uniform float4 viewOrigin,
           uniform float4 lightProjectS,
           uniform float4 lightProjectT,
	   uniform float4 lightProjectQ,
           uniform float4 lightFalloffS,
	   uniform float4 bumpMatrixS,
	   uniform float4 bumpMatrixT,
	   uniform float4 diffuseMatrixS,
	   uniform float4 diffuseMatrixT,
	   uniform float4 specularMatrixS,
	   uniform float4 specularMatrixT,
	   uniform float4 colorModulate,
           uniform float4 colorAdd,
	   out float3 lightVector   : TEXCOORD0,
 	   out float2 bumpST	    : TEXCOORD1,
	   out float2 lightFalloff  : TEXCOORD2,
           out float3 lightProjection : TEXCOORD3,
	   out float2 diffuseST       : TEXCOORD4,
           out float2 specularST      : TEXCOORD5,
	   out float3 halfAngleVector : TEXCOORD6,
           out float4 primaryColor    : COL0,
           out float4 hpos            : POSITION )
{
  // normal map texgen
  bumpST = mul( float2x4( bumpMatrixS, bumpMatrixT ), texCoord );

  // light falloff texgen
  lightFalloff.x = dot( lightFalloffS, position );
  lightFalloff.y = 0.5;
  
  // light projection texgen
  lightProjection = mul( float3x4( lightProjectS, lightProjectT, lightProjectQ ), position );

  // diffuse map texgen
  diffuseST = mul( float2x4( diffuseMatrixS, diffuseMatrixT ), texCoord );

  // specular map texgen
  specularST = mul( float2x4( specularMatrixS, specularMatrixT ), texCoord );

  // light and halfangle vectors
  float3x3 TBN = float3x3( tangent0, tangent1, normal );
  
  float3 L = lightOrigin.xyz - position.xyz;
  float3 V = viewOrigin.xyz - position.xyz;
  float3 H = normalize(L) + normalize(V);

  lightVector =     mul( TBN, L );
  halfAngleVector = mul( TBN, H );


  // primary color
  primaryColor = color * colorModulate + colorAdd;

  // position
  hpos = mul(glstate.matrix.mvp, position); 
}
