foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 29 Jan 2023 12:48:27 +0000 (14:48 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 29 Jan 2023 12:48:27 +0000 (14:48 +0200)
src/frac.c
src/frac.h
src/geom.c
src/geom.h

index 8a6bcae..071b5c2 100644 (file)
@@ -4,6 +4,7 @@
 #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)
 {
@@ -70,6 +71,8 @@ int frac_num_cells(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;
@@ -97,11 +100,49 @@ int frac_gen_points(struct fracture *frac, int num)
        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;
index 03ae4e6..72192b7 100644 (file)
@@ -3,11 +3,12 @@
 
 #include "cmesh.h"
 #include "cgmath/cgmath.h"
+#include "geom.h"
 
 struct frac_cell {
        cgm_vec3 pt;
        struct cmesh *mesh;
-       cgm_vec4 *planes;                       /* dynarr */
+       struct plane *planes;                   /* dynarr */
 };
 
 struct fracture {
index 2178664..0b94385 100644 (file)
@@ -42,6 +42,37 @@ void poly_plane(const struct poly *poly, struct plane *plane)
        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;
@@ -93,3 +124,91 @@ float ray_poly(const cgm_ray *ray, const struct poly *poly)
        }
        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;
+
+}
index 14faa82..ebb6659 100644 (file)
@@ -21,9 +21,12 @@ 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 poly_plane(const struct poly *poly, struct plane *plane);
+int plane_poly(const struct plane *plane, struct poly *poly, float size);
 
 /* returns negative if there's no intersection, parametric distance if there is */
 float ray_plane(const cgm_ray *ray, const struct plane *plane);
 float ray_poly(const cgm_ray *ray, const struct poly *poly);
 
+int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *plane);
+
 #endif /* GEOM_H_ */