libpsys
changeset 1:874a942853ad
foobar
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Sat, 24 Sep 2011 20:44:42 +0300 |
parents | 1c8eb90a6989 |
children | 6e5342a2529a |
files | examples/simple/Makefile examples/simple/simple.c src/psys.c src/psys.h src/psys_gl.c src/psys_impl.h |
diffstat | 6 files changed, 223 insertions(+), 20 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/examples/simple/Makefile Sat Sep 24 20:44:42 2011 +0300 1.3 @@ -0,0 +1,30 @@ 1.4 +src = $(wildcard *.c) 1.5 +obj = $(src:.c=.o) 1.6 +dep = $(obj:.o=.d) 1.7 +bin = simple 1.8 + 1.9 +incdir = ../../src 1.10 +libdir = ../.. 1.11 +liba = $(libdir)/libpsys.a 1.12 + 1.13 +CC = gcc 1.14 +CFLAGS = -pedantic -Wall -g -I$(incdir) `pkg-config --cflags vmath` 1.15 +LDFLAGS = -L$(libdir) $(liba) $(libgl) -lanim `pkg-config --libs vmath` -lm 1.16 + 1.17 +ifeq ($(shell uname -s), Darwin) 1.18 + libgl = -framework OpenGL -framework GLUT 1.19 +else 1.20 + libgl = -lGL -lGLU -lglut 1.21 +endif 1.22 + 1.23 +$(bin): $(obj) $(liba) 1.24 + $(CC) -o $@ $(obj) $(LDFLAGS) 1.25 + 1.26 +-include $(dep) 1.27 + 1.28 +%.d: %.c 1.29 + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.o=.d) >$@ 1.30 + 1.31 +.PHONY: clean 1.32 +clean: 1.33 + rm -f $(obj) $(bin)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/examples/simple/simple.c Sat Sep 24 20:44:42 2011 +0300 2.3 @@ -0,0 +1,133 @@ 2.4 +#include <stdio.h> 2.5 +#include <stdlib.h> 2.6 + 2.7 +#ifndef __APPLE__ 2.8 +#include <GL/glut.h> 2.9 +#else 2.10 +#include <GLUT/glut.h> 2.11 +#endif 2.12 + 2.13 +#include <vmath.h> 2.14 +#include "psys.h" 2.15 + 2.16 +void disp(void); 2.17 +void idle(void); 2.18 +void reshape(int x, int y); 2.19 +void keyb(unsigned char key, int x, int y); 2.20 +void mouse(int bn, int state, int x, int y); 2.21 +void motion(int x, int y); 2.22 +vec3_t get_mouse_hit(float x, float y); 2.23 + 2.24 +struct psys_emitter *ps; 2.25 + 2.26 +int main(int argc, char **argv) 2.27 +{ 2.28 + glutInitWindowSize(800, 600); 2.29 + glutInit(&argc, argv); 2.30 + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 2.31 + glutCreateWindow("libpsys example: simple"); 2.32 + 2.33 + glutDisplayFunc(disp); 2.34 + glutReshapeFunc(reshape); 2.35 + glutKeyboardFunc(keyb); 2.36 + glutMouseFunc(mouse); 2.37 + glutMotionFunc(motion); 2.38 + glutIdleFunc(idle); 2.39 + 2.40 + glEnable(GL_CULL_FACE); 2.41 + 2.42 + if(!(ps = psys_create())) { 2.43 + return 1; 2.44 + } 2.45 + psys_set_grav(ps, v3_cons(0, -1, 0), 0); 2.46 + psys_set_life(ps, 2, 0); 2.47 + 2.48 + glutMainLoop(); 2.49 + return 0; 2.50 +} 2.51 + 2.52 +void disp(void) 2.53 +{ 2.54 + static unsigned int prev_msec; 2.55 + unsigned int msec = glutGet(GLUT_ELAPSED_TIME); 2.56 + 2.57 + glMatrixMode(GL_MODELVIEW); 2.58 + glLoadIdentity(); 2.59 + glTranslatef(0, 0, -10); 2.60 + 2.61 + glClear(GL_COLOR_BUFFER_BIT); 2.62 + 2.63 + psys_update(ps, (msec - prev_msec) / 1000.0); 2.64 + psys_draw(ps); 2.65 + 2.66 + glutSwapBuffers(); 2.67 +} 2.68 + 2.69 +void idle(void) 2.70 +{ 2.71 + glutPostRedisplay(); 2.72 +} 2.73 + 2.74 +void reshape(int x, int y) 2.75 +{ 2.76 + glViewport(0, 0, x, y); 2.77 + 2.78 + glMatrixMode(GL_PROJECTION); 2.79 + glLoadIdentity(); 2.80 + gluPerspective(45.0, (float)x / (float)y, 1.0, 1000.0); 2.81 +} 2.82 + 2.83 +void keyb(unsigned char key, int x, int y) 2.84 +{ 2.85 + switch(key) { 2.86 + case 27: 2.87 + exit(0); 2.88 + } 2.89 +} 2.90 + 2.91 +static int bnstate[32]; 2.92 +void mouse(int bn, int state, int x, int y) 2.93 +{ 2.94 + bnstate[bn - GLUT_LEFT_BUTTON] = state == GLUT_DOWN; 2.95 + if(bn == GLUT_LEFT_BUTTON) { 2.96 + psys_set_rate(ps, state == GLUT_DOWN ? 1.0 : 0.0, 0); 2.97 + psys_set_pos(ps, get_mouse_hit(x, y), 0); 2.98 + } 2.99 +} 2.100 + 2.101 +void motion(int x, int y) 2.102 +{ 2.103 + if(bnstate[0]) { 2.104 + psys_set_pos(ps, get_mouse_hit(x, y), 0); 2.105 + } 2.106 +} 2.107 + 2.108 +vec3_t get_mouse_hit(float x, float y) 2.109 +{ 2.110 + double mv[16], proj[16]; 2.111 + int vp[4]; 2.112 + double res_x, res_y, res_z; 2.113 + float t; 2.114 + vec3_t res, pnear, pfar; 2.115 + 2.116 + glGetDoublev(GL_MODELVIEW_MATRIX, mv); 2.117 + glGetDoublev(GL_PROJECTION_MATRIX, proj); 2.118 + glGetIntegerv(GL_VIEWPORT, vp); 2.119 + 2.120 + y = vp[3] - y; 2.121 + 2.122 + gluUnProject(x, y, 0, mv, proj, vp, &res_x, &res_y, &res_z); 2.123 + pnear.x = res_x; 2.124 + pnear.y = res_y; 2.125 + pnear.z = res_z; 2.126 + 2.127 + gluUnProject(x, y, 1, mv, proj, vp, &res_x, &res_y, &res_z); 2.128 + pfar.x = res_x; 2.129 + pfar.y = res_y; 2.130 + pfar.z = res_z; 2.131 + 2.132 + t = fabs(pnear.z) / fabs(pfar.z - pnear.z); 2.133 + res = v3_add(pnear, v3_scale(v3_sub(pfar, pnear), t)); 2.134 + 2.135 + return res; 2.136 +}
3.1 --- a/src/psys.c Sat Sep 24 07:22:07 2011 +0300 3.2 +++ b/src/psys.c Sat Sep 24 20:44:42 2011 +0300 3.3 @@ -48,15 +48,23 @@ 3.4 memset(em, 0, sizeof *em); 3.5 3.6 if(anm_init_node(&em->prs) == -1) { 3.7 + psys_destroy(em); 3.8 return -1; 3.9 } 3.10 if(anm_init_track(&em->rate) == -1) { 3.11 - anm_destroy_node(&em->prs); 3.12 + psys_destroy(em); 3.13 + return -1; 3.14 + } 3.15 + if(anm_init_track(&em->life) == -1) { 3.16 + psys_destroy(em); 3.17 return -1; 3.18 } 3.19 if(init_v3track(&em->dir) == -1) { 3.20 - anm_destroy_node(&em->prs); 3.21 - anm_destroy_track(&em->rate); 3.22 + psys_destroy(em); 3.23 + return -1; 3.24 + } 3.25 + if(init_v3track(&em->grav) == -1) { 3.26 + psys_destroy(em); 3.27 return -1; 3.28 } 3.29 3.30 @@ -106,11 +114,21 @@ 3.31 anm_set_value(&em->rate, ANM_SEC2TM(tm), rate); 3.32 } 3.33 3.34 +void psys_set_life(struct psys_emitter *em, float life, float tm) 3.35 +{ 3.36 + anm_set_value(&em->life, ANM_SEC2TM(tm), life); 3.37 +} 3.38 + 3.39 void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm) 3.40 { 3.41 set_v3value(&em->dir, ANM_SEC2TM(tm), dir); 3.42 } 3.43 3.44 +void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm) 3.45 +{ 3.46 + set_v3value(&em->grav, ANM_SEC2TM(tm), grav); 3.47 +} 3.48 + 3.49 3.50 void psys_clear_collision_planes(struct psys_emitter *em) 3.51 { 3.52 @@ -120,7 +138,7 @@ 3.53 while(plane) { 3.54 struct col_plane *tmp = plane; 3.55 plane = plane->next; 3.56 - pfree(tmp); 3.57 + free(tmp); 3.58 } 3.59 } 3.60 3.61 @@ -191,6 +209,10 @@ 3.62 return em->cur_dir; 3.63 } 3.64 3.65 +vec3_t psys_get_grav(struct psys_emitter *em) 3.66 +{ 3.67 + return em->cur_grav; 3.68 +} 3.69 3.70 /* --- update and render --- */ 3.71 3.72 @@ -205,23 +227,24 @@ 3.73 3.74 atm = ANM_SEC2TM(tm); 3.75 3.76 - em->cur_rate = anm_get_value(&em->rate, atm) 3.77 + em->cur_rate = anm_get_value(&em->rate, atm); 3.78 dt = tm - em->last_update; 3.79 3.80 /* how many particles to spawn for this interval ? */ 3.81 spawn_count = em->cur_rate * dt; 3.82 3.83 #ifndef SUB_UPDATE_POS 3.84 - em->pos = anm_get_position(&em->prs, atm); 3.85 + em->cur_pos = anm_get_position(&em->prs, atm); 3.86 #endif 3.87 em->cur_dir = get_v3value(&em->dir, atm); 3.88 em->cur_life = anm_get_value(&em->life, atm); 3.89 + em->cur_grav = get_v3value(&em->grav, atm); 3.90 3.91 spawn_dt = dt / (float)spawn_count; 3.92 for(i=0; i<spawn_count; i++) { 3.93 #ifdef SUB_UPDATE_POS 3.94 /* update emitter position for this spawning */ 3.95 - em->pos = anm_get_position(&em->prs, ANM_SEC2TM(em->last_update + spawn_dt)); 3.96 + em->cur_pos = anm_get_position(&em->prs, ANM_SEC2TM(em->last_update + spawn_dt)); 3.97 #endif 3.98 3.99 if(!(p = palloc())) { 3.100 @@ -235,7 +258,7 @@ 3.101 /* update all particles */ 3.102 p = em->plist; 3.103 while(p) { 3.104 - em->update(em, p, tm, dt, upd_cls); 3.105 + em->update(em, p, tm, dt, em->upd_cls); 3.106 p = p->next; 3.107 } 3.108 3.109 @@ -259,17 +282,17 @@ 3.110 struct psys_particle *p; 3.111 3.112 if(em->draw_start) { 3.113 - em->draw_start(em, em->cls); 3.114 + em->draw_start(em, em->draw_cls); 3.115 } 3.116 3.117 p = em->plist; 3.118 while(p) { 3.119 - em->draw(em, p, em->cls); 3.120 + em->draw(em, p, em->draw_cls); 3.121 p = p->next; 3.122 } 3.123 3.124 if(em->draw_end) { 3.125 - em->draw_end(em, em->cls); 3.126 + em->draw_end(em, em->draw_cls); 3.127 } 3.128 } 3.129 3.130 @@ -286,17 +309,19 @@ 3.131 3.132 static void update_particle(struct psys_emitter *em, struct psys_particle *p, float tm, float dt, void *cls) 3.133 { 3.134 - vec3_t forces; 3.135 + vec3_t accel; 3.136 3.137 - forces.x = em->cur_grav.x * p->mass - p->vel.x * em->drag; 3.138 - forces.y = em->cur_grav.y * p->mass - p->vel.y * em->drag; 3.139 - forces.z = em->cur_grav.z * p->mass - p->vel.z * em->drag; 3.140 + accel.x = em->cur_grav.x - p->vel.x * em->drag; 3.141 + accel.y = em->cur_grav.y - p->vel.y * em->drag; 3.142 + accel.z = em->cur_grav.z - p->vel.z * em->drag; 3.143 + 3.144 + p->vel.x += accel.x * dt; 3.145 + p->vel.y += accel.y * dt; 3.146 + p->vel.z += accel.z * dt; 3.147 3.148 p->pos.x += p->vel.x * dt; 3.149 p->pos.y += p->vel.y * dt; 3.150 p->pos.z += p->vel.z * dt; 3.151 - 3.152 - 3.153 } 3.154 3.155 /* --- v3track helper --- */ 3.156 @@ -359,7 +384,7 @@ 3.157 3.158 if(p) { 3.159 memset(p, 0, sizeof *p); 3.160 - reset_pattr(&p->attr); 3.161 + /*reset_pattr(&p->attr);*/ 3.162 } 3.163 return p; 3.164 }
4.1 --- a/src/psys.h Sat Sep 24 07:22:07 2011 +0300 4.2 +++ b/src/psys.h Sat Sep 24 20:44:42 2011 +0300 4.3 @@ -33,7 +33,9 @@ 4.4 void psys_set_pivot(struct psys_emitter *em, vec3_t pivot); 4.5 4.6 void psys_set_rate(struct psys_emitter *em, float rate, float tm); 4.7 +void psys_set_life(struct psys_emitter *em, float life, float tm); 4.8 void psys_set_dir(struct psys_emitter *em, vec3_t dir, float tm); 4.9 +void psys_set_grav(struct psys_emitter *em, vec3_t grav, float tm); 4.10 4.11 void psys_clear_collision_planes(struct psys_emitter *em); 4.12 int psys_add_collision_plane(struct psys_emitter *em, plane_t plane, float elast); 4.13 @@ -52,6 +54,7 @@ 4.14 float psys_get_rate(struct psys_emitter *em); 4.15 float psys_get_life(struct psys_emitter *em); 4.16 vec3_t psys_get_dir(struct psys_emitter *em); 4.17 +vec3_t psys_get_grav(struct psys_emitter *em); 4.18 4.19 /* update and render */ 4.20
5.1 --- a/src/psys_gl.c Sat Sep 24 07:22:07 2011 +0300 5.2 +++ b/src/psys_gl.c Sat Sep 24 20:44:42 2011 +0300 5.3 @@ -10,6 +10,15 @@ 5.4 { 5.5 float xform[16]; 5.6 5.7 + vec3_t pos = psys_get_pos(em); 5.8 + 5.9 + glPointSize(5.0); 5.10 + glBegin(GL_POINTS); 5.11 + glColor3f(1, 0, 0); 5.12 + glVertex3f(pos.x, pos.y, pos.z); 5.13 + glColor3f(1, 1, 1); 5.14 + glEnd(); 5.15 + 5.16 glMatrixMode(GL_MODELVIEW); 5.17 glPushMatrix(); 5.18
6.1 --- a/src/psys_impl.h Sat Sep 24 07:22:07 2011 +0300 6.2 +++ b/src/psys_impl.h Sat Sep 24 20:44:42 2011 +0300 6.3 @@ -50,15 +50,18 @@ 6.4 6.5 /* calculated on update */ 6.6 vec3_t cur_pos; 6.7 - qut_t cur_rot; 6.8 + quat_t cur_rot; 6.9 float cur_rate, cur_life; 6.10 vec3_t cur_dir; 6.11 + vec3_t cur_grav; 6.12 }; 6.13 6.14 6.15 struct psys_particle { 6.16 vec3_t pos, vel; 6.17 - float life, size, mass; 6.18 + float life, size; 6.19 + 6.20 + struct psys_particle *next; 6.21 }; 6.22 6.23 void psys_gl_draw_start(struct psys_emitter *em, void *cls);