shell mesh
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 7 Feb 2023 22:14:17 +0000 (00:14 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 7 Feb 2023 22:14:17 +0000 (00:14 +0200)
main.c
src/cmesh.c
src/cmesh.h
src/frac.c
src/frac.h
src/geom.c

diff --git a/main.c b/main.c
index 724fd70..2218f45 100644 (file)
--- a/main.c
+++ b/main.c
@@ -8,6 +8,7 @@
 #include "meshgen.h"
 #include "frac.h"
 #include "sdr.h"
+#include "dynarr.h"
 
 static const char *vsdr_src =
        "varying vec3 v_norm, v_ldir, v_vdir;\n"
@@ -57,7 +58,8 @@ static unsigned int sdr;
 
 static int cur, pending;
 static int show_orig = 1;
-static int show_points;
+static int show_points, show_planes, show_shell;
+static int cur_cell;
 
 
 int main(int argc, char **argv)
@@ -135,7 +137,8 @@ static void update(void)
        if(pending > cur) {
                switch(cur) {
                case 0:
-                       if(frac_gen_points(&frac, 16) == -1) {
+                       printf("Generate points...\n");
+                       if(frac_gen_points(&frac, 16) != -1) {
                                cur++;
                        } else {
                                pending = cur;
@@ -144,22 +147,28 @@ static void update(void)
                        break;
 
                case 1:
+                       printf("Build cells...\n");
                        if(frac_build_cells(&frac) != -1) {
                                cur++;
                        } else {
                                pending = cur;
                        }
+                       show_planes = 1;
                        break;
 
                case 2:
+                       printf("Construct shell...\n");
                        if(frac_build_shell(&frac) != -1) {
                                cur++;
                        } else {
                                pending = cur;
                        }
+                       show_orig = 0;
+                       show_shell = 1;
                        break;
 
                case 3:
+                       printf("Construct walls...\n");
                        if(frac_build_walls(&frac) != -1) {
                                cur++;
                        } else {
@@ -176,7 +185,8 @@ static void update(void)
 
 static void display(void)
 {
-       int i, num;
+       int i, j, num;
+       struct poly *poly;
 
        update();
 
@@ -198,15 +208,19 @@ static void display(void)
                bind_program(0);
 
                glPushAttrib(GL_ENABLE_BIT);
-               glDisable(GL_DEPTH_TEST);
                glDisable(GL_LIGHTING);
+               glDisable(GL_DEPTH_TEST);
                glEnable(GL_BLEND);
                glBlendFunc(GL_ONE, GL_ONE);
 
                glPointSize(2.0f);
                glBegin(GL_POINTS);
-               glColor3f(0.1, 0.8, 0.1);
                for(i=0; i<num; i++) {
+                       if(cur_cell == i) {
+                               glColor3f(0.8, 1, 0.1);
+                       } else {
+                               glColor3f(0.1, 0.8, 0.1);
+                       }
                        glVertex3fv(&frac.cells[i].pt.x);
                }
                glEnd();
@@ -214,6 +228,31 @@ static void display(void)
                glPopAttrib();
        }
 
+       if(show_planes) {
+               bind_program(0);
+
+               glPushAttrib(GL_ENABLE_BIT);
+               glDisable(GL_LIGHTING);
+
+               poly = frac.cells[cur_cell].polys;
+               for(i=0; i<frac.cells[cur_cell].num_polys; i++) {
+                       glBegin(GL_LINE_LOOP);
+                       glColor3f(0.5, 0.5, 0);
+                       for(j=0; j<dynarr_size(poly->verts); j++) {
+                               glVertex3fv(&poly->verts[j].pos.x);
+                       }
+                       glEnd();
+                       poly++;
+               }
+
+               glPopAttrib();
+       }
+
+       if(show_shell) {
+               bind_program(sdr);
+               cmesh_draw(frac.cells[cur_cell].mesh);
+       }
+
        assert(glGetError() == GL_NO_ERROR);
        glutSwapBuffers();
 }
@@ -247,6 +286,25 @@ static void keydown(unsigned char key, int x, int y)
                glutPostRedisplay();
                break;
 
+       case 'P':
+               show_planes ^= 1;
+               glutPostRedisplay();
+               break;
+
+       case ']':
+               cur_cell = (cur_cell + 1) % frac_num_cells(&frac);
+               printf("current cell: %d\n", cur_cell);
+               glutPostRedisplay();
+               break;
+
+       case '[':
+               if(--cur_cell < 0) {
+                       cur_cell = frac_num_cells(&frac) - 1;
+                       printf("current cell: %d\n", cur_cell);
+                       glutPostRedisplay();
+               }
+               break;
+
        default:
                if(key >= '1' && key <= '4') {
                        n = key - '0';
index 71f58af..3492ef2 100644 (file)
@@ -61,9 +61,9 @@ struct cmesh {
 };
 
 
-static int clone(struct cmesh *cmdest, struct cmesh *cmsrc, struct submesh *sub);
-static int pre_draw(struct cmesh *cm);
-static void post_draw(struct cmesh *cm, int cur_sdr);
+static int clone(struct cmesh *cmdest, const struct cmesh *cmsrc, struct submesh *sub);
+static int pre_draw(const struct cmesh *cm);
+static void post_draw(const struct cmesh *cm, int cur_sdr);
 static void update_buffers(struct cmesh *cm);
 static void update_wire_ibo(struct cmesh *cm);
 static void calc_aabb(struct cmesh *cm);
@@ -176,12 +176,12 @@ void cmesh_clear(struct cmesh *cm)
        cmesh_clear_submeshes(cm);
 }
 
-int cmesh_clone(struct cmesh *cmdest, struct cmesh *cmsrc)
+int cmesh_clone(struct cmesh *cmdest, const struct cmesh *cmsrc)
 {
        return clone(cmdest, cmsrc, 0);
 }
 
-static int clone(struct cmesh *cmdest, struct cmesh *cmsrc, struct submesh *sub)
+static int clone(struct cmesh *cmdest, const struct cmesh *cmsrc, struct submesh *sub)
 {
        int i, nelem, vstart, vcount, istart, icount;
        char *srcname, *name = 0;
@@ -240,7 +240,8 @@ static int clone(struct cmesh *cmdest, struct cmesh *cmsrc, struct submesh *sub)
                free(cmdest->vattr[i].data);
 
                if(cmesh_has_attrib(cmsrc, i)) {
-                       cmesh_attrib(cmsrc, i); /* force validation of the actual data on the source mesh */
+                       /* force validation of the actual data on the source mesh */
+                       cmesh_attrib((struct cmesh*)cmsrc, i);
 
                        nelem = cmsrc->vattr[i].nelem;
                        cmdest->vattr[i].nelem = nelem;
@@ -256,7 +257,8 @@ static int clone(struct cmesh *cmdest, struct cmesh *cmsrc, struct submesh *sub)
        }
 
        if(cmesh_indexed(cmsrc)) {
-               cmesh_index(cmsrc);     /* force validation .... */
+               /* force validation .... */
+               cmesh_index((struct cmesh*)cmsrc);
 
                cmdest->idata = iarr;
                cmdest->icount = icount;
@@ -334,12 +336,12 @@ int cmesh_set_name(struct cmesh *cm, const char *name)
        return 0;
 }
 
-const char *cmesh_name(struct cmesh *cm)
+const char *cmesh_name(const struct cmesh *cm)
 {
        return cm->name;
 }
 
-int cmesh_has_attrib(struct cmesh *cm, int attr)
+int cmesh_has_attrib(const struct cmesh *cm, int attr)
 {
        if(attr < 0 || attr >= CMESH_NUM_ATTR) {
                return 0;
@@ -347,7 +349,7 @@ int cmesh_has_attrib(struct cmesh *cm, int attr)
        return cm->vattr[attr].vbo_valid | cm->vattr[attr].data_valid;
 }
 
-int cmesh_indexed(struct cmesh *cm)
+int cmesh_indexed(const struct cmesh *cm)
 {
        return cm->ibo_valid | cm->idata_valid;
 }
@@ -394,7 +396,7 @@ float *cmesh_attrib(struct cmesh *cm, int attr)
        return (float*)cmesh_attrib_ro(cm, attr);
 }
 
-const float *cmesh_attrib_ro(struct cmesh *cm, int attr)
+const float *cmesh_attrib_ro(const struct cmesh *cm, int attr)
 {
        void *tmp;
        int nelem;
@@ -407,23 +409,25 @@ const float *cmesh_attrib_ro(struct cmesh *cm, int attr)
 #if GL_ES_VERSION_2_0
                return 0;
 #else
-               if(!cm->vattr[attr].vbo_valid) {
+               struct cmesh *m = (struct cmesh*)cm;
+
+               if(!m->vattr[attr].vbo_valid) {
                        return 0;
                }
 
                /* local data copy unavailable, grab the data from the vbo */
-               nelem = cm->vattr[attr].nelem;
-               if(!(cm->vattr[attr].data = malloc(cm->nverts * nelem * sizeof(float)))) {
+               nelem = m->vattr[attr].nelem;
+               if(!(m->vattr[attr].data = malloc(m->nverts * nelem * sizeof(float)))) {
                        return 0;
                }
-               cm->vattr[attr].count = cm->nverts * nelem;
+               m->vattr[attr].count = m->nverts * nelem;
 
-               glBindBuffer(GL_ARRAY_BUFFER, cm->vattr[attr].vbo);
+               glBindBuffer(GL_ARRAY_BUFFER, m->vattr[attr].vbo);
                tmp = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
-               memcpy(cm->vattr[attr].data, tmp, cm->nverts * nelem * sizeof(float));
+               memcpy(m->vattr[attr].data, tmp, m->nverts * nelem * sizeof(float));
                glUnmapBuffer(GL_ARRAY_BUFFER);
 
-               cm->vattr[attr].data_valid = 1;
+               m->vattr[attr].data_valid = 1;
 #endif
        }
        return cm->vattr[attr].data;
@@ -435,17 +439,22 @@ float *cmesh_attrib_at(struct cmesh *cm, int attr, int idx)
        return vptr ? vptr + idx * cm->vattr[attr].nelem : 0;
 }
 
-const float *cmesh_attrib_at_ro(struct cmesh *cm, int attr, int idx)
+const float *cmesh_attrib_at_ro(const struct cmesh *cm, int attr, int idx)
 {
        const float *vptr = cmesh_attrib_ro(cm, attr);
        return vptr ? vptr + idx * cm->vattr[attr].nelem : 0;
 }
 
-int cmesh_attrib_count(struct cmesh *cm, int attr)
+int cmesh_attrib_count(const struct cmesh *cm, int attr)
 {
        return cmesh_has_attrib(cm, attr) ? cm->nverts : 0;
 }
 
+int cmesh_attrib_nelem(const struct cmesh *cm, int attr)
+{
+       return cmesh_has_attrib(cm, attr) ? cm->vattr[attr].nelem : 0;
+}
+
 int cmesh_push_attrib(struct cmesh *cm, int attr, float *v)
 {
        float *vptr;
@@ -549,7 +558,7 @@ unsigned int *cmesh_index(struct cmesh *cm)
        return (unsigned int*)cmesh_index_ro(cm);
 }
 
-const unsigned int *cmesh_index_ro(struct cmesh *cm)
+const unsigned int *cmesh_index_ro(const struct cmesh *cm)
 {
        int nidx;
        unsigned int *tmp;
@@ -558,31 +567,33 @@ const unsigned int *cmesh_index_ro(struct cmesh *cm)
 #if GL_ES_VERSION_2_0
                return 0;
 #else
-               if(!cm->ibo_valid) {
+               struct cmesh *m = (struct cmesh*)cm;
+
+               if(!m->ibo_valid) {
                        return 0;
                }
 
                /* local copy is unavailable, grab the data from the ibo */
-               nidx = cm->nfaces * 3;
-               if(!(tmp = malloc(nidx * sizeof *cm->idata))) {
+               nidx = m->nfaces * 3;
+               if(!(tmp = malloc(nidx * sizeof *m->idata))) {
                        return 0;
                }
-               free(cm->idata);
-               cm->idata = tmp;
-               cm->icount = nidx;
+               free(m->idata);
+               m->idata = tmp;
+               m->icount = nidx;
 
-               glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cm->ibo);
+               glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo);
                tmp = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY);
-               memcpy(cm->idata, tmp, nidx * sizeof *cm->idata);
+               memcpy(m->idata, tmp, nidx * sizeof *m->idata);
                glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
 
-               cm->idata_valid = 1;
+               m->idata_valid = 1;
 #endif
        }
        return cm->idata;
 }
 
-int cmesh_index_count(struct cmesh *cm)
+int cmesh_index_count(const struct cmesh *cm)
 {
        return cm->nfaces * 3;
 }
@@ -604,7 +615,7 @@ int cmesh_push_index(struct cmesh *cm, unsigned int idx)
        return 0;
 }
 
-int cmesh_poly_count(struct cmesh *cm)
+int cmesh_poly_count(const struct cmesh *cm)
 {
        if(cm->nfaces) {
                return cm->nfaces;
@@ -638,7 +649,7 @@ void cmesh_invalidate_index(struct cmesh *cm)
        cm->ibo_valid = 0;
 }
 
-int cmesh_append(struct cmesh *cmdest, struct cmesh *cmsrc)
+int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc)
 {
        int i, nelem, newsz, origsz, srcsz;
        float *vptr;
@@ -784,7 +795,7 @@ int cmesh_remove_submesh(struct cmesh *cm, int idx)
        return 0;
 }
 
-int cmesh_find_submesh(struct cmesh *cm, const char *name)
+int cmesh_find_submesh(const struct cmesh *cm, const char *name)
 {
        int idx = 0;
        struct submesh *sm = cm->sublist;
@@ -799,12 +810,12 @@ int cmesh_find_submesh(struct cmesh *cm, const char *name)
        return -1;
 }
 
-int cmesh_submesh_count(struct cmesh *cm)
+int cmesh_submesh_count(const struct cmesh *cm)
 {
        return cm->subcount;
 }
 
-static struct submesh *get_submesh(struct cmesh *m, int idx)
+static struct submesh *get_submesh(const struct cmesh *m, int idx)
 {
        struct submesh *sm = m->sublist;
        while(sm && --idx >= 0) {
@@ -813,7 +824,7 @@ static struct submesh *get_submesh(struct cmesh *m, int idx)
        return sm;
 }
 
-int cmesh_clone_submesh(struct cmesh *cmdest, struct cmesh *cm, int subidx)
+int cmesh_clone_submesh(struct cmesh *cmdest, const struct cmesh *cm, int subidx)
 {
        struct submesh *sub;
 
@@ -827,28 +838,16 @@ int cmesh_clone_submesh(struct cmesh *cmdest, struct cmesh *cm, int subidx)
 /* assemble a complete vertex by adding all the useful attributes */
 int cmesh_vertex(struct cmesh *cm, float x, float y, float z)
 {
-       int i, j;
+       int i;
 
        cgm_wcons(cm->cur_val + CMESH_ATTR_VERTEX, x, y, z, 1.0f);
        cm->vattr[CMESH_ATTR_VERTEX].data_valid = 1;
        cm->vattr[CMESH_ATTR_VERTEX].nelem = 3;
 
        for(i=0; i<CMESH_NUM_ATTR; i++) {
-               if(cm->vattr[i].data_valid) {
-                       int newsz = cm->vattr[i].count + cm->vattr[i].nelem;
-                       float *tmp = realloc(cm->vattr[i].data, newsz * sizeof *tmp);
-                       if(!tmp) return -1;
-                       tmp += cm->vattr[i].count;
-
-                       cm->vattr[i].data = tmp;
-                       cm->vattr[i].count = newsz;
-
-                       for(j=0; j<cm->vattr[i].nelem; j++) {
-                               *tmp++ = *(&cm->cur_val[i].x + j);
-                       }
+               if(cm->vattr[i].nelem > 0) {
+                       cmesh_push_attrib(cm, i, &cm->cur_val[i].x);
                }
-               cm->vattr[i].vbo_valid = 0;
-               cm->vattr[i].data_valid = 1;
        }
 
        if(cm->idata_valid) {
@@ -1066,13 +1065,13 @@ void cmesh_calc_face_normals(struct cmesh *cm)
        /* TODO */
 }
 
-static int pre_draw(struct cmesh *cm)
+static int pre_draw(const struct cmesh *cm)
 {
        int i, loc, cur_sdr;
 
        glGetIntegerv(GL_CURRENT_PROGRAM, &cur_sdr);
 
-       update_buffers(cm);
+       update_buffers((struct cmesh*)cm);
 
        if(!cm->vattr[CMESH_ATTR_VERTEX].vbo_valid) {
                return -1;
@@ -1125,7 +1124,7 @@ static int pre_draw(struct cmesh *cm)
        return cur_sdr;
 }
 
-void cmesh_draw(struct cmesh *cm)
+void cmesh_draw(const struct cmesh *cm)
 {
        int cur_sdr;
 
@@ -1144,7 +1143,7 @@ void cmesh_draw(struct cmesh *cm)
        post_draw(cm, cur_sdr);
 }
 
-void cmesh_draw_range(struct cmesh *cm, int start, int count)
+void cmesh_draw_range(const struct cmesh *cm, int start, int count)
 {
        int cur_sdr;
 
@@ -1163,7 +1162,7 @@ void cmesh_draw_range(struct cmesh *cm, int start, int count)
        post_draw(cm, cur_sdr);
 }
 
-void cmesh_draw_submesh(struct cmesh *cm, int subidx)
+void cmesh_draw_submesh(const struct cmesh *cm, int subidx)
 {
        struct submesh *sm = cm->sublist;
 
@@ -1179,7 +1178,7 @@ void cmesh_draw_submesh(struct cmesh *cm, int subidx)
        }
 }
 
-static void post_draw(struct cmesh *cm, int cur_sdr)
+static void post_draw(const struct cmesh *cm, int cur_sdr)
 {
        int i;
 
@@ -1211,14 +1210,14 @@ static void post_draw(struct cmesh *cm, int cur_sdr)
        }
 }
 
-void cmesh_draw_wire(struct cmesh *cm, float linesz)
+void cmesh_draw_wire(const struct cmesh *cm, float linesz)
 {
        int cur_sdr, nfaces;
 
        if((cur_sdr = pre_draw(cm)) == -1) {
                return;
        }
-       update_wire_ibo(cm);
+       update_wire_ibo((struct cmesh*)cm);
 
        nfaces = cmesh_poly_count(cm);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cm->wire_ibo);
@@ -1228,7 +1227,7 @@ void cmesh_draw_wire(struct cmesh *cm, float linesz)
        post_draw(cm, cur_sdr);
 }
 
-void cmesh_draw_vertices(struct cmesh *cm, float ptsz)
+void cmesh_draw_vertices(const struct cmesh *cm, float ptsz)
 {
        int cur_sdr;
        if((cur_sdr = pre_draw(cm)) == -1) {
@@ -1243,7 +1242,7 @@ void cmesh_draw_vertices(struct cmesh *cm, float ptsz)
        post_draw(cm, cur_sdr);
 }
 
-void cmesh_draw_normals(struct cmesh *cm, float len)
+void cmesh_draw_normals(const struct cmesh *cm, float len)
 {
 #ifndef GL_ES_VERSION_2_0
        int i, cur_sdr, vert_nelem, norm_nelem;
@@ -1287,7 +1286,7 @@ void cmesh_draw_normals(struct cmesh *cm, float len)
 #endif /* GL_ES_VERSION_2_0 */
 }
 
-void cmesh_draw_tangents(struct cmesh *cm, float len)
+void cmesh_draw_tangents(const struct cmesh *cm, float len)
 {
 #ifndef GL_ES_VERSION_2_0
        int i, cur_sdr, vert_nelem, tang_nelem;
@@ -1432,10 +1431,10 @@ static void calc_aabb(struct cmesh *cm)
        cm->aabb_valid = 1;
 }
 
-void cmesh_aabbox(struct cmesh *cm, cgm_vec3 *vmin, cgm_vec3 *vmax)
+void cmesh_aabbox(const struct cmesh *cm, cgm_vec3 *vmin, cgm_vec3 *vmax)
 {
        if(!cm->aabb_valid) {
-               calc_aabb(cm);
+               calc_aabb((struct cmesh*)cm);
        }
        *vmin = cm->aabb_min;
        *vmax = cm->aabb_max;
@@ -1475,13 +1474,13 @@ static void calc_bsph(struct cmesh *cm)
        cm->bsph_valid = 1;
 }
 
-float cmesh_bsphere(struct cmesh *cm, cgm_vec3 *center, float *rad)
+float cmesh_bsphere(const struct cmesh *cm, cgm_vec3 *center, float *rad)
 {
        if(!cm->bsph_valid) {
-               calc_bsph(cm);
+               calc_bsph((struct cmesh*)cm);
        }
-       *center = cm->bsph_center;
-       *rad = cm->bsph_radius;
+       if(center) *center = cm->bsph_center;
+       if(rad) *rad = cm->bsph_radius;
        return cm->bsph_radius;
 }
 
@@ -1491,7 +1490,7 @@ void cmesh_texcoord_gen_plane(struct cmesh *cm, cgm_vec3 *norm, cgm_vec3 *tang);
 void cmesh_texcoord_gen_box(struct cmesh *cm);
 void cmesh_texcoord_gen_cylinder(struct cmesh *cm);
 
-int cmesh_dump(struct cmesh *cm, const char *fname)
+int cmesh_dump(const struct cmesh *cm, const char *fname)
 {
        FILE *fp = fopen(fname, "wb");
        if(fp) {
@@ -1502,7 +1501,7 @@ int cmesh_dump(struct cmesh *cm, const char *fname)
        return -1;
 }
 
-int cmesh_dump_file(struct cmesh *cm, FILE *fp)
+int cmesh_dump_file(const struct cmesh *cm, FILE *fp)
 {
        static const char *label[] = { "pos", "nor", "tan", "tex", "col", "bw", "bid", "tex2" };
        static const char *elemfmt[] = { 0, " %s(%g)", " %s(%g, %g)", " %s(%g, %g, %g)", " %s(%g, %g, %g, %g)", 0 };
@@ -1543,7 +1542,7 @@ int cmesh_dump_file(struct cmesh *cm, FILE *fp)
        return 0;
 }
 
-int cmesh_dump_obj(struct cmesh *cm, const char *fname)
+int cmesh_dump_obj(const struct cmesh *cm, const char *fname)
 {
        FILE *fp = fopen(fname, "wb");
        if(fp) {
@@ -1557,7 +1556,7 @@ int cmesh_dump_obj(struct cmesh *cm, const char *fname)
 #define HAS_VN 1
 #define HAS_VT 2
 
-int cmesh_dump_obj_file(struct cmesh *cm, FILE *fp, int voffs)
+int cmesh_dump_obj_file(const struct cmesh *cm, FILE *fp, int voffs)
 {
        static const char *fmtstr[] = {" %u", " %u//%u", " %u/%u", " %u/%u/%u"};
        int i, j, num, nelem;
index 920e39d..9c12d01 100644 (file)
@@ -32,13 +32,13 @@ int cmesh_init(struct cmesh *cm);
 void cmesh_destroy(struct cmesh *cm);
 
 void cmesh_clear(struct cmesh *cm);
-int cmesh_clone(struct cmesh *cmdest, struct cmesh *cmsrc);
+int cmesh_clone(struct cmesh *cmdest, const struct cmesh *cmsrc);
 
 int cmesh_set_name(struct cmesh *cm, const char *name);
-const char *cmesh_name(struct cmesh *cm);
+const char *cmesh_name(const struct cmesh *cm);
 
-int cmesh_has_attrib(struct cmesh *cm, int attr);
-int cmesh_indexed(struct cmesh *cm);
+int cmesh_has_attrib(const struct cmesh *cm, int attr);
+int cmesh_indexed(const struct cmesh *cm);
 
 /* vdata can be 0, in which case only memory is allocated
  * returns pointer to the attribute array
@@ -46,10 +46,11 @@ int cmesh_indexed(struct cmesh *cm);
 float *cmesh_set_attrib(struct cmesh *cm, int attr, int nelem, unsigned int num,
                const float *vdata);
 float *cmesh_attrib(struct cmesh *cm, int attr);                       /* invalidates VBO */
-const float *cmesh_attrib_ro(struct cmesh *cm, int attr);      /* doesn't invalidate */
+const float *cmesh_attrib_ro(const struct cmesh *cm, int attr);        /* doesn't invalidate */
 float *cmesh_attrib_at(struct cmesh *cm, int attr, int idx);
-const float *cmesh_attrib_at_ro(struct cmesh *cm, int attr, int idx);
-int cmesh_attrib_count(struct cmesh *cm, int attr);
+const float *cmesh_attrib_at_ro(const struct cmesh *cm, int attr, int idx);
+int cmesh_attrib_count(const struct cmesh *cm, int attr);
+int cmesh_attrib_nelem(const struct cmesh *cm, int attr);
 int cmesh_push_attrib(struct cmesh *cm, int attr, float *v);
 int cmesh_push_attrib1f(struct cmesh *cm, int attr, float x);
 int cmesh_push_attrib2f(struct cmesh *cm, int attr, float x, float y);
@@ -61,26 +62,26 @@ int cmesh_push_attrib4f(struct cmesh *cm, int attr, float x, float y, float z, f
  */
 unsigned int *cmesh_set_index(struct cmesh *cm, int num, const unsigned int *indices);
 unsigned int *cmesh_index(struct cmesh *cm);   /* invalidates IBO */
-const unsigned int *cmesh_index_ro(struct cmesh *cm);  /* doesn't invalidate */
-int cmesh_index_count(struct cmesh *cm);
+const unsigned int *cmesh_index_ro(const struct cmesh *cm);    /* doesn't invalidate */
+int cmesh_index_count(const struct cmesh *cm);
 int cmesh_push_index(struct cmesh *cm, unsigned int idx);
 
-int cmesh_poly_count(struct cmesh *cm);
+int cmesh_poly_count(const struct cmesh *cm);
 
 /* attr can be -1 to invalidate all attributes */
 void cmesh_invalidate_vbo(struct cmesh *cm, int attr);
 void cmesh_invalidate_ibo(struct cmesh *cm);
 
-int cmesh_append(struct cmesh *cmdest, struct cmesh *cmsrc);
+int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc);
 
 /* submeshes */
 void cmesh_clear_submeshes(struct cmesh *cm);
 /* a submesh is defined as a consecutive range of faces */
 int cmesh_submesh(struct cmesh *cm, const char *name, int fstart, int fcount);
 int cmesh_remove_submesh(struct cmesh *cm, int idx);
-int cmesh_find_submesh(struct cmesh *cm, const char *name);
-int cmesh_submesh_count(struct cmesh *cm);
-int cmesh_clone_submesh(struct cmesh *cmdest, struct cmesh *cm, int subidx);
+int cmesh_find_submesh(const struct cmesh *cm, const char *name);
+int cmesh_submesh_count(const struct cmesh *cm);
+int cmesh_clone_submesh(struct cmesh *cmdest, const struct cmesh *cm, int subidx);
 
 /* immediate-mode style mesh construction interface */
 int cmesh_vertex(struct cmesh *cm, float x, float y, float z);
@@ -102,22 +103,22 @@ int cmesh_explode(struct cmesh *cm);      /* undo all vertex sharing */
 /* this is only guaranteed to work on an exploded mesh */
 void cmesh_calc_face_normals(struct cmesh *cm);
 
-void cmesh_draw(struct cmesh *cm);
-void cmesh_draw_range(struct cmesh *cm, int start, int count);
-void cmesh_draw_submesh(struct cmesh *cm, int subidx); /* XXX only for indexed meshes currently */
-void cmesh_draw_wire(struct cmesh *cm, float linesz);
-void cmesh_draw_vertices(struct cmesh *cm, float ptsz);
-void cmesh_draw_normals(struct cmesh *cm, float len);
-void cmesh_draw_tangents(struct cmesh *cm, float len);
+void cmesh_draw(const struct cmesh *cm);
+void cmesh_draw_range(const struct cmesh *cm, int start, int count);
+void cmesh_draw_submesh(const struct cmesh *cm, int subidx);   /* XXX only for indexed meshes currently */
+void cmesh_draw_wire(const struct cmesh *cm, float linesz);
+void cmesh_draw_vertices(const struct cmesh *cm, float ptsz);
+void cmesh_draw_normals(const struct cmesh *cm, float len);
+void cmesh_draw_tangents(const struct cmesh *cm, float len);
 
 /* get the bounding box in local space. The result will be cached and subsequent
  * calls will return the same box. The cache gets invalidated by any functions that
  * can affect the vertex data
  */
-void cmesh_aabbox(struct cmesh *cm, cgm_vec3 *vmin, cgm_vec3 *vmax);
+void cmesh_aabbox(const struct cmesh *cm, cgm_vec3 *vmin, cgm_vec3 *vmax);
 
 /* get the bounding sphere in local space. The result will be cached ... see above */
-float cmesh_bsphere(struct cmesh *cm, cgm_vec3 *center, float *rad);
+float cmesh_bsphere(const struct cmesh *cm, cgm_vec3 *center, float *rad);
 
 /* texture coordinate manipulation */
 void cmesh_texcoord_apply_xform(struct cmesh *cm, float *xform);
@@ -128,10 +129,10 @@ void cmesh_texcoord_gen_cylinder(struct cmesh *cm);
 /* FILE I/O */
 int cmesh_load(struct cmesh *cm, const char *fname);
 
-int cmesh_dump(struct cmesh *cm, const char *fname);
-int cmesh_dump_file(struct cmesh *cm, FILE *fp);
-int cmesh_dump_obj(struct cmesh *cm, const char *fname);
-int cmesh_dump_obj_file(struct cmesh *cm, FILE *fp, int voffs);
+int cmesh_dump(const struct cmesh *cm, const char *fname);
+int cmesh_dump_file(const struct cmesh *cm, FILE *fp);
+int cmesh_dump_obj(const struct cmesh *cm, const char *fname);
+int cmesh_dump_obj_file(const struct cmesh *cm, FILE *fp, int voffs);
 
 
 
index 93cb963..048b8a0 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 #include "frac.h"
 #include "dynarr.h"
 
@@ -31,12 +32,20 @@ void frac_destroy(struct fracture *frac)
        }
 }
 
+static int init_cell(struct frac_cell *cell)
+{
+       memset(cell, 0, sizeof *cell);
+       if(!(cell->mesh = cmesh_alloc())) {
+               return -1;
+       }
+       return 0;
+}
+
 static void destroy_cell(struct frac_cell *cell)
 {
        if(!cell) return;
-
+       free(cell->polys);
        cmesh_free(cell->mesh);
-       dynarr_free(cell->planes);
 }
 
 void frac_mesh(struct fracture *frac, const struct cmesh *m)
@@ -49,17 +58,10 @@ int frac_point(struct fracture *frac, float x, float y, float z)
        struct frac_cell cell;
        struct frac_cell *tmp;
 
+       init_cell(&cell);
        cgm_vcons(&cell.pt, x, y, z);
-       if(!(cell.mesh = cmesh_alloc())) {
-               return -1;
-       }
-       if(!(cell.planes = dynarr_alloc(0, sizeof *cell.planes))) {
-               cmesh_free(cell.mesh);
-               return -1;
-       }
        if(!(tmp = dynarr_push(frac->cells, &cell))) {
-               cmesh_free(cell.mesh);
-               dynarr_free(cell.planes);
+               destroy_cell(&cell);
                return -1;
        }
        frac->cells = tmp;
@@ -113,12 +115,13 @@ int frac_build_cells(struct fracture *frac)
                }
        }
 
-       return -1;
+       return 0;
 }
 
 static int build_cell(struct fracture *frac, int cellidx)
 {
        int i, j, num, clipres;
+       int *valid_planes;
        struct plane plane;
        struct frac_cell *cell = frac->cells + cellidx;
        struct poly poly, clipped, *polys, *pptr;
@@ -129,7 +132,7 @@ static int build_cell(struct fracture *frac, int cellidx)
        }
 
        cmesh_bsphere(frac->mesh, 0, &bsize);
-       size *= 2;
+       bsize *= 2;
 
        num = dynarr_size(frac->cells);
        for(i=0; i<num; i++) {
@@ -161,8 +164,11 @@ static int build_cell(struct fracture *frac, int cellidx)
                                /* completely clipped, mark it for removal */
                                valid_planes[i] = 0;
                                cell->num_polys--;
+                               destroy_poly(&clipped);
                                break;
                        }
+                       destroy_poly(polys + i);
+                       polys[i] = clipped;
                }
        }
 
@@ -178,13 +184,116 @@ static int build_cell(struct fracture *frac, int cellidx)
                        destroy_poly(polys + i);
                }
        }
-       darr_free(polys);
+       dynarr_free(polys);
+       return 0;
+}
+
+static int mesh_poly(struct poly *poly, const struct cmesh *mesh, int faceidx)
+{
+       int i, vsz, nsz, uvsz;
+       struct vertex vert, *tmpvert;
+       const float *varr, *narr, *uvarr;
+       unsigned int vidx;
+
+       if(init_poly(poly) == -1) {
+               return -1;
+       }
+
+       varr = cmesh_attrib_ro(mesh, CMESH_ATTR_VERTEX);
+       narr = cmesh_attrib_ro(mesh, CMESH_ATTR_NORMAL);
+       uvarr = cmesh_attrib_ro(mesh, CMESH_ATTR_TEXCOORD);
+       vsz = cmesh_attrib_nelem(mesh, CMESH_ATTR_VERTEX);
+       nsz = cmesh_attrib_nelem(mesh, CMESH_ATTR_NORMAL);
+       uvsz = cmesh_attrib_nelem(mesh, CMESH_ATTR_TEXCOORD);
+
+       for(i=0; i<3; i++) {
+               if(cmesh_indexed(mesh)) {
+                       vidx = cmesh_index_ro(mesh)[faceidx * 3 + i];
+               } else {
+                       vidx = faceidx * 3 + i;
+               }
+               vert.pos.x = varr[vidx * vsz];
+               vert.pos.y = varr[vidx * vsz + 1];
+               vert.pos.z = varr[vidx * vsz + 2];
+               vert.norm.x = narr[vidx * nsz];
+               vert.norm.y = narr[vidx * nsz + 1];
+               vert.norm.z = narr[vidx * nsz + 2];
+               vert.uv.x = uvarr[vidx * uvsz];
+               vert.uv.y = uvarr[vidx * uvsz + 1];
+
+               if(!(tmpvert = dynarr_push(poly->verts, &vert))) {
+                       destroy_poly(poly);
+                       return -1;
+               }
+               poly->verts = tmpvert;
+       }
+       return 0;
+}
+
+#define ADD_VERTEX(mesh, vert) \
+       do { \
+               cmesh_normal(mesh, (vert)->norm.x, (vert)->norm.y, (vert)->norm.z); \
+               cmesh_texcoord(mesh, (vert)->uv.x, (vert)->uv.y, 0); \
+               if(cmesh_vertex(mesh, (vert)->pos.x, (vert)->pos.y, (vert)->pos.z) == -1) { \
+                       fprintf(stderr, "SKATA\n"); \
+                       abort(); \
+               } \
+       } while(0)
+
+static int build_cell_shell(struct cmesh *mesh, const struct cmesh *orig,
+               const struct frac_cell *cell)
+{
+       int i, j, k, nfaces, clipres;
+       struct plane plane;
+       struct poly poly, clipped;
+       struct vertex *vert;
+
+       nfaces = cmesh_poly_count(orig);
+       for(i=0; i<nfaces; i++) {
+               if(mesh_poly(&poly, orig, i) == -1) {
+                       cmesh_destroy(mesh);
+                       return -1;
+               }
+
+               for(j=0; j<cell->num_polys; j++) {
+                       poly_plane(cell->polys + j, &plane);
+
+                       init_poly(&clipped);
+                       if((clipres = clip_poly(&clipped, &poly, &plane)) < 0) {
+                               destroy_poly(&clipped);
+                               break;
+                       }
+                       destroy_poly(&poly);
+                       poly = clipped;
+               }
+
+               if(j < cell->num_polys) {
+                       continue;
+               }
+
+               vert = poly.verts + 1;
+               for(k=0; k<dynarr_size(poly.verts)-2; k++) {
+                       ADD_VERTEX(mesh, poly.verts);
+                       ADD_VERTEX(mesh, vert); vert++;
+                       ADD_VERTEX(mesh, vert);
+               }
+               destroy_poly(&poly);
+       }
        return 0;
 }
 
 int frac_build_shell(struct fracture *frac)
 {
-       return -1;
+       int i, num_cells;
+
+       num_cells = dynarr_size(frac->cells);
+       for(i=0; i<num_cells; i++) {
+               if(build_cell_shell(frac->cells[i].mesh, frac->mesh, frac->cells + i) == -1) {
+                       return -1;
+               }
+       }
+
+       return 0;
 }
 
 int frac_build_walls(struct fracture *frac)
index 8a7e022..7b08107 100644 (file)
@@ -9,6 +9,8 @@ struct frac_cell {
        cgm_vec3 pt;
        struct poly *polys;
        int num_polys;
+
+       struct cmesh *mesh;
 };
 
 struct fracture {
index 4e30628..67c3c31 100644 (file)
@@ -32,7 +32,7 @@ void poly_normal(const struct poly *poly, cgm_vec3 *n)
        va = poly->verts[1].pos;
        cgm_vsub(&va, &poly->verts[0].pos);
        vb = poly->verts[2].pos;
-       cgm_vsub(&vb, &poly->verts[2].pos);
+       cgm_vsub(&vb, &poly->verts[0].pos);
 
        cgm_vcross(n, &va, &vb);
        cgm_vnormalize(n);
@@ -138,6 +138,11 @@ int init_poly(struct poly *p)
        return p->verts ? 0 : -1;
 }
 
+void destroy_poly(struct poly *p)
+{
+       dynarr_free(p->verts);
+}
+
 /* returns:
  *  1 -> both inside
  *  0 -> straddling and clipped
@@ -203,7 +208,7 @@ int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *pla
        int i, nextidx, res = 0, vnum;
        int edges_clipped = 0;
 
-       dynarr_clear(pout->verts);
+       DYNARR_CLEAR(pout->verts);
 
        vnum = dynarr_size(pin->verts);
        for(i=0; i<vnum; i++) {