#version 450
#include "common.glsl"
#include "worldFrameData.glsl"

struct Particle
{
    vec4 startPos;
    vec4 startVel;
    vec4 acceleration;
    vec4 startSize;
    vec4 endSize;
    vec4 startColor;
    vec4 endColor;
    uvec3 baseVoxel;
    uint startTime;
    uint endTime;
};

layout(
    std430,
    set = GLSL_PARTICLES_EMITTER_DESCRIPTOR_SET,
    binding = 0
) readonly buffer EmitterBuffer
{
    Particle particles[];
} particlesBuffer;

layout(location = 0) out vec4 passColor;

vec3 cubeVertices[] = {
    vec3(-1.0f, 1.0f, -1.0f),                       // 0
    vec3(-1.0f, -1.0f, -1.0f),                      // 1
    vec3(1.0f, -1.0f, -1.0f),                       // 2
    vec3(1.0f, 1.0f, -1.0f),                        // 3
    vec3(-1.0f, -1.0f, 1.0f),                       // 4
    vec3(-1.0f, 1.0f, 1.0f),                        // 5
    vec3(1.0f, -1.0f, 1.0f),                        // 6
    vec3(1.0f, 1.0f, 1.0f),                         // 7
};

void main()
{
    Particle particle = particlesBuffer.particles[gl_InstanceIndex];
    if (uFrameData.ticks >= particle.endTime)
    {
        gl_Position = vec4(0.0);
        return;
    };

    ivec3 relBase = ivec3(particle.baseVoxel - uFrameData.cameraVoxel);
    vec3 relOffset = (particle.startPos.xyz*8.0) - uFrameData.cameraOffset;
    vec3 relStartPos = ((vec3(relBase) + relOffset)) / 8.0;

    float factor = float(uFrameData.ticks - particle.startTime) / float(particle.endTime - particle.startTime);
    passColor = mix(particle.startColor, particle.endColor, factor);
    vec4 size = mix(particle.startSize, particle.endSize, factor);
    float timePassed = float(uFrameData.ticks - particle.startTime)/100.0;
    vec3 pos = relStartPos +
        timePassed * particle.startVel.xyz +
        0.5 * timePassed * timePassed * particle.acceleration.xyz;

    gl_Position = uFrameData.proj * uFrameData.view * vec4(cubeVertices[gl_VertexIndex] * size.xyz + pos, 1.0);
}