10 #include "cgmath/cgmath.h"
13 #define BBOX_SIZE 10.0f
14 #define BBOX_HEIGHT 15.0f
15 #define BBOX_HSZ (BBOX_SIZE / 2.0f)
16 #define BBOX_HH (BBOX_HEIGHT / 2.0f)
18 #define VOX_YRES (VOX_RES * BBOX_HEIGHT / BBOX_SIZE)
19 #define VOX_STEP (BBOX_SIZE / (float)VOX_RES)
20 #define VOX_YSTEP (BBOX_HEIGHT / (float)VOX_YRES)
22 #define VBUF_MAX_TRIS 256
23 #define VBUF_SIZE (VBUF_MAX_TRIS * 3)
25 static struct g3d_vertex *vbuf;
26 static struct metasurface *msurf;
27 static struct mobject **mobj;
30 static int num_mobj, cur_obj;
33 static int mousebn[3];
34 static int mousex, mousey;
35 static float cam_theta, cam_phi;
38 static void update(float tsec);
39 static void draw_metaballs(void);
47 g3d_framebuffer(FB_WIDTH, FB_HEIGHT, framebuf);
48 g3d_viewport(0, 0, FB_WIDTH, FB_HEIGHT);
50 g3d_clear_color(0, 0, 0);
52 g3d_matrix_mode(G3D_PROJECTION);
54 g3d_perspective(60.0f, 1.33333, 0.5, 500.0);
56 g3d_enable(G3D_CULL_FACE);
57 g3d_enable(G3D_DEPTH_TEST);
58 g3d_enable(G3D_LIGHTING);
59 g3d_enable(G3D_LIGHT0);
61 g3d_polygon_mode(G3D_GOURAUD);
63 if(!(msurf = msurf_create())) {
66 msurf_set_threshold(msurf, 8);
67 msurf_set_inside(msurf, MSURF_GREATER);
68 msurf_set_bounds(msurf, -BBOX_HSZ, -BBOX_HH, -BBOX_HSZ, BBOX_HSZ, BBOX_HH, BBOX_HSZ);
69 msurf_set_resolution(msurf, VOX_RES, VOX_YRES, VOX_RES);
70 msurf_enable(msurf, MSURF_NORMALIZE);
72 vbuf = malloc_nf(VBUF_SIZE * sizeof *vbuf);
75 mobj = malloc(num_mobj * sizeof *mobj);
76 mobj[0] = metaobj_sgi();
77 mobj[1] = metaobj_sflake();
82 void game_shutdown(void)
86 static void update(float tsec)
91 float *vox = msurf_voxels(msurf);
93 mobj[cur_obj]->update(mobj[cur_obj], tsec);
95 for(i=0; i<VOX_RES; i++) {
96 pos.z = -BBOX_HSZ + i * VOX_STEP;
97 for(j=0; j<VOX_YRES; j++) {
98 pos.y = -BBOX_HH + j * VOX_YSTEP;
99 for(k=0; k<VOX_RES; k++) {
100 pos.x = -BBOX_HSZ + k * VOX_STEP;
102 /* initialize with the vertical distance for the pool */
103 energy = 5.0 / (pos.y + BBOX_HH * 0.98);
105 energy += mobj[cur_obj]->eval(mobj[cur_obj], &pos);
112 msurf_polygonize(msurf);
117 unsigned long msec = game_getmsec();
118 float tsec = (float)msec / 1000.0f;
122 g3d_clear(G3D_COLOR_BUFFER_BIT | G3D_DEPTH_BUFFER_BIT);
124 g3d_matrix_mode(G3D_MODELVIEW);
126 g3d_translate(0, 1, -15);
127 g3d_rotate(cam_phi, 1, 0, 0);
128 g3d_rotate(cam_theta, 0, 1, 0);
129 /*g3d_rotate(tsec * 50.0f, 1, 0, 0);
130 g3d_rotate(tsec * 30.0f, 0, 0, 1);
138 static void draw_metaballs(void)
140 int i, nverts, vbuf_count;
142 struct g3d_vertex *vbptr;
145 nverts = msurf_vertex_count(msurf);
146 varr = msurf_vertices(msurf);
147 narr = msurf_normals(msurf);
150 for(i=0; i<nverts; i++) {
151 vbuf_count = vbptr - vbuf;
152 if(vbuf_count >= VBUF_SIZE) {
153 g3d_draw(G3D_TRIANGLES, vbuf, vbuf_count);
171 g3d_draw(G3D_TRIANGLES, vbuf, vbptr - vbuf);
177 void game_keyboard(int key, int press)
179 if(key == 27) game_quit();
182 void game_mouse(int bn, int press, int x, int y)
189 if(press && !grabbed) {
191 } else if(!press && grabbed) {
197 void game_motion(int x, int y)
204 if((dx | dy) == 0) return;
208 mobj[cur_obj]->pos.x += dx * 0.1;
209 mobj[cur_obj]->pos.y -= dy * 0.1;
213 cam_theta += (float)dx * (0.6f * 1.333333333f);
214 cam_phi += (float)dy * 0.6f;
215 if(cam_phi < -90) cam_phi = -90;
216 if(cam_phi > 90) cam_phi = 90;