trying to fix the clipping bugs
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 11 Feb 2023 12:32:51 +0000 (14:32 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 11 Feb 2023 12:32:51 +0000 (14:32 +0200)
main.c
src/cmesh.c
src/frac.c
src/frac.h
src/geom.c
src/geom.h
src/meshgen.c

diff --git a/main.c b/main.c
index 2218f45..258cbd5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -116,12 +116,21 @@ static int init(void)
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60);
 
        mesh = cmesh_alloc();
-       gen_torus(mesh, 2, 0.8, 24, 12, 1, 1);
+       //gen_torus(mesh, 2, 0.8, 24, 12, 1, 1);
+       //gen_sphere(mesh, 2, 12, 6, 1, 1);
+       gen_box(mesh, 2, 2, 2, 0, 0);
 
        if(frac_init(&frac) == -1) {
                return -1;
        }
        frac_mesh(&frac, mesh);
+       frac.cell_gap = 0.1;
+
+       //frac_gen_points(&frac, 16);
+       frac_point(&frac, -5, 0, 0);
+       frac_point(&frac, 5, 0, 0);
+       show_points = 1;
+       cur = 1;
 
        return 0;
 }
@@ -138,7 +147,7 @@ static void update(void)
                switch(cur) {
                case 0:
                        printf("Generate points...\n");
-                       if(frac_gen_points(&frac, 16) != -1) {
+                       if(frac_gen_points(&frac, 2) != -1) {
                                cur++;
                        } else {
                                pending = cur;
@@ -199,13 +208,16 @@ static void display(void)
        glMatrixMode(GL_MODELVIEW);
        glLoadMatrixf(view_mat);
 
+       bind_program(0);
+       glShadeModel(GL_FLAT);
+
        if(show_orig) {
-               bind_program(sdr);
+               //bind_program(sdr);
                cmesh_draw(mesh);
+               bind_program(0);
        }
        if(show_points) {
                num = frac_num_cells(&frac);
-               bind_program(0);
 
                glPushAttrib(GL_ENABLE_BIT);
                glDisable(GL_LIGHTING);
@@ -229,8 +241,6 @@ static void display(void)
        }
 
        if(show_planes) {
-               bind_program(0);
-
                glPushAttrib(GL_ENABLE_BIT);
                glDisable(GL_LIGHTING);
 
@@ -249,8 +259,9 @@ static void display(void)
        }
 
        if(show_shell) {
-               bind_program(sdr);
+               //bind_program(sdr);
                cmesh_draw(frac.cells[cur_cell].mesh);
+               bind_program(0);
        }
 
        assert(glGetError() == GL_NO_ERROR);
index 3492ef2..249c69c 100644 (file)
@@ -11,7 +11,7 @@
 struct cmesh_vattrib {
        int nelem;      /* num elements per attribute [1, 4] */
        float *data;
-       unsigned int count;
+       unsigned int count;     /* number of floats in data */
        unsigned int vbo;
        int vbo_valid, data_valid;
 };
@@ -246,7 +246,7 @@ static int clone(struct cmesh *cmdest, const struct cmesh *cmsrc, struct submesh
                        nelem = cmsrc->vattr[i].nelem;
                        cmdest->vattr[i].nelem = nelem;
                        cmdest->vattr[i].data = varr[i];
-                       cmdest->vattr[i].count = vcount;
+                       cmdest->vattr[i].count = vcount * nelem;
                        vptr = cmsrc->vattr[i].data + vstart * nelem;
                        memcpy(cmdest->vattr[i].data, vptr, vcount * nelem * sizeof(float));
                        cmdest->vattr[i].data_valid = 1;
@@ -669,7 +669,7 @@ int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc)
                        assert(cmdest->vattr[i].nelem == cmsrc->vattr[i].nelem);
                        nelem = cmdest->vattr[i].nelem;
                        origsz = cmdest->nverts * nelem;
-                       newsz = cmdest->nverts + cmsrc->nverts * nelem;
+                       newsz = (cmdest->nverts + cmsrc->nverts) * nelem;
 
                        if(!(vptr = realloc(cmdest->vattr[i].data, newsz * sizeof *vptr))) {
                                return -1;
@@ -704,6 +704,9 @@ int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc)
                }
        }
 
+       cmdest->nverts += cmsrc->nverts;
+       cmdest->nfaces += cmsrc->nfaces;
+
        cmdest->wire_ibo_valid = 0;
        cmdest->aabb_valid = 0;
        cmdest->bsph_valid = 0;
@@ -930,6 +933,10 @@ void cmesh_apply_xform(struct cmesh *cm, float *xform, float *dir_xform)
        cgm_vec3 n, t;
        float *vptr;
 
+       if(!dir_xform) {
+               dir_xform = xform;
+       }
+
        for(i=0; i<cm->nverts; i++) {
                if(!(vptr = get_vec4(cm, CMESH_ATTR_VERTEX, i, &v))) {
                        return;
index a6ce0a8..4263c65 100644 (file)
@@ -132,17 +132,19 @@ static int build_cell(struct fracture *frac, int cellidx)
        }
 
        cmesh_bsphere(frac->mesh, 0, &bsize);
-       bsize *= 2;
+       bsize *= 8;
 
        num = dynarr_size(frac->cells);
        for(i=0; i<num; i++) {
                if(i == cellidx) continue;
-               midplane(&plane, &cell->pt, &frac->cells[i].pt);
-               plane_poly(&plane, &poly, bsize);
-               if(!(pptr = dynarr_push(polys, &poly))) {
-                       return -1;
+               midplane(&plane, &frac->cells[i].pt, &cell->pt, frac->cell_gap);
+               if(plane_sdist(&plane, &cell->pt) > 0.0f) {
+                       plane_poly(&plane, &poly, bsize);
+                       if(!(pptr = dynarr_push(polys, &poly))) {
+                               return -1;
+                       }
+                       polys = pptr;
                }
-               polys = pptr;
        }
 
        num = dynarr_size(polys);
@@ -191,7 +193,7 @@ static int build_cell(struct fracture *frac, int cellidx)
 static int mesh_poly(struct poly *poly, const struct cmesh *mesh, int faceidx)
 {
        int i, vsz, nsz, uvsz;
-       struct vertex vert, *tmpvert;
+       struct vertex *tmpvert, vert = {0};
        const float *varr, *narr, *uvarr;
        unsigned int vidx;
 
@@ -215,11 +217,15 @@ static int mesh_poly(struct poly *poly, const struct cmesh *mesh, int faceidx)
                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(narr) {
+                       vert.norm.x = narr[vidx * nsz];
+                       vert.norm.y = narr[vidx * nsz + 1];
+                       vert.norm.z = narr[vidx * nsz + 2];
+               }
+               if(uvarr) {
+                       vert.uv.x = uvarr[vidx * uvsz];
+                       vert.uv.y = uvarr[vidx * uvsz + 1];
+               }
 
                if(!(tmpvert = dynarr_push(poly->verts, &vert))) {
                        destroy_poly(poly);
@@ -258,6 +264,10 @@ static int build_cell_shell(struct cmesh *mesh, const struct cmesh *orig,
        cplanes = alloca(cell->num_polys * sizeof *cplanes);
        for(i=0; i<cell->num_polys; i++) {
                poly_plane(cell->polys + i, cplanes + i);
+               /* flip the plane normal towards the inside of the cell, to clip everything
+                * outside the cell
+                */
+               cgm_vcons(&cplanes[i].norm, -cplanes[i].norm.x, -cplanes[i].norm.y, -cplanes[i].norm.z);
        }
 
        nfaces = cmesh_poly_count(orig);
@@ -290,6 +300,7 @@ static int build_cell_shell(struct cmesh *mesh, const struct cmesh *orig,
                                if((clipres = clip_poly(&wallclipped, cell->polys + j, &plane)) < 0) {
                                        /* mark for deletion */
                                        delwall[j] = 1;
+                                       destroy_poly(&wallclipped);
                                } else if(clipres == 0) {
                                        destroy_poly(cell->polys + j);
                                        cell->polys[j] = wallclipped;
index 7b08107..0049f09 100644 (file)
@@ -16,6 +16,7 @@ struct frac_cell {
 struct fracture {
        struct cmesh *mesh;                     /* no ownership */
        struct frac_cell *cells;        /* dynarr */
+       float cell_gap;
 };
 
 int frac_init(struct fracture *frac);
index 25c4d0a..996a484 100644 (file)
@@ -10,19 +10,19 @@ float plane_dist(const struct plane *p, const cgm_vec3 *pt)
 
 float plane_sdist(const struct plane *p, const cgm_vec3 *pt)
 {
-       cgm_vec3 v = p->pt;
-       cgm_vsub(&v, pt);
+       cgm_vec3 v = *pt;
+       cgm_vsub(&v, &p->pt);
        return cgm_vdot(&v, &p->norm);
 }
 
-void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b)
+void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b, float offs)
 {
        p->norm = *b;
        cgm_vsub(&p->norm, a);
        cgm_vnormalize(&p->norm);
-       p->pt.x = a->x + p->norm.x * 0.5f;
-       p->pt.y = a->y + p->norm.y * 0.5f;
-       p->pt.z = a->z + p->norm.z * 0.5f;
+       p->pt.x = (a->x + b->x) * 0.5f + p->norm.x * offs;
+       p->pt.y = (a->y + b->y) * 0.5f + p->norm.y * offs;
+       p->pt.z = (a->z + b->z) * 0.5f + p->norm.z * offs;
 }
 
 void poly_normal(const struct poly *poly, cgm_vec3 *n)
@@ -170,7 +170,10 @@ static int clip_edge(struct poly *pout, const struct vertex *v0, const struct ve
                        return 1;
                } else {
                        /* going out */
-                       t = ray_plane(&ray, plane);
+                       if((t = ray_plane(&ray, plane)) < 0.0f) {
+                               t = 0.0f;
+                       }
+                       assert(t <= 1.0f);
                        cgm_raypos(&vnew.pos, &ray, t);
 
                        cgm_vlerp(&vnew.norm, &v0->norm, &v1->norm, t);
@@ -183,7 +186,10 @@ static int clip_edge(struct poly *pout, const struct vertex *v0, const struct ve
                /* start outside */
                if(d1 >= 0) {
                        /* going in */
-                       t = ray_plane(&ray, plane);
+                       if((t = ray_plane(&ray, plane)) < 0.0f) {
+                               t = 0.0f;
+                       }
+                       assert(t <= 1.0f);
                        cgm_raypos(&vnew.pos, &ray, t);
 
                        cgm_vlerp(&vnew.norm, &v0->norm, &v1->norm, t);
index a66d163..7fc183c 100644 (file)
@@ -18,7 +18,7 @@ struct poly {
 
 float plane_dist(const struct plane *p, const cgm_vec3 *pt);
 float plane_sdist(const struct plane *p, const cgm_vec3 *pt);
-void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b);
+void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b, float offs);
 
 void poly_plane(const struct poly *poly, struct plane *plane);
 int plane_poly(const struct plane *plane, struct poly *poly, float size);
index 3cc3188..cbce81c 100644 (file)
@@ -73,9 +73,9 @@ void gen_sphere(struct cmesh *mesh, float rad, int usub, int vsub, float urange,
                                *idxarr++ = idx + 1;
                                *idxarr++ = idx + vverts + 1;
 
+                               *idxarr++ = idx + vverts;
                                *idxarr++ = idx;
                                *idxarr++ = idx + vverts + 1;
-                               *idxarr++ = idx + vverts;
                        }
 
                        v += dv;