X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fblob_exhibit.cc;fp=src%2Fblob_exhibit.cc;h=1dcc80e3d0a906750e4066b77b2daf78f594a43d;hb=004eca3966c8cc7bed607311a90d56eecab1752f;hp=0000000000000000000000000000000000000000;hpb=a550cf151e8fc6626e788fb2bdc72cf03565ff8b;p=laserbrain_demo diff --git a/src/blob_exhibit.cc b/src/blob_exhibit.cc new file mode 100644 index 0000000..1dcc80e --- /dev/null +++ b/src/blob_exhibit.cc @@ -0,0 +1,137 @@ +#include "blob_exhibit.h" +#include "blobs/metasurf.h" +#include "app.h" + +struct Metaball { + Vec3 pos; + float energy; + Vec3 path_scale, path_offset; + float phase_offset, speed; +}; +#define NUM_MBALLS 8 + +static Metaball def_mball_data[] = { + {Vec3(0, 0, 0), 2.18038, Vec3(1.09157, 1.69766, 1), Vec3(0.622818, 0.905624, 0), 1.24125, 0.835223}, + {Vec3(0, 0, 0), 2.03646, Vec3(0.916662, 1.2161, 1), Vec3(0.118734, 0.283516, 0), 2.29201, 1.0134}, + {Vec3(0, 0, 0), 2.40446, Vec3(1.87429, 1.57595, 1), Vec3(0.298566, -0.788474, 0), 3.8137, 0.516301}, + {Vec3(0, 0, 0), 0.985774, Vec3(0.705847, 0.735019, 1), Vec3(0.669189, -0.217922, 0), 0.815497, 0.608809}, + {Vec3(0, 0, 0), 2.49785, Vec3(0.827385, 1.75867, 1), Vec3(0.0284513, 0.247808, 0), 1.86002, 1.13755}, + {Vec3(0, 0, 0), 1.54857, Vec3(1.24037, 0.938775, 1), Vec3(1.04011, 0.596987, 0), 3.30964, 1.26991}, + {Vec3(0, 0, 0), 1.30046, Vec3(1.83729, 1.02869, 1), Vec3(-0.476708, 0.676994, 0), 5.77441, 0.569755}, + {Vec3(0, 0, 0), 2.39865, Vec3(1.28899, 0.788321, 1), Vec3(-0.910677, 0.359099, 0), 5.5935, 0.848893} +}; + +struct BlobPriv { + 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; imballs[i] = def_mball_data[i]; + } +} + +BlobExhibit::~BlobExhibit() +{ + delete priv; +} + +bool BlobExhibit::init() +{ + 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); + + priv->tex = texman.get_texture("data/sphmap.jpg"); + return true; +} + +void BlobExhibit::destroy() +{ + msurf_free(priv->msurf); + priv->msurf = 0; +} + +void BlobExhibit::update(float dt) +{ + double sec = time_msec / 1000.0; + + for(int i=0; imballs[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; + } +} + +void BlobExhibit::draw() const +{ + pre_draw(); + + glPushAttrib(GL_ENABLE_BIT); + + glUseProgram(0); + + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + priv->tex->bind(); + + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + + glFrontFace(GL_CW); + glBegin(GL_TRIANGLES); + glColor3f(1, 1, 1); + msurf_polygonize(priv->msurf); + glEnd(); + glFrontFace(GL_CCW); + + glPopAttrib(); + + post_draw(); +} + +static void vertex(struct metasurface *ms, float x, float y, float z) +{ + static const float delta = 0.01; + + 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; + + glNormal3f(dfdx, dfdy, dfdz); + glVertex3f(x, y, z); +} + +static float eval(struct metasurface *ms, float x, float y, float z) +{ + float sum = 0.0f; + BlobPriv *priv = (BlobPriv*)msurf_get_user_data(ms); + + for(int i=0; imballs[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; + + sum += priv->mballs[i].energy / dsq; + } + return sum; +}