updated files from meshfrac_alt
[meshfrac] / src / geom.c
index 0b94385..996a484 100644 (file)
@@ -1,3 +1,5 @@
+#include <stdio.h>
+#include <assert.h>
 #include "geom.h"
 #include "dynarr.h"
 
@@ -8,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)
@@ -30,7 +32,7 @@ void poly_normal(const struct poly *poly, cgm_vec3 *n)
        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);
@@ -46,7 +48,8 @@ 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;
+       cgm_vec3 up, right;
+       struct vertex *vptr;
        size *= 0.5f;
 
        if(!(poly->verts = dynarr_alloc(4, sizeof *poly->verts))) {
@@ -60,17 +63,20 @@ int plane_poly(const struct plane *plane, struct poly *poly, float size)
        }
        cgm_vcross(&right, &up, &plane->norm);
        cgm_vnormalize(&right);
-       cgm_vcross(&up, &plane.norm, &right);
+       cgm_vcross(&up, &plane->norm, &right);
        cgm_vnormalize(&up);
 
+       vptr = poly->verts;
        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;
-
-
-
+               vptr->pos.x = plane->pt.x + (right.x * corn[i][0] + up.x * corn[i][1]) * size;
+               vptr->pos.y = plane->pt.y + (right.y * corn[i][0] + up.y * corn[i][1]) * size;
+               vptr->pos.z = plane->pt.z + (right.z * corn[i][0] + up.z * corn[i][1]) * size;
 
+               vptr->norm = plane->norm;
+               vptr->uv.x = vptr->uv.y = 0;
+               vptr++;
+       }
+       return 0;
 }
 
 float ray_plane(const cgm_ray *ray, const struct plane *plane)
@@ -125,6 +131,17 @@ float ray_poly(const cgm_ray *ray, const struct poly *poly)
        return t;
 }
 
+int init_poly(struct poly *p)
+{
+       p->verts = dynarr_alloc(0, sizeof *p->verts);
+       assert(p->verts);
+       return p->verts ? 0 : -1;
+}
+
+void destroy_poly(struct poly *p)
+{
+       dynarr_free(p->verts);
+}
 
 /* returns:
  *  1 -> both inside
@@ -136,21 +153,15 @@ static int clip_edge(struct poly *pout, const struct vertex *v0, const struct ve
 {
        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.origin = 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) {
@@ -159,12 +170,15 @@ static int clip_edge(struct poly *pout, const struct vertex *v0, const struct ve
                        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);
+                       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);
+                       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);
                }
@@ -172,12 +186,15 @@ 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);
-                       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);
+                       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);
+                       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 ... */
@@ -197,7 +214,7 @@ int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *pla
        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++) {
@@ -212,3 +229,35 @@ int clip_poly(struct poly *pout, const struct poly *pin, const struct plane *pla
        return edges_clipped > 0 ? 0 : 1;
 
 }
+
+int poly_poly(const struct poly *p1, const struct poly *p2)
+{
+       int i, vnum1, vnum2;
+       float t;
+       cgm_ray ray;
+
+       vnum1 = dynarr_size(p1->verts);
+       vnum2 = dynarr_size(p2->verts);
+
+       for(i=0; i<vnum1; i++) {
+               ray.origin = p1->verts[i].pos;
+               ray.dir = p1->verts[(i + 1) & vnum1].pos;
+               cgm_vsub(&ray.dir, &ray.origin);
+
+               if((t = ray_poly(&ray, p2)) >= 0.0f && t <= 1.0f) {
+                       return 1;
+               }
+       }
+
+       for(i=0; i<vnum2; i++) {
+               ray.origin = p2->verts[i].pos;
+               ray.dir = p2->verts[(i + 1) & vnum2].pos;
+               cgm_vsub(&ray.dir, &ray.origin);
+
+               if((t = ray_poly(&ray, p1)) >= 0.0f && t <= 1.0f) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}