#ifndef EZ3D_TRIANGLE_H #define EZ3D_TRIANGLE_H #include /* * Vertex as three floats, used for parameter passing, and readability. */ typedef struct { float x; float y; float z; } vertex_t; /* * Vector (x, y, z) as double for intermediate computations. * Doubles are not output to STL, it goes back to float. */ typedef struct { double x; double y; double z; } dvec_t; /* * Triangle as three vertex indicies. */ typedef struct { uint32_t v[3]; } triangle_t; /* * Difference of two verticies. * Output is double but not really more accurate, this is for consistency. * delta = b - a; */ inline static void vertex_diff(const vertex_t *a, const vertex_t *b, dvec_t *delta) { delta->x = (double)b->x - (double)a->x; delta->y = (double)b->y - (double)a->y; delta->z = (double)b->z - (double)a->z; } /* * Midpoint between two verticies. * Output is only float for compatibility with other vertex_t. * mid = (a + b) / 2; */ inline static void vertex_mid(const vertex_t *a, const vertex_t *b, vertex_t *mid) { mid->x = 0.5 * (b->x + a->x); mid->y = 0.5 * (b->y + a->y); mid->z = 0.5 * (b->z + a->z); } /* * Return 1 iff *p is inside the cube with far corners *c00 and *c11 * Otherwise return 0 to show it is outside; */ inline static int vertex_cube_is_inside(const vertex_t *c00, const vertex_t *c11, vertex_t *p) { vertex_t hi, lo; lo.x = fminf(c00->x, c11->x); lo.y = fminf(c00->y, c11->y); lo.z = fminf(c00->z, c11->z); hi.x = fmaxf(c00->x, c11->x); hi.y = fmaxf(c00->y, c11->y); hi.z = fmaxf(c00->z, c11->z); if (p->x < lo.x || p->x > hi.x) return 0; if (p->y < lo.y || p->y > hi.y) return 0; if (p->z < lo.z || p->z > hi.z) return 0; return 1; } /* * Unnormalized winding normal of triangle (a,b,c). */ inline static void tri_normal_vec(const vertex_t *a, const vertex_t *b, const vertex_t *c, dvec_t *norm) { dvec_t uvec, wvec; vertex_diff(a, b, &uvec); vertex_diff(a, c, &wvec); norm->x = (double)uvec.y * (double)wvec.z - (double)uvec.z * (double)wvec.y; norm->y = (double)uvec.z * (double)wvec.x - (double)uvec.x * (double)wvec.z; norm->z = (double)uvec.x * (double)wvec.y - (double)uvec.y * (double)wvec.x; } /* * Standard dot product of two vectors. */ inline static double tri_dot_prod(const dvec_t *a, const dvec_t *b) { return a->x * b->x + a->y * b->y + a->z * b->z; } /* * Pythagorean length of out[3] above for normal vectors. */ inline static double tri_normal_len(dvec_t *norm) { return sqrt(tri_dot_prod(norm, norm)); } #endif /* EZ3D_TRIANGLE_H */