15 struct g3d_vertex *varr;
25 static int init(void);
26 static void destroy(void);
27 static void start(long trans_time);
28 static void draw(void);
29 static void draw_mesh(struct mesh *mesh);
30 static void zsort(struct mesh *m);
32 static void calc_voxel_field(void);
34 static struct screen scr = {
42 static float cam_theta, cam_phi = 25;
43 static float cam_dist = 10;
44 static struct mesh mmesh;
46 static struct metasurface *msurf;
49 #define VOL_SCALE 10.0f
50 #define VOX_DIST (VOL_SCALE / VOL_SZ)
51 #define VOL_HALF_SCALE (VOL_SCALE * 0.5f)
54 static struct metaball mball[NUM_MBALLS];
58 struct screen *metaballs_screen(void)
65 mball[0].energy = 1.2;
66 mball[1].energy = 0.8;
67 mball[2].energy = 1.0;
69 if(!(msurf = msurf_create())) {
70 fprintf(stderr, "failed to initialize metasurf\n");
73 msurf_set_resolution(msurf, VOL_SZ, VOL_SZ, VOL_SZ);
74 msurf_set_bounds(msurf, -VOL_HALF_SCALE, -VOL_HALF_SCALE, -VOL_HALF_SCALE,
75 VOL_HALF_SCALE, VOL_HALF_SCALE, VOL_HALF_SCALE);
76 msurf_set_threshold(msurf, 1.7);
77 msurf_set_inside(msurf, MSURF_GREATER);
79 mmesh.prim = G3D_TRIANGLES;
82 mmesh.vcount = mmesh.icount = 0;
87 static void destroy(void)
92 static void start(long trans_time)
94 g3d_matrix_mode(G3D_PROJECTION);
96 g3d_perspective(50.0, 1.3333333, 0.5, 100.0);
98 g3d_enable(G3D_CULL_FACE);
99 g3d_enable(G3D_LIGHTING);
100 g3d_enable(G3D_LIGHT0);
102 g3d_polygon_mode(G3D_GOURAUD);
105 static void update(void)
107 static int prev_mx, prev_my;
108 static unsigned int prev_bmask;
111 if((mouse_bmask ^ prev_bmask) == 0) {
112 int dx = mouse_x - prev_mx;
113 int dy = mouse_y - prev_my;
116 if(mouse_bmask & 1) {
117 cam_theta += dx * 1.0;
120 if(cam_phi < -90) cam_phi = -90;
121 if(cam_phi > 90) cam_phi = 90;
123 if(mouse_bmask & 4) {
124 cam_dist += dy * 0.5;
126 if(cam_dist < 0) cam_dist = 0;
133 prev_bmask = mouse_bmask;
137 float tsec = time_msec / 1000.0f;
138 static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8};
139 static float speed[] = {0.8, 1.4, 1.0};
140 static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}};
141 static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}};
143 for(i=0; i<NUM_MBALLS; i++) {
144 float t = (tsec + phase[i]) * speed[i];
147 float x = sin(t + j * M_PI / 2.0);
148 mball[i].pos[j] = offset[i][j] + x * scale[i][j];
154 msurf_polygonize(msurf);
156 mmesh.vcount = msurf_vertex_count(msurf);
157 mmesh.varr = msurf_vertices(msurf);
160 static void draw(void)
166 memset(fb_pixels, 0, fb_width * fb_height * 2);
168 for(i=0; i<120; i++) {
169 for(j=0; j<160; j++) {
170 fb_pixels[(i + 60) * 320 + (j + 80)] = 0x1e7;
173 g3d_viewport(80, 60, 160, 120);
175 g3d_matrix_mode(G3D_MODELVIEW);
177 g3d_translate(0, 0, -cam_dist);
178 g3d_rotate(cam_phi, 1, 0, 0);
179 g3d_rotate(cam_theta, 0, 1, 0);
181 g3d_light_pos(0, -10, 10, 20);
185 g3d_mtl_diffuse(0.6, 0.6, 0.6);
189 g3d_viewport(0, 0, fb_width, fb_height);
191 swap_buffers(fb_pixels);
194 static void draw_mesh(struct mesh *mesh)
197 g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
199 g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
204 struct g3d_vertex *varr;
208 static int zsort_cmp(const void *aptr, const void *bptr)
210 const float *m = zsort_cls.xform;
212 const struct g3d_vertex *va = (const struct g3d_vertex*)aptr;
213 const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr;
215 float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
216 float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
221 za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
222 zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
227 static void zsort(struct mesh *m)
229 int nfaces = m->vcount / m->prim;
231 zsort_cls.varr = m->varr;
232 zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
234 qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
237 static void calc_voxel_field(void)
242 if(!(voxptr = msurf_voxels(msurf))) {
243 fprintf(stderr, "failed to allocate voxel field\n");
247 for(i=0; i<VOL_SZ; i++) {
248 float z = -VOL_HALF_SCALE + i * VOX_DIST;
250 for(j=0; j<VOL_SZ; j++) {
251 float y = -VOL_HALF_SCALE + j * VOX_DIST;
253 for(k=0; k<VOL_SZ; k++) {
254 float x = -VOL_HALF_SCALE + k * VOX_DIST;
257 for(b=0; b<NUM_MBALLS; b++) {
258 float dx = mball[b].pos[0] - x;
259 float dy = mball[b].pos[1] - y;
260 float dz = mball[b].pos[2] - z;
262 float lensq = dx * dx + dy * dy + dz * dz;
264 val += lensq == 0.0f ? 1024.0f : mball[b].energy / lensq;