#ifndef __TRANSFORMS__HLSL__
#define __TRANSFORMS__HLSL__

#include "Uniforms.hlsl"

#if NbBonesPerVertex > 0

float4x3 GetWorldTransform(float4 BlendWeights, float4 BlendIndices, uniform int iNbBonesPerPertex)
{
    float4x3 BoneTransform = (float4x3)0;

    int4 indices = D3DCOLORtoUBYTE4(BlendIndices);
    // Calculate normalized fourth bone weight
    BlendWeights[iNbBonesPerPertex-1] = 1;

    for (int i=0; i<iNbBonesPerPertex-1; ++i)
    {
        BlendWeights[iNbBonesPerPertex-1] -= BlendWeights[i];
    }

    // Calculate bone transform
    for (int i=0; i<iNbBonesPerPertex; ++i)
    {
        BoneTransform += BlendWeights[i] * SkinBoneMatrix3[indices[i]];
    }

    return BoneTransform;
}
#endif

float4x3 GetWorldTransform(VS_INPUT In)
{
    float4x3 BoneTransform = (float4x3)0;

#if NbBonesPerVertex > 0
    BoneTransform = GetWorldTransform(In.BlendWeights, In.BlendIndices, NbBonesPerVertex);
#else
    BoneTransform = World;
#endif
    return BoneTransform;
}

float4x4 GetWorldViewProjTransform(VS_INPUT In)
{
    float4x4 BoneTransform = (float4x4)0;

#if NbBonesPerVertex > 0
    BoneTransform = mul( float4x4( GetWorldTransform(In)[0].xyz, 0.0f,
                                   GetWorldTransform(In)[1].xyz, 0.0f,
                                   GetWorldTransform(In)[2].xyz, 0.0f,
                                   GetWorldTransform(In)[3].xyz, 1.0f), ViewProj ) ;
#else
    BoneTransform = WorldViewProj;
#endif
    return BoneTransform;
}

float3 OffsetCorrection(float3 vWSPos, float3 vNormal, float fOffset)
{
    //If the offset is along the normal, this code below can be use
    /*float3 vViewDir = normalize(vWSPos - EyePos);    
    //Compute plan equation
    float4 vPlan = float4(vNormal, dot(-vNormal, vWSPos));
    float fDenominator = dot(dot(vPlan.xyz, vPlan.xyz),float3(1.0f,1.0f,1.0));
    //Compute amout of view direction vector to be on the offset plan
    vPoint = vWSPos + vViewDir;
    vProjPoint = vPoint - vPlan.xyz * (dot(float4(vPoint,1.0f), vPlan) / fDenominator);
    float fRatio = -fOffset/length(vViewDir-(vProjPoint-vWSPos));
    //Compute final position
    return vWSPos + vViewDir * fRatio;*/


    //Tweak if offset is vertical and not along the normal
    /*float3 vViewDir = normalize(vWSPos - EyePos);    
    float fRatio = fOffset/vViewDir.z;
    return vWSPos + vViewDir * float3(fRatio,fRatio,-fRatio);*/

    float3 vPointOnPlan = vWSPos - float3(0.0f, 0.0f, fOffset);
    float4 vPlan = float4(vNormal, dot(-vNormal, vPointOnPlan));

    float3 vViewDir = normalize(vWSPos - EyePos);
    float fSolve = dot(vWSPos, -vPlan.xyz) - vPlan.w;
    float fDenominator = dot(vPlan.xyz,vViewDir);

    float3 vIntersection = vWSPos + (fSolve/fDenominator) * vViewDir;
    return vIntersection;
}

#endif
