4 float plane_dist(const struct plane *p, const cgm_vec3 *pt)
6 return fabs(plane_sdist(p, pt));
9 float plane_sdist(const struct plane *p, const cgm_vec3 *pt)
13 return cgm_vdot(&v, &p->norm);
16 void midplane(struct plane *p, const cgm_vec3 *a, const cgm_vec3 *b)
19 cgm_vsub(&p->norm, a);
20 cgm_vnormalize(&p->norm);
21 p->pt.x = a->x + p->norm.x * 0.5f;
22 p->pt.y = a->y + p->norm.y * 0.5f;
23 p->pt.z = a->z + p->norm.z * 0.5f;
26 void poly_normal(const struct poly *poly, cgm_vec3 *n)
30 va = poly->verts[1].pos;
31 cgm_vsub(&va, &poly->verts[0].pos);
32 vb = poly->verts[2].pos;
33 cgm_vsub(&vb, &poly->verts[2].pos);
35 cgm_vcross(n, &va, &vb);
39 void poly_plane(const struct poly *poly, struct plane *plane)
41 plane->pt = poly->verts[0].pos;
42 poly_normal(poly, &plane->norm);
45 float ray_plane(const cgm_ray *ray, const struct plane *plane)
50 ndotdir = cgm_vdot(&plane->norm, &ray->dir);
51 if(fabs(ndotdir) < 1e-4) {
56 cgm_vsub(&pptdir, &ray->origin);
57 t = cgm_vdot(&plane->norm, &pptdir) / ndotdir;
64 float ray_poly(const cgm_ray *ray, const struct poly *poly)
68 cgm_vec3 hitp, vdir, edir, indir, vcross, incross;
71 poly_plane(poly, &plane);
72 if((t = ray_plane(ray, &plane)) < 0.0f) {
75 cgm_raypos(&hitp, ray, t);
77 /* see if the point is inside or outside the polygon */
78 nverts = dynarr_size(poly->verts);
79 for(i=0; i<nverts; i++) {
81 cgm_vsub(&hitp, &poly->verts[i].pos);
82 edir = poly->verts[(i + 1) & nverts].pos;
83 cgm_vsub(&edir, &poly->verts[i].pos);
84 indir = poly->verts[(i + 2) & nverts].pos;
85 cgm_vsub(&indir, &poly->verts[i].pos);
87 cgm_vcross(&vcross, &vdir, &edir);
88 cgm_vcross(&incross, &indir, &edir);
90 if(cgm_vdot(&vcross, &incross) < 0.0f) {