2019-12-17 21:29:36 +00:00
|
|
|
#include <malloc.h>
|
2020-01-08 16:33:01 +00:00
|
|
|
#include <stdlib.h>
|
2019-12-18 17:18:55 +00:00
|
|
|
|
|
|
|
#include "particlesystem.h"
|
2019-12-17 21:29:36 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initializes a particle
|
|
|
|
*/
|
2019-12-28 12:54:53 +00:00
|
|
|
particle *initParticle(vector3f *pos, vector3f *dir, vector3f *color, float age)
|
2019-12-17 21:29:36 +00:00
|
|
|
{
|
|
|
|
particle *p = malloc(sizeof(particle));
|
|
|
|
p->position = pos;
|
2020-03-08 20:03:48 +00:00
|
|
|
p->velocity = dir;
|
2019-12-28 12:54:53 +00:00
|
|
|
p->color = color;
|
|
|
|
p->age = age;
|
2019-12-17 21:29:36 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initializes an emitter
|
|
|
|
*/
|
|
|
|
emitter *initEmitter(vector3f *pos, int pamount)
|
|
|
|
{
|
|
|
|
emitter *e = malloc(sizeof(emitter));
|
|
|
|
e->position = pos;
|
|
|
|
e->particles = malloc(sizeof(particle *) * pamount);
|
|
|
|
e->pamount = pamount;
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initializes a particle system
|
|
|
|
*/
|
|
|
|
particle_system *initParticleSystem(int eamount)
|
|
|
|
{
|
|
|
|
particle_system *ps = malloc(sizeof(particle_system));
|
|
|
|
ps->emitters = malloc(sizeof(emitter *) * eamount);
|
|
|
|
ps->eamount = eamount;
|
|
|
|
return ps;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Updates particles
|
|
|
|
*/
|
2020-04-01 20:17:35 +00:00
|
|
|
void updateParticles(float dt, particle_system *ps, CalculatePositionFunction calculatePosition, CalculateColorFunction calculateColor)
|
2019-12-17 21:29:36 +00:00
|
|
|
{
|
2019-12-20 13:24:52 +00:00
|
|
|
emitter *e;
|
2019-12-28 12:54:53 +00:00
|
|
|
particle *p;
|
2019-12-20 13:24:52 +00:00
|
|
|
for (int i = 0; i < ps->eamount; i++)
|
|
|
|
{
|
|
|
|
e = (ps->emitters)[i];
|
|
|
|
for (int j = 0; j < e->pamount; j++)
|
|
|
|
{
|
2019-12-28 12:54:53 +00:00
|
|
|
p = (e->particles)[j];
|
2020-01-08 16:33:01 +00:00
|
|
|
|
2020-03-13 13:04:49 +00:00
|
|
|
if (p->age < 0 || p->position->x > 1 || p->position->y > 1 || p->position->z > 1)
|
2020-01-08 16:33:01 +00:00
|
|
|
{
|
|
|
|
resetParticle(e, p);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
calculatePosition(p, dt);
|
|
|
|
calculateColor(p);
|
|
|
|
p->age -= 0.1f;
|
|
|
|
}
|
2019-12-20 13:24:52 +00:00
|
|
|
}
|
|
|
|
}
|
2019-12-17 21:29:36 +00:00
|
|
|
}
|
|
|
|
|
2020-01-08 16:33:01 +00:00
|
|
|
void resetParticle(emitter *e, particle *p)
|
|
|
|
{
|
|
|
|
p->position->x = e->position->x;
|
|
|
|
p->position->y = e->position->y;
|
|
|
|
p->position->z = e->position->z;
|
|
|
|
|
2020-04-01 12:40:21 +00:00
|
|
|
p->velocity->x = ((float) ((rand() % 2 ? -1 : 1) * rand())) / RAND_MAX;
|
|
|
|
p->velocity->y = ((float) ((rand() % 2 ? -1 : 1) * rand())) / RAND_MAX;
|
|
|
|
p->velocity->z = ((float) ((rand() % 2 ? -1 : 1) * rand())) / RAND_MAX;
|
2020-01-08 16:33:01 +00:00
|
|
|
|
2020-02-11 18:01:50 +00:00
|
|
|
p->age = rand() / 10;
|
2020-01-08 16:33:01 +00:00
|
|
|
}
|
|
|
|
|
2019-12-17 21:29:36 +00:00
|
|
|
/*
|
|
|
|
* Draws particles
|
|
|
|
*/
|
|
|
|
int drawParticles(particle_system *particleSystem)
|
|
|
|
{
|
2020-04-01 12:40:21 +00:00
|
|
|
return 0;
|
2019-12-17 21:29:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initializes a vector
|
|
|
|
* For that it allocates memory that must be freed later
|
|
|
|
*/
|
|
|
|
vector3f *initVector3f(float x, float y, float z)
|
|
|
|
{
|
|
|
|
vector3f *vector = malloc(sizeof(vector3f));
|
|
|
|
vector->x = x;
|
|
|
|
vector->y = y;
|
|
|
|
vector->z = z;
|
|
|
|
return vector;
|
2019-12-20 13:24:52 +00:00
|
|
|
}
|
|
|
|
|
2020-01-08 15:58:38 +00:00
|
|
|
/*
|
|
|
|
* Frees a given particle and all corresponding data
|
|
|
|
*/
|
|
|
|
void freeParticle(particle *p)
|
|
|
|
{
|
|
|
|
free(p->position);
|
2020-03-08 20:03:48 +00:00
|
|
|
free(p->velocity);
|
2020-01-08 15:58:38 +00:00
|
|
|
free(p->color);
|
|
|
|
free(p);
|
|
|
|
}
|
|
|
|
|
2019-12-20 13:24:52 +00:00
|
|
|
/*
|
|
|
|
* Frees a given emitter and all corresponding particles
|
|
|
|
*/
|
|
|
|
void freeEmitter(emitter *e)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < e->pamount; j++)
|
|
|
|
{
|
2020-01-08 15:58:38 +00:00
|
|
|
freeParticle((e->particles)[j]);
|
2019-12-20 13:24:52 +00:00
|
|
|
}
|
|
|
|
|
2020-02-11 18:01:50 +00:00
|
|
|
free(e->position);
|
2019-12-20 13:24:52 +00:00
|
|
|
free(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Frees all emitters within a particle system
|
|
|
|
*/
|
|
|
|
void freeEmitters(particle_system *ps)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < ps->eamount; i++)
|
|
|
|
{
|
|
|
|
freeEmitter((ps->emitters)[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Frees all emitters and particles within a particle system
|
|
|
|
*/
|
|
|
|
void freeParticleSystem(particle_system *ps)
|
|
|
|
{
|
|
|
|
freeEmitters(ps);
|
|
|
|
free(ps);
|
|
|
|
}
|
2020-02-11 18:01:50 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates float array out of a particle system
|
|
|
|
*/
|
|
|
|
float *serializeParticlesystem(particle_system *ps)
|
|
|
|
{
|
|
|
|
int particleAmount = 0;
|
|
|
|
for (int i = 0; i < ps->eamount; i++)
|
|
|
|
{
|
|
|
|
particleAmount += (ps->emitters[i])->pamount;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long particleBytesAmount = sizeof(vector3f) * 3 + sizeof(float);
|
2020-03-16 19:46:54 +00:00
|
|
|
float *vert = malloc(particleAmount * particleBytesAmount);
|
2020-02-11 18:01:50 +00:00
|
|
|
|
|
|
|
emitter *e;
|
|
|
|
particle *p;
|
|
|
|
for (int y = 0, j = 0; y < ps->eamount; y++)
|
|
|
|
{
|
|
|
|
e = (ps->emitters)[y];
|
|
|
|
for (int x = 0; x < e->pamount; x++)
|
|
|
|
{
|
|
|
|
p = e->particles[x];
|
2020-03-16 19:46:54 +00:00
|
|
|
|
2020-02-11 18:01:50 +00:00
|
|
|
// Position
|
|
|
|
vert[j++] = p->position->x;
|
|
|
|
vert[j++] = p->position->y;
|
|
|
|
vert[j++] = p->position->z;
|
|
|
|
|
|
|
|
// Direction
|
2020-03-08 20:03:48 +00:00
|
|
|
vert[j++] = p->velocity->x;
|
|
|
|
vert[j++] = p->velocity->y;
|
|
|
|
vert[j++] = p->velocity->z;
|
2020-02-11 18:01:50 +00:00
|
|
|
|
|
|
|
// Color
|
|
|
|
vert[j++] = p->color->x;
|
|
|
|
vert[j++] = p->color->y;
|
|
|
|
vert[j++] = p->color->z;
|
|
|
|
|
|
|
|
// Age
|
|
|
|
vert[j++] = p->age;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vert;
|
|
|
|
}
|
2020-03-16 19:46:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Inits random particles
|
|
|
|
*/
|
|
|
|
void initRandomParticles(emitter *e)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < e->pamount; i++)
|
|
|
|
{
|
|
|
|
vector3f *pos = initVector3f(e->position->x, e->position->y, e->position->z);
|
|
|
|
vector3f *dir = initVector3f(((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
|
|
|
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
|
|
|
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX);
|
|
|
|
vector3f *color = initVector3f(((float) (rand() % 255)) / 255,
|
|
|
|
((float) (rand() % 255)) / 255,
|
|
|
|
((float) (rand() % 255)) / 255);
|
|
|
|
(e->particles)[i] = initParticle(pos, dir, color, (float) (rand() % (UPPER_AGE - LOWER_AGE + 1) + LOWER_AGE));
|
|
|
|
}
|
2020-04-01 20:17:35 +00:00
|
|
|
}
|