#include "blob_exhibit.h"
#include "blobs/metasurf.h"
#include "app.h"
+#include <imago2.h>
struct Metaball {
Vec3 pos;
};
struct BlobPriv {
+ AABox vol;
metasurface *msurf;
Metaball mballs[NUM_MBALLS];
Texture *tex;
};
-static void vertex(struct metasurface *ms, float x, float y, float z);
-static float eval(struct metasurface *ms, float x, float y, float z);
-
-
BlobExhibit::BlobExhibit()
{
priv = new BlobPriv;
for(int i=0; i<NUM_MBALLS; i++) {
priv->mballs[i] = def_mball_data[i];
}
+ priv->vol = AABox(Vec3(-3.5, -3.5, -3.5), Vec3(3.5, 3.5, 3.5));
}
BlobExhibit::~BlobExhibit()
{
+ destroy();
delete priv;
}
if(!(priv->msurf = msurf_create())) {
return false;
}
- msurf_set_user_data(priv->msurf, priv);
msurf_set_threshold(priv->msurf, 8);
msurf_set_inside(priv->msurf, MSURF_GREATER);
- msurf_set_bounds(priv->msurf, -3.5, 3.5, -3.5, 3.5, -3.5, 3.5);
- msurf_eval_func(priv->msurf, eval);
- msurf_vertex_func(priv->msurf, vertex);
+ msurf_set_bounds(priv->msurf, priv->vol.min.x, priv->vol.min.y, priv->vol.min.z,
+ priv->vol.max.x, priv->vol.max.y, priv->vol.max.z);
+ msurf_enable(priv->msurf, MSURF_NORMALIZE);
priv->tex = texman.get_texture("data/sphmap.jpg");
+
return true;
}
void BlobExhibit::destroy()
{
- msurf_free(priv->msurf);
- priv->msurf = 0;
+ if(priv->msurf) {
+ msurf_free(priv->msurf);
+ priv->msurf = 0;
+ }
}
void BlobExhibit::update(float dt)
{
double sec = time_msec / 1000.0;
+ float xmin, xmax, ymin, ymax, zmin, zmax;
+ int xres, yres, zres;
+
+ if(!msurf_voxels(priv->msurf)) {
+ return;
+ }
+
+ msurf_get_bounds(priv->msurf, &xmin, &ymin, &zmin, &xmax, &ymax, &zmax);
+ msurf_get_resolution(priv->msurf, &xres, &yres, &zres);
+
+ float xstep = (xmax - xmin) / xres;
+ float ystep = (ymax - ymin) / yres;
+ float zstep = (zmax - zmin) / zres;
+
for(int i=0; i<NUM_MBALLS; i++) {
float t = fmod(sec * priv->mballs[i].speed + priv->mballs[i].phase_offset, M_PI * 2.0);
priv->mballs[i].pos.x = cos(t) * priv->mballs[i].path_scale.x + priv->mballs[i].path_offset.x;
priv->mballs[i].pos.y = sin(t) * priv->mballs[i].path_scale.y + priv->mballs[i].path_offset.y;
priv->mballs[i].pos.z = -cos(t) * priv->mballs[i].path_scale.z + priv->mballs[i].path_offset.z;
}
+
+ float max_energy = 0.0f;
+
+#pragma omp parallel for
+ for(int i=0; i<zres; i++) {
+ float z = zmin + i * zstep;
+ float *voxptr = msurf_slice(priv->msurf, i);
+
+ for(int j=0; j<yres; j++) {
+ float y = ymin + j * ystep;
+
+ for(int k=0; k<xres; k++) {
+ float x = xmin + k * xstep;
+
+ float sum = 0.0f;
+ for(int n=0; n<NUM_MBALLS; n++) {
+ float dx = x - priv->mballs[n].pos.x;
+ float dy = y - priv->mballs[n].pos.y;
+ float dz = z - priv->mballs[n].pos.z;
+ float dsq = dx * dx + dy * dy + dz * dz;
+
+ sum += priv->mballs[n].energy / dsq;
+ }
+ *voxptr++ = sum;
+ if(sum > max_energy) max_energy = sum;
+ }
+ }
+ }
+
+ msurf_polygonize(priv->msurf);
}
void BlobExhibit::draw() const
{
- pre_draw();
-
glPushAttrib(GL_ENABLE_BIT);
glUseProgram(0);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
+ glEnable(GL_NORMALIZE);
priv->tex->bind();
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
+ if(node) {
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glMultMatrixf(node->get_matrix()[0]);
+ }
+
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(1, -1, 1);
- glFrontFace(GL_CW);
- glBegin(GL_TRIANGLES);
- glColor3f(1, 1, 1);
- msurf_polygonize(priv->msurf);
- glEnd();
- glFrontFace(GL_CCW);
+ int nverts = msurf_vertex_count(priv->msurf);
+ float *varr = msurf_vertices(priv->msurf);
+ float *narr = msurf_normals(priv->msurf);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
+ glColor3f(1, 1, 1);
- glPopAttrib();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, varr);
+ glNormalPointer(GL_FLOAT, 0, narr);
- post_draw();
-}
+ glDrawArrays(GL_TRIANGLES, 0, nverts);
-static void vertex(struct metasurface *ms, float x, float y, float z)
-{
- static const float delta = 0.01;
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
- float val = eval(ms, x, y, z);
- float dfdx = eval(ms, x + delta, y, z) - val;
- float dfdy = eval(ms, x, y + delta, z) - val;
- float dfdz = eval(ms, x, y, z + delta) - val;
+ /*
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
- glNormal3f(dfdx, dfdy, dfdz);
- glVertex3f(x, y, z);
-}
+ varr = msurf_vertices(priv->msurf);
+ narr = msurf_normals(priv->msurf);
-static float eval(struct metasurface *ms, float x, float y, float z)
-{
- float sum = 0.0f;
- BlobPriv *priv = (BlobPriv*)msurf_get_user_data(ms);
+ glBegin(GL_LINES);
+ glColor3f(0, 1, 0);
- for(int i=0; i<NUM_MBALLS; i++) {
- float dx = x - priv->mballs[i].pos.x;
- float dy = y - priv->mballs[i].pos.y;
- float dz = z - priv->mballs[i].pos.z;
- float dsq = dx * dx + dy * dy + dz * dz;
+ float nscale = 0.2;
+ for(int i=0; i<nverts; i++) {
+ glVertex3f(varr[0], varr[1], varr[2]);
+ glVertex3f(varr[0] + narr[0] * nscale, varr[1] + narr[1] * nscale, varr[2] + narr[2] * nscale);
+ varr += 3;
+ narr += 3;
+ }
+ glEnd();
+ */
- sum += priv->mballs[i].energy / dsq;
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ if(node) {
+ glPopMatrix();
}
- return sum;
+
+ glPopAttrib();
+}
+
+const AABox &BlobExhibit::get_aabox() const
+{
+ Box box = Box(priv->vol, node ? node->get_matrix() : Mat4::identity);
+ calc_bounding_aabox(&aabb, &box);
+ return aabb;
}