////////////////////////////////////////////////////////////
// Standard Include Functions for Shaders
// Ben Smith
// Jan 26th, 2006
////////////////////////////////////////////////////////////

//Shared constants
/*shared float4x4 View : VIEW;
shared float4x4 ViewProjection : VIEWPROJECTION;
shared float4x4 Projection : PROJECTION;
shared float3   CameraEye;
shared float3   CameraView;
shared float2   ScreenDims;
shared float3   LightDir;
shared float4x4 Billboard;*/

//Shared Constants
shared float3   CameraEye;
shared float3   CameraSide;
shared float3   CameraUp;
shared float3   mDiffuse;
shared float3   mSpecular;
shared float3   mEmissive;
shared float    mPower;
shared float	mAlpha;
shared texture  Tex;
shared float3   CameraView;
shared float3   LightDir;
shared float4x4 ViewProjection : VIEWPROJECTION;
shared float4x4 Projection : PROJECTION;
shared float4x4 Billboard;




float3 PhongVertexLighting(float4 vertexModel, float3 normalModel, float4x4 worldMat,
	float3 camEye, float3 lightDir, float3 mDiffuse, float3 mSpecular, float3 mEmissive, float mPower)
{
	//Transform normal to world space and normalize
    float3 nNormal = normalize(mul(normalModel,(float3x3)worldMat));
    
    //Camera's View Vector
    float3 camView = normalize(camEye - mul(vertexModel,worldMat));
    
    //Diffuse component
    float diffuseI  = saturate(dot(nNormal,-lightDir));
    
    //R = 2* (N.L) * N - L; // why can't you use the half-way vector here ben?
    float3 reflect = normalize(2*diffuseI*nNormal-lightDir);
    
    //S = R.V^n
    float  specularI = pow(saturate(dot(reflect,camView)),mPower);
    
    float3 color = mSpecular*specularI + mDiffuse*diffuseI + mEmissive;
    return color;
}

float3x3 QuaternionToMatrix(float4 q)
{
	float3x3 o = (float3x3)0;
	float s = q.x, x = q.y, y = q.z, z = q.w;
	
	o[0][0] = 1.0 - 2.0*y*y - 2.0*z*z;
	o[1][0] = 2.0*x*y - 2.0*s*z;
	o[2][0] = 2.0*x*z + 2.0*s*y;
	o[0][1] = 2.0*x*y + 2.0*s*z;
	o[1][1] = 1.0 - 2.0*x*x - 2.0*z*z;
	o[2][1] = 2.0*y*z - 2.0*s*x;
	o[0][2] = 2.0*x*z - 2.0*s*y;
	o[1][2] = 2.0*y*z + 2.0*s*x;
	o[2][2] = 1.0 - 2.0*x*x - 2.0*y*y;
	
	return o;
}