#define	GLSL_DEFORM_EXPAND	1.0
#define	GLSL_DEFORM_WAVE	2.0
#define	GLSL_DEFORM_BULGE	3.0
#define	GLSL_DEFORM_MOVE	4.0

#define	GF_NONE			0.0
#define	GF_SIN			1.0
#define	GF_SQUARE		2.0
#define	GF_TRIANGLE		3.0
#define	GF_SAWTOOTH		4.0
#define	GF_INVERSE_SAWTOOTH	5.0

in	vec3	attr_Position;
in	vec3	attr_Position2;
in	vec4	attr_Color;
in	vec2	attr_texCoords;
in	vec2	attr_lightCoords;
in	vec3	attr_Normal;

uniform	float	u_deformParms[19];	// MAX_SHADER_DEFORMS * 5 + MAX_SHADER_DEFORMS + 1
uniform	float	u_backlerp;
uniform vec4	u_instanceParms;	// for instances only (u_backlerp < 0.0) = vec4(vec3(clientOrigin), distanceCull)

float TABLE(in float table, in float v)
{
	if (table == GF_SIN)
		return sin(v);
	if (table == GF_SQUARE)
		return sign(sin(v));
	if (table == GF_TRIANGLE)
		return max(1.0 - abs(v), 0.0);
	if (table == GF_SAWTOOTH)
		return v - floor(v);
	if (table == GF_INVERSE_SAWTOOTH)
		return 1.0 - (v - floor(v));
	return 0.0;	// GF_NONE
}

include randomRotation.inc
float Rand(vec2 co)
{
	return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
}

vec4 DeformGeometry(out mat2 rmat)
{
	float f, offs;
	vec3 mask;
	int j = 0, deformOffs = 0;
	int numDeforms = int(u_deformParms[deformOffs++]);

	vec3 xyz;

	if (u_backlerp < 0.0)
	{  /// instancing
		// rotation
		rmat = randomRotation(attr_Position2.xy);
		vec2 xyRotated = rmat * attr_Position.xy;
		// scale
		float scale = mix(-u_backlerp, 1.0, Rand(attr_Position2.xy));
		// disappearance scale
		float dist = length(u_instanceParms.xyz - attr_Position2);
		float halfDistanceCull = u_instanceParms.w * 0.75;
		if (dist > halfDistanceCull)
			scale *= (u_instanceParms.w - dist) / (u_instanceParms.w - halfDistanceCull);
		// final xyz
		xyz = scale * vec3(xyRotated, attr_Position.z) + attr_Position2;
		offs = attr_Position.z;
		mask = vec3(1.0, 1.0, 0.0);
	}
	if (u_backlerp >= 0.0)
	{
		rmat = mat2(1.0, 0.0, 0.0, 1.0);
		xyz = mix(attr_Position, attr_Position2, u_backlerp);
		offs = 1.0;
		mask = vec3(1.0);
	}

	// unroll deform loop (#define MAX_SHADER_DEFORMS 3)
	// for stupid NVidia GLSL compiler (new Detonator + old cards like 9600GT/8500GT)
	if (numDeforms > 0)
		include deform_Loop.inc
	if (numDeforms > 1)
		include deform_Loop.inc
	if (numDeforms > 2)
		include deform_Loop.inc

	return vec4(xyz, 1.0);
}
