10 #include "cgmath/cgmath.h"
12 #define BBOX_SIZE 10.0f
13 #define BBOX_HEIGHT 15.0f
14 #define BBOX_HSZ (BBOX_SIZE / 2.0f)
15 #define BBOX_HH (BBOX_HEIGHT / 2.0f)
17 #define VOX_YRES (VOX_RES * BBOX_HEIGHT / BBOX_SIZE)
18 #define VOX_STEP (BBOX_SIZE / (float)VOX_RES)
19 #define VOX_YSTEP (BBOX_HEIGHT / (float)VOX_YRES)
21 #define VBUF_MAX_TRIS 256
22 #define VBUF_SIZE (VBUF_MAX_TRIS * 3)
35 static struct g3d_mesh mesh;
36 static struct g3d_vertex *vbuf;
37 static struct metasurface *msurf;
38 static struct mball *balls;
40 static struct mcapsule *caps;
43 static void update(float tsec);
44 static void draw_metaballs(void);
45 static float capsule_distsq(struct mcapsule *c, cgm_vec3 *pos);
47 static cgm_vec3 sgiv[] = {
48 {2.794170, 4.254175, 2.738066},
49 {2.794170, 4.254174, -4.358471},
50 {-2.173414, 4.254174, -4.358471},
51 {-2.173414, -2.842363, -4.358470},
52 {4.923134, -2.842363, -4.358471},
53 {4.923134, 2.125212, -4.358471},
54 {4.923134, 2.125212, 2.738066},
55 {4.923134, -4.971326, 2.738067},
56 {4.923134, -4.971326, -2.229511},
57 {-2.173413, -4.971326, -2.229511},
58 {-2.173413, -4.971325, 4.867042},
59 {2.794170, -4.971325, 4.867042},
60 {2.794170, 2.125213, 4.867042},
61 {-4.302382, 2.125213, 4.867042},
62 {-4.302383, -2.842362, 4.867042},
63 {-4.302382, -2.842363, -2.229511},
64 {-4.302382, 4.254175, -2.229512},
65 {-4.302383, 4.254175, 2.738066}
76 g3d_framebuffer(FB_WIDTH, FB_HEIGHT, framebuf);
77 g3d_viewport(0, 0, FB_WIDTH, FB_HEIGHT);
79 g3d_clear_color(0, 0, 0);
81 g3d_matrix_mode(G3D_PROJECTION);
83 g3d_perspective(60.0f, 1.33333, 0.5, 500.0);
85 g3d_enable(G3D_CULL_FACE);
86 g3d_enable(G3D_DEPTH_TEST);
87 g3d_enable(G3D_LIGHTING);
88 g3d_enable(G3D_LIGHT0);
90 g3d_polygon_mode(G3D_GOURAUD);
92 gen_torus_mesh(&mesh, 2.0, 0.7, 24, 12);
94 if(!(msurf = msurf_create())) {
97 msurf_set_threshold(msurf, 8);
98 msurf_set_inside(msurf, MSURF_GREATER);
99 msurf_set_bounds(msurf, -BBOX_HSZ, -BBOX_HH, -BBOX_HSZ, BBOX_HSZ, BBOX_HH, BBOX_HSZ);
100 msurf_set_resolution(msurf, VOX_RES, VOX_YRES, VOX_RES);
101 msurf_enable(msurf, MSURF_NORMALIZE);
103 vbuf = malloc_nf(VBUF_SIZE * sizeof *vbuf);
106 balls = calloc_nf(num_balls, sizeof *balls);
107 num_caps = sizeof sgiv / sizeof *sgiv;
108 caps = calloc_nf(num_caps, sizeof *caps);
110 for(i=0; i<num_balls; i++) {
115 cgm_mtranslate(mat, 0, -BBOX_HH / 2, 0);
116 cgm_mrotate_y(mat, -M_PI / 4.0f);
117 cgm_mrotate_x(mat, M_PI / 4.0f);
119 for(i=0; i<num_caps; i++) {
121 caps[i].end[0] = sgiv[i];
122 cgm_vscale(caps[i].end, 0.6);
123 caps[i].end[1] = sgiv[(i + 1) % num_caps];
124 cgm_vscale(caps[i].end + 1, 0.6);
126 cgm_vmul_m4v3(caps[i].end, mat);
127 cgm_vmul_m4v3(caps[i].end + 1, mat);
132 void game_shutdown(void)
136 static void update(float tsec)
141 float *vox = msurf_voxels(msurf);
143 for(i=0; i<num_balls; i++) {
144 balls[i].pos.y = sin(tsec) * BBOX_HH;
147 float y = sin(tsec) * BBOX_HH / 80.0f;
148 for(i=0; i<num_caps; i++) {
149 caps[i].end[0].y += y;
150 caps[i].end[1].y += y;
151 caps[i].len = cgm_vdist(caps[i].end, caps[i].end + 1);
154 for(i=0; i<VOX_RES; i++) {
155 pos.z = -BBOX_HSZ + i * VOX_STEP;
156 for(j=0; j<VOX_YRES; j++) {
157 pos.y = -BBOX_HH + j * VOX_YSTEP;
158 for(k=0; k<VOX_RES; k++) {
159 pos.x = -BBOX_HSZ + k * VOX_STEP;
161 /* initialize with the vertical distance for the pool */
162 energy = 5.0 / (pos.y + BBOX_HH * 0.98);
164 /* add the contribution of the balls */
165 for(n=0; n<num_balls; n++) {
166 dsq = cgm_vdist_sq(&balls[n].pos, &pos);
167 energy += balls[n].energy / dsq;
170 /* add the contribution of the capsules */
171 for(n=0; n<num_caps; n++) {
172 dsq = capsule_distsq(caps + n, &pos);
173 energy += caps[n].energy / dsq;
181 msurf_polygonize(msurf);
186 unsigned long msec = game_getmsec();
187 float tsec = (float)msec / 1000.0f;
191 g3d_clear(G3D_COLOR_BUFFER_BIT | G3D_DEPTH_BUFFER_BIT);
193 g3d_matrix_mode(G3D_MODELVIEW);
195 g3d_translate(0, 1, -15);
196 /*g3d_rotate(tsec * 50.0f, 1, 0, 0);
197 g3d_rotate(tsec * 30.0f, 0, 0, 1);
205 static void draw_metaballs(void)
207 int i, nverts, vbuf_count;
209 struct g3d_vertex *vbptr;
212 nverts = msurf_vertex_count(msurf);
213 varr = msurf_vertices(msurf);
214 narr = msurf_normals(msurf);
217 for(i=0; i<nverts; i++) {
218 vbuf_count = vbptr - vbuf;
219 if(vbuf_count >= VBUF_SIZE) {
220 g3d_draw(G3D_TRIANGLES, vbuf, vbuf_count);
238 g3d_draw(G3D_TRIANGLES, vbuf, vbptr - vbuf);
244 void game_keyboard(int key, int press)
246 if(key == 27) game_quit();
249 void game_mouse(int bn, int press, int x, int y)
253 void game_motion(int x, int y)
257 static float capsule_distsq(struct mcapsule *c, cgm_vec3 *pos)
260 cgm_vec3 pp, dir, pdir;
262 dir = c->end[1]; cgm_vsub(&dir, c->end);
264 float s = 1.0f / c->len;
269 pdir = *pos; cgm_vsub(&pdir, c->end);
270 t = cgm_vdot(&dir, &pdir);
273 return cgm_vdist_sq(c->end, pos);
276 return cgm_vdist_sq(c->end + 1, pos);
280 cgm_vadd_scaled(&pp, &dir, t);
281 return cgm_vdist_sq(&pp, pos);