X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fgeom.c;h=996a4849412ab16b529f6c3b34d560124e701ffd;hb=HEAD;hp=0b943851b6211792a107f773d2b658cb44f9ed37;hpb=34e07fdc87e289e9ce574df7755e5e781136c20b;p=meshfrac diff --git a/src/geom.c b/src/geom.c index 0b94385..996a484 100644 --- a/src/geom.c +++ b/src/geom.c @@ -1,3 +1,5 @@ +#include +#include #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 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; iverts[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; iverts[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; +}