X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fmetaball.c;h=94049125442905aec4a95014ca30d3e9b58a81a6;hp=a6dec99c454a70661358c6e12922fb85e1ec6d20;hb=3398fc6c4188104048f99b650a6cb90beda9b6ed;hpb=134c9e63e9a7602cd2e0a3c05557edb0c9753c74 diff --git a/src/metaball.c b/src/metaball.c index a6dec99..9404912 100644 --- a/src/metaball.c +++ b/src/metaball.c @@ -9,14 +9,7 @@ #include "gfxutil.h" #include "util.h" #include "metasurf.h" -#include "dynarr.h" - -struct mesh { - int prim; - struct g3d_vertex *varr; - int16_t *iarr; - int vcount, icount; -}; +#include "mesh.h" struct metaball { float energy; @@ -27,12 +20,8 @@ static int init(void); static void destroy(void); static void start(long trans_time); static void draw(void); -static void draw_mesh(struct mesh *mesh); -static void zsort(struct mesh *m); static void calc_voxel_field(void); -static float eval(struct metasurface *ms, float x, float y, float z); -static void emit_vertex(struct metasurface *ms, float x, float y, float z); static struct screen scr = { "metaballs", @@ -43,20 +32,20 @@ static struct screen scr = { }; static float cam_theta, cam_phi = 25; -static float cam_dist = 3; -static struct mesh mmesh; +static float cam_dist = 10; +static struct g3d_mesh mmesh; static struct metasurface *msurf; #define VOL_SZ 32 #define VOL_SCALE 10.0f +#define VOX_DIST (VOL_SCALE / VOL_SZ) #define VOL_HALF_SCALE (VOL_SCALE * 0.5f) -static float *volume; -#define VOXEL(x, y, z) (volume[(z) * VOL_SZ * VOL_SZ + (y) * VOL_SZ + (x)]) #define NUM_MBALLS 3 static struct metaball mball[NUM_MBALLS]; +static int dbg; struct screen *metaballs_screen(void) { @@ -65,11 +54,6 @@ struct screen *metaballs_screen(void) static int init(void) { - if(!(volume = malloc(VOL_SZ * VOL_SZ * VOL_SZ * sizeof *volume))) { - fprintf(stderr, "failed to allocate %dx%dx%d voxel field\n", VOL_SZ, VOL_SZ, VOL_SZ); - return -1; - } - mball[0].energy = 1.2; mball[1].energy = 0.8; mball[2].energy = 1.0; @@ -79,11 +63,10 @@ static int init(void) return -1; } msurf_set_resolution(msurf, VOL_SZ, VOL_SZ, VOL_SZ); - msurf_set_bounds(msurf, 0, 0, 0, VOL_SCALE, VOL_SCALE, VOL_SCALE); - msurf_eval_func(msurf, eval); - msurf_set_threshold(msurf, 0.5); + msurf_set_bounds(msurf, -VOL_HALF_SCALE, -VOL_HALF_SCALE, -VOL_HALF_SCALE, + VOL_HALF_SCALE, VOL_HALF_SCALE, VOL_HALF_SCALE); + msurf_set_threshold(msurf, 1.7); msurf_set_inside(msurf, MSURF_GREATER); - msurf_vertex_func(msurf, emit_vertex); mmesh.prim = G3D_TRIANGLES; mmesh.varr = 0; @@ -95,7 +78,7 @@ static int init(void) static void destroy(void) { - dynarr_free(mmesh.varr); + msurf_free(msurf); } static void start(long trans_time) @@ -108,146 +91,88 @@ static void start(long trans_time) g3d_enable(G3D_LIGHTING); g3d_enable(G3D_LIGHT0); - g3d_polygon_mode(G3D_WIRE); + g3d_polygon_mode(G3D_GOURAUD); } static void update(void) { - static int prev_mx, prev_my; - static unsigned int prev_bmask; - - if(mouse_bmask) { - if((mouse_bmask ^ prev_bmask) == 0) { - int dx = mouse_x - prev_mx; - int dy = mouse_y - prev_my; + int i, j; + float tsec = time_msec / 1000.0f; + static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8}; + static float speed[] = {0.8, 1.4, 1.0}; + static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}}; + static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}}; - if(dx || dy) { - if(mouse_bmask & 1) { - cam_theta += dx * 1.0; - cam_phi += dy * 1.0; + mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist); - if(cam_phi < -90) cam_phi = -90; - if(cam_phi > 90) cam_phi = 90; - } - if(mouse_bmask & 4) { - cam_dist += dy * 0.5; + for(i=0; iiarr) { - g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount); - } else { - g3d_draw(mesh->prim, mesh->varr, mesh->vcount); - } -} - -static struct { - struct g3d_vertex *varr; - const float *xform; -} zsort_cls; - -static int zsort_cmp(const void *aptr, const void *bptr) -{ - const int16_t *a = (const int16_t*)aptr; - const int16_t *b = (const int16_t*)bptr; - - const float *m = zsort_cls.xform; - - const struct g3d_vertex *va = zsort_cls.varr + a[0]; - const struct g3d_vertex *vb = zsort_cls.varr + b[0]; - - float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - - va = zsort_cls.varr + a[2]; - vb = zsort_cls.varr + b[2]; - - za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - - return za - zb; -} - -static void zsort(struct mesh *m) -{ - int nfaces = m->icount / m->prim; - - zsort_cls.varr = m->varr; - zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0); + g3d_viewport(0, 0, fb_width, fb_height); - qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_cmp); + swap_buffers(fb_pixels); } static void calc_voxel_field(void) { int i, j, k, b; - float *voxptr = volume; + float *voxptr; + + if(!(voxptr = msurf_voxels(msurf))) { + fprintf(stderr, "failed to allocate voxel field\n"); + abort(); + } for(i=0; i= 0 && xidx < VOL_SZ); - assert(yidx >= 0 && yidx < VOL_SZ); - assert(zidx >= 0 && zidx < VOL_SZ); - - return VOXEL(xidx, yidx, zidx); -} - -static void emit_vertex(struct metasurface *ms, float x, float y, float z) -{ - struct g3d_vertex v; - - v.x = x - VOL_HALF_SCALE; - v.y = y - VOL_HALF_SCALE; - v.z = z - VOL_HALF_SCALE; - v.r = cround64(255.0 * x / VOL_SCALE); - v.g = cround64(255.0 * y / VOL_SCALE); - v.b = cround64(255.0 * z / VOL_SCALE); - - mmesh.varr = dynarr_push(mmesh.varr, &v); - assert(mmesh.varr); - ++mmesh.vcount; + ++dbg; }