#include "dynarr.h"
static void destroy_cell(struct frac_cell *cell);
+static int build_cell(struct fracture *frac, int cellidx);
int frac_init(struct fracture *frac)
{
return dynarr_size(frac->cells);
}
+/* --- step 1: generate a bunch of points (or let the user add them manually) */
+
int frac_gen_points(struct fracture *frac, int num)
{
int i;
return 0;
}
+
+/* --- step 2: construct voronoi cells bounded by planes */
+
int frac_build_cells(struct fracture *frac)
{
+ int i;
+
+ for(i=0; i<dynarr_size(frac->cells); i++) {
+ if(build_cell(frac, i) == -1) {
+ return -1;
+ }
+ }
+
return -1;
}
+static int build_cell(struct fracture *frac, int cellidx)
+{
+ int i, j, num;
+ struct plane plane, *pptr;
+ struct frac_cell *cell = frac->cells + cellidx;
+
+ num = dynarr_size(frac->cells);
+ for(i=0; i<num; i++) {
+ if(i == cellidx) continue;
+ midplane(&plane, &cell->pt, &frac->cells[i].pt);
+ if(!(pptr = dynarr_push(cell->planes, &plane))) {
+ return -1;
+ }
+ cell->planes = pptr;
+ }
+
+ /* clip all planes against each other to end up with a convex cell */
+ num = dynarr_size(cell->planes);
+ for(i=0; i<num; i++) {
+ for(j=0; j<num; j++) {
+ if(i == j) continue;
+
+ clip_poly...
+ }
+ }
+}
+
int frac_build_shell(struct fracture *frac)
{
return -1;
poly_normal(poly, &plane->norm);
}
+int plane_poly(const struct plane *plane, struct poly *poly, float size)
+{
+ static const float corn[][2] = {{1,1}, {-1,1}, {-1,-1}, {1, -1}};
+ int i;
+ cgm_vec3 pos, up, right, dir;
+ size *= 0.5f;
+
+ if(!(poly->verts = dynarr_alloc(4, sizeof *poly->verts))) {
+ fprintf(stderr, "plane_poly: failed to allocate polygon vertices\n");
+ return -1;
+ }
+
+ cgm_vcons(&up, 0, 1, 0);
+ if(1.0f - fabs(cgm_vdot(&up, &plane->norm)) < 1e-2) {
+ cgm_vcons(&up, 0, 0, -1);
+ }
+ cgm_vcross(&right, &up, &plane->norm);
+ cgm_vnormalize(&right);
+ cgm_vcross(&up, &plane.norm, &right);
+ cgm_vnormalize(&up);
+
+ for(i=0; i<4; i++) {
+ v.x = plane->pt.x + (right.x * corn[i][0] + up.x * corn[i][1]) * size;
+ v.y = plane->pt.y + (right.y * corn[i][0] + up.y * corn[i][1]) * size;
+ v.z = plane->pt.z + (right.z * corn[i][0] + up.z * corn[i][1]) * size;
+
+
+
+
+}
+
float ray_plane(const cgm_ray *ray, const struct plane *plane)
{
float ndotdir, t;
}
return t;
}
+
+
+/* returns:
+ * 1 -> both inside
+ * 0 -> straddling and clipped
+ * -1 -> both outside
+ */
+static int clip_edge(struct poly *pout, const struct vertex *v0, const struct vertex *v1,
+ const struct plane *plane)
+{
+ float d0, d1, t;
+ cgm_ray ray;
+ int i, vnum = dynarr_size(pout->verts);
+ struct vertex vnew;
+
+ d0 = plane_sdist(plane, &v0->pos);
+ d1 = plane_sdist(plane, &v1->pos);
+
+ ray.orig = v0->pos;
+ ray.dir = v1->pos;
+ cgm_vsub(&ray.dir, &v0->pos);
+
+ for(i=0; i<3; i++) {
+ ray.origin[i] = pos0[i];
+ ray.dir[i] = pos1[i] - pos0[i];
+ }
+
+ if(d0 >= 0.0) {
+ /* start inside */
+ if(d1 >= 0.0) {
+ /* all inside */
+ DYNARR_PUSH(pout->verts, v1); /* append v1 */
+ return 1;
+ } else {
+ /* going out */
+ t = ray_plane(&ray, plane);
+ cgm_raypos(&vnew->pos, &ray, t);
+
+ cgm_vlerp(&vnew->norm, &v0->norm, &v1->norm, t);
+ vnew->uv.x = cgm_lerp(v0->uv.x, v1->uv.x, t);
+ vnew->uv.y = cgm_lerp(v0->uv.y, v1->uv.y, t);
+ /* append new vertex on the intersection point */
+ DYNARR_PUSH(pout->verts, &vnew);
+ }
+ } else {
+ /* start outside */
+ if(d1 >= 0) {
+ /* going in */
+ t = ray_plane(&ray, plane);
+ cgm_raypos(&vnew->pos, &ray, t);
+
+ cgm_vlerp(&vnew->norm, &v0->norm, &v1->norm, t);
+ vnew->uv.x = cgm_lerp(v0->uv.x, v1->uv.x, t);
+ vnew->uv.y = cgm_lerp(v0->uv.y, v1->uv.y, t);
+ /* append new vertex on the intersection point */
+ DYNARR_PUSH(pout->verts, &vnew);
+ /* then append v1 ... */
+ DYNARR_PUSH(pout->verts, v1);
+ } else {
+ /* all outside */
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *plane)
+{
+ int i, nextidx, res = 0, vnum;
+ int edges_clipped = 0;
+
+ dynarr_clear(pout->verts);
+
+ vnum = dynarr_size(pin->verts);
+ for(i=0; i<vnum; i++) {
+ nextidx = i + 1;
+ if(nextidx >= vnum) nextidx = 0;
+ res = clip_edge(pout, pin->verts + i, pin->verts + nextidx, plane);
+ if(res == 0) {
+ ++edges_clipped;
+ }
+ }
+
+ return edges_clipped > 0 ? 0 : 1;
+
+}