/*******************************************************************/
/*                                                                 */
/* Module: flora_common.cg                                         */
/*                                                                 */
/* Author: John Buckley                                            */
/*                                                                 */
/* Description:                                                    */
/*                                                                 */
/*   Flora Material Class - Common Routines                        */
/*                                                                 */
/* Copyright 2005 Sony Online Entertainment.  All rights reserved. */
/*                                                                 */
/*******************************************************************/

/* Defines */

#define FLORA_ALPHASTARTDIST 10.0f
#define FLORA_ALPHAENDDIST   40.0f
#define FLORA_WORLDNORMAL    { 0.0f, 1.0f, 0.0f }
#define FLORA_WINDDIR1       { 1.0f, 0.0f, 0.0f }
#define FLORA_WINDDIR2       { 0.707f, 0.0f, 0.707f }
#define FLORA_WINDMAGN       { 0.075f, 0.03f }

/* Input Vertex Formats */

struct Vertex_Flora
 {
  float4 Pos       : POSITION;
  //float2 UV0       : TEXCOORD0;
 };

/* Fragment Vertex Formats */

struct Fragment_Flora
 {
  float4 Pos        : POSITION;
  float2 ColorUV    : TEXCOORD0; 
  float4 Diff       : COLOR0;
  float  FogDepth   : FOG; 
 };

/**********************************/
/* ComputeSunVertexLighting       */
/**********************************/

float3 ComputeSunVertexLighting(
        float3 SunDir,
        float4 SunColor,
        float3 WorldNormal )
 {
  float3 Color;

  Color.rgb = -min( dot( WorldNormal, SunDir ), 0.0f ) * SunColor.rgb;

  return(Color);
 }

/**********************************/
/* ComputePL4VertexLighting       */
/**********************************/

float3 ComputePL4VertexLighting(
        float3 WorldPos,
        float3 WorldNormal,
        float4 LightPLLoc[4],
        float4 LightPLColor[4] )
 {
  float4 Color;
  float3 Diff1, Diff2, Diff3, Diff4;
  float4 Dot;
  float4 Dist, RDist;
  float4 Atten;
  
  Diff1 = WorldPos - LightPLLoc[0].xyz;     // Diff
  Diff2 = WorldPos - LightPLLoc[1].xyz;
  Diff3 = WorldPos - LightPLLoc[2].xyz;
  Diff4 = WorldPos - LightPLLoc[3].xyz;

  Dot.x = dot( Diff1, WorldNormal );  // Vertex Normal * Diff
  Dot.y = dot( Diff2, WorldNormal );
  Dot.z = dot( Diff3, WorldNormal );
  Dot.w = dot( Diff4, WorldNormal );
  Dot   = min( float4( 0.0f, 0.0f, 0.0f, 0.0f ), Dot );  

  Dist.x = dot( Diff1, Diff1 );       // Dist^2
  Dist.y = dot( Diff2, Diff2 );
  Dist.z = dot( Diff3, Diff3 );
  Dist.w = dot( Diff4, Diff4 );

  RDist  = rsqrt( Dist );             // 1 / Dist
  Dist  *= RDist;                     // Dist = Dist^2 / Dist  

  float4 LightPLRRadius = float4(LightPLLoc[0].w, LightPLLoc[1].w, LightPLLoc[2].w, LightPLLoc[3].w);
  
  Atten  = Dist * LightPLRRadius;     // Dist / Radius
  Atten  = 1.0f - Atten;              // 1.0f - Dist / Radius
  Atten  = min( Atten, 1.0f );        // Clamp between 0 and 1
  Atten  = max( Atten, 0.0f );
  
  Dot   *= RDist;                     // Vertex Normal * Normalized Diff

  Atten  = -Dot * Atten;              // (-Vertex Normal * NormalizedDiff) * Atten

  Color  = (Atten.x * LightPLColor[0]);
  Color += (Atten.y * LightPLColor[1]);
  Color += (Atten.z * LightPLColor[2]);
  Color += (Atten.w * LightPLColor[3]);

  return Color.rgb;
 }

/**********************************/
/* CalcVertexAnim                 */
/**********************************/

float3 CalcVertexAnim(float3 Pos, 
                      float  VertexAnimScale, 
                      float3 WindDir1, 
                      float3 WindDir2,
                      float2 WindMagn,
                      float2 Sway )
 {
  float2 Anim;
  float3 VertexAnim;

  Anim.x      = dot(Pos.xyz, WindDir1);
  Anim.y      = dot(Pos.xyz, WindDir2);
  Anim        = frac(Anim + Sway);
  Anim        = sin((Anim - 0.5f) * 2.0f * 3.1415f);
  Anim       *= WindMagn;
  VertexAnim  = (WindDir1 * Anim.x * VertexAnimScale);
  VertexAnim += (WindDir2 * Anim.y * VertexAnimScale);

  return VertexAnim;
 }

/* End of File */

