From: John Tsiombikas Date: Sat, 11 Feb 2023 12:32:51 +0000 (+0200) Subject: trying to fix the clipping bugs X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=meshfrac;a=commitdiff_plain;h=59a8deae3d561aa3797a6bf25c76803fe098cdf0 trying to fix the clipping bugs --- diff --git a/main.c b/main.c index 2218f45..258cbd5 100644 --- 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); diff --git a/src/cmesh.c b/src/cmesh.c index 3492ef2..249c69c 100644 --- a/src/cmesh.c +++ b/src/cmesh.c @@ -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; inverts; i++) { if(!(vptr = get_vec4(cm, CMESH_ATTR_VERTEX, i, &v))) { return; diff --git a/src/frac.c b/src/frac.c index a6ce0a8..4263c65 100644 --- a/src/frac.c +++ b/src/frac.c @@ -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; ipt, &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; inum_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; diff --git a/src/frac.h b/src/frac.h index 7b08107..0049f09 100644 --- a/src/frac.h +++ b/src/frac.h @@ -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); diff --git a/src/geom.c b/src/geom.c index 25c4d0a..996a484 100644 --- a/src/geom.c +++ b/src/geom.c @@ -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); diff --git a/src/geom.h b/src/geom.h index a66d163..7fc183c 100644 --- a/src/geom.h +++ b/src/geom.h @@ -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); diff --git a/src/meshgen.c b/src/meshgen.c index 3cc3188..cbce81c 100644 --- a/src/meshgen.c +++ b/src/meshgen.c @@ -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;