1
0
rwu_particles_informatikpro.../particlesystem.c

211 lines
4.9 KiB
C
Raw Normal View History

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
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
}
/*
* 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);
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++)
{
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);
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-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;
}
/*
* 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
}