

#version 150 compatibility 

//
// Uniform variable section
//
uniform mat4 mat_view ;
uniform mat4 mat_proj ;
uniform mat4 mat_world ;


//
// Variying section
//
out vec4 color ;
out vec3 light_dir ;
out vec3 normal ;

/// The particle data passed via a texture buffer.
/// It should be indexed via the vertex id.
/// The layout of the buffer in this sample is:
/// Position(vec3), Velocity(vec3)
uniform samplerBuffer particle_data_buffer ;

const float div = (1.0/6.0) ;

vec3 light_source = vec3(1000.0,0.0,-1000.0) ;

/// The quaternion rotation operator rotates an input vector by the specified angle
/// @param vector [in] The vector to be rotated
/// @param angle [in] The angle specified in the quaternion
/// @param axis [in] The quaterion rotation vector
/// @return the rotated vector
vec3 Lq( float angle, vec3 axis, vec3 vector )
{
	return ((2.0*angle*angle)-1.0)*vector + 2.0*dot(axis,vector)*axis + 2.0 * angle * cross(axis,vector) ;
}


float smoothed_pulse( float t )
{
	
	return smoothstep(0.0,0.25,t) - smoothstep(0.75,1.0, t) ;
}

void main()
{
	color = vec4(1.0) ;
	// the w-component will receive the scaling factor of the
	// instance
	vec4 vertex = vec4(gl_Vertex.xyz, 0.0) ;
	
	vec4 position ;
	vec4 velocity ;
	vec4 quaternion ;
	
	//
	// access the particle's data through the instance id.
	// Texture buffer object layout
	// -----------------------------------------------------------
	// 1. Position vec3
	// 2. Mass float
	// 3. Velocity vec3
	// 4. t-parameter of the particle [0, max life] -> [0,1]
	// 5. quaternion vec4


	// here the position of the instance also has the mass encoded in the w-component.
	// The mass will be used for scaling the geometry.
	{
		position = texelFetch( particle_data_buffer, gl_InstanceID*3 ) ;
		velocity = texelFetch( particle_data_buffer, (gl_InstanceID*3)+1 ) ;
		quaternion = texelFetch( particle_data_buffer, (gl_InstanceID*3)+2 ) ;

		//color = quaternion.xyzw ;

		// scaling before translation.
		vertex.xyz *= position.w ;
		//vertex.xyz *= position.w * smoothed_pulse(velocity.w) ;

		vertex.xyz = Lq(quaternion.w, quaternion.xyz, vertex.xyz) ;
		
		position += vertex ;
		//position.xyz += vertex.xyz * position.w ;
		
		//position.xyz = Lq(quaternion.w, quaternion.xyz, position.xyz) ;

		// just reset the w-component in order to get correct projection.
		position.w = 1.0 ;
	}

	light_dir = light_source - vec3(mat_world*position) ;
	light_dir = normalize(light_dir) ;
	normal = normalize(Lq(quaternion.w, quaternion.xyz, gl_Normal.xyz)) ;
	normal = vec3(mat_world * vec4(normal,0.0)) ;

	// transform to projection space.
	// need camera rotation matrix and projection matrix.
	position = mat_proj * mat_view * position ;

	gl_Position = vec4(position) ;
}