/*******************************************************************/
/*                                                                 */
/*                      ADOBE CONFIDENTIAL                         */
/*                   _ _ _ _ _ _ _ _ _ _ _ _ _                     */
/*                                                                 */
/* Copyright 2004 Adobe Systems Incorporated                       */
/* All Rights Reserved.                                            */
/*                                                                 */
/* NOTICE:  All information contained herein is, and remains the   */
/* property of Adobe Systems Incorporated and its suppliers, if    */
/* any.  The intellectual and technical concepts contained         */
/* herein are proprietary to Adobe Systems Incorporated and its    */
/* suppliers and may be covered by U.S. and Foreign Patents,       */
/* patents in process, and are protected by trade secret or        */
/* copyright law.  Dissemination of this information or            */
/* reproduction of this material is strictly forbidden unless      */
/* prior written permission is obtained from Adobe Systems         */
/* Incorporated.                                                   */
/*                                                                 */
/*******************************************************************/


/*
**-----------------------------------------------------------------------------
** Effect File Variables
**-----------------------------------------------------------------------------
*/

uniform float4x4	gWorldViewProj : WorldViewProjection; // This matrix will be loaded by the application
uniform float4x4	gWorldViewInverse;
uniform float4x4	gWorldView;
uniform float4		gLightPosition;
uniform float4		gLightColor = float4(0.8,0.8,0.8,1.0);
uniform float		gCurrentParameter;
uniform float		gAspectRatio;
uniform float		gPAR;
uniform float		gTranslateX;
uniform float		gTranslateY;
uniform float4		gEyePosition;
uniform float		gPI;
texture				gVideoTexture;

uniform float4		gC1;
uniform float4		gC2;
uniform float4		gC3;
uniform float4		gC4;
uniform float4		gC5;
uniform float4		gC6;
uniform float4		gC7;
uniform float4		gC8;
uniform float4		gC9;
uniform float		dir;

/*
**-----------------------------------------
**		Sampler States
**-----------------------------------------
*/
//incoming video texture
sampler Sampler = sampler_state
{
    Texture   = (gVideoTexture);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

/*
**-----------------------------------------------------------------------------
** Vertex Definitions
**-----------------------------------------------------------------------------
** APP_OUTPUT is the structure in which we receive the vertices from the application
*/
struct APP_OUTPUT
{
    float3 mPosition	: POSITION;
	float3 mNormal		: NORMAL;
	float2 mTexCoord	: TEXCOORD0;
	
};

/* 
** Pixel Shader structure declaration (For Foreground mesh)
*/

struct VS_OUTPUT 
{
  float4 mHPosition		: POSITION;		// coord position in window
  float2 mTexcoord		: TEXCOORD0;	// wavy or fleck map texture coordinates
  float3 mLightVec		: TEXCOORD1;	// position of light relative to point
  float3 mHalfVec		: TEXCOORD2;	// Blinn halfangle
  float3 mNormal		: TEXCOORD3;
};

/* 
** Pixel Shader structure declaration (For Background Mesh)
*/
struct PLAIN_VS_OUTPUT 
{
	float4 mHPosition		: POSITION;		// coord position in window
	float2 mTexcoord		: TEXCOORD0;	// texture coordinates
};

/*
** TEMP_OUT is a temporary structure for the DoSphereCurl function
*/
struct TEMP_OUT
{
	float4 mPosition	: POSITION;
	float3 mNormal		: NORMAL0;
};

/*
**------------------------------------------------
**		Sphere Morphing Effect
**------------------------------------------------
*/
TEMP_OUT DoSphereCurl( float3 position)
{
	TEMP_OUT returnVertex;
	float dist, radius, tempFrameAspectRatio, tempPixelAspectRatio;
	float3 tempVertex;
	
	returnVertex.mPosition = float4(position,1.0f);
	//[NOTE]	ayusman	06/09/2004
	//Use the constants passed from the application to approximate a square to a circle using Quadratic bezier curve.
	//f(u,v) = v*v(gC1*u*u+gC2*u+gC3)+2*v(gC4*u*u+gC5*u+gC6)+(gC7*u*u+gC8*u+gC9) where u,v belongs to [0,1].
	//gC1-gC9 are the constants which are calculated from 8 control points in the application.
	returnVertex.mPosition.xy = float2((position.y*position.y)*((gC1.x)*(position.x*position.x)+(gC2.x)*position.x+gC3.x),(position.y*position.y)*((gC1.y)*(position.x*position.x)+(gC2.y)*position.x+gC3.y));
	returnVertex.mPosition.xy+=float2(((2*position.y)*((gC4.x)*position.x*position.x+(gC5.x)*position.x+(gC6.x))),((2*position.y)*((gC4.y)*position.x*position.x+(gC5.y)*position.x+(gC6.y))));
	returnVertex.mPosition.xy+=float2(((gC7.x)*position.x*position.x+(gC8.x)*position.x+(gC9.x)),((gC7.y)*position.x*position.x+(gC8.y)*position.x+(gC9.y)));
	//translate the model to be centered around the origin
	returnVertex.mPosition.xy -= 0.5f;	
	//Scale it to fit the screen
	returnVertex.mPosition.xy *= 4;
	//Model width = 4 and height = 4. So radius is sqrt(8)= 2.82843
	radius =  2.82843;
	dist = length(returnVertex.mPosition.xy);
	tempVertex = returnVertex.mPosition;

	//[NOTE]	ayusman	06/09/2004
	//As we are only approximating a square to a circle, we dont get a perfect circle.
	radius = radius - 0.065;
	if( dist < radius)
	{
		float sinVal, cosVal,theta;
		theta = (dist*gPI)/(radius*2);
		sincos(theta, sinVal, cosVal);
		if(dist != 0.0005)
		{
			tempVertex =  returnVertex.mPosition*radius*sinVal/dist;
		}
		tempVertex.z = -(dir)*radius *cosVal;
	}
	else
	{
		tempVertex =  returnVertex.mPosition*radius/dist;
	}
	returnVertex.mPosition.xyz = lerp(returnVertex.mPosition.xyz, tempVertex, gCurrentParameter);	
	returnVertex.mNormal = lerp(float3(0.0f, 0.0f, dir), (normalize(float3(tempVertex.xy,-tempVertex.z))),  gCurrentParameter);		
	tempFrameAspectRatio = lerp(gAspectRatio,1.0f,gCurrentParameter);
	tempPixelAspectRatio = lerp(1.0f,gPAR,gCurrentParameter);
	returnVertex.mPosition.x*= (tempFrameAspectRatio/tempPixelAspectRatio);

	return returnVertex;
}

/*
**-------------------------------------------------------------------------
** Sphere Transition effect - Vertex Shader(For Foreground Mesh)
**-------------------------------------------------------------------------
*/
VS_OUTPUT sphere_transition_vs(APP_OUTPUT In)
{
    VS_OUTPUT Out;

    // copy texture coordinates
	Out.mTexcoord.xy = In.mTexCoord.xy;
    
    TEMP_OUT tempVertex = DoSphereCurl(float3(In.mPosition.xyz));
	
	// transform vertex position into homogenous clip-space
    Out.mHPosition = mul(gWorldViewProj, tempVertex.mPosition);
	//[NOTE]	ayusman	07/28/2004
	//Translating by a factor to take care of DirectX error which shifts by half pixel
	Out.mHPosition.xy -= float2( gTranslateX, -gTranslateY );
    
    // store light vector
    Out.mLightVec = gLightPosition.xyz;
   
   	//compute the half vector    
    Out.mHalfVec = normalize(Out.mLightVec + gEyePosition);
	Out.mHalfVec.z = dot( tempVertex.mNormal, Out.mHalfVec );
	
	//Clamping the normal to [0,1] as ps1.3 clamps vectors to [0,1]
	Out.mNormal = 0.5 * tempVertex.mNormal + 0.5;
	Out.mLightVec = 0.5 * Out.mLightVec + 0.5;

	return Out;
}
/*
**-------------------------------------------------------------------------
** Sphere Transition effect - pixel Shader 1_3(For Foreground Mesh)
**-------------------------------------------------------------------------
*/

float4 sphere_transition_ps_1_3(VS_OUTPUT In) : COLOR
{   
	float4 outColor, color1;
	float diffuse, specular,ambient=0.20f;
	
	color1 = tex2D( Sampler, In.mTexcoord );
	//Getting back the original normal and LightVector
	In.mNormal = 2 *(In.mNormal - 0.5f);
	In.mLightVec = 2 *(In.mLightVec - 0.5f);
	
	diffuse = dot ( In.mNormal, In.mLightVec );
	specular = In.mHalfVec.z;
	specular *= specular;
	specular *= specular;
	specular *= specular;
	
	outColor.xyz = color1*(diffuse+ambient)+ (specular)*color1*float3(0.45,0.45,0.45);
	outColor.a = color1.a;
	
    return outColor;
}

/*
**-------------------------------------------------------------------------
** Sphere Transition effect - Plain Vertex Shader(For Background Mesh)
**-------------------------------------------------------------------------
*/
PLAIN_VS_OUTPUT sphere_transition_vs_plain(APP_OUTPUT In)
{
	PLAIN_VS_OUTPUT Out;

	// copy texture coordinates
	Out.mTexcoord.xy = In.mTexCoord.xy;
	
	// transform vertex position into homogenous clip-space
	Out.mHPosition = mul(gWorldViewProj,float4(In.mPosition.x*gAspectRatio,In.mPosition.y,In.mPosition.z,1.0f));
	
	//[NOTE]	ayusman	07/28/2004
	//Translating by a factor to take care of DirectX error which shifts by half pixel
	Out.mHPosition.xy -= float2( gTranslateX, -gTranslateY );
	return Out;
}


/*
**-------------------------------------------------------------------------
** Sphere Transition effect - Plain Pixel Shader 1_3(For Background Mesh)
**-------------------------------------------------------------------------
*/

float4 sphere_transition_ps_1_3_plain(PLAIN_VS_OUTPUT In) : COLOR
{   
	float4 color1 = tex2D( Sampler, In.mTexcoord );
	return color1;
}

technique sphere_transition_1_3
{
    pass Pass0
    {
		//For Background Mesh (SourceB Video)
		Sampler[0] = (Sampler); 
		VertexShader = compile vs_1_1 sphere_transition_vs_plain();
		PixelShader  = compile ps_1_3 sphere_transition_ps_1_3_plain();
		
    }
    pass Pass1
    {
		//For Foreground Mesh (SourceA Video)
		Sampler[0] = (Sampler); 
		VertexShader = compile vs_1_1 sphere_transition_vs();
		PixelShader  = compile ps_1_3 sphere_transition_ps_1_3();
    }
}
