# HG changeset patch # User John Tsiombikas # Date 1317098552 -10800 # Node ID 613d2bf3ea1fb97dd80de802ed8c5b05e77c56a7 # Parent 0fe624ffcb4f459776a6afc75cd771c534b6b631 almost finished with the reorg diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/pstrack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pstrack.c Tue Sep 27 07:42:32 2011 +0300 @@ -0,0 +1,97 @@ +#include "pstrack.h" + +int psys_init_track(struct psys_track *track) +{ + track->cache_tm = ANM_TIME_INVAL; + + if(anm_init_track(&track->trk) == -1) { + return -1; + } + return 0; +} + +void psys_destroy_track(struct psys_track *track) +{ + anm_destroy_track(&track->trk); +} + +int psys_init_track3(struct psys_track3 *track) +{ + track->cache_tm = ANM_TIME_INVAL; + + if(anm_init_track(&track->x) == -1) { + return -1; + } + if(anm_init_track(&track->y) == -1) { + anm_destroy_track(&track->x); + return -1; + } + if(anm_init_track(&track->z) == -1) { + anm_destroy_track(&track->x); + anm_destroy_track(&track->z); + return -1; + } + return 0; +} + +void psys_destroy_track3(struct psys_track3 *track) +{ + anm_destroy_track(&track->x); + anm_destroy_track(&track->y); + anm_destroy_track(&track->z); +} + +void psys_eval_track(struct psys_track *track, anm_time_t tm) +{ + if(track->cache_tm != tm) { + track->cache_tm = tm; + track->cache_val = anm_get_value(&track->trk, tm); + } +} + +void psys_set_value(struct psys_track *track, anm_time_t tm, float v) +{ + anm_set_value(&track->trk, tm, v); + track->cache_tm = ANM_TIME_INVAL; +} + +float psys_get_value(struct psys_track *track, anm_time_t tm) +{ + psys_eval_track(track, tm); + return track->cache_val; +} + +float psys_get_cur_value(struct psys_track *track) +{ + return track->cache_val; +} + + +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm) +{ + if(track->cache_tm != tm) { + track->cache_tm = tm; + track->cache_vec.x = anm_get_value(&track->x, tm); + track->cache_vec.y = anm_get_value(&track->y, tm); + track->cache_vec.z = anm_get_value(&track->z, tm); + } +} + +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v) +{ + anm_set_value(&track->x, tm, v.x); + anm_set_value(&track->y, tm, v.y); + anm_set_value(&track->z, tm, v.z); + track->cache_tm = ANM_TIME_INVAL; +} + +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm) +{ + psys_eval_track3(track, tm); + return track->cache_vec; +} + +vec3_t psys_get_cur_value3(struct psys_track3 *track) +{ + return track->cache_vec; +} diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/pstrack.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pstrack.h Tue Sep 27 07:42:32 2011 +0300 @@ -0,0 +1,37 @@ +#ifndef PSTRACK_H_ +#define PSTRACK_H_ + +#include +#include + +struct psys_track { + struct anm_track trk; + + anm_time_t cache_tm; + float cache_val; +}; + +struct psys_track3 { + struct anm_track x, y, z; + + anm_time_t cache_tm; + vec3_t cache_vec; +}; + +int psys_init_track(struct psys_track *track); +void psys_destroy_track(struct psys_track *track); + +int psys_init_track3(struct psys_track3 *track); +void psys_destroy_track3(struct psys_track3 *track); + +void psys_eval_track(struct psys_track *track, anm_time_t tm); +void psys_set_value(struct psys_track *track, anm_time_t tm, float v); +float psys_get_value(struct psys_track *track, anm_time_t tm); +float psys_get_cur_value(struct psys_track *track); + +void psys_eval_track3(struct psys_track3 *track, anm_time_t tm); +void psys_set_value3(struct psys_track3 *track, anm_time_t tm, vec3_t v); +vec3_t psys_get_value3(struct psys_track3 *track, anm_time_t tm); +vec3_t psys_get_cur_value3(struct psys_track3 *track); + +#endif /* PSTRACK_H_ */ diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/psys.c --- a/src/psys.c Mon Sep 26 18:25:18 2011 +0300 +++ b/src/psys.c Tue Sep 27 07:42:32 2011 +0300 @@ -3,19 +3,12 @@ #include #include #include -#include "psys_impl.h" +#include "psys.h" +#include "psys_gl.h" static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls); static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls); -static int init_anm_track_vec3(struct anm_track_vec3 *v3t); -static void destroy_anm_track_vec3(struct anm_track_vec3 *v3t); -static void set_v3value(struct anm_track_vec3 *v3t, anm_time_t tm, vec3_t v); -static vec3_t get_v3value(struct anm_track_vec3 *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; @@ -50,26 +43,13 @@ { memset(em, 0, sizeof *em); - if(anm_init_node(&em->prs) == -1) - goto err; - if(init_anm_track_vec3(&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_anm_track_vec3(&em->dir) == -1) - goto err; - if(init_anm_track_vec3(&em->dir_range) == -1) - goto err; - if(init_anm_track_vec3(&em->grav) == -1) - goto err; + if(anm_init_node(&em->prs) == -1) { + return -1; + } + if(psys_init_attr(&em->attr) == -1) { + anm_destroy_node(&em->prs); + return -1; + } em->spawn = spawn; em->update = update_particle; @@ -77,11 +57,7 @@ em->draw = psys_gl_draw; em->draw_start = psys_gl_draw_start; em->draw_end = psys_gl_draw_end; - return 0; -err: - psys_destroy(em); - return -1; } void psys_destroy(struct psys_emitter *em) @@ -95,26 +71,12 @@ pfree(tmp); } - anm_destroy_node(&em->prs); - destroy_anm_track_vec3(&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_anm_track_vec3(&em->dir); - destroy_anm_track_vec3(&em->dir_range); - destroy_anm_track_vec3(&em->grav); + psys_destroy_attr(&em->attr); } -void psys_set_texture(struct psys_emitter *em, unsigned int tex) -{ - em->tex = tex; -} - -void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm) +void psys_set_pos(struct psys_emitter *em, vec3_t pos, 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) @@ -127,42 +89,13 @@ anm_set_pivot(&em->prs, pivot); } -void psys_set_rate(struct psys_emitter *em, float rate, float tm) -{ - anm_set_value(&em->rate, ANM_SEC2TM(tm), rate); -} - -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_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) -{ - set_v3value(&em->grav, ANM_SEC2TM(tm), grav); -} - - void psys_clear_collision_planes(struct psys_emitter *em) { - struct col_plane *plane; + struct psys_plane *plane; plane = em->planes; while(plane) { - struct col_plane *tmp = plane; + struct psys_plane *tmp = plane; plane = plane->next; free(tmp); } @@ -170,7 +103,7 @@ int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast) { - struct col_plane *node; + struct psys_plane *node; if(!(node = malloc(sizeof *node))) { return -1; @@ -186,6 +119,8 @@ { p->next = em->plist; em->plist = p; + + em->pcount++; } void psys_spawn_func(struct psys_emitter *em, psys_spawn_func_t func, void *cls) @@ -216,17 +151,19 @@ float dt, spawn_dt, spawn_tm; int i, spawn_count; struct psys_particle *p, pdummy; - anm_time_t atm; + anm_time_t atm = ANM_SEC2TM(tm); assert(em->spawn && em->update); - atm = ANM_SEC2TM(tm); + dt = tm - em->last_update; + if(dt <= 0.0) { + return; + } - em->cur_rate = anm_get_value(&em->rate, atm); - dt = tm - em->last_update; + psys_eval_attr(&em->attr, atm); /* how many particles to spawn for this interval ? */ - em->spawn_acc += em->cur_rate * dt; + em->spawn_acc += psys_get_cur_value(&em->attr.rate) * dt; if(em->spawn_acc >= 1.0) { spawn_count = em->spawn_acc; em->spawn_acc = fmod(em->spawn_acc, 1.0); @@ -234,13 +171,13 @@ spawn_count = 0; } - em->cur_dir = get_v3value(&em->dir, atm); - em->cur_life = anm_get_value(&em->life, atm); - em->cur_grav = get_v3value(&em->grav, atm); - spawn_dt = dt / (float)spawn_count; spawn_tm = em->last_update; for(i=0; ipcount >= em->attr.max_particles) { + break; + } + /* update emitter position for this spawning */ em->cur_pos = anm_get_position(&em->prs, ANM_SEC2TM(spawn_tm)); @@ -298,10 +235,14 @@ static int spawn(struct psys_emitter *em, struct psys_particle *p, void *cls) { - 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; + struct psys_rnd3 rpos; + rpos.value = em->cur_pos; + rpos.range = psys_get_cur_value3(&em->attr.spawn_range); + + p->pos = psys_eval_rnd3(&rpos); + p->vel = psys_eval_anm_rnd3(&em->attr.dir, PSYS_EVAL_CUR); + p->size = psys_eval_anm_rnd(&em->attr.size, PSYS_EVAL_CUR); + p->life = psys_eval_anm_rnd(&em->attr.life, PSYS_EVAL_CUR); psys_add_particle(em, p); return 0; @@ -309,11 +250,13 @@ static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls) { - vec3_t accel; + vec3_t accel, grav; - accel.x = em->cur_grav.x - p->vel.x * em->drag; - accel.y = em->cur_grav.y - p->vel.y * em->drag; - accel.z = em->cur_grav.z - p->vel.z * em->drag; + grav = psys_get_cur_value3(&em->attr.grav); + + accel.x = grav.x - p->vel.x * em->attr.drag; + accel.y = grav.y - p->vel.y * em->attr.drag; + accel.z = grav.z - p->vel.z * em->attr.drag; p->vel.x += accel.x * dt; p->vel.y += accel.y * dt; @@ -326,48 +269,6 @@ p->life -= dt; } -/* --- anm_track_vec3 helper --- */ - -int init_anm_track_vec3(struct anm_track_vec3 *v3t) -{ - if(anm_init_track(&v3t->x) == -1) { - return -1; - } - if(anm_init_track(&v3t->y) == -1) { - anm_destroy_track(&v3t->x); - return -1; - } - if(anm_init_track(&v3t->z) == -1) { - anm_destroy_track(&v3t->x); - anm_destroy_track(&v3t->y); - return -1; - } - return 0; -} - -static void destroy_anm_track_vec3(struct anm_track_vec3 *v3t) -{ - anm_destroy_track(&v3t->x); - anm_destroy_track(&v3t->y); - anm_destroy_track(&v3t->z); -} - -static void set_v3value(struct anm_track_vec3 *v3t, anm_time_t tm, vec3_t v) -{ - anm_set_value(&v3t->x, tm, v.x); - anm_set_value(&v3t->y, tm, v.y); - anm_set_value(&v3t->z, tm, v.z); -} - -static vec3_t get_v3value(struct anm_track_vec3 *v3t, anm_time_t tm) -{ - vec3_t v; - v.x = anm_get_value(&v3t->x, tm); - v.y = anm_get_value(&v3t->y, tm); - v.z = anm_get_value(&v3t->z, tm); - return v; -} - /* --- particle allocation pool --- */ static struct psys_particle *palloc(void) @@ -384,10 +285,6 @@ } pthread_mutex_unlock(&pool_lock); - if(p) { - memset(p, 0, sizeof *p); - /*reset_pattr(&p->attr);*/ - } return p; } @@ -399,17 +296,3 @@ 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 0fe624ffcb4f -r 613d2bf3ea1f src/psys.h --- a/src/psys.h Mon Sep 26 18:25:18 2011 +0300 +++ b/src/psys.h Tue Sep 27 07:42:32 2011 +0300 @@ -4,10 +4,18 @@ #include #include #include "rndval.h" +#include "pattr.h" -struct anm_track_vec3 { - struct anm_track x, y, z; -}; +struct psys_particle; +struct psys_emitter; + +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*); + +typedef void (*psys_draw_func_t)(struct psys_emitter*, struct psys_particle*, void*); +typedef void (*psys_draw_start_func_t)(struct psys_emitter*, void*); +typedef void (*psys_draw_end_func_t)(struct psys_emitter*, void*); + struct psys_plane { plane_t p; @@ -15,29 +23,19 @@ struct psys_plane *next; }; -struct psys_particle; struct psys_emitter { - float last_update; + struct anm_node prs; + vec3_t cur_pos; - 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 */ + struct psys_attributes attr; /* list of active particles */ struct psys_particle *plist; + int pcount; /* number of active particles */ /* list of collision planes */ - struct col_plane *planes; + struct psys_plane *planes; /* custom spawn closure */ void *spawn_cls; @@ -53,16 +51,8 @@ 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; + float spawn_acc; /* partial spawn accumulator */ + float last_update; /* last update time (to calc dt) */ }; @@ -74,13 +64,6 @@ }; -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*); - -typedef void (*psys_draw_func_t)(struct psys_emitter*, struct psys_particle*, void*); -typedef void (*psys_draw_start_func_t)(struct psys_emitter*, void*); -typedef void (*psys_draw_end_func_t)(struct psys_emitter*, void*); - struct psys_emitter *psys_create(void); void psys_free(struct psys_emitter *em); @@ -89,18 +72,10 @@ void psys_destroy(struct psys_emitter *em); /* set properties */ -void psys_set_texture(struct psys_emitter *em, unsigned int tex); - -void psys_set_pos(struct psys_emitter *em, vec3_t pos, vec3_t range, float tm); +void psys_set_pos(struct psys_emitter *em, vec3_t pos, 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 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); int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast); diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/psys_gl.c --- a/src/psys_gl.c Mon Sep 26 18:25:18 2011 +0300 +++ b/src/psys_gl.c Tue Sep 27 07:42:32 2011 +0300 @@ -1,10 +1,19 @@ +#include +#include + #ifndef __APPLE__ +#ifdef WIN32 +#include +#endif + #include #else #include #endif -#include "psys_impl.h" +#include +#include "psys.h" +#include "psys_gl.h" void psys_gl_draw_start(struct psys_emitter *em, void *cls) { @@ -25,9 +34,9 @@ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - if(em->tex) { + if(em->attr.tex) { glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, em->tex); + glBindTexture(GL_TEXTURE_2D, em->attr.tex); } glDepthMask(0); @@ -63,3 +72,31 @@ glMatrixMode(GL_MODELVIEW); glPopMatrix(); } + + +unsigned int psys_gl_load_texture(const char *fname, void *cls) +{ + unsigned int tex; + void *pixels; + int xsz, ysz; + + if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32))) { + return 0; + } + + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, xsz, ysz, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + img_free_pixels(pixels); + return tex; +} + +void psys_gl_unload_texture(unsigned int tex, void *cls) +{ + glDeleteTextures(1, &tex); +} diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/rndval.c --- a/src/rndval.c Mon Sep 26 18:25:18 2011 +0300 +++ b/src/rndval.c Tue Sep 27 07:42:32 2011 +0300 @@ -3,11 +3,11 @@ int psys_init_anm_rnd(struct psys_anm_rnd *r) { - if(anm_init_track(&r->value) == -1) { + if(psys_init_track(&r->value) == -1) { return -1; } - if(anm_init_track(&r->range) == -1) { - anm_destroy_track(&r->value); + if(psys_init_track(&r->range) == -1) { + psys_destroy_track(&r->value); return -1; } return 0; @@ -15,17 +15,17 @@ void psys_destroy_anm_rnd(struct psys_anm_rnd *r) { - anm_destroy_track(&r->value); - anm_destroy_track(&r->range); + psys_destroy_track(&r->value); + psys_destroy_track(&r->range); } int psys_init_anm_rnd3(struct psys_anm_rnd3 *r) { - if(anm_init_track3(&r->value) == -1) { + if(psys_init_track3(&r->value) == -1) { return -1; } - if(anm_init_track3(&r->range) == -1) { - anm_destroy_track3(&r->value); + if(psys_init_track3(&r->range) == -1) { + psys_destroy_track3(&r->value); return -1; } return 0; @@ -33,8 +33,8 @@ void psys_destroy_anm_rnd3(struct psys_anm_rnd3 *r) { - anm_destroy_track3(&r->value); - anm_destroy_track3(&r->range); + psys_destroy_track3(&r->value); + psys_destroy_track3(&r->range); } @@ -55,20 +55,26 @@ 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; + struct psys_rnd tmp; + if(tm == ANM_TIME_INVAL) { + tmp.value = psys_get_cur_value(&r->value); + tmp.range = psys_get_cur_value(&r->range); + } else { + tmp.value = psys_get_value(&r->value, tm); + tmp.range = psys_get_value(&r->range, tm); } - return psys_eval_rnd(&r->cur); + return psys_eval_rnd(&tmp); } 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; + struct psys_rnd3 tmp; + if(tm == ANM_TIME_INVAL) { + tmp.value = psys_get_cur_value3(&r->value); + tmp.range = psys_get_cur_value3(&r->range); + } else { + tmp.value = psys_get_value3(&r->value, tm); + tmp.range = psys_get_value3(&r->range, tm); } - return psys_eval_rnd3(&r->cur); + return psys_eval_rnd3(&tmp); } diff -r 0fe624ffcb4f -r 613d2bf3ea1f src/rndval.h --- a/src/rndval.h Mon Sep 26 18:25:18 2011 +0300 +++ b/src/rndval.h Tue Sep 27 07:42:32 2011 +0300 @@ -2,8 +2,7 @@ #define RNDVAL_H_ #include -#include -#include "anm_track3.h" +#include "pstrack.h" struct psys_rnd { float value, range; @@ -14,19 +13,14 @@ }; struct psys_anm_rnd { - struct anm_track value, range; - /* current cache */ - anm_time_t cur_tm; - struct psys_rnd cur; + struct psys_track value, range; }; struct psys_anm_rnd3 { - struct anm_track3 value, range; - /* current cache */ - anm_time_t cur_tm; - struct psys_rnd3 cur; + struct psys_track3 value, range; }; +#define PSYS_EVAL_CUR ANM_TIME_INVAL int psys_init_anm_rnd(struct psys_anm_rnd *v); void psys_destroy_anm_rnd(struct psys_anm_rnd *v);