// Software vertex shader generated by Wild Magic.
//
// var float3   kModelPosition        $vin.POSITION
// var float3   kModelNormal          $vin.NORMAL
// var float2   kInBaseTCoord         $vin.TEXCOORD0
// var float4   kClipPosition         $vout.POSITION
// var float2   kOutBaseTCoord        $vout.TEXCOORD0
// var float    fOutInterpolateFactor $vout.TEXCOORD1
// var float3   kWorldNormal          $vout.TEXCOORD2
// var float3   kEyeDirection         $vout.TEXCOORD3
// var float4x4 WVPMatrix             c[0]
// var float4x4 WMatrix               c[4]
// var float3   CameraWorldPosition   c[8]
// var float    InterpolateFactor     c[9]

#include "Wm4SoftRenderer.h"
#include "Wm4Matrix4.h"
#include "Wm4Vector3.h"

namespace Wm4
{

void v_Iridescence (const float* afRegister, const float* afInVertex,
    float* afOutVertex)
{
    // Get the register items.
    const Matrix4f& rkWVPMatrix = *(const Matrix4f*)&afRegister[0];
    const Matrix4f& rkWMatrix = *(const Matrix4f*)&afRegister[16];
    const Vector3f& rkCameraWorldPosition =
        *(const Vector3f*)&afRegister[32];
    float fInterpolateFactor = afRegister[36];

    // Get the input items.
    Vector4f kModelPosition(afInVertex[0],afInVertex[1],afInVertex[2],1.0f);
    Vector4f kModelNormal(afInVertex[3],afInVertex[4],afInVertex[5],0.0f);
    const Vector2f& rkInBaseTCoord = *(const Vector2f*)&afInVertex[6];

    // Access the output items.
    Vector4f& rkClipPosition = *(Vector4f*)&afOutVertex[0];
    Vector2f& rkOutBaseTCoord = *(Vector2f*)&afOutVertex[4];
    float& rfOutInterpolateFactor = afOutVertex[6];
    Vector3f& rkWorldNormal = *(Vector3f*)&afOutVertex[7];
    Vector3f& rkEyeDirection = *(Vector3f*)&afOutVertex[10];

    // *** program ***

    // Transform the position from model space to clip space.
    rkClipPosition = kModelPosition*rkWVPMatrix;
    
    // Transform the position from model space to world space.
    Vector3f kWorldPosition = (Vector3f)(kModelPosition*rkWMatrix);

    // Transform the normal from model space to world space.  In case the
    // model-to-world matrix has nonunit scales, the resulting vector must
    // be normalized.
    rkWorldNormal = (Vector3f)(kModelNormal*rkWMatrix);
    rkWorldNormal.Normalize();

    // Calculate the incident direction.
    rkEyeDirection = kWorldPosition - rkCameraWorldPosition;
    rkEyeDirection.Normalize();

    // Pass through the base texture coordinate.
    rkOutBaseTCoord = rkInBaseTCoord;

    // Pass through the interpolation factor.
    rfOutInterpolateFactor = fInterpolateFactor;
}

WM4_IMPLEMENT_VPROGRAM(Iridescence);
WM4_REGISTER_VPROGRAM(Iridescence);

}
