#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"
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)
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;
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 {
static void display(void)
{
- int i, num;
+ int i, j, num;
+ struct poly *poly;
update();
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();
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();
}
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';
};
-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);
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;
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;
}
if(cmesh_indexed(cmsrc)) {
- cmesh_index(cmsrc); /* force validation .... */
+ /* force validation .... */
+ cmesh_index((struct cmesh*)cmsrc);
cmdest->idata = iarr;
cmdest->icount = icount;
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;
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;
}
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;
#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;
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;
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;
#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;
}
return 0;
}
-int cmesh_poly_count(struct cmesh *cm)
+int cmesh_poly_count(const struct cmesh *cm)
{
if(cm->nfaces) {
return cm->nfaces;
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;
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;
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) {
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;
/* 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) {
/* 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;
return cur_sdr;
}
-void cmesh_draw(struct cmesh *cm)
+void cmesh_draw(const struct cmesh *cm)
{
int cur_sdr;
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;
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;
}
}
-static void post_draw(struct cmesh *cm, int cur_sdr)
+static void post_draw(const struct cmesh *cm, int cur_sdr)
{
int i;
}
}
-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);
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) {
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;
#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;
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;
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;
}
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) {
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 };
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) {
#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;
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
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);
*/
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);
/* 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);
/* 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);
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "frac.h"
#include "dynarr.h"
}
}
+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)
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;
}
}
- 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;
}
cmesh_bsphere(frac->mesh, 0, &bsize);
- size *= 2;
+ bsize *= 2;
num = dynarr_size(frac->cells);
for(i=0; i<num; i++) {
/* completely clipped, mark it for removal */
valid_planes[i] = 0;
cell->num_polys--;
+ destroy_poly(&clipped);
break;
}
+ destroy_poly(polys + i);
+ polys[i] = clipped;
}
}
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)
cgm_vec3 pt;
struct poly *polys;
int num_polys;
+
+ struct cmesh *mesh;
};
struct fracture {
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);
return p->verts ? 0 : -1;
}
+void destroy_poly(struct poly *p)
+{
+ dynarr_free(p->verts);
+}
+
/* returns:
* 1 -> both inside
* 0 -> straddling and clipped
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++) {