From 004eca3966c8cc7bed607311a90d56eecab1752f Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 6 Dec 2016 06:19:25 +0200 Subject: [PATCH] added a non-interactive blobs exhibit --- Makefile | 6 +- src/app.cc | 52 ++++++ src/blob_exhibit.cc | 137 +++++++++++++++ src/blob_exhibit.h | 23 +++ src/blobs/mcubes.h | 294 ++++++++++++++++++++++++++++++++ src/blobs/metasurf.c | 452 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/blobs/metasurf.h | 79 +++++++++ src/exhibit.cc | 41 +++++ src/exhibit.h | 3 + src/ui.cc | 50 ++++++ src/ui.h | 3 + 11 files changed, 1137 insertions(+), 3 deletions(-) create mode 100644 src/blob_exhibit.cc create mode 100644 src/blob_exhibit.h create mode 100644 src/blobs/mcubes.h create mode 100644 src/blobs/metasurf.c create mode 100644 src/blobs/metasurf.h create mode 100644 src/exhibit.cc diff --git a/Makefile b/Makefile index 71a41d1..431e362 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -src = $(wildcard src/*.cc) $(wildcard src/machine/*.cc) -csrc = $(wildcard src/*.c) $(wildcard src/machine/*.c) +src = $(wildcard src/*.cc) $(wildcard src/machine/*.cc) $(wildcard src/blobs/*.cc) +csrc = $(wildcard src/*.c) $(wildcard src/machine/*.c) $(wildcard src/blobs/*.c) obj = $(src:.cc=.o) $(csrc:.c=.o) dep = $(obj:.o=.d) bin = demo -opt = -O0 +opt = -O3 -ffast-math dbg = -g incpath = -Isrc -Isrc/machine -I/usr/local/include `pkg-config --cflags sdl2` diff --git a/src/app.cc b/src/app.cc index 665ded4..ca750fa 100644 --- a/src/app.cc +++ b/src/app.cc @@ -13,12 +13,14 @@ #include "ui.h" #include "opt.h" #include "post.h" +#include "blob_exhibit.h" #define NEAR_CLIP 5.0 #define FAR_CLIP 10000.0 static void draw_scene(); static void toggle_flight(); +static void calc_framerate(); long time_msec; int win_width, win_height; @@ -50,12 +52,17 @@ static bool gpad_bnstate[64]; static Vec2 joy_move, joy_look; static float joy_deadzone = 0.01; +static float framerate; + static Mat4 view_matrix, mouse_view_matrix, proj_matrix; static MetaScene *mscn; static unsigned int sdr_post_gamma; static long prev_msec; +static BlobExhibit *blobs; +static bool show_blobs; + bool app_init(int argc, char **argv) { @@ -109,6 +116,13 @@ bool app_init(int argc, char **argv) dir.y = 0; cam_theta = rad_to_deg(acos(dot(dir, Vec3(0, 0, 1)))); + blobs = new BlobExhibit; + blobs->node = new SceneNode; + blobs->init(); + blobs->node->set_position(Vec3(-250, 150, 250)); + blobs->node->set_scaling(Vec3(20, 20, 20)); + blobs->node->update(0); + if(!(sdr_ltmap_notex = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-notex.p.glsl"))) { return false; } @@ -138,6 +152,10 @@ void app_cleanup() goatvr_shutdown(); } + blobs->destroy(); + delete blobs->node; + delete blobs; + texman.clear(); sceneman.clear(); } @@ -166,6 +184,9 @@ static void update(float dt) sceneman.update(); mscn->update(dt); + if(show_blobs) { + blobs->update(dt); + } float speed = walk_speed * dt; Vec3 dir; @@ -319,6 +340,8 @@ void app_display() app_swap_buffers(); } assert(glGetError() == GL_NO_ERROR); + + calc_framerate(); } @@ -330,6 +353,9 @@ static void draw_scene() set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3); mscn->draw(); + if(show_blobs) { + blobs->draw(); + } if(show_walk_mesh && mscn->walk_mesh) { glPushAttrib(GL_ENABLE_BIT); @@ -351,6 +377,7 @@ static void draw_scene() glPopAttrib(); } + print_text(Vec2(9 * win_width / 10, 20), Vec3(1, 1, 0), "fps: %.1f", framerate); draw_ui(); } @@ -427,6 +454,11 @@ void app_keyboard(int key, bool pressed) mouse_speed *= 0.8; show_message("mouse speed: %g", mouse_speed); break; + + case 'b': + show_blobs = !show_blobs; + show_message("blobs: %s\n", show_blobs ? "on" : "off"); + break; } } @@ -513,6 +545,11 @@ void app_gamepad_button(int bn, bool pressed) toggle_flight(); break; + case GPAD_X: + show_blobs = !show_blobs; + show_message("blobs: %s\n", show_blobs ? "on" : "off"); + break; + default: break; } @@ -534,3 +571,18 @@ static void toggle_flight() show_message("walk mode\n"); } } + +static void calc_framerate() +{ + static int nframes; + static long prev_upd; + + long elapsed = time_msec - prev_upd; + if(elapsed >= 1000) { + framerate = (float)nframes / (float)(elapsed * 0.001); + nframes = 1; + prev_upd = time_msec; + } else { + ++nframes; + } +} 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; +} diff --git a/src/blob_exhibit.h b/src/blob_exhibit.h new file mode 100644 index 0000000..001047a --- /dev/null +++ b/src/blob_exhibit.h @@ -0,0 +1,23 @@ +#ifndef BLOB_EXHIBIT_H_ +#define BLOB_EXHIBIT_H_ + +#include "exhibit.h" + +struct BlobPriv; + +class BlobExhibit : public Exhibit { +private: + BlobPriv *priv; + +public: + BlobExhibit(); + ~BlobExhibit(); + + bool init(); + void destroy(); + + void update(float dt); + void draw() const; +}; + +#endif // BLOB_EXHIBIT_H_ diff --git a/src/blobs/mcubes.h b/src/blobs/mcubes.h new file mode 100644 index 0000000..2a9034d --- /dev/null +++ b/src/blobs/mcubes.h @@ -0,0 +1,294 @@ +static int mc_edge_table[256] = { + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 +}; + + +static int mc_tri_table[256][16] = { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1}, + {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1}, + {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1}, + {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1}, + {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1}, + {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1}, + {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1}, + {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1}, + {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1}, + {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1}, + {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1}, + {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1}, + {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1}, + {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1}, + {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1}, + {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1}, + {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1}, + {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1}, + {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1}, + {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1}, + {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1}, + {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1}, + {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1}, + {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1}, + {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1}, + {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1}, + {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1}, + {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1}, + {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1}, + {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1}, + {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1}, + {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1}, + {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1}, + {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1}, + {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1}, + {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1}, + {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1}, + {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1}, + {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1}, + {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1}, + {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1}, + {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1}, + {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1}, + {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1}, + {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1}, + {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1}, + {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1}, + {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1}, + {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1}, + {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1}, + {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1}, + {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1}, + {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1}, + {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1}, + {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1}, + {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1}, + {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1}, + {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1}, + {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1}, + {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1}, + {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1}, + {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1}, + {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1}, + {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1}, + {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1}, + {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1}, + {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1}, + {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1}, + {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1}, + {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1}, + {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1}, + {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1}, + {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1}, + {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1}, + {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1}, + {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1}, + {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1}, + {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1}, + {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1}, + {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1}, + {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1}, + {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1}, + {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1}, + {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1}, + {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1}, + {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1}, + {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1}, + {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1}, + {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1}, + {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1}, + {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1}, + {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1}, + {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1}, + {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1}, + {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1}, + {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1}, + {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1}, + {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1}, + {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1}, + {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1}, + {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1}, + {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1}, + {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1}, + {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1}, + {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1}, + {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1}, + {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1}, + {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1}, + {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1}, + {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1}, + {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1}, + {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1}, + {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1}, + {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1}, + {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1}, + {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1}, + {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1}, + {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1}, + {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1}, + {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1}, + {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1}, + {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1}, + {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1}, + {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1}, + {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1}, + {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1}, + {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1}, + {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} +}; diff --git a/src/blobs/metasurf.c b/src/blobs/metasurf.c new file mode 100644 index 0000000..2207b3d --- /dev/null +++ b/src/blobs/metasurf.c @@ -0,0 +1,452 @@ +/* +metasurf - a library for implicit surface polygonization +Copyright (C) 2011-2016 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ +/* this is pulled from: https://github.com/jtsiomb/metasurf */ +#include +#include +#include "metasurf.h" +#include "mcubes.h" + +#undef USE_MTETRA +#define USE_MCUBES + +#if (defined(USE_MTETRA) && defined(USE_MCUBES)) || (!defined(USE_MTETRA) && !defined(USE_MCUBES)) +#error "pick either USE_MTETRA or USE_MCUBES, not both..." +#endif + +typedef float vec3[3]; + +struct metasurface { + vec3 min, max; + int res[3]; + float thres; + + msurf_eval_func_t eval; + msurf_vertex_func_t vertex; + msurf_normal_func_t normal; + void *udata; + + float dx, dy, dz; + int flip; + + vec3 vbuf[3]; + int nverts; +}; + +static int msurf_init(struct metasurface *ms); +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz); +#ifdef USE_MTETRA +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val); +#endif +#ifdef USE_MCUBES +static void process_cube(struct metasurface *ms, vec3 *pos, float *val); +#endif + + +struct metasurface *msurf_create(void) +{ + struct metasurface *ms; + + if(!(ms = malloc(sizeof *ms))) { + return 0; + } + if(msurf_init(ms) == -1) { + free(ms); + } + return ms; +} + +void msurf_free(struct metasurface *ms) +{ + free(ms); +} + +static int msurf_init(struct metasurface *ms) +{ + ms->thres = 0.0; + ms->eval = 0; + ms->vertex = 0; + ms->normal = 0; + ms->udata = 0; + ms->min[0] = ms->min[1] = ms->min[2] = -1.0; + ms->max[0] = ms->max[1] = ms->max[2] = 1.0; + ms->res[0] = ms->res[1] = ms->res[2] = 40; + ms->nverts = 0; + + ms->dx = ms->dy = ms->dz = 0.001; + ms->flip = 0; + + return 0; +} + +void msurf_set_user_data(struct metasurface *ms, void *udata) +{ + ms->udata = udata; +} + +void *msurf_get_user_data(struct metasurface *ms) +{ + return ms->udata; +} + +void msurf_set_inside(struct metasurface *ms, int inside) +{ + switch(inside) { + case MSURF_GREATER: + ms->flip = 0; + break; + + case MSURF_LESS: + ms->flip = 1; + break; + + default: + fprintf(stderr, "msurf_inside expects MSURF_GREATER or MSURF_LESS\n"); + } +} + +int msurf_get_inside(struct metasurface *ms) +{ + return ms->flip ? MSURF_LESS : MSURF_GREATER; +} + +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func) +{ + ms->eval = func; +} + +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func) +{ + ms->vertex = func; +} + +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func) +{ + ms->normal = func; +} + +void msurf_set_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax) +{ + ms->min[0] = xmin; + ms->min[1] = ymin; + ms->min[2] = zmin; + ms->max[0] = xmax; + ms->max[1] = ymax; + ms->max[2] = zmax; +} + +void msurf_get_bounds(struct metasurface *ms, float *xmin, float *ymin, float *zmin, float *xmax, float *ymax, float *zmax) +{ + *xmin = ms->min[0]; + *ymin = ms->min[1]; + *zmin = ms->min[2]; + *xmax = ms->max[0]; + *ymax = ms->max[1]; + *zmax = ms->max[2]; +} + +void msurf_set_resolution(struct metasurface *ms, int xres, int yres, int zres) +{ + ms->res[0] = xres; + ms->res[1] = yres; + ms->res[2] = zres; +} + +void msurf_get_resolution(struct metasurface *ms, int *xres, int *yres, int *zres) +{ + *xres = ms->res[0]; + *yres = ms->res[1]; + *zres = ms->res[2]; +} + +void msurf_set_threshold(struct metasurface *ms, float thres) +{ + ms->thres = thres; +} + +float msurf_get_threshold(struct metasurface *ms) +{ + return ms->thres; +} + + +int msurf_polygonize(struct metasurface *ms) +{ + int i, j, k; + vec3 pos, delta; + + if(!ms->eval || !ms->vertex) { + fprintf(stderr, "you need to set eval and vertex callbacks before calling msurf_polygonize\n"); + return -1; + } + + for(i=0; i<3; i++) { + delta[i] = (ms->max[i] - ms->min[i]) / (float)ms->res[i]; + } + + pos[0] = ms->min[0]; + for(i=0; ires[0] - 1; i++) { + pos[1] = ms->min[1]; + for(j=0; jres[1] - 1; j++) { + + pos[2] = ms->min[2]; + for(k=0; kres[2] - 1; k++) { + + process_cell(ms, pos, delta); + + pos[2] += delta[2]; + } + pos[1] += delta[1]; + } + pos[0] += delta[0]; + } + return 0; +} + + +static void process_cell(struct metasurface *ms, vec3 pos, vec3 sz) +{ + int i; + vec3 p[8]; + float val[8]; + +#ifdef USE_MTETRA + static int tetra[][4] = { + {0, 2, 3, 7}, + {0, 2, 6, 7}, + {0, 4, 6, 7}, + {0, 6, 1, 2}, + {0, 6, 1, 4}, + {5, 6, 1, 4} + }; +#endif + + static const float offs[][3] = { + {0.0f, 0.0f, 0.0f}, + {1.0f, 0.0f, 0.0f}, + {1.0f, 1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 1.0f}, + {1.0f, 0.0f, 1.0f}, + {1.0f, 1.0f, 1.0f}, + {0.0f, 1.0f, 1.0f} + }; + + for(i=0; i<8; i++) { + p[i][0] = pos[0] + sz[0] * offs[i][2]; + p[i][1] = pos[1] + sz[1] * offs[i][1]; + p[i][2] = pos[2] + sz[2] * offs[i][0]; + + val[i] = ms->eval(ms, p[i][0], p[i][1], p[i][2]); + } + +#ifdef USE_MTETRA + for(i=0; i<6; i++) { + process_tetra(ms, tetra[i], p, val); + } +#endif +#ifdef USE_MCUBES + process_cube(ms, p, val); +#endif +} + + +/* ---- marching cubes implementation ---- */ +#ifdef USE_MCUBES + +static unsigned int mc_bitcode(float *val, float thres); + +static void process_cube(struct metasurface *ms, vec3 *pos, float *val) +{ + static const int pidx[12][2] = { + {0, 1}, {1, 2}, {2, 3}, {3, 0}, {4, 5}, {5, 6}, + {6, 7}, {7, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7} + }; + int i, j; + vec3 vert[12]; + unsigned int code = mc_bitcode(val, ms->thres); + + if(ms->flip) { + code = ~code & 0xff; + } + + if(mc_edge_table[code] == 0) { + return; + } + + for(i=0; i<12; i++) { + if(mc_edge_table[code] & (1 << i)) { + int p0 = pidx[i][0]; + int p1 = pidx[i][1]; + + float t = (ms->thres - val[p0]) / (val[p1] - val[p0]); + vert[i][0] = pos[p0][0] + (pos[p1][0] - pos[p0][0]) * t; + vert[i][1] = pos[p0][1] + (pos[p1][1] - pos[p0][1]) * t; + vert[i][2] = pos[p0][2] + (pos[p1][2] - pos[p0][2]) * t; + } + } + + for(i=0; mc_tri_table[code][i] != -1; i+=3) { + for(j=0; j<3; j++) { + float *v = vert[mc_tri_table[code][i + j]]; + + if(ms->normal) { + float dfdx, dfdy, dfdz; + dfdx = ms->eval(ms, v[0] - ms->dx, v[1], v[2]) - ms->eval(ms, v[0] + ms->dx, v[1], v[2]); + dfdy = ms->eval(ms, v[0], v[1] - ms->dy, v[2]) - ms->eval(ms, v[0], v[1] + ms->dy, v[2]); + dfdz = ms->eval(ms, v[0], v[1], v[2] - ms->dz) - ms->eval(ms, v[0], v[1], v[2] + ms->dz); + + if(ms->flip) { + dfdx = -dfdx; + dfdy = -dfdy; + dfdz = -dfdz; + } + ms->normal(ms, dfdx, dfdy, dfdz); + } + + /* TODO multithreadied polygon emmit */ + ms->vertex(ms, v[0], v[1], v[2]); + } + } +} + +static unsigned int mc_bitcode(float *val, float thres) +{ + unsigned int i, res = 0; + + for(i=0; i<8; i++) { + if(val[i] > thres) { + res |= 1 << i; + } + } + return res; +} +#endif /* USE_MCUBES */ + + +/* ---- marching tetrahedra implementation (incomplete) ---- */ +#ifdef USE_MTETRA + +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres); +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev) + + +#define REVBIT(x) ((x) & 8) +#define INV(x) (~(x) & 0xf) +#define EDGE(a, b) emmit(ms, val[idx[a]], val[idx[b]], pos[idx[a]], pos[idx[b]], REVBIT(code)) +static void process_tetra(struct metasurface *ms, int *idx, vec3 *pos, float *val) +{ + unsigned int code = mt_bitcode(val[idx[0]], val[idx[1]], val[idx[2]], val[idx[3]], ms->thres); + + switch(code) { + case 1: + case INV(1): + EDGE(0, 1); + EDGE(0, 2); + EDGE(0, 3); + break; + + case 2: + case INV(2): + EDGE(1, 0); + EDGE(1, 3); + EDGE(1, 2); + break; + + case 3: + case INV(3): + EDGE(0, 3); + EDGE(0, 2); + EDGE(1, 3); + + EDGE(1, 3); + EDGE(1, 2); + EDGE(0, 2); + break; + + case 4: + case INV(4): + EDGE(2, 0); + EDGE(2, 1); + EDGE(2, 3); + break; + + case 5: + case INV(5): + EDGE(0, 1); + EDGE(2, 3); + EDGE(0, 3); + + EDGE(0, 1); + EDGE(1, 2); + EDGE(2, 3); + break; + + case 6: + case INV(6): + EDGE(0, 1); + EDGE(1, 3); + EDGE(2, 3); + + EDGE(0, 1); + EDGE(0, 2); + EDGE(2, 3); + break; + + case 7: + case INV(7): + EDGE(3, 0); + EDGE(3, 2); + EDGE(3, 1); + break; + + default: + break; /* cases 0 and 15 */ + } +} + +#define BIT(i) ((v##i > thres) ? (1 << i) : 0) +static unsigned int mt_bitcode(float v0, float v1, float v2, float v3, float thres) +{ + return BIT(0) | BIT(1) | BIT(2) | BIT(3); +} + +static void emmit(struct metasurface *ms, float v0, float v1, vec3 p0, vec3 p1, int rev) +{ + int i; + float t = (ms->thres - v0) / (v1 - v0); + + vec3 p; + for(i=0; i<3; i++) { + p[i] = p0[i] + (p1[i] - p0[i]) * t; + } + ms->vertex(ms, p[0], p[1], p[2]); + + /*for(i=0; i<3; i++) { + ms->vbuf[ms->nverts][i] = p0[i] + (p1[i] - p0[i]) * t; + } + + if(++ms->nverts >= 3) { + ms->nverts = 0; + + for(i=0; i<3; i++) { + int idx = rev ? (2 - i) : i; + ms->vertex(ms, ms->vbuf[idx][0], ms->vbuf[idx][1], ms->vbuf[idx][2]); + } + }*/ +} +#endif /* USE_MTETRA */ diff --git a/src/blobs/metasurf.h b/src/blobs/metasurf.h new file mode 100644 index 0000000..77d2920 --- /dev/null +++ b/src/blobs/metasurf.h @@ -0,0 +1,79 @@ +/* +metasurf - a library for implicit surface polygonization +Copyright (C) 2011-2015 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see . +*/ +/* this is pulled from: https://github.com/jtsiomb/metasurf */ +#ifndef METASURF_H_ +#define METASURF_H_ + +#define MSURF_GREATER 1 +#define MSURF_LESS 0 + +struct metasurface; + +typedef float (*msurf_eval_func_t)(struct metasurface *ms, float, float, float); +typedef void (*msurf_vertex_func_t)(struct metasurface *ms, float, float, float); +typedef void (*msurf_normal_func_t)(struct metasurface *ms, float, float, float); + +#ifdef __cplusplus +extern "C" { +#endif + +struct metasurface *msurf_create(void); +void msurf_free(struct metasurface *ms); + +void msurf_set_user_data(struct metasurface *ms, void *udata); +void *msurf_get_user_data(struct metasurface *ms); + +/* which is inside above or below the threshold */ +void msurf_set_inside(struct metasurface *ms, int inside); +int msurf_get_inside(struct metasurface *ms); + +/* set a scalar field evaluator function */ +void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func); + +/* set a generated vertex callback function */ +void msurf_vertex_func(struct metasurface *ms, msurf_vertex_func_t func); + +/* set a generated surface normal callback function (unused yet) */ +void msurf_normal_func(struct metasurface *ms, msurf_normal_func_t func); + +/* set the bounding box (default: -1, -1, -1, 1, 1, 1) + * keep this as tight as possible to avoid wasting grid resolution + */ +void msurf_set_bounds(struct metasurface *ms, float xmin, float ymin, float zmin, float xmax, float ymax, float zmax); +void msurf_get_bounds(struct metasurface *ms, float *xmin, float *ymin, float *zmin, float *xmax, float *ymax, float *zmax); + +/* resolution of the 3D evaluation grid, the bigger, the better, the slower + * (default: 40, 40, 40) + */ +void msurf_set_resolution(struct metasurface *ms, int xres, int yres, int zres); +void msurf_get_resolution(struct metasurface *ms, int *xres, int *yres, int *zres); + +/* isosurface threshold value (default: 0) */ +void msurf_set_threshold(struct metasurface *ms, float thres); +float msurf_get_threshold(struct metasurface *ms); + + +/* finally call this to perform the polygonization */ +int msurf_polygonize(struct metasurface *ms); + + +#ifdef __cplusplus +} +#endif + +#endif /* METASURF_H_ */ diff --git a/src/exhibit.cc b/src/exhibit.cc new file mode 100644 index 0000000..8653343 --- /dev/null +++ b/src/exhibit.cc @@ -0,0 +1,41 @@ +#include "exhibit.h" +#include "snode.h" + +Exhibit::Exhibit() +{ +} + +void *Exhibit::select(const Ray &ray) const +{ + return 0; // TODO +} + +void *Exhibit::select(const Sphere &sph) const +{ + return 0; // TODO +} + +void Exhibit::update(float dt) +{ +} + +void Exhibit::pre_draw() const +{ + if(node) { + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glMultMatrixf(node->get_matrix()[0]); + } +} + +void Exhibit::draw() const +{ +} + +void Exhibit::post_draw() const +{ + if(node) { + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } +} diff --git a/src/exhibit.h b/src/exhibit.h index c607fdb..c4c0ec9 100644 --- a/src/exhibit.h +++ b/src/exhibit.h @@ -23,7 +23,10 @@ public: virtual void *select(const Sphere &sph) const; virtual void update(float dt = 0.0f); + + virtual void pre_draw() const; virtual void draw() const; + virtual void post_draw() const; }; #endif // EXHIBIT_H_ diff --git a/src/ui.cc b/src/ui.cc index 1a18324..a0babe4 100644 --- a/src/ui.cc +++ b/src/ui.cc @@ -19,6 +19,14 @@ struct Message { }; static Message *msglist; +struct Text { + char *str; + Vec2 pos; + Vec3 color; + Text *next; +}; +static Text *txlist; + static long timeout = 2000; static long trans_time = 250; static dtx_font *font; @@ -71,6 +79,33 @@ void show_messagev(long timeout, const Vec3 &color, const char *fmt, va_list ap) msglist = dummy.next; } +void print_text(const Vec2 &pos, const Vec3 &color, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + print_textv(pos, color, fmt, ap); + va_end(ap); +} + +void print_textv(const Vec2 &pos, const Vec3 &color, const char *fmt, va_list ap) +{ + char buf[512]; + + init(); + + vsnprintf(buf, sizeof buf, fmt, ap); + + Text *tx = new Text; + int len = strlen(buf); + tx->str = new char[len + 1]; + memcpy(tx->str, buf, len + 1); + tx->color = color; + tx->pos = Vec2(pos.x, -pos.y); + + tx->next = txlist; + txlist = tx; +} + void draw_ui() { if(!font) return; @@ -111,6 +146,21 @@ void draw_ui() msg = msg->next; } + while(txlist) { + Text *tx = txlist; + txlist = txlist->next; + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(tx->pos.x, tx->pos.y, 0); + + glColor3f(tx->color.x, tx->color.y, tx->color.z); + dtx_string(tx->str); + + delete [] tx->str; + delete tx; + } + glPopAttrib(); glMatrixMode(GL_PROJECTION); diff --git a/src/ui.h b/src/ui.h index dbd693d..088fb82 100644 --- a/src/ui.h +++ b/src/ui.h @@ -9,6 +9,9 @@ void show_message(const char *fmt, ...); void show_message(long timeout, const Vec3 &color, const char *fmt, ...); void show_messagev(long timeout, const Vec3 &color, const char *fmt, va_list ap); +void print_text(const Vec2 &pos, const Vec3 &color, const char *fmt, ...); +void print_textv(const Vec2 &pos, const Vec3 &color, const char *fmt, va_list ap); + void draw_ui(); #endif // UI_H_ -- 1.7.10.4