# HG changeset patch # User John Tsiombikas # Date 1316886282 -10800 # Node ID 874a942853ad019b982177491baa86417e65dab9 # Parent 1c8eb90a698933109711a6e4d6a1576cf209e1d1 foobar diff -r 1c8eb90a6989 -r 874a942853ad examples/simple/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/simple/Makefile Sat Sep 24 20:44:42 2011 +0300 @@ -0,0 +1,30 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +dep = $(obj:.o=.d) +bin = simple + +incdir = ../../src +libdir = ../.. +liba = $(libdir)/libpsys.a + +CC = gcc +CFLAGS = -pedantic -Wall -g -I$(incdir) `pkg-config --cflags vmath` +LDFLAGS = -L$(libdir) $(liba) $(libgl) -lanim `pkg-config --libs vmath` -lm + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT +else + libgl = -lGL -lGLU -lglut +endif + +$(bin): $(obj) $(liba) + $(CC) -o $@ $(obj) $(LDFLAGS) + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.o=.d) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 1c8eb90a6989 -r 874a942853ad examples/simple/simple.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/simple/simple.c Sat Sep 24 20:44:42 2011 +0300 @@ -0,0 +1,133 @@ +#include +#include + +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include +#include "psys.h" + +void disp(void); +void idle(void); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); +vec3_t get_mouse_hit(float x, float y); + +struct psys_emitter *ps; + +int main(int argc, char **argv) +{ + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutCreateWindow("libpsys example: simple"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutIdleFunc(idle); + + glEnable(GL_CULL_FACE); + + if(!(ps = psys_create())) { + return 1; + } + psys_set_grav(ps, v3_cons(0, -1, 0), 0); + psys_set_life(ps, 2, 0); + + glutMainLoop(); + return 0; +} + +void disp(void) +{ + static unsigned int prev_msec; + unsigned int msec = glutGet(GLUT_ELAPSED_TIME); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -10); + + glClear(GL_COLOR_BUFFER_BIT); + + psys_update(ps, (msec - prev_msec) / 1000.0); + psys_draw(ps); + + glutSwapBuffers(); +} + +void idle(void) +{ + glutPostRedisplay(); +} + +void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0); +} + +void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + } +} + +static int bnstate[32]; +void mouse(int bn, int state, int x, int y) +{ + bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN; + if(bn == GLUT_LEFT_BUTTON) { + psys_set_rate(ps, state == GLUT_DOWN ? 1.0 : 0.0, 0); + psys_set_pos(ps, get_mouse_hit(x, y), 0); + } +} + +void motion(int x, int y) +{ + if(bnstate[0]) { + psys_set_pos(ps, get_mouse_hit(x, y), 0); + } +} + +vec3_t get_mouse_hit(float x, float y) +{ + double mv[16], proj[16]; + int vp[4]; + double res_x, res_y, res_z; + float t; + vec3_t res, pnear, pfar; + + glGetDoublev(GL_MODELVIEW_MATRIX, mv); + glGetDoublev(GL_PROJECTION_MATRIX, proj); + glGetIntegerv(GL_VIEWPORT, vp); + + y = vp[3] - y; + + gluUnProject(x, y, 0, mv, proj, vp, &res_x, &res_y, &res_z); + pnear.x = res_x; + pnear.y = res_y; + pnear.z = res_z; + + gluUnProject(x, y, 1, mv, proj, vp, &res_x, &res_y, &res_z); + pfar.x = res_x; + pfar.y = res_y; + pfar.z = res_z; + + t = fabs(pnear.z) / fabs(pfar.z - pnear.z); + res = v3_add(pnear, v3_scale(v3_sub(pfar, pnear), t)); + + return res; +} diff -r 1c8eb90a6989 -r 874a942853ad src/psys.c --- a/src/psys.c Sat Sep 24 07:22:07 2011 +0300 +++ b/src/psys.c Sat Sep 24 20:44:42 2011 +0300 @@ -48,15 +48,23 @@ memset(em, 0, sizeof *em); if(anm_init_node(&em->prs) == -1) { + psys_destroy(em); return -1; } if(anm_init_track(&em->rate) == -1) { - anm_destroy_node(&em->prs); + psys_destroy(em); + return -1; + } + if(anm_init_track(&em->life) == -1) { + psys_destroy(em); return -1; } if(init_v3track(&em->dir) == -1) { - anm_destroy_node(&em->prs); - anm_destroy_track(&em->rate); + psys_destroy(em); + return -1; + } + if(init_v3track(&em->grav) == -1) { + psys_destroy(em); return -1; } @@ -106,11 +114,21 @@ anm_set_value(&em->rate, ANM_SEC2TM(tm), rate); } +void psys_set_life(struct psys_emitter *em, float life, float tm) +{ + anm_set_value(&em->life, ANM_SEC2TM(tm), life); +} + void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm) { set_v3value(&em->dir, ANM_SEC2TM(tm), dir); } +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) { @@ -120,7 +138,7 @@ while(plane) { struct col_plane *tmp = plane; plane = plane->next; - pfree(tmp); + free(tmp); } } @@ -191,6 +209,10 @@ return em->cur_dir; } +vec3_t psys_get_grav(struct psys_emitter *em) +{ + return em->cur_grav; +} /* --- update and render --- */ @@ -205,23 +227,24 @@ atm = ANM_SEC2TM(tm); - em->cur_rate = anm_get_value(&em->rate, atm) + em->cur_rate = anm_get_value(&em->rate, atm); dt = tm - em->last_update; /* how many particles to spawn for this interval ? */ spawn_count = em->cur_rate * dt; #ifndef SUB_UPDATE_POS - em->pos = anm_get_position(&em->prs, atm); + em->cur_pos = anm_get_position(&em->prs, atm); #endif 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; for(i=0; ipos = anm_get_position(&em->prs, ANM_SEC2TM(em->last_update + spawn_dt)); + em->cur_pos = anm_get_position(&em->prs, ANM_SEC2TM(em->last_update + spawn_dt)); #endif if(!(p = palloc())) { @@ -235,7 +258,7 @@ /* update all particles */ p = em->plist; while(p) { - em->update(em, p, tm, dt, upd_cls); + em->update(em, p, tm, dt, em->upd_cls); p = p->next; } @@ -259,17 +282,17 @@ struct psys_particle *p; if(em->draw_start) { - em->draw_start(em, em->cls); + em->draw_start(em, em->draw_cls); } p = em->plist; while(p) { - em->draw(em, p, em->cls); + em->draw(em, p, em->draw_cls); p = p->next; } if(em->draw_end) { - em->draw_end(em, em->cls); + em->draw_end(em, em->draw_cls); } } @@ -286,17 +309,19 @@ static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls) { - vec3_t forces; + vec3_t accel; - forces.x = em->cur_grav.x * p->mass - p->vel.x * em->drag; - forces.y = em->cur_grav.y * p->mass - p->vel.y * em->drag; - forces.z = em->cur_grav.z * p->mass - p->vel.z * em->drag; + 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; + + p->vel.x += accel.x * dt; + p->vel.y += accel.y * dt; + p->vel.z += accel.z * dt; p->pos.x += p->vel.x * dt; p->pos.y += p->vel.y * dt; p->pos.z += p->vel.z * dt; - - } /* --- v3track helper --- */ @@ -359,7 +384,7 @@ if(p) { memset(p, 0, sizeof *p); - reset_pattr(&p->attr); + /*reset_pattr(&p->attr);*/ } return p; } diff -r 1c8eb90a6989 -r 874a942853ad src/psys.h --- a/src/psys.h Sat Sep 24 07:22:07 2011 +0300 +++ b/src/psys.h Sat Sep 24 20:44:42 2011 +0300 @@ -33,7 +33,9 @@ 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_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); @@ -52,6 +54,7 @@ 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 */ diff -r 1c8eb90a6989 -r 874a942853ad src/psys_gl.c --- a/src/psys_gl.c Sat Sep 24 07:22:07 2011 +0300 +++ b/src/psys_gl.c Sat Sep 24 20:44:42 2011 +0300 @@ -10,6 +10,15 @@ { float xform[16]; + vec3_t pos = psys_get_pos(em); + + glPointSize(5.0); + glBegin(GL_POINTS); + glColor3f(1, 0, 0); + glVertex3f(pos.x, pos.y, pos.z); + glColor3f(1, 1, 1); + glEnd(); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); diff -r 1c8eb90a6989 -r 874a942853ad src/psys_impl.h --- a/src/psys_impl.h Sat Sep 24 07:22:07 2011 +0300 +++ b/src/psys_impl.h Sat Sep 24 20:44:42 2011 +0300 @@ -50,15 +50,18 @@ /* calculated on update */ vec3_t cur_pos; - qut_t cur_rot; + quat_t cur_rot; float cur_rate, cur_life; vec3_t cur_dir; + vec3_t cur_grav; }; struct psys_particle { vec3_t pos, vel; - float life, size, mass; + float life, size; + + struct psys_particle *next; }; void psys_gl_draw_start(struct psys_emitter *em, void *cls);