X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Ffrac.c;h=048b8a04df5b887f9192c88a6fb4cda6d98e580c;hb=47382e57c60544c263e6822ea8d76025c758c7b2;hp=93cb963951ea5d351a2c407aa0eac068db1dc7ad;hpb=82bf18c392447827912146ba65145500c9c25385;p=meshfrac diff --git a/src/frac.c b/src/frac.c index 93cb963..048b8a0 100644 --- a/src/frac.c +++ b/src/frac.c @@ -1,5 +1,6 @@ #include #include +#include #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; inum_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; inum_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; kcells); + for(i=0; icells[i].mesh, frac->mesh, frac->cells + i) == -1) { + return -1; + } + } + + return 0; } int frac_build_walls(struct fracture *frac)