//
// Standard lighting
// Atmosphere & single texture
//

#include "atmosphere.cg"
#include "lighting.cg"

#define MAX_MATRICES 225 // defined in source code, max 75 bones per skeleton * 3 rows per matrix

// App to vertex
struct a2v
{
  float4 Position   : POSITION;
  float3 normal     : NORMAL;
  float2 tc0        : TEXCOORD0;
  float4 boneWeights: TEXCOORD6;
  float4 boneIndexes: TEXCOORD7;  
};

// Vertex to pixel shader structure
struct v2p
{
  float4 Position       : POSITION;
  float4 FPosition			: TEXCOORD4;    // For fragment shader
  float3 normal         : TEXCOORD5;
  float4 RayleighColor  : TEXCOORD2;
  float4 MieColor       : TEXCOORD3;
  float2 tc0            : TEXCOORD0;
  float3 Direction		  : TEXCOORD1;
  float  extinction		  : TEXCOORD6;
  float3  Color		      : COLOR;
};

void main(
  // a2v
  in  a2v IN,
  out v2p OUT,

  // Constants
  uniform float4x4 modelViewProj,
  uniform float4x4 modelMatrix,
  //uniform float4x4 modelView,
  uniform float3   lightDirection,
  uniform float3   eyePosW,
  uniform float3   lightColor,
  // Animation
  uniform float4   boneMatrixArray[MAX_MATRICES],
  // Atmosphere
  uniform float    sunIntensity,
  uniform float    atmosRayleigh,
  uniform float    atmosMie,
  uniform float    extinctionFactor
)
{

  // skinning
  float index;
  float3 netPosition =0, netNormal = 0, bonePosition;
  float3x3 rotate;
  float3x4 model;
  
  for(int i = 0; i < 4; ++i)
  {
    index = IN.boneIndexes[i];
    model = float3x4(  boneMatrixArray[index+0],
                       boneMatrixArray[index+1],
                       boneMatrixArray[index+2]);
                                
    bonePosition = mul(model, float4(IN.Position.xyz, 1));
    
    rotate = float3x3( model[0].xyz,
                       model[1].xyz,
                       model[2].xyz);
    
    netPosition += IN.boneWeights[i] * bonePosition;
    netNormal += IN.boneWeights[i] * mul(rotate, IN.normal);
  }
  
  // Transform to clipspace
  OUT.FPosition.xyz=mul(modelMatrix,float4(netPosition,1)).xyz;
  OUT.Position=mul(modelViewProj,float4(netPosition,1));
  netPosition=OUT.Position.xyz;
  OUT.normal=normalize(netNormal);
  netNormal=normalize(mul((float3x3)modelMatrix,normalize(netNormal)));
 
  
  // Atmosphere
  CalculateAtmosphere(atmosRayleigh,atmosMie,sunIntensity,eyePosW,netPosition.xyz,lightDirection,
    OUT.RayleighColor,OUT.MieColor,OUT.Direction);

  // Extinction factor of regular color
  OUT.extinction=CalculateAtmosphereExtinction(netPosition.xyz,atmosRayleigh,atmosMie,extinctionFactor);
  
  
  // Pass texcoords and such
  OUT.tc0=IN.tc0;
  OUT.normal=netNormal;
}
