// Software vertex shader generated by Wild Magic.
//
// var float3   kModelPosition $vin.POSITION
// var float3   kModelNormal   $vin.NORMAL
// var float4   kClipPosition  $vout.POSITION
// var float2   kBaseTCoord    $vout.TEXCOORD0
// var float4x4 WVPMatrix      c[0]
// var float4x4 WVMatrix       c[4]

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

namespace Wm4
{

void v_SphereMap (const float* afRegister, const float* afInVertex,
    float* afOutVertex)
{
    // Get the register items.
    const Matrix4f& rkWVPMatrix = *(const Matrix4f*)&afRegister[0];
    const Matrix4f& rkWVMatrix = *(const Matrix4f*)&afRegister[16];

    // Get the input items.
    Vector4f kModelPosition(afInVertex[0],afInVertex[1],afInVertex[2],1.0f);
    Vector4f kModelNormal(afInVertex[3],afInVertex[4],afInVertex[5],0.0f);

    // Access the output items.
    Vector4f& rkClipPosition = *(Vector4f*)&afOutVertex[0];
    Vector2f& rkBaseTCoord = *(Vector2f*)&afOutVertex[4];

    // *** program ***

    // Transform the position from model space to clip space.
    rkClipPosition = kModelPosition*rkWVPMatrix;

    // Transform the normal from model space to eye space.
    Vector3f kESNormal = (Vector3f)(kModelNormal*rkWVMatrix);
    kESNormal.Normalize();

    // Calculate the eye direction (in eye space).
    Vector3f kEyeDirection = (Vector3f)(kModelPosition*rkWVMatrix);
    kEyeDirection.Normalize();

    // Calculate the reflection vector.
    float fDot = kEyeDirection.Dot(kESNormal);
    Vector3f kReflection = Reflect(kEyeDirection,kESNormal);

    // Calculate the texture coordinates.
    float fOmRz = kReflection.Z() - 1.0f;
    float fInvM = Mathf::InvSqrt(kReflection.X()*kReflection.X() +
        kReflection.Y()*kReflection.Y() + fOmRz*fOmRz);
    rkBaseTCoord.X() = 0.5f*(kReflection.X()*fInvM + 1.0f);
    rkBaseTCoord.Y() = 0.5f*(kReflection.Y()*fInvM + 1.0f);
}

WM4_IMPLEMENT_VPROGRAM(SphereMap);
WM4_REGISTER_VPROGRAM(SphereMap);

}
