// Dog Ears Effect
//
// Copyright Outerspace Software, all rights reserved

string description = "This effect rotates a part of your layer like you fold the corner of a page in a book to mark where you are.";

float4x4	World;
float4x4	ViewProjection;
float4x4	WorldInverseTranspose;
float4		LightPos;
float4		EyePos;

float4		AmbientCol;
float4		DiffuseCol;
float4		SpecularCol;
float		Power = 100;

float4		MyTextureResolution0;

float PI=3.14159;

float4 Prop0
<
string UIName="Flap Position";
float UIMin=-200;
float UIMax=200;
float3 UIDefault=float3(0,20,0);
int UISliders=3;
float UIScale=1;
bool UIInteger=false;
int UIWidget=0;
> = float4(0,20,0,0);

float4 Prop1
<
string UIName="Flap Rotation";
float UIMin=-3.14;
float UIMax=3.14;
float3 UIDefault=float3(0,0,0);
int UISliders=2;
float UIScale=57.2;
bool UIInteger=false;
int UIWidget=0;
> = float4(0,0,0,0);

float4 Prop2
<
string UIName="Flap Translation";
float UIMin=-200;
float UIMax=200;
float3 UIDefault=float3(0,0,0);
int UISliders=3;
float UIScale=1;
bool UIInteger=false;
int UIWidget=0;
> = float4(0,0,0,0);

float4 Prop3
<
string UIName="Flap Rotation Centre Offset";
float UIMin=-200;
float UIMax=200;
float3 UIDefault=float3(0,0,0);
int UISliders=3;
float UIScale=1;
bool UIInteger=false;
int UIWidget=0;
> = float4(0,0,0,0);

float4 Prop4
<
string UIName="Flap Colour";
float UIMin=0;
float UIMax=1;
float3 UIDefault=float3(1,0,0);
int UISliders=3;
float UIScale=255;
bool UIInteger=true;
int UIWidget=2;
> = float4(1,0,0,1);

texture MyTexture0;
sampler MyTextureSampler0 = sampler_state
{
   Texture = <MyTexture0>;
   MinFilter = Linear;
   MagFilter = Linear;
   MipFilter = Linear;   
   AddressU  = Wrap;
   AddressV  = Wrap;
};

struct VS_INPUT{
	float4 position:	POSITION;
	float3 normal:		NORMAL;
	float3 diffuse:		COLOR;
	float2 tex:		TEXCOORD0;
};

struct VS_OUTPUT{
	float4 position:	POSITION;
	float2 tex:		TEXCOORD0;
	float4 worldpos:	TEXCOORD1;
	float4 modelpos:	TEXCOORD2;
	float3 normal:		TEXCOORD3;	
};

struct PS_OUTPUT{
    float4 color:		COLOR;
};

VS_OUTPUT GetPos(VS_INPUT input, float inAngle){
	VS_OUTPUT output;      
	
	float4 pos1;
	float4 pos2;

	pos1.xyz = input.position.xyz - (Prop3.xyz + Prop0.xyz);
	pos1.w=1;

	pos2.x = pos1.x*cos(Prop1.y) - pos1.y*sin(Prop1.y);
	pos2.y = pos1.x*sin(Prop1.y) + pos1.y*cos(Prop1.y);
	pos2.z = pos1.z;
	pos2.w = 1;

	pos1.x = pos2.x;
	pos1.y = pos2.y*cos(inAngle) - pos2.z*sin(inAngle);
	pos1.z = pos2.y*sin(inAngle) + pos2.z*cos(inAngle);
	pos1.w = 1;

	pos2.x = pos1.x*cos(-Prop1.y) - pos1.y*sin(-Prop1.y);
	pos2.y = pos1.x*sin(-Prop1.y) + pos1.y*cos(-Prop1.y);
	pos2.z = pos1.z;
	pos2.w = 1;

	pos1.xyz = pos2.xyz + (Prop3.xyz + Prop0.xyz) + Prop2.xyz;
	pos1.w=1;

	pos2 = mul(pos1, World);

	output.worldpos = pos2;
	output.position = mul(pos2, ViewProjection);

	output.tex = input.tex;
	output.modelpos = input.position;

	pos2.x = input.normal.x*cos(Prop1.y) - input.normal.y*sin(Prop1.y);
	pos2.y = input.normal.x*sin(Prop1.y) + input.normal.y*cos(Prop1.y);
	pos2.z = input.normal.z;

	pos1.x = pos2.x;
	pos1.y = pos2.y*cos(inAngle) - pos2.z*sin(inAngle);
	pos1.z = pos2.y*sin(inAngle) + pos2.z*cos(inAngle);

	pos2.x = pos1.x*cos(-Prop1.y) - pos1.y*sin(-Prop1.y);
	pos2.y = pos1.x*sin(-Prop1.y) + pos1.y*cos(-Prop1.y);
	pos2.z = pos1.z;

	output.normal = normalize(mul(pos2,WorldInverseTranspose));
	return output;
}

VS_OUTPUT VS1(VS_INPUT input){
	VS_OUTPUT output;
	float4 pos = mul(input.position, World);
	output.worldpos=pos; 
	output.position = mul(pos, ViewProjection);
	output.tex = input.tex;
	output.modelpos = input.position;
	output.normal = normalize(mul(input.normal,WorldInverseTranspose));
	return output;
}

VS_OUTPUT VS2(VS_INPUT input){
	return GetPos(input,-Prop1.x);
}

float4 GetColour(VS_OUTPUT input, float4 inDiffuseColour){
	float3 NormalVector		= normalize(input.normal);
	float3 LightVector		= normalize(LightPos - input.worldpos);
	float3 EyeVector		= normalize(EyePos   - input.worldpos);
	float3 LightReflectionVector	= -reflect(LightVector,NormalVector);

	//ambient component
	float4 c=AmbientCol;

	//diffuse component
	c += inDiffuseColour * saturate(dot(NormalVector, LightVector));

	//specular component
	c += SpecularCol * pow(saturate(dot(EyeVector, LightReflectionVector)),Power);
	
	c.w = DiffuseCol.w;
	return c;
}

PS_OUTPUT PS1(VS_OUTPUT input){
	PS_OUTPUT output;

	float4 c=GetColour(input,DiffuseCol);
	if(MyTextureResolution0.x>0) c*=tex2D(MyTextureSampler0, input.tex);

	float2 pos=input.modelpos.xy - Prop0.xy;
	float y = pos.x*sin(Prop1.y) + pos.y*cos(Prop1.y);
	if(y>0) c.w=0;

	output.color = c;
	return output;
}

PS_OUTPUT PS2(VS_OUTPUT input){
	PS_OUTPUT output;

	float4 c=DiffuseCol;
	c.xyz=Prop4.xyz;

	c=GetColour(input,c);
	if(MyTextureResolution0.x>0) c*=tex2D(MyTextureSampler0, input.tex);

	float2 pos=input.modelpos.xy - Prop0.xy;
	float y = pos.x*sin(Prop1.y) + pos.y*cos(Prop1.y);
	if(y<0) c.w=0;

	output.color = c;
	return output;
}

technique Shader
{
    pass P1
    {
	Alphablendenable= TRUE;
	SRCBLEND	= SRCALPHA;
	DESTBLEND	= INVSRCALPHA;
	ALPHAARG1[0]	= DIFFUSE;
	ALPHAOP[0]	= SELECTARG1;
	ALPHATESTENABLE	= TRUE;
	ALPHAREF	= 1;
	ALPHAFUNC	= GREATEREQUAL;
	CullMode	= CCW;
	ZFUNC		= LESSEQUAL;
		
        VertexShader	= compile vs_1_1 VS1();
        PixelShader	= compile ps_2_0 PS1();
    }
    pass P2
    {
        VertexShader	= compile vs_1_1 VS2();
        PixelShader	= compile ps_2_0 PS2();
    }
}
