From 7e22a9e6549bf0ff36dc9a73c243de1f4b36b4a4 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 2 Jan 2023 05:52:41 +0200 Subject: [PATCH] more utility functions in geom --- src/geom.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/geom.h | 15 +++++++++++++ 2 files changed, 87 insertions(+) diff --git a/src/geom.c b/src/geom.c index f7e1740..2178664 100644 --- a/src/geom.c +++ b/src/geom.c @@ -1,4 +1,5 @@ #include "geom.h" +#include "dynarr.h" float plane_dist(const struct plane *p, const cgm_vec3 *pt) { @@ -21,3 +22,74 @@ void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b) p->pt.y = a->y + p->norm.y * 0.5f; p->pt.z = a->z + p->norm.z * 0.5f; } + +void poly_normal(const struct poly *poly, cgm_vec3 *n) +{ + cgm_vec3 va, vb; + + 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_vcross(n, &va, &vb); + cgm_vnormalize(n); +} + +void poly_plane(const struct poly *poly, struct plane *plane) +{ + plane->pt = poly->verts[0].pos; + poly_normal(poly, &plane->norm); +} + +float ray_plane(const cgm_ray *ray, const struct plane *plane) +{ + float ndotdir, t; + cgm_vec3 pptdir; + + ndotdir = cgm_vdot(&plane->norm, &ray->dir); + if(fabs(ndotdir) < 1e-4) { + return -1.0f; + } + + pptdir = plane->pt; + cgm_vsub(&pptdir, &ray->origin); + t = cgm_vdot(&plane->norm, &pptdir) / ndotdir; + if(t < 1e-6) { + return -1.0f; + } + return t; +} + +float ray_poly(const cgm_ray *ray, const struct poly *poly) +{ + float t; + struct plane plane; + cgm_vec3 hitp, vdir, edir, indir, vcross, incross; + int i, nverts; + + poly_plane(poly, &plane); + if((t = ray_plane(ray, &plane)) < 0.0f) { + return -1.0f; + } + cgm_raypos(&hitp, ray, t); + + /* see if the point is inside or outside the polygon */ + nverts = dynarr_size(poly->verts); + for(i=0; iverts[i].pos); + edir = poly->verts[(i + 1) & nverts].pos; + cgm_vsub(&edir, &poly->verts[i].pos); + indir = poly->verts[(i + 2) & nverts].pos; + cgm_vsub(&indir, &poly->verts[i].pos); + + cgm_vcross(&vcross, &vdir, &edir); + cgm_vcross(&incross, &indir, &edir); + + if(cgm_vdot(&vcross, &incross) < 0.0f) { + return -1.0f; + } + } + return t; +} diff --git a/src/geom.h b/src/geom.h index fa492f0..14faa82 100644 --- a/src/geom.h +++ b/src/geom.h @@ -7,8 +7,23 @@ struct plane { cgm_vec3 pt, norm; }; +struct vertex { + cgm_vec3 pos, norm; + cgm_vec2 uv; +}; + +struct poly { + struct vertex *verts; /* dynarr */ +}; + float plane_dist(const struct plane *p, const cgm_vec3 *pt); 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); + +/* 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); + #endif /* GEOM_H_ */ -- 1.7.10.4