# HG changeset patch # User John Tsiombikas # Date 1317050411 -10800 # Node ID 133094e2f5a5fe8284de8c975295571a266aa035 # Parent 6e5342a2529a70de2ab888a528b8b21906b47ca6 reorganizing diff -r 6e5342a2529a -r 133094e2f5a5 src/psys.c --- a/src/psys.c Sun Sep 25 04:26:51 2011 +0300 +++ b/src/psys.c Mon Sep 26 18:20:11 2011 +0300 @@ -13,6 +13,9 @@ static void set_v3value(struct v3track *v3t, anm_time_t tm, vec3_t v); static vec3_t get_v3value(struct v3track *v3t, anm_time_t tm); +static float random_val(float x, float range); +static vec3_t random_vec3(vec3_t v, vec3_t range); + /* particle pool */ static struct psys_particle *ppool; static int ppool_size; @@ -47,26 +50,26 @@ { memset(em, 0, sizeof *em); - if(anm_init_node(&em->prs) == -1) { - psys_destroy(em); - return -1; - } - if(anm_init_track(&em->rate) == -1) { - psys_destroy(em); - return -1; - } - if(anm_init_track(&em->life) == -1) { - psys_destroy(em); - return -1; - } - if(init_v3track(&em->dir) == -1) { - psys_destroy(em); - return -1; - } - if(init_v3track(&em->grav) == -1) { - psys_destroy(em); - return -1; - } + if(anm_init_node(&em->prs) == -1) + goto err; + if(init_v3track(&em->pos_range) == -1) + goto err; + if(anm_init_track(&em->rate) == -1) + goto err; + if(anm_init_track(&em->life) == -1) + goto err; + if(anm_init_track(&em->life_range) == -1) + goto err; + if(anm_init_track(&em->size) == -1) + goto err; + if(anm_init_track(&em->size_range) == -1) + goto err; + if(init_v3track(&em->dir) == -1) + goto err; + if(init_v3track(&em->dir_range) == -1) + goto err; + if(init_v3track(&em->grav) == -1) + goto err; em->spawn = spawn; em->update = update_particle; @@ -76,6 +79,9 @@ em->draw_end = psys_gl_draw_end; return 0; +err: + psys_destroy(em); + return -1; } void psys_destroy(struct psys_emitter *em) @@ -90,8 +96,14 @@ } anm_destroy_node(&em->prs); + destroy_v3track(&em->pos_range); anm_destroy_track(&em->rate); + anm_destroy_track(&em->life); + anm_destroy_track(&em->size); + anm_destroy_track(&em->size_range); destroy_v3track(&em->dir); + destroy_v3track(&em->dir_range); + destroy_v3track(&em->grav); } void psys_set_texture(struct psys_emitter *em, unsigned int tex) @@ -99,9 +111,10 @@ em->tex = tex; } -void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm) +void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm) { anm_set_position(&em->prs, pos, ANM_SEC2TM(tm)); + set_v3value(&em->pos_range, ANM_SEC2TM(tm), range); } void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm) @@ -119,14 +132,22 @@ anm_set_value(&em->rate, ANM_SEC2TM(tm), rate); } -void psys_set_life(struct psys_emitter *em, float life, float tm) +void psys_set_life(struct psys_emitter *em, float life, float range, float tm) { anm_set_value(&em->life, ANM_SEC2TM(tm), life); + anm_set_value(&em->life_range, ANM_SEC2TM(tm), range); } -void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm) +void psys_set_size(struct psys_emitter *em, float size, float range, float tm) +{ + anm_set_value(&em->size, ANM_SEC2TM(tm), size); + anm_set_value(&em->size_range, ANM_SEC2TM(tm), range); +} + +void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm) { set_v3value(&em->dir, ANM_SEC2TM(tm), dir); + set_v3value(&em->dir_range, ANM_SEC2TM(tm), range); } void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm) @@ -313,9 +334,9 @@ static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls) { - p->pos = em->cur_pos; - p->vel = em->cur_dir; - p->size = 1.0; + p->pos = random_vec3(em->cur_pos, em->cur_pos_range); + p->vel = random_vec3(em->cur_dir, em->dir_range); + p->size = random_val(em->cur_size, em->cur_size_range); p->life = em->cur_life; psys_add_particle(em, p); @@ -414,3 +435,17 @@ ppool_size++; pthread_mutex_unlock(&pool_lock); } + +static float random_val(float x, float range) +{ + return x + range * (float)rand() / (float)RAND_MAX - 0.5 * range; +} + +static vec3_t random_vec3(vec3_t v, vec3_t range) +{ + vec3_t res; + res.x = random_val(v.x, range.x); + res.y = random_val(v.y, range.y); + res.z = random_val(v.z, range.z); + return res; +} diff -r 6e5342a2529a -r 133094e2f5a5 src/psys.h --- a/src/psys.h Sun Sep 25 04:26:51 2011 +0300 +++ b/src/psys.h Mon Sep 26 18:20:11 2011 +0300 @@ -1,9 +1,79 @@ #ifndef LIBPSYS_H_ #define LIBPSYS_H_ -struct psys_emitter; +#include +#include +#include "rndval.h" + +struct anm_track_vec3 { + struct anm_track x, y, z; +}; + +struct psys_plane { + plane_t p; + float elasticity; + struct psys_plane *next; +}; + struct psys_particle; +struct psys_emitter { + float last_update; + + unsigned int tex; + + struct anm_node prs; + struct anm_track_vec3 pos_range; + + struct anm_track rate; + struct anm_track life, life_range; + struct anm_track size, size_range; + struct anm_track_vec3 dir, dir_range; + struct anm_track_vec3 grav; + + float drag; /* I don't think this needs to animate */ + + /* list of active particles */ + struct psys_particle *plist; + + /* list of collision planes */ + struct col_plane *planes; + + /* custom spawn closure */ + void *spawn_cls; + psys_spawn_func_t spawn; + + /* custom particle update closure */ + void *upd_cls; + psys_update_func_t update; + + /* custom draw closure */ + void *draw_cls; + psys_draw_func_t draw; + psys_draw_start_func_t draw_start; + psys_draw_end_func_t draw_end; + + /* calculated on update */ + vec3_t cur_pos, cur_pos_range; + quat_t cur_rot; + float cur_rate, cur_life; + float cur_size, cur_size_range; + vec3_t cur_dir; + vec3_t cur_grav; + + /* partial spawn accumulator */ + float spawn_acc; +}; + + +struct psys_particle { + vec3_t pos, vel; + float life, size; + + struct psys_particle *next; +}; + + typedef int (*psys_spawn_func_t)(struct psys_emitter*, struct psys_particle*, void*); typedef void (*psys_update_func_t)(struct psys_emitter*, struct psys_particle*, float, float, void*); @@ -21,13 +91,14 @@ /* set properties */ void psys_set_texture(struct psys_emitter *em, unsigned int tex); -void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm); +void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm); void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm); void psys_set_pivot(struct psys_emitter *em, vec3_t pivot); void psys_set_rate(struct psys_emitter *em, float rate, float tm); -void psys_set_life(struct psys_emitter *em, float life, float tm); -void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm); +void psys_set_life(struct psys_emitter *em, float life, float range, float tm); +void psys_set_size(struct psys_emitter *em, float size, float range, float tm); +void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm); void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm); void psys_clear_collision_planes(struct psys_emitter *em); @@ -40,16 +111,6 @@ void psys_draw_func(struct psys_emitter *em, psys_draw_func_t draw, psys_draw_start_func_t start, psys_draw_end_func_t end, void *cls); - -/* query emitter state */ -unsigned int psys_get_texture(struct psys_emitter *em); -vec3_t psys_get_pos(struct psys_emitter *em); -quat_t psys_get_rot(struct psys_emitter *em); -float psys_get_rate(struct psys_emitter *em); -float psys_get_life(struct psys_emitter *em); -vec3_t psys_get_dir(struct psys_emitter *em); -vec3_t psys_get_grav(struct psys_emitter *em); - /* update and render */ void psys_update(struct psys_emitter *em, float tm); diff -r 6e5342a2529a -r 133094e2f5a5 src/psys_gl.c --- a/src/psys_gl.c Sun Sep 25 04:26:51 2011 +0300 +++ b/src/psys_gl.c Mon Sep 26 18:20:11 2011 +0300 @@ -23,7 +23,7 @@ glDisable(GL_LIGHTING); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); if(em->tex) { glEnable(GL_TEXTURE_2D); diff -r 6e5342a2529a -r 133094e2f5a5 src/psys_impl.h --- a/src/psys_impl.h Sun Sep 25 04:26:51 2011 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -#ifndef PSYS_IMPL_H_ -#define PSYS_IMPL_H_ - -#include -#include "psys.h" - -struct v3track { - struct anm_track x, y, z; -}; - -struct col_plane { - plane_t p; - float elasticity; - struct col_plane *next; -}; - -struct psys_particle; - -struct psys_emitter { - float last_update; - - struct anm_node prs; - - unsigned int tex; - - struct anm_track rate; - struct anm_track life; - struct v3track dir; - struct v3track grav; - - float drag; /* I don't think this needs to animate */ - - /* list of active particles */ - struct psys_particle *plist; - - /* list of collision planes */ - struct col_plane *planes; - - /* custom spawn closure */ - void *spawn_cls; - psys_spawn_func_t spawn; - - /* custom particle update closure */ - void *upd_cls; - psys_update_func_t update; - - /* custom draw closure */ - void *draw_cls; - psys_draw_func_t draw; - psys_draw_start_func_t draw_start; - psys_draw_end_func_t draw_end; - - /* calculated on update */ - vec3_t cur_pos; - quat_t cur_rot; - float cur_rate, cur_life; - vec3_t cur_dir; - vec3_t cur_grav; - - /* partial spawn accumulator */ - float spawn_acc; -}; - - -struct psys_particle { - vec3_t pos, vel; - float life, size; - - struct psys_particle *next; -}; - -void psys_gl_draw_start(struct psys_emitter *em, void *cls); -void psys_gl_draw(struct psys_emitter *em, struct psys_particle *p, void *cls); -void psys_gl_draw_end(struct psys_emitter *em, void *cls); - -#endif /* PSYS_IMPL_H_ */ diff -r 6e5342a2529a -r 133094e2f5a5 src/rndval.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rndval.c Mon Sep 26 18:20:11 2011 +0300 @@ -0,0 +1,74 @@ +#include +#include "rndval.h" + +int psys_init_anm_rnd(struct psys_anm_rnd *r) +{ + if(anm_init_track(&r->value) == -1) { + return -1; + } + if(anm_init_track(&r->range) == -1) { + anm_destroy_track(&r->value); + return -1; + } + return 0; +} + +void psys_destroy_anm_rnd(struct psys_anm_rnd *r) +{ + anm_destroy_track(&r->value); + anm_destroy_track(&r->range); +} + +int psys_init_anm_rnd3(struct psys_anm_rnd3 *r) +{ + if(anm_init_track3(&r->value) == -1) { + return -1; + } + if(anm_init_track3(&r->range) == -1) { + anm_destroy_track3(&r->value); + return -1; + } + return 0; +} + +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *r) +{ + anm_destroy_track3(&r->value); + anm_destroy_track3(&r->range); +} + + +float psys_eval_rnd(struct psys_rnd *r) +{ + return r->value + r->range * (float)rand() / (float)RAND_MAX - 0.5 * r->range; +} + +vec3_t psys_eval_rnd3(struct psys_rnd3 *r) +{ + vec3_t res; + res.x = r->value.x + r->range.x * (float)rand() / (float)RAND_MAX - 0.5 * r->range.x; + res.y = r->value.y + r->range.y * (float)rand() / (float)RAND_MAX - 0.5 * r->range.y; + res.z = r->value.z + r->range.z * (float)rand() / (float)RAND_MAX - 0.5 * r->range.z; + return res; +} + + +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm) +{ + if(r->cur_tm != tm) { + r->cur.value = anm_get_value(&r->value, tm); + r->cur.range = anm_get_value(&r->range, tm); + r->cur_tm = tm; + } + return psys_eval_rnd(&r->cur); +} + +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm) +{ + if(r->cur_tm != tm) { + r->cur.value = anm_get_value3(&r->value, tm); + r->cur.range = anm_get_value3(&r->range, tm); + r->cur_tm = tm; + } + return psys_eval_rnd3(&r->cur); +} diff -r 6e5342a2529a -r 133094e2f5a5 src/rndval.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/rndval.h Mon Sep 26 18:20:11 2011 +0300 @@ -0,0 +1,43 @@ +#ifndef RNDVAL_H_ +#define RNDVAL_H_ + +#include +#include +#include "anm_track3.h" + +struct psys_rnd { + float value, range; +}; + +struct psys_rnd3 { + vec3_t value, range; +}; + +struct psys_anm_rnd { + struct anm_track value, range; + /* current cache */ + anm_time_t cur_tm; + struct psys_rnd cur; +}; + +struct psys_anm_rnd3 { + struct anm_track3 value, range; + /* current cache */ + anm_time_t cur_tm; + struct psys_rnd3 cur; +}; + + +int psys_init_anm_rnd(struct psys_anm_rnd *v); +void psys_destroy_anm_rnd(struct psys_anm_rnd *v); +int psys_init_anm_rnd3(struct psys_anm_rnd3 *v); +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *v); + +float psys_eval_rnd(struct psys_rnd *r); +vec3_t psys_eval_rnd3(struct psys_rnd3 *r); + +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm); +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm); + + +#endif /* RNDVAL_H_ */