

#ifndef PI
#define PI 3.14159265359
#endif

#define PTR_BUFF_ATTR

layout (std430) PTR_BUFF_ATTR buffer ParticlePositionsData {
	vec4 position[];
} prt_positions;

struct ParticleState
{
	float life_time;
	float life_span;
	float generation_id;
	uint  color;
};

layout (std430) PTR_BUFF_ATTR buffer ParticleStatesData {
	ParticleState state[];
} prt_states;

layout (std430) PTR_BUFF_ATTR buffer ParticlePrefixSumData {
	uint prefix_sum[];
} prt_prefix_sum;

bool prt_is_alive(uint id)
{
	return prt_states.state[id].life_time < prt_states.state[id].life_span;
}

bool prt_is_alive(ParticleState state)
{
	return state.life_time < state.life_span;	
}

ParticleState prt_get_state(uint id)
{
	return prt_states.state[id];
}

void prt_set_state(uint id, ParticleState state)
{
	prt_states.state[id] = state;
}

void prt_spawn(uint id, float life_span)
{
	prt_states.state[id].life_time = 0.0;
	prt_states.state[id].life_span = life_span;
	prt_states.state[id].generation_id += 1.0;
}

void prt_spawn(inout ParticleState state, float life_span)
{
	state.life_time = 0.0;
	state.life_span = life_span;
	state.generation_id += 1.0;
}

void prt_set_position(uint id, vec3 p)
{	
	prt_positions.position[id].xyz = p;
}

vec3 prt_get_position(uint id)
{	
	return prt_positions.position[id].xyz;
}

float prt_get_generation_id(uint id)
{
	return prt_states.state[id].generation_id;
}

vec4 prt_get_color(uint id)
{
	vec4 c = vec4(1.0);
	c.rgb = color_convert_uint_to_float3(prt_states.state[id].color);
	return c;
}

void prt_set_color(uint id, vec3 c)
{
	uint v = color_convert_rgb_float3_uint(c);
	prt_states.state[id].color = v;
}

void prt_set_color(inout ParticleState state, vec3 c)
{
	uint v = color_convert_rgb_float3_uint(c);
	state.color = v;
}

void prt_advance_life(uint id, float time_step, float max_lifespan)
{
	prt_states.state[id].life_time += time_step;
	prt_states.state[id].life_span = min(prt_states.state[id].life_span, max_lifespan);
}

void prt_advance_life(inout ParticleState state, float time_step, float max_lifespan)
{
	state.life_time += time_step;
	state.life_span = min(state.life_span, max_lifespan);
}