#version 330 core

uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform samplerBuffer instance_data;
uniform float time;

layout (location = 0) in vec3 POSITION;
layout (location = 1) in vec3 NORMAL;
layout (location = 4) in vec2 TEXCOORD;

out vec2 pos_zw;
out vec3 normal;
out vec3 ec_pos;
out vec2 uv;

void rotateAroundY(inout vec3 p, inout vec3 n, in float angle)
{
	float s = sin(angle);
	float c = cos(angle);

	float x = p.x;
	p.x = x*c - p.z*s;
	p.z = x*s + p.z*c;

	x = n.x;
	n.x = x*c - n.z*s;
	n.z = x*s + n.z*c;
}

void addWind(inout vec3 p, float h)
{
	float angle = p.x*p.z + time;
	float s = sin(angle);
	float c = cos(angle);
	vec3 wind = vec3(c - s, 0.0, s + c);
	wind *= smoothstep(0.2, 1.0, h) * 0.1;
	p += wind;
}

void main()
{
	vec4 PosRot = texelFetch(instance_data, gl_InstanceID);
	vec3 p = POSITION;
	vec3 n = NORMAL;
	rotateAroundY(p, n, PosRot.w);
	p += PosRot.xyz;
	addWind(p, POSITION.y);

	uv = TEXCOORD;
	normal = normalize(NormalMatrix * n);
	ec_pos = vec3(ModelViewMatrix * vec4(p, 1.0));

	vec4 proj_pos = ModelViewProjectionMatrix * vec4(p, 1.0);
	pos_zw = proj_pos.zw;
	gl_Position = proj_pos;
}

