libpsys

changeset 5:613d2bf3ea1f

almost finished with the reorg
author John Tsiombikas <nuclear@mutantstargoat.com>
date Tue, 27 Sep 2011 07:42:32 +0300
parents 0fe624ffcb4f
children d774738f50f6
files src/pstrack.c src/pstrack.h src/psys.c src/psys.h src/psys_gl.c src/rndval.c src/rndval.h
diffstat 7 files changed, 264 insertions(+), 235 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/pstrack.c	Tue Sep 27 07:42:32 2011 +0300
     1.3 @@ -0,0 +1,97 @@
     1.4 +#include "pstrack.h"
     1.5 +
     1.6 +int psys_init_track(struct psys_track *track)
     1.7 +{
     1.8 +	track->cache_tm = ANM_TIME_INVAL;
     1.9 +
    1.10 +	if(anm_init_track(&track->trk) == -1) {
    1.11 +		return -1;
    1.12 +	}
    1.13 +	return 0;
    1.14 +}
    1.15 +
    1.16 +void psys_destroy_track(struct psys_track *track)
    1.17 +{
    1.18 +	anm_destroy_track(&track->trk);
    1.19 +}
    1.20 +
    1.21 +int psys_init_track3(struct psys_track3 *track)
    1.22 +{
    1.23 +	track->cache_tm = ANM_TIME_INVAL;
    1.24 +
    1.25 +	if(anm_init_track(&track->x) == -1) {
    1.26 +		return -1;
    1.27 +	}
    1.28 +	if(anm_init_track(&track->y) == -1) {
    1.29 +		anm_destroy_track(&track->x);
    1.30 +		return -1;
    1.31 +	}
    1.32 +	if(anm_init_track(&track->z) == -1) {
    1.33 +		anm_destroy_track(&track->x);
    1.34 +		anm_destroy_track(&track->z);
    1.35 +		return -1;
    1.36 +	}
    1.37 +	return 0;
    1.38 +}
    1.39 +
    1.40 +void psys_destroy_track3(struct psys_track3 *track)
    1.41 +{
    1.42 +	anm_destroy_track(&track->x);
    1.43 +	anm_destroy_track(&track->y);
    1.44 +	anm_destroy_track(&track->z);
    1.45 +}
    1.46 +
    1.47 +void psys_eval_track(struct psys_track *track, anm_time_t tm)
    1.48 +{
    1.49 +	if(track->cache_tm != tm) {
    1.50 +		track->cache_tm = tm;
    1.51 +		track->cache_val = anm_get_value(&track->trk, tm);
    1.52 +	}
    1.53 +}
    1.54 +
    1.55 +void psys_set_value(struct psys_track *track, anm_time_t tm, float v)
    1.56 +{
    1.57 +	anm_set_value(&track->trk, tm, v);
    1.58 +	track->cache_tm = ANM_TIME_INVAL;
    1.59 +}
    1.60 +
    1.61 +float psys_get_value(struct psys_track *track, anm_time_t tm)
    1.62 +{
    1.63 +	psys_eval_track(track, tm);
    1.64 +	return track->cache_val;
    1.65 +}
    1.66 +
    1.67 +float psys_get_cur_value(struct psys_track *track)
    1.68 +{
    1.69 +	return track->cache_val;
    1.70 +}
    1.71 +
    1.72 +
    1.73 +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm)
    1.74 +{
    1.75 +	if(track->cache_tm != tm) {
    1.76 +		track->cache_tm = tm;
    1.77 +		track->cache_vec.x = anm_get_value(&track->x, tm);
    1.78 +		track->cache_vec.y = anm_get_value(&track->y, tm);
    1.79 +		track->cache_vec.z = anm_get_value(&track->z, tm);
    1.80 +	}
    1.81 +}
    1.82 +
    1.83 +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v)
    1.84 +{
    1.85 +	anm_set_value(&track->x, tm, v.x);
    1.86 +	anm_set_value(&track->y, tm, v.y);
    1.87 +	anm_set_value(&track->z, tm, v.z);
    1.88 +	track->cache_tm = ANM_TIME_INVAL;
    1.89 +}
    1.90 +
    1.91 +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm)
    1.92 +{
    1.93 +	psys_eval_track3(track, tm);
    1.94 +	return track->cache_vec;
    1.95 +}
    1.96 +
    1.97 +vec3_t psys_get_cur_value3(struct psys_track3 *track)
    1.98 +{
    1.99 +	return track->cache_vec;
   1.100 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/pstrack.h	Tue Sep 27 07:42:32 2011 +0300
     2.3 @@ -0,0 +1,37 @@
     2.4 +#ifndef PSTRACK_H_
     2.5 +#define PSTRACK_H_
     2.6 +
     2.7 +#include <vmath.h>
     2.8 +#include <anim/anim.h>
     2.9 +
    2.10 +struct psys_track {
    2.11 +	struct anm_track trk;
    2.12 +
    2.13 +	anm_time_t cache_tm;
    2.14 +	float cache_val;
    2.15 +};
    2.16 +
    2.17 +struct psys_track3 {
    2.18 +	struct anm_track x, y, z;
    2.19 +
    2.20 +	anm_time_t cache_tm;
    2.21 +	vec3_t cache_vec;
    2.22 +};
    2.23 +
    2.24 +int psys_init_track(struct psys_track *track);
    2.25 +void psys_destroy_track(struct psys_track *track);
    2.26 +
    2.27 +int psys_init_track3(struct psys_track3 *track);
    2.28 +void psys_destroy_track3(struct psys_track3 *track);
    2.29 +
    2.30 +void psys_eval_track(struct psys_track *track, anm_time_t tm);
    2.31 +void psys_set_value(struct psys_track *track, anm_time_t tm, float v);
    2.32 +float psys_get_value(struct psys_track *track, anm_time_t tm);
    2.33 +float psys_get_cur_value(struct psys_track *track);
    2.34 +
    2.35 +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm);
    2.36 +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v);
    2.37 +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm);
    2.38 +vec3_t psys_get_cur_value3(struct psys_track3 *track);
    2.39 +
    2.40 +#endif	/* PSTRACK_H_ */
     3.1 --- a/src/psys.c	Mon Sep 26 18:25:18 2011 +0300
     3.2 +++ b/src/psys.c	Tue Sep 27 07:42:32 2011 +0300
     3.3 @@ -3,19 +3,12 @@
     3.4  #include <assert.h>
     3.5  #include <pthread.h>
     3.6  #include <vmath.h>
     3.7 -#include "psys_impl.h"
     3.8 +#include "psys.h"
     3.9 +#include "psys_gl.h"
    3.10  
    3.11  static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls);
    3.12  static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls);
    3.13  
    3.14 -static int init_anm_track_vec3(struct anm_track_vec3 *v3t);
    3.15 -static void destroy_anm_track_vec3(struct anm_track_vec3 *v3t);
    3.16 -static void set_v3value(struct anm_track_vec3 *v3t, anm_time_t tm, vec3_t v);
    3.17 -static vec3_t get_v3value(struct anm_track_vec3 *v3t, anm_time_t tm);
    3.18 -
    3.19 -static float random_val(float x, float range);
    3.20 -static vec3_t random_vec3(vec3_t v, vec3_t range);
    3.21 -
    3.22  /* particle pool */
    3.23  static struct psys_particle *ppool;
    3.24  static int ppool_size;
    3.25 @@ -50,26 +43,13 @@
    3.26  {
    3.27  	memset(em, 0, sizeof *em);
    3.28  
    3.29 -	if(anm_init_node(&em->prs) == -1)
    3.30 -		goto err;
    3.31 -	if(init_anm_track_vec3(&em->pos_range) == -1)
    3.32 -		goto err;
    3.33 -	if(anm_init_track(&em->rate) == -1)
    3.34 -		goto err;
    3.35 -	if(anm_init_track(&em->life) == -1)
    3.36 -		goto err;
    3.37 -	if(anm_init_track(&em->life_range) == -1)
    3.38 -		goto err;
    3.39 -	if(anm_init_track(&em->size) == -1)
    3.40 -		goto err;
    3.41 -	if(anm_init_track(&em->size_range) == -1)
    3.42 -		goto err;
    3.43 -	if(init_anm_track_vec3(&em->dir) == -1)
    3.44 -		goto err;
    3.45 -	if(init_anm_track_vec3(&em->dir_range) == -1)
    3.46 -		goto err;
    3.47 -	if(init_anm_track_vec3(&em->grav) == -1)
    3.48 -		goto err;
    3.49 +	if(anm_init_node(&em->prs) == -1) {
    3.50 +		return -1;
    3.51 +	}
    3.52 +	if(psys_init_attr(&em->attr) == -1) {
    3.53 +		anm_destroy_node(&em->prs);
    3.54 +		return -1;
    3.55 +	}
    3.56  
    3.57  	em->spawn = spawn;
    3.58  	em->update = update_particle;
    3.59 @@ -77,11 +57,7 @@
    3.60  	em->draw = psys_gl_draw;
    3.61  	em->draw_start = psys_gl_draw_start;
    3.62  	em->draw_end = psys_gl_draw_end;
    3.63 -
    3.64  	return 0;
    3.65 -err:
    3.66 -	psys_destroy(em);
    3.67 -	return -1;
    3.68  }
    3.69  
    3.70  void psys_destroy(struct psys_emitter *em)
    3.71 @@ -95,26 +71,12 @@
    3.72  		pfree(tmp);
    3.73  	}
    3.74  
    3.75 -	anm_destroy_node(&em->prs);
    3.76 -	destroy_anm_track_vec3(&em->pos_range);
    3.77 -	anm_destroy_track(&em->rate);
    3.78 -	anm_destroy_track(&em->life);
    3.79 -	anm_destroy_track(&em->size);
    3.80 -	anm_destroy_track(&em->size_range);
    3.81 -	destroy_anm_track_vec3(&em->dir);
    3.82 -	destroy_anm_track_vec3(&em->dir_range);
    3.83 -	destroy_anm_track_vec3(&em->grav);
    3.84 +	psys_destroy_attr(&em->attr);
    3.85  }
    3.86  
    3.87 -void psys_set_texture(struct psys_emitter *em, unsigned int tex)
    3.88 -{
    3.89 -	em->tex = tex;
    3.90 -}
    3.91 -
    3.92 -void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm)
    3.93 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm)
    3.94  {
    3.95  	anm_set_position(&em->prs, pos, ANM_SEC2TM(tm));
    3.96 -	set_v3value(&em->pos_range, ANM_SEC2TM(tm), range);
    3.97  }
    3.98  
    3.99  void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm)
   3.100 @@ -127,42 +89,13 @@
   3.101  	anm_set_pivot(&em->prs, pivot);
   3.102  }
   3.103  
   3.104 -void psys_set_rate(struct psys_emitter *em, float rate, float tm)
   3.105 -{
   3.106 -	anm_set_value(&em->rate, ANM_SEC2TM(tm), rate);
   3.107 -}
   3.108 -
   3.109 -void psys_set_life(struct psys_emitter *em, float life, float range, float tm)
   3.110 -{
   3.111 -	anm_set_value(&em->life, ANM_SEC2TM(tm), life);
   3.112 -	anm_set_value(&em->life_range, ANM_SEC2TM(tm), range);
   3.113 -}
   3.114 -
   3.115 -void psys_set_size(struct psys_emitter *em, float size, float range, float tm)
   3.116 -{
   3.117 -	anm_set_value(&em->size, ANM_SEC2TM(tm), size);
   3.118 -	anm_set_value(&em->size_range, ANM_SEC2TM(tm), range);
   3.119 -}
   3.120 -
   3.121 -void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm)
   3.122 -{
   3.123 -	set_v3value(&em->dir, ANM_SEC2TM(tm), dir);
   3.124 -	set_v3value(&em->dir_range, ANM_SEC2TM(tm), range);
   3.125 -}
   3.126 -
   3.127 -void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm)
   3.128 -{
   3.129 -	set_v3value(&em->grav, ANM_SEC2TM(tm), grav);
   3.130 -}
   3.131 -
   3.132 -
   3.133  void psys_clear_collision_planes(struct psys_emitter *em)
   3.134  {
   3.135 -	struct col_plane *plane;
   3.136 +	struct psys_plane *plane;
   3.137  
   3.138  	plane = em->planes;
   3.139  	while(plane) {
   3.140 -		struct col_plane *tmp = plane;
   3.141 +		struct psys_plane *tmp = plane;
   3.142  		plane = plane->next;
   3.143  		free(tmp);
   3.144  	}
   3.145 @@ -170,7 +103,7 @@
   3.146  
   3.147  int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast)
   3.148  {
   3.149 -	struct col_plane *node;
   3.150 +	struct psys_plane *node;
   3.151  
   3.152  	if(!(node = malloc(sizeof *node))) {
   3.153  		return -1;
   3.154 @@ -186,6 +119,8 @@
   3.155  {
   3.156  	p->next = em->plist;
   3.157  	em->plist = p;
   3.158 +
   3.159 +	em->pcount++;
   3.160  }
   3.161  
   3.162  void psys_spawn_func(struct psys_emitter *em, psys_spawn_func_t func, void *cls)
   3.163 @@ -216,17 +151,19 @@
   3.164  	float dt, spawn_dt, spawn_tm;
   3.165  	int i, spawn_count;
   3.166  	struct psys_particle *p, pdummy;
   3.167 -	anm_time_t atm;
   3.168 +	anm_time_t atm = ANM_SEC2TM(tm);
   3.169  
   3.170  	assert(em->spawn && em->update);
   3.171  
   3.172 -	atm = ANM_SEC2TM(tm);
   3.173 +	dt = tm - em->last_update;
   3.174 +	if(dt <= 0.0) {
   3.175 +		return;
   3.176 +	}
   3.177  
   3.178 -	em->cur_rate = anm_get_value(&em->rate, atm);
   3.179 -	dt = tm - em->last_update;
   3.180 +	psys_eval_attr(&em->attr, atm);
   3.181  
   3.182  	/* how many particles to spawn for this interval ? */
   3.183 -	em->spawn_acc += em->cur_rate * dt;
   3.184 +	em->spawn_acc += psys_get_cur_value(&em->attr.rate) * dt;
   3.185  	if(em->spawn_acc >= 1.0) {
   3.186  		spawn_count = em->spawn_acc;
   3.187  		em->spawn_acc = fmod(em->spawn_acc, 1.0);
   3.188 @@ -234,13 +171,13 @@
   3.189  		spawn_count = 0;
   3.190  	}
   3.191  
   3.192 -	em->cur_dir = get_v3value(&em->dir, atm);
   3.193 -	em->cur_life = anm_get_value(&em->life, atm);
   3.194 -	em->cur_grav = get_v3value(&em->grav, atm);
   3.195 -
   3.196  	spawn_dt = dt / (float)spawn_count;
   3.197  	spawn_tm = em->last_update;
   3.198  	for(i=0; i<spawn_count; i++) {
   3.199 +		if(em->pcount >= em->attr.max_particles) {
   3.200 +			break;
   3.201 +		}
   3.202 +
   3.203  		/* update emitter position for this spawning */
   3.204  		em->cur_pos = anm_get_position(&em->prs, ANM_SEC2TM(spawn_tm));
   3.205  
   3.206 @@ -298,10 +235,14 @@
   3.207  
   3.208  static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls)
   3.209  {
   3.210 -	p->pos = random_vec3(em->cur_pos, em->cur_pos_range);
   3.211 -	p->vel = random_vec3(em->cur_dir, em->dir_range);
   3.212 -	p->size = random_val(em->cur_size, em->cur_size_range);
   3.213 -	p->life = em->cur_life;
   3.214 +	struct psys_rnd3 rpos;
   3.215 +	rpos.value = em->cur_pos;
   3.216 +	rpos.range = psys_get_cur_value3(&em->attr.spawn_range);
   3.217 +
   3.218 +	p->pos = psys_eval_rnd3(&rpos);
   3.219 +	p->vel = psys_eval_anm_rnd3(&em->attr.dir, PSYS_EVAL_CUR);
   3.220 +	p->size = psys_eval_anm_rnd(&em->attr.size, PSYS_EVAL_CUR);
   3.221 +	p->life = psys_eval_anm_rnd(&em->attr.life, PSYS_EVAL_CUR);
   3.222  
   3.223  	psys_add_particle(em, p);
   3.224  	return 0;
   3.225 @@ -309,11 +250,13 @@
   3.226  
   3.227  static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls)
   3.228  {
   3.229 -	vec3_t accel;
   3.230 +	vec3_t accel, grav;
   3.231  
   3.232 -	accel.x = em->cur_grav.x - p->vel.x * em->drag;
   3.233 -	accel.y = em->cur_grav.y - p->vel.y * em->drag;
   3.234 -	accel.z = em->cur_grav.z - p->vel.z * em->drag;
   3.235 +	grav = psys_get_cur_value3(&em->attr.grav);
   3.236 +
   3.237 +	accel.x = grav.x - p->vel.x * em->attr.drag;
   3.238 +	accel.y = grav.y - p->vel.y * em->attr.drag;
   3.239 +	accel.z = grav.z - p->vel.z * em->attr.drag;
   3.240  
   3.241  	p->vel.x += accel.x * dt;
   3.242  	p->vel.y += accel.y * dt;
   3.243 @@ -326,48 +269,6 @@
   3.244  	p->life -= dt;
   3.245  }
   3.246  
   3.247 -/* --- anm_track_vec3 helper --- */
   3.248 -
   3.249 -int init_anm_track_vec3(struct anm_track_vec3 *v3t)
   3.250 -{
   3.251 -	if(anm_init_track(&v3t->x) == -1) {
   3.252 -		return -1;
   3.253 -	}
   3.254 -	if(anm_init_track(&v3t->y) == -1) {
   3.255 -		anm_destroy_track(&v3t->x);
   3.256 -		return -1;
   3.257 -	}
   3.258 -	if(anm_init_track(&v3t->z) == -1) {
   3.259 -		anm_destroy_track(&v3t->x);
   3.260 -		anm_destroy_track(&v3t->y);
   3.261 -		return -1;
   3.262 -	}
   3.263 -	return 0;
   3.264 -}
   3.265 -
   3.266 -static void destroy_anm_track_vec3(struct anm_track_vec3 *v3t)
   3.267 -{
   3.268 -	anm_destroy_track(&v3t->x);
   3.269 -	anm_destroy_track(&v3t->y);
   3.270 -	anm_destroy_track(&v3t->z);
   3.271 -}
   3.272 -
   3.273 -static void set_v3value(struct anm_track_vec3 *v3t, anm_time_t tm, vec3_t v)
   3.274 -{
   3.275 -	anm_set_value(&v3t->x, tm, v.x);
   3.276 -	anm_set_value(&v3t->y, tm, v.y);
   3.277 -	anm_set_value(&v3t->z, tm, v.z);
   3.278 -}
   3.279 -
   3.280 -static vec3_t get_v3value(struct anm_track_vec3 *v3t, anm_time_t tm)
   3.281 -{
   3.282 -	vec3_t v;
   3.283 -	v.x = anm_get_value(&v3t->x, tm);
   3.284 -	v.y = anm_get_value(&v3t->y, tm);
   3.285 -	v.z = anm_get_value(&v3t->z, tm);
   3.286 -	return v;
   3.287 -}
   3.288 -
   3.289  /* --- particle allocation pool --- */
   3.290  
   3.291  static struct psys_particle *palloc(void)
   3.292 @@ -384,10 +285,6 @@
   3.293  	}
   3.294  	pthread_mutex_unlock(&pool_lock);
   3.295  
   3.296 -	if(p) {
   3.297 -		memset(p, 0, sizeof *p);
   3.298 -		/*reset_pattr(&p->attr);*/
   3.299 -	}
   3.300  	return p;
   3.301  }
   3.302  
   3.303 @@ -399,17 +296,3 @@
   3.304  	ppool_size++;
   3.305  	pthread_mutex_unlock(&pool_lock);
   3.306  }
   3.307 -
   3.308 -static float random_val(float x, float range)
   3.309 -{
   3.310 -	return x + range * (float)rand() / (float)RAND_MAX - 0.5 * range;
   3.311 -}
   3.312 -
   3.313 -static vec3_t random_vec3(vec3_t v, vec3_t range)
   3.314 -{
   3.315 -	vec3_t res;
   3.316 -	res.x = random_val(v.x, range.x);
   3.317 -	res.y = random_val(v.y, range.y);
   3.318 -	res.z = random_val(v.z, range.z);
   3.319 -	return res;
   3.320 -}
     4.1 --- a/src/psys.h	Mon Sep 26 18:25:18 2011 +0300
     4.2 +++ b/src/psys.h	Tue Sep 27 07:42:32 2011 +0300
     4.3 @@ -4,10 +4,18 @@
     4.4  #include <vmath.h>
     4.5  #include <anim/anim.h>
     4.6  #include "rndval.h"
     4.7 +#include "pattr.h"
     4.8  
     4.9 -struct anm_track_vec3 {
    4.10 -	struct anm_track x, y, z;
    4.11 -};
    4.12 +struct psys_particle;
    4.13 +struct psys_emitter;
    4.14 +
    4.15 +typedef int (*psys_spawn_func_t)(struct psys_emitter*, struct psys_particle*, void*);
    4.16 +typedef void (*psys_update_func_t)(struct psys_emitter*, struct psys_particle*, float, float, void*);
    4.17 +
    4.18 +typedef void (*psys_draw_func_t)(struct psys_emitter*, struct psys_particle*, void*);
    4.19 +typedef void (*psys_draw_start_func_t)(struct psys_emitter*, void*);
    4.20 +typedef void (*psys_draw_end_func_t)(struct psys_emitter*, void*);
    4.21 +
    4.22  
    4.23  struct psys_plane {
    4.24  	plane_t p;
    4.25 @@ -15,29 +23,19 @@
    4.26  	struct psys_plane *next;
    4.27  };
    4.28  
    4.29 -struct psys_particle;
    4.30  
    4.31  struct psys_emitter {
    4.32 -	float last_update;
    4.33 +	struct anm_node prs;
    4.34 +	vec3_t cur_pos;
    4.35  
    4.36 -	unsigned int tex;
    4.37 -
    4.38 -	struct anm_node prs;
    4.39 -	struct anm_track_vec3 pos_range;
    4.40 -
    4.41 -	struct anm_track rate;
    4.42 -	struct anm_track life, life_range;
    4.43 -	struct anm_track size, size_range;
    4.44 -	struct anm_track_vec3 dir, dir_range;
    4.45 -	struct anm_track_vec3 grav;
    4.46 -
    4.47 -	float drag;	/* I don't think this needs to animate */
    4.48 +	struct psys_attributes attr;
    4.49  
    4.50  	/* list of active particles */
    4.51  	struct psys_particle *plist;
    4.52 +	int pcount;	/* number of active particles */
    4.53  
    4.54  	/* list of collision planes */
    4.55 -	struct col_plane *planes;
    4.56 +	struct psys_plane *planes;
    4.57  
    4.58  	/* custom spawn closure */
    4.59  	void *spawn_cls;
    4.60 @@ -53,16 +51,8 @@
    4.61  	psys_draw_start_func_t draw_start;
    4.62  	psys_draw_end_func_t draw_end;
    4.63  
    4.64 -	/* calculated on update */
    4.65 -	vec3_t cur_pos, cur_pos_range;
    4.66 -	quat_t cur_rot;
    4.67 -	float cur_rate, cur_life;
    4.68 -	float cur_size, cur_size_range;
    4.69 -	vec3_t cur_dir;
    4.70 -	vec3_t cur_grav;
    4.71 -
    4.72 -	/* partial spawn accumulator */
    4.73 -	float spawn_acc;
    4.74 +	float spawn_acc;	/* partial spawn accumulator */
    4.75 +	float last_update;	/* last update time (to calc dt) */
    4.76  };
    4.77  
    4.78  
    4.79 @@ -74,13 +64,6 @@
    4.80  };
    4.81  
    4.82  
    4.83 -typedef int (*psys_spawn_func_t)(struct psys_emitter*, struct psys_particle*, void*);
    4.84 -typedef void (*psys_update_func_t)(struct psys_emitter*, struct psys_particle*, float, float, void*);
    4.85 -
    4.86 -typedef void (*psys_draw_func_t)(struct psys_emitter*, struct psys_particle*, void*);
    4.87 -typedef void (*psys_draw_start_func_t)(struct psys_emitter*, void*);
    4.88 -typedef void (*psys_draw_end_func_t)(struct psys_emitter*, void*);
    4.89 -
    4.90  
    4.91  struct psys_emitter *psys_create(void);
    4.92  void psys_free(struct psys_emitter *em);
    4.93 @@ -89,18 +72,10 @@
    4.94  void psys_destroy(struct psys_emitter *em);
    4.95  
    4.96  /* set properties */
    4.97 -void psys_set_texture(struct psys_emitter *em, unsigned int tex);
    4.98 -
    4.99 -void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm);
   4.100 +void psys_set_pos(struct psys_emitter *em, vec3_t pos, float tm);
   4.101  void psys_set_rot(struct psys_emitter *em, quat_t rot, float tm);
   4.102  void psys_set_pivot(struct psys_emitter *em, vec3_t pivot);
   4.103  
   4.104 -void psys_set_rate(struct psys_emitter *em, float rate, float tm);
   4.105 -void psys_set_life(struct psys_emitter *em, float life, float range, float tm);
   4.106 -void psys_set_size(struct psys_emitter *em, float size, float range, float tm);
   4.107 -void psys_set_dir(struct psys_emitter *em, vec3_t dir, vec3_t range, float tm);
   4.108 -void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm);
   4.109 -
   4.110  void psys_clear_collision_planes(struct psys_emitter *em);
   4.111  int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast);
   4.112  
     5.1 --- a/src/psys_gl.c	Mon Sep 26 18:25:18 2011 +0300
     5.2 +++ b/src/psys_gl.c	Tue Sep 27 07:42:32 2011 +0300
     5.3 @@ -1,10 +1,19 @@
     5.4 +#include <string.h>
     5.5 +#include <errno.h>
     5.6 +
     5.7  #ifndef __APPLE__
     5.8 +#ifdef WIN32
     5.9 +#include <windows.h>
    5.10 +#endif
    5.11 +
    5.12  #include <GL/gl.h>
    5.13  #else
    5.14  #include <OpenGL/gl.h>
    5.15  #endif
    5.16  
    5.17 -#include "psys_impl.h"
    5.18 +#include <imago2.h>
    5.19 +#include "psys.h"
    5.20 +#include "psys_gl.h"
    5.21  
    5.22  void psys_gl_draw_start(struct psys_emitter *em, void *cls)
    5.23  {
    5.24 @@ -25,9 +34,9 @@
    5.25  	glEnable(GL_BLEND);
    5.26  	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    5.27  
    5.28 -	if(em->tex) {
    5.29 +	if(em->attr.tex) {
    5.30  		glEnable(GL_TEXTURE_2D);
    5.31 -		glBindTexture(GL_TEXTURE_2D, em->tex);
    5.32 +		glBindTexture(GL_TEXTURE_2D, em->attr.tex);
    5.33  	}
    5.34  
    5.35  	glDepthMask(0);
    5.36 @@ -63,3 +72,31 @@
    5.37  	glMatrixMode(GL_MODELVIEW);
    5.38  	glPopMatrix();
    5.39  }
    5.40 +
    5.41 +
    5.42 +unsigned int psys_gl_load_texture(const char *fname, void *cls)
    5.43 +{
    5.44 +	unsigned int tex;
    5.45 +	void *pixels;
    5.46 +	int xsz, ysz;
    5.47 +
    5.48 +	if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) {
    5.49 +		return 0;
    5.50 +	}
    5.51 +
    5.52 +	glGenTextures(1, &tex);
    5.53 +	glBindTexture(GL_TEXTURE_2D, tex);
    5.54 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    5.55 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    5.56 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    5.57 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    5.58 +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, xsz, ysz, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    5.59 +
    5.60 +	img_free_pixels(pixels);
    5.61 +	return tex;
    5.62 +}
    5.63 +
    5.64 +void psys_gl_unload_texture(unsigned int tex, void *cls)
    5.65 +{
    5.66 +	glDeleteTextures(1, &tex);
    5.67 +}
     6.1 --- a/src/rndval.c	Mon Sep 26 18:25:18 2011 +0300
     6.2 +++ b/src/rndval.c	Tue Sep 27 07:42:32 2011 +0300
     6.3 @@ -3,11 +3,11 @@
     6.4  
     6.5  int psys_init_anm_rnd(struct psys_anm_rnd *r)
     6.6  {
     6.7 -	if(anm_init_track(&r->value) == -1) {
     6.8 +	if(psys_init_track(&r->value) == -1) {
     6.9  		return -1;
    6.10  	}
    6.11 -	if(anm_init_track(&r->range) == -1) {
    6.12 -		anm_destroy_track(&r->value);
    6.13 +	if(psys_init_track(&r->range) == -1) {
    6.14 +		psys_destroy_track(&r->value);
    6.15  		return -1;
    6.16  	}
    6.17  	return 0;
    6.18 @@ -15,17 +15,17 @@
    6.19  
    6.20  void psys_destroy_anm_rnd(struct psys_anm_rnd *r)
    6.21  {
    6.22 -	anm_destroy_track(&r->value);
    6.23 -	anm_destroy_track(&r->range);
    6.24 +	psys_destroy_track(&r->value);
    6.25 +	psys_destroy_track(&r->range);
    6.26  }
    6.27  
    6.28  int psys_init_anm_rnd3(struct psys_anm_rnd3 *r)
    6.29  {
    6.30 -	if(anm_init_track3(&r->value) == -1) {
    6.31 +	if(psys_init_track3(&r->value) == -1) {
    6.32  		return -1;
    6.33  	}
    6.34 -	if(anm_init_track3(&r->range) == -1) {
    6.35 -		anm_destroy_track3(&r->value);
    6.36 +	if(psys_init_track3(&r->range) == -1) {
    6.37 +		psys_destroy_track3(&r->value);
    6.38  		return -1;
    6.39  	}
    6.40  	return 0;
    6.41 @@ -33,8 +33,8 @@
    6.42  
    6.43  void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *r)
    6.44  {
    6.45 -	anm_destroy_track3(&r->value);
    6.46 -	anm_destroy_track3(&r->range);
    6.47 +	psys_destroy_track3(&r->value);
    6.48 +	psys_destroy_track3(&r->range);
    6.49  }
    6.50  
    6.51  
    6.52 @@ -55,20 +55,26 @@
    6.53  
    6.54  float psys_eval_anm_rnd(struct psys_anm_rnd *r, anm_time_t tm)
    6.55  {
    6.56 -	if(r->cur_tm != tm) {
    6.57 -		r->cur.value = anm_get_value(&r->value, tm);
    6.58 -		r->cur.range = anm_get_value(&r->range, tm);
    6.59 -		r->cur_tm = tm;
    6.60 +	struct psys_rnd tmp;
    6.61 +	if(tm == ANM_TIME_INVAL) {
    6.62 +		tmp.value = psys_get_cur_value(&r->value);
    6.63 +		tmp.range = psys_get_cur_value(&r->range);
    6.64 +	} else {
    6.65 +		tmp.value = psys_get_value(&r->value, tm);
    6.66 +		tmp.range = psys_get_value(&r->range, tm);
    6.67  	}
    6.68 -	return psys_eval_rnd(&r->cur);
    6.69 +	return psys_eval_rnd(&tmp);
    6.70  }
    6.71  
    6.72  vec3_t psys_eval_anm_rnd3(struct psys_anm_rnd3 *r, anm_time_t tm)
    6.73  {
    6.74 -	if(r->cur_tm != tm) {
    6.75 -		r->cur.value = anm_get_value3(&r->value, tm);
    6.76 -		r->cur.range = anm_get_value3(&r->range, tm);
    6.77 -		r->cur_tm = tm;
    6.78 +	struct psys_rnd3 tmp;
    6.79 +	if(tm == ANM_TIME_INVAL) {
    6.80 +		tmp.value = psys_get_cur_value3(&r->value);
    6.81 +		tmp.range = psys_get_cur_value3(&r->range);
    6.82 +	} else {
    6.83 +		tmp.value = psys_get_value3(&r->value, tm);
    6.84 +		tmp.range = psys_get_value3(&r->range, tm);
    6.85  	}
    6.86 -	return psys_eval_rnd3(&r->cur);
    6.87 +	return psys_eval_rnd3(&tmp);
    6.88  }
     7.1 --- a/src/rndval.h	Mon Sep 26 18:25:18 2011 +0300
     7.2 +++ b/src/rndval.h	Tue Sep 27 07:42:32 2011 +0300
     7.3 @@ -2,8 +2,7 @@
     7.4  #define RNDVAL_H_
     7.5  
     7.6  #include <vmath.h>
     7.7 -#include <anim/anim.h>
     7.8 -#include "anm_track3.h"
     7.9 +#include "pstrack.h"
    7.10  
    7.11  struct psys_rnd {
    7.12  	float value, range;
    7.13 @@ -14,19 +13,14 @@
    7.14  };
    7.15  
    7.16  struct psys_anm_rnd {
    7.17 -	struct anm_track value, range;
    7.18 -	/* current cache */
    7.19 -	anm_time_t cur_tm;
    7.20 -	struct psys_rnd cur;
    7.21 +	struct psys_track value, range;
    7.22  };
    7.23  
    7.24  struct psys_anm_rnd3 {
    7.25 -	struct anm_track3 value, range;
    7.26 -	/* current cache */
    7.27 -	anm_time_t cur_tm;
    7.28 -	struct psys_rnd3 cur;
    7.29 +	struct psys_track3 value, range;
    7.30  };
    7.31  
    7.32 +#define PSYS_EVAL_CUR	ANM_TIME_INVAL
    7.33  
    7.34  int psys_init_anm_rnd(struct psys_anm_rnd *v);
    7.35  void psys_destroy_anm_rnd(struct psys_anm_rnd *v);