#include <stdio.h>
+#include <assert.h>
#include "geom.h"
#include "dynarr.h"
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)
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);
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
return 1;
} else {
/* going out */
- t = ray_plane(&ray, plane);
+ 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);
/* start outside */
if(d1 >= 0) {
/* going in */
- t = ray_plane(&ray, plane);
+ 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);
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++) {
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;
+}