#version 430 core

uniform struct Matrices
{
	mat4 projMatrix;
	mat4 modelViewMatrix;
} matrices;

struct particlaData{
    int exists;
    vec3 position;
    vec4 rotation;
    vec3 scale;
};

layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inTexCoord;
layout (location = 2) in vec3 inNormCoord;

layout(std140, binding = 3) buffer ParticleData
{
    particlaData data[];
} particles;

out vec4 processedColor;
out vec2 texCoord;
flat out uint outExist;

mat4 BuildRotation3d(vec3 axis, float angle) 
{
  axis = normalize(axis);
  float s = sin(angle);
  float c = cos(angle);
  float oc = 1.0 - c;

  return mat4(
    oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
    oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
    oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
    0.0,                                0.0,                                0.0,                                1.0
  );
}

mat4 BuildTransform(vec3 delta, vec3 scale, vec4 rotation)
{
    mat4 m;
    m[0][0] = scale.x;
    m[1][1] = scale.y;
    m[2][2] = scale.z;
    m[3] = vec4(delta, 1.0);
    return m * BuildRotation3d(rotation.xyz, rotation.w);
}

void main()
{
	if(particles.data[gl_InstanceID].exists == 0){
		gl_Position = vec4(inPosition, 1.0);
	}
    else{
    	gl_Position = matrices.projMatrix * matrices.modelViewMatrix * BuildTransform(particles.data[gl_InstanceID].position, particles.data[gl_InstanceID].scale, particles.data[gl_InstanceID].rotation) * vec4(inPosition, 1.0);
    }

	texCoord = inTexCoord;
	processedColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
	outExist = particles.data[gl_InstanceID].exists;
}