#include "mesh.h"
#include "metasurf.h"
#include "util.h"
+#include "cgmath/cgmath.h"
#define BBOX_SIZE 10.0f
+#define BBOX_HEIGHT 15.0f
#define BBOX_HSZ (BBOX_SIZE / 2.0f)
+#define BBOX_HH (BBOX_HEIGHT / 2.0f)
#define VOX_RES 30
+#define VOX_YRES (VOX_RES * BBOX_HEIGHT / BBOX_SIZE)
#define VOX_STEP (BBOX_SIZE / (float)VOX_RES)
+#define VOX_YSTEP (BBOX_HEIGHT / (float)VOX_YRES)
#define VBUF_MAX_TRIS 256
#define VBUF_SIZE (VBUF_MAX_TRIS * 3)
struct mball {
float energy;
- float x, y, z;
+ cgm_vec3 pos;
+};
+
+struct mcapsule {
+ float energy;
+ cgm_vec3 end[2];
+ float len;
};
static struct g3d_mesh mesh;
static struct metasurface *msurf;
static struct mball *balls;
static int num_balls;
+static struct mcapsule *caps;
+static int num_caps;
static void update(float tsec);
static void draw_metaballs(void);
+static float capsule_distsq(struct mcapsule *c, cgm_vec3 *pos);
+
+static cgm_vec3 sgiv[] = {
+ {2.794170, 4.254175, 2.738066},
+ {2.794170, 4.254174, -4.358471},
+ {-2.173414, 4.254174, -4.358471},
+ {-2.173414, -2.842363, -4.358470},
+ {4.923134, -2.842363, -4.358471},
+ {4.923134, 2.125212, -4.358471},
+ {4.923134, 2.125212, 2.738066},
+ {4.923134, -4.971326, 2.738067},
+ {4.923134, -4.971326, -2.229511},
+ {-2.173413, -4.971326, -2.229511},
+ {-2.173413, -4.971325, 4.867042},
+ {2.794170, -4.971325, 4.867042},
+ {2.794170, 2.125213, 4.867042},
+ {-4.302382, 2.125213, 4.867042},
+ {-4.302383, -2.842362, 4.867042},
+ {-4.302382, -2.842363, -2.229511},
+ {-4.302382, 4.254175, -2.229512},
+ {-4.302383, 4.254175, 2.738066}
+};
int game_init(void)
{
int i;
+ float mat[16];
init_colormgr();
g3d_init();
- g3d_framebuffer(320, 200, framebuf);
- g3d_viewport(0, 0, 320, 200);
+ g3d_framebuffer(FB_WIDTH, FB_HEIGHT, framebuf);
+ g3d_viewport(0, 0, FB_WIDTH, FB_HEIGHT);
g3d_clear_color(0, 0, 0);
}
msurf_set_threshold(msurf, 8);
msurf_set_inside(msurf, MSURF_GREATER);
- msurf_set_bounds(msurf, -BBOX_HSZ, -BBOX_HSZ, -BBOX_HSZ, BBOX_HSZ, BBOX_HSZ, BBOX_HSZ);
- msurf_set_resolution(msurf, VOX_RES, VOX_RES, VOX_RES);
+ msurf_set_bounds(msurf, -BBOX_HSZ, -BBOX_HH, -BBOX_HSZ, BBOX_HSZ, BBOX_HH, BBOX_HSZ);
+ msurf_set_resolution(msurf, VOX_RES, VOX_YRES, VOX_RES);
msurf_enable(msurf, MSURF_NORMALIZE);
vbuf = malloc_nf(VBUF_SIZE * sizeof *vbuf);
- num_balls = 1;
+ num_balls = 0;
balls = calloc_nf(num_balls, sizeof *balls);
+ num_caps = sizeof sgiv / sizeof *sgiv;
+ caps = calloc_nf(num_caps, sizeof *caps);
for(i=0; i<num_balls; i++) {
- balls[i].energy = 20;
+ balls[i].energy = 5;
+ }
+
+ cgm_midentity(mat);
+ cgm_mtranslate(mat, 0, -BBOX_HH / 2, 0);
+ cgm_mrotate_y(mat, -M_PI / 4.0f);
+ cgm_mrotate_x(mat, M_PI / 4.0f);
+
+ for(i=0; i<num_caps; i++) {
+ caps[i].energy = 1;
+ caps[i].end[0] = sgiv[i];
+ cgm_vscale(caps[i].end, 0.6);
+ caps[i].end[1] = sgiv[(i + 1) % num_caps];
+ cgm_vscale(caps[i].end + 1, 0.6);
+
+ cgm_vmul_m4v3(caps[i].end, mat);
+ cgm_vmul_m4v3(caps[i].end + 1, mat);
}
return 0;
}
static void update(float tsec)
{
int i, j, k, n;
- float x, y, z, dx, dy, dz, dsq, energy;
+ float dsq, energy;
+ cgm_vec3 pos;
float *vox = msurf_voxels(msurf);
for(i=0; i<num_balls; i++) {
- balls[i].y = sin(tsec) * 5.0f;
+ balls[i].pos.y = sin(tsec) * BBOX_HH;
+ }
+
+ float y = sin(tsec) * BBOX_HH / 80.0f;
+ for(i=0; i<num_caps; i++) {
+ caps[i].end[0].y += y;
+ caps[i].end[1].y += y;
+ caps[i].len = cgm_vdist(caps[i].end, caps[i].end + 1);
}
for(i=0; i<VOX_RES; i++) {
- z = -BBOX_HSZ + i * VOX_STEP;
- for(j=0; j<VOX_RES; j++) {
- y = -BBOX_HSZ + j * VOX_STEP;
+ pos.z = -BBOX_HSZ + i * VOX_STEP;
+ for(j=0; j<VOX_YRES; j++) {
+ pos.y = -BBOX_HH + j * VOX_YSTEP;
for(k=0; k<VOX_RES; k++) {
- x = -BBOX_HSZ + k * VOX_STEP;
+ pos.x = -BBOX_HSZ + k * VOX_STEP;
/* initialize with the vertical distance for the pool */
- energy = 5.0 / (y + BBOX_HSZ * 0.98);
+ energy = 5.0 / (pos.y + BBOX_HH * 0.98);
/* add the contribution of the balls */
for(n=0; n<num_balls; n++) {
- dx = x - balls[n].x;
- dy = y - balls[n].y;
- dz = z - balls[n].z;
- dsq = dx * dx + dy * dy + dz * dz;
-
+ dsq = cgm_vdist_sq(&balls[n].pos, &pos);
energy += balls[n].energy / dsq;
}
+
+ /* add the contribution of the capsules */
+ for(n=0; n<num_caps; n++) {
+ dsq = capsule_distsq(caps + n, &pos);
+ energy += caps[n].energy / dsq;
+ }
+
*vox++ = energy;
}
}
g3d_matrix_mode(G3D_MODELVIEW);
g3d_load_identity();
- g3d_translate(0, 0, -15);
+ g3d_translate(0, 1, -15);
/*g3d_rotate(tsec * 50.0f, 1, 0, 0);
g3d_rotate(tsec * 30.0f, 0, 0, 1);
void game_motion(int x, int y)
{
}
+
+static float capsule_distsq(struct mcapsule *c, cgm_vec3 *pos)
+{
+ float t;
+ cgm_vec3 pp, dir, pdir;
+
+ dir = c->end[1]; cgm_vsub(&dir, c->end);
+ if(c->len != 0.0f) {
+ float s = 1.0f / c->len;
+ dir.x *= s;
+ dir.y *= s;
+ dir.z *= s;
+ }
+ pdir = *pos; cgm_vsub(&pdir, c->end);
+ t = cgm_vdot(&dir, &pdir);
+
+ if(t < 0.0f) {
+ return cgm_vdist_sq(c->end, pos);
+ }
+ if(t > c->len) {
+ return cgm_vdist_sq(c->end + 1, pos);
+ }
+
+ pp = c->end[0];
+ cgm_vadd_scaled(&pp, &dir, t);
+ return cgm_vdist_sq(&pp, pos);
+}