libpsys

changeset 3:133094e2f5a5

reorganizing
author John Tsiombikas <nuclear@mutantstargoat.com>
date Mon, 26 Sep 2011 18:20:11 +0300
parents 6e5342a2529a
children 0fe624ffcb4f
files src/psys.c src/psys.h src/psys_gl.c src/psys_impl.h src/rndval.c src/rndval.h
diffstat 6 files changed, 254 insertions(+), 117 deletions(-) [+]
line diff
     1.1 --- a/src/psys.c	Sun Sep 25 04:26:51 2011 +0300
     1.2 +++ b/src/psys.c	Mon Sep 26 18:20:11 2011 +0300
     1.3 @@ -13,6 +13,9 @@
     1.4  static void set_v3value(struct v3track *v3t, anm_time_t tm, vec3_t v);
     1.5  static vec3_t get_v3value(struct v3track *v3t, anm_time_t tm);
     1.6  
     1.7 +static float random_val(float x, float range);
     1.8 +static vec3_t random_vec3(vec3_t v, vec3_t range);
     1.9 +
    1.10  /* particle pool */
    1.11  static struct psys_particle *ppool;
    1.12  static int ppool_size;
    1.13 @@ -47,26 +50,26 @@
    1.14  {
    1.15  	memset(em, 0, sizeof *em);
    1.16  
    1.17 -	if(anm_init_node(&em->prs) == -1) {
    1.18 -		psys_destroy(em);
    1.19 -		return -1;
    1.20 -	}
    1.21 -	if(anm_init_track(&em->rate) == -1) {
    1.22 -		psys_destroy(em);
    1.23 -		return -1;
    1.24 -	}
    1.25 -	if(anm_init_track(&em->life) == -1) {
    1.26 -		psys_destroy(em);
    1.27 -		return -1;
    1.28 -	}
    1.29 -	if(init_v3track(&em->dir) == -1) {
    1.30 -		psys_destroy(em);
    1.31 -		return -1;
    1.32 -	}
    1.33 -	if(init_v3track(&em->grav) == -1) {
    1.34 -		psys_destroy(em);
    1.35 -		return -1;
    1.36 -	}
    1.37 +	if(anm_init_node(&em->prs) == -1)
    1.38 +		goto err;
    1.39 +	if(init_v3track(&em->pos_range) == -1)
    1.40 +		goto err;
    1.41 +	if(anm_init_track(&em->rate) == -1)
    1.42 +		goto err;
    1.43 +	if(anm_init_track(&em->life) == -1)
    1.44 +		goto err;
    1.45 +	if(anm_init_track(&em->life_range) == -1)
    1.46 +		goto err;
    1.47 +	if(anm_init_track(&em->size) == -1)
    1.48 +		goto err;
    1.49 +	if(anm_init_track(&em->size_range) == -1)
    1.50 +		goto err;
    1.51 +	if(init_v3track(&em->dir) == -1)
    1.52 +		goto err;
    1.53 +	if(init_v3track(&em->dir_range) == -1)
    1.54 +		goto err;
    1.55 +	if(init_v3track(&em->grav) == -1)
    1.56 +		goto err;
    1.57  
    1.58  	em->spawn = spawn;
    1.59  	em->update = update_particle;
    1.60 @@ -76,6 +79,9 @@
    1.61  	em->draw_end = psys_gl_draw_end;
    1.62  
    1.63  	return 0;
    1.64 +err:
    1.65 +	psys_destroy(em);
    1.66 +	return -1;
    1.67  }
    1.68  
    1.69  void psys_destroy(struct psys_emitter *em)
    1.70 @@ -90,8 +96,14 @@
    1.71  	}
    1.72  
    1.73  	anm_destroy_node(&em->prs);
    1.74 +	destroy_v3track(&em->pos_range);
    1.75  	anm_destroy_track(&em->rate);
    1.76 +	anm_destroy_track(&em->life);
    1.77 +	anm_destroy_track(&em->size);
    1.78 +	anm_destroy_track(&em->size_range);
    1.79  	destroy_v3track(&em->dir);
    1.80 +	destroy_v3track(&em->dir_range);
    1.81 +	destroy_v3track(&em->grav);
    1.82  }
    1.83  
    1.84  void psys_set_texture(struct psys_emitter *em, unsigned int tex)
    1.85 @@ -99,9 +111,10 @@
    1.86  	em->tex = tex;
    1.87  }
    1.88  
    1.89 -void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm)
    1.90 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm)
    1.91  {
    1.92  	anm_set_position(&em->prs, pos, ANM_SEC2TM(tm));
    1.93 +	set_v3value(&em->pos_range, ANM_SEC2TM(tm), range);
    1.94  }
    1.95  
    1.96  void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm)
    1.97 @@ -119,14 +132,22 @@
    1.98  	anm_set_value(&em->rate, ANM_SEC2TM(tm), rate);
    1.99  }
   1.100  
   1.101 -void psys_set_life(struct psys_emitter *em, float life, float tm)
   1.102 +void psys_set_life(struct psys_emitter *em, float life, float range, float tm)
   1.103  {
   1.104  	anm_set_value(&em->life, ANM_SEC2TM(tm), life);
   1.105 +	anm_set_value(&em->life_range, ANM_SEC2TM(tm), range);
   1.106  }
   1.107  
   1.108 -void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm)
   1.109 +void psys_set_size(struct psys_emitter *em, float size, float range, float tm)
   1.110 +{
   1.111 +	anm_set_value(&em->size, ANM_SEC2TM(tm), size);
   1.112 +	anm_set_value(&em->size_range, ANM_SEC2TM(tm), range);
   1.113 +}
   1.114 +
   1.115 +void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm)
   1.116  {
   1.117  	set_v3value(&em->dir, ANM_SEC2TM(tm), dir);
   1.118 +	set_v3value(&em->dir_range, ANM_SEC2TM(tm), range);
   1.119  }
   1.120  
   1.121  void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm)
   1.122 @@ -313,9 +334,9 @@
   1.123  
   1.124  static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls)
   1.125  {
   1.126 -	p->pos = em->cur_pos;
   1.127 -	p->vel = em->cur_dir;
   1.128 -	p->size = 1.0;
   1.129 +	p->pos = random_vec3(em->cur_pos, em->cur_pos_range);
   1.130 +	p->vel = random_vec3(em->cur_dir, em->dir_range);
   1.131 +	p->size = random_val(em->cur_size, em->cur_size_range);
   1.132  	p->life = em->cur_life;
   1.133  
   1.134  	psys_add_particle(em, p);
   1.135 @@ -414,3 +435,17 @@
   1.136  	ppool_size++;
   1.137  	pthread_mutex_unlock(&pool_lock);
   1.138  }
   1.139 +
   1.140 +static float random_val(float x, float range)
   1.141 +{
   1.142 +	return x + range * (float)rand() / (float)RAND_MAX - 0.5 * range;
   1.143 +}
   1.144 +
   1.145 +static vec3_t random_vec3(vec3_t v, vec3_t range)
   1.146 +{
   1.147 +	vec3_t res;
   1.148 +	res.x = random_val(v.x, range.x);
   1.149 +	res.y = random_val(v.y, range.y);
   1.150 +	res.z = random_val(v.z, range.z);
   1.151 +	return res;
   1.152 +}
     2.1 --- a/src/psys.h	Sun Sep 25 04:26:51 2011 +0300
     2.2 +++ b/src/psys.h	Mon Sep 26 18:20:11 2011 +0300
     2.3 @@ -1,9 +1,79 @@
     2.4  #ifndef LIBPSYS_H_
     2.5  #define LIBPSYS_H_
     2.6  
     2.7 -struct psys_emitter;
     2.8 +#include <vmath.h>
     2.9 +#include <anim/anim.h>
    2.10 +#include "rndval.h"
    2.11 +
    2.12 +struct anm_track_vec3 {
    2.13 +	struct anm_track x, y, z;
    2.14 +};
    2.15 +
    2.16 +struct psys_plane {
    2.17 +	plane_t p;
    2.18 +	float elasticity;
    2.19 +	struct psys_plane *next;
    2.20 +};
    2.21 +
    2.22  struct psys_particle;
    2.23  
    2.24 +struct psys_emitter {
    2.25 +	float last_update;
    2.26 +
    2.27 +	unsigned int tex;
    2.28 +
    2.29 +	struct anm_node prs;
    2.30 +	struct anm_track_vec3 pos_range;
    2.31 +
    2.32 +	struct anm_track rate;
    2.33 +	struct anm_track life, life_range;
    2.34 +	struct anm_track size, size_range;
    2.35 +	struct anm_track_vec3 dir, dir_range;
    2.36 +	struct anm_track_vec3 grav;
    2.37 +
    2.38 +	float drag;	/* I don't think this needs to animate */
    2.39 +
    2.40 +	/* list of active particles */
    2.41 +	struct psys_particle *plist;
    2.42 +
    2.43 +	/* list of collision planes */
    2.44 +	struct col_plane *planes;
    2.45 +
    2.46 +	/* custom spawn closure */
    2.47 +	void *spawn_cls;
    2.48 +	psys_spawn_func_t spawn;
    2.49 +
    2.50 +	/* custom particle update closure */
    2.51 +	void *upd_cls;
    2.52 +	psys_update_func_t update;
    2.53 +
    2.54 +	/* custom draw closure */
    2.55 +	void *draw_cls;
    2.56 +	psys_draw_func_t draw;
    2.57 +	psys_draw_start_func_t draw_start;
    2.58 +	psys_draw_end_func_t draw_end;
    2.59 +
    2.60 +	/* calculated on update */
    2.61 +	vec3_t cur_pos, cur_pos_range;
    2.62 +	quat_t cur_rot;
    2.63 +	float cur_rate, cur_life;
    2.64 +	float cur_size, cur_size_range;
    2.65 +	vec3_t cur_dir;
    2.66 +	vec3_t cur_grav;
    2.67 +
    2.68 +	/* partial spawn accumulator */
    2.69 +	float spawn_acc;
    2.70 +};
    2.71 +
    2.72 +
    2.73 +struct psys_particle {
    2.74 +	vec3_t pos, vel;
    2.75 +	float life, size;
    2.76 +
    2.77 +	struct psys_particle *next;
    2.78 +};
    2.79 +
    2.80 +
    2.81  typedef int (*psys_spawn_func_t)(struct psys_emitter*, struct psys_particle*, void*);
    2.82  typedef void (*psys_update_func_t)(struct psys_emitter*, struct psys_particle*, float, float, void*);
    2.83  
    2.84 @@ -21,13 +91,14 @@
    2.85  /* set properties */
    2.86  void psys_set_texture(struct psys_emitter *em, unsigned int tex);
    2.87  
    2.88 -void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm);
    2.89 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm);
    2.90  void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm);
    2.91  void psys_set_pivot(struct psys_emitter *em, vec3_t pivot);
    2.92  
    2.93  void psys_set_rate(struct psys_emitter *em, float rate, float tm);
    2.94 -void psys_set_life(struct psys_emitter *em, float life, float tm);
    2.95 -void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm);
    2.96 +void psys_set_life(struct psys_emitter *em, float life, float range, float tm);
    2.97 +void psys_set_size(struct psys_emitter *em, float size, float range, float tm);
    2.98 +void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm);
    2.99  void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm);
   2.100  
   2.101  void psys_clear_collision_planes(struct psys_emitter *em);
   2.102 @@ -40,16 +111,6 @@
   2.103  void psys_draw_func(struct psys_emitter *em, psys_draw_func_t draw,
   2.104  		psys_draw_start_func_t start, psys_draw_end_func_t end, void *cls);
   2.105  
   2.106 -
   2.107 -/* query emitter state */
   2.108 -unsigned int psys_get_texture(struct psys_emitter *em);
   2.109 -vec3_t psys_get_pos(struct psys_emitter *em);
   2.110 -quat_t psys_get_rot(struct psys_emitter *em);
   2.111 -float psys_get_rate(struct psys_emitter *em);
   2.112 -float psys_get_life(struct psys_emitter *em);
   2.113 -vec3_t psys_get_dir(struct psys_emitter *em);
   2.114 -vec3_t psys_get_grav(struct psys_emitter *em);
   2.115 -
   2.116  /* update and render */
   2.117  
   2.118  void psys_update(struct psys_emitter *em, float tm);
     3.1 --- a/src/psys_gl.c	Sun Sep 25 04:26:51 2011 +0300
     3.2 +++ b/src/psys_gl.c	Mon Sep 26 18:20:11 2011 +0300
     3.3 @@ -23,7 +23,7 @@
     3.4  	glDisable(GL_LIGHTING);
     3.5  
     3.6  	glEnable(GL_BLEND);
     3.7 -	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     3.8 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
     3.9  
    3.10  	if(em->tex) {
    3.11  		glEnable(GL_TEXTURE_2D);
     4.1 --- a/src/psys_impl.h	Sun Sep 25 04:26:51 2011 +0300
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,76 +0,0 @@
     4.4 -#ifndef PSYS_IMPL_H_
     4.5 -#define PSYS_IMPL_H_
     4.6 -
     4.7 -#include <anim/anim.h>
     4.8 -#include "psys.h"
     4.9 -
    4.10 -struct v3track {
    4.11 -	struct anm_track x, y, z;
    4.12 -};
    4.13 -
    4.14 -struct col_plane {
    4.15 -	plane_t p;
    4.16 -	float elasticity;
    4.17 -	struct col_plane *next;
    4.18 -};
    4.19 -
    4.20 -struct psys_particle;
    4.21 -
    4.22 -struct psys_emitter {
    4.23 -	float last_update;
    4.24 -
    4.25 -	struct anm_node prs;
    4.26 -
    4.27 -	unsigned int tex;
    4.28 -
    4.29 -	struct anm_track rate;
    4.30 -	struct anm_track life;
    4.31 -	struct v3track dir;
    4.32 -	struct v3track grav;
    4.33 -
    4.34 -	float drag;	/* I don't think this needs to animate */
    4.35 -
    4.36 -	/* list of active particles */
    4.37 -	struct psys_particle *plist;
    4.38 -
    4.39 -	/* list of collision planes */
    4.40 -	struct col_plane *planes;
    4.41 -
    4.42 -	/* custom spawn closure */
    4.43 -	void *spawn_cls;
    4.44 -	psys_spawn_func_t spawn;
    4.45 -
    4.46 -	/* custom particle update closure */
    4.47 -	void *upd_cls;
    4.48 -	psys_update_func_t update;
    4.49 -
    4.50 -	/* custom draw closure */
    4.51 -	void *draw_cls;
    4.52 -	psys_draw_func_t draw;
    4.53 -	psys_draw_start_func_t draw_start;
    4.54 -	psys_draw_end_func_t draw_end;
    4.55 -
    4.56 -	/* calculated on update */
    4.57 -	vec3_t cur_pos;
    4.58 -	quat_t cur_rot;
    4.59 -	float cur_rate, cur_life;
    4.60 -	vec3_t cur_dir;
    4.61 -	vec3_t cur_grav;
    4.62 -
    4.63 -	/* partial spawn accumulator */
    4.64 -	float spawn_acc;
    4.65 -};
    4.66 -
    4.67 -
    4.68 -struct psys_particle {
    4.69 -	vec3_t pos, vel;
    4.70 -	float life, size;
    4.71 -
    4.72 -	struct psys_particle *next;
    4.73 -};
    4.74 -
    4.75 -void psys_gl_draw_start(struct psys_emitter *em, void *cls);
    4.76 -void psys_gl_draw(struct psys_emitter *em, struct psys_particle *p, void *cls);
    4.77 -void psys_gl_draw_end(struct psys_emitter *em, void *cls);
    4.78 -
    4.79 -#endif	/* PSYS_IMPL_H_ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/rndval.c	Mon Sep 26 18:20:11 2011 +0300
     5.3 @@ -0,0 +1,74 @@
     5.4 +#include <stdlib.h>
     5.5 +#include "rndval.h"
     5.6 +
     5.7 +int psys_init_anm_rnd(struct psys_anm_rnd *r)
     5.8 +{
     5.9 +	if(anm_init_track(&r->value) == -1) {
    5.10 +		return -1;
    5.11 +	}
    5.12 +	if(anm_init_track(&r->range) == -1) {
    5.13 +		anm_destroy_track(&r->value);
    5.14 +		return -1;
    5.15 +	}
    5.16 +	return 0;
    5.17 +}
    5.18 +
    5.19 +void psys_destroy_anm_rnd(struct psys_anm_rnd *r)
    5.20 +{
    5.21 +	anm_destroy_track(&r->value);
    5.22 +	anm_destroy_track(&r->range);
    5.23 +}
    5.24 +
    5.25 +int psys_init_anm_rnd3(struct psys_anm_rnd3 *r)
    5.26 +{
    5.27 +	if(anm_init_track3(&r->value) == -1) {
    5.28 +		return -1;
    5.29 +	}
    5.30 +	if(anm_init_track3(&r->range) == -1) {
    5.31 +		anm_destroy_track3(&r->value);
    5.32 +		return -1;
    5.33 +	}
    5.34 +	return 0;
    5.35 +}
    5.36 +
    5.37 +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *r)
    5.38 +{
    5.39 +	anm_destroy_track3(&r->value);
    5.40 +	anm_destroy_track3(&r->range);
    5.41 +}
    5.42 +
    5.43 +
    5.44 +float psys_eval_rnd(struct psys_rnd *r)
    5.45 +{
    5.46 +	return r->value + r->range * (float)rand() / (float)RAND_MAX - 0.5 * r->range;
    5.47 +}
    5.48 +
    5.49 +vec3_t psys_eval_rnd3(struct psys_rnd3 *r)
    5.50 +{
    5.51 +	vec3_t res;
    5.52 +	res.x = r->value.x + r->range.x * (float)rand() / (float)RAND_MAX - 0.5 * r->range.x;
    5.53 +	res.y = r->value.y + r->range.y * (float)rand() / (float)RAND_MAX - 0.5 * r->range.y;
    5.54 +	res.z = r->value.z + r->range.z * (float)rand() / (float)RAND_MAX - 0.5 * r->range.z;
    5.55 +	return res;
    5.56 +}
    5.57 +
    5.58 +
    5.59 +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm)
    5.60 +{
    5.61 +	if(r->cur_tm != tm) {
    5.62 +		r->cur.value = anm_get_value(&r->value, tm);
    5.63 +		r->cur.range = anm_get_value(&r->range, tm);
    5.64 +		r->cur_tm = tm;
    5.65 +	}
    5.66 +	return psys_eval_rnd(&r->cur);
    5.67 +}
    5.68 +
    5.69 +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm)
    5.70 +{
    5.71 +	if(r->cur_tm != tm) {
    5.72 +		r->cur.value = anm_get_value3(&r->value, tm);
    5.73 +		r->cur.range = anm_get_value3(&r->range, tm);
    5.74 +		r->cur_tm = tm;
    5.75 +	}
    5.76 +	return psys_eval_rnd3(&r->cur);
    5.77 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/rndval.h	Mon Sep 26 18:20:11 2011 +0300
     6.3 @@ -0,0 +1,43 @@
     6.4 +#ifndef RNDVAL_H_
     6.5 +#define RNDVAL_H_
     6.6 +
     6.7 +#include <vmath.h>
     6.8 +#include <anim/anim.h>
     6.9 +#include "anm_track3.h"
    6.10 +
    6.11 +struct psys_rnd {
    6.12 +	float value, range;
    6.13 +};
    6.14 +
    6.15 +struct psys_rnd3 {
    6.16 +	vec3_t value, range;
    6.17 +};
    6.18 +
    6.19 +struct psys_anm_rnd {
    6.20 +	struct anm_track value, range;
    6.21 +	/* current cache */
    6.22 +	anm_time_t cur_tm;
    6.23 +	struct psys_rnd cur;
    6.24 +};
    6.25 +
    6.26 +struct psys_anm_rnd3 {
    6.27 +	struct anm_track3 value, range;
    6.28 +	/* current cache */
    6.29 +	anm_time_t cur_tm;
    6.30 +	struct psys_rnd3 cur;
    6.31 +};
    6.32 +
    6.33 +
    6.34 +int psys_init_anm_rnd(struct psys_anm_rnd *v);
    6.35 +void psys_destroy_anm_rnd(struct psys_anm_rnd *v);
    6.36 +int psys_init_anm_rnd3(struct psys_anm_rnd3 *v);
    6.37 +void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *v);
    6.38 +
    6.39 +float psys_eval_rnd(struct psys_rnd *r);
    6.40 +vec3_t psys_eval_rnd3(struct psys_rnd3 *r);
    6.41 +
    6.42 +float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm);
    6.43 +vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm);
    6.44 +
    6.45 +
    6.46 +#endif	/* RNDVAL_H_ */