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);