X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Frasterize;a=blobdiff_plain;f=tri.h;h=de36ae66a8988a3ddd78492e1093e9b6f3d2445e;hp=7170d4a3db3d3a399b04ccf172c10534d017c35e;hb=c875478cdd823c7df8fdc859941bd9e5948c9315;hpb=0f2508a4f227523a6b7e54798487af19d06a6ce9 diff --git a/tri.h b/tri.h index 7170d4a..de36ae6 100644 --- a/tri.h +++ b/tri.h @@ -5,9 +5,10 @@ * mcgarvey@eng.utah.edu */ -#ifndef __TRI_H__ -#define __TRI_H__ +#ifndef _TRI_H_ +#define _TRI_H_ +#include "aabb.h" #include "mat.h" #include "vert.h" @@ -26,7 +27,7 @@ typedef struct tri tri_t; /* * Initialize a triangle. */ -__fast__ +INLINE_MAYBE void tri_init(tri_t* t, vert_t a, vert_t b, vert_t c) { t->a = a; @@ -38,7 +39,7 @@ void tri_init(tri_t* t, vert_t a, vert_t b, vert_t c) /* * Create a new triangle. */ -__fast__ +INLINE_MAYBE tri_t tri_new(vert_t a, vert_t b, vert_t c) { tri_t t; @@ -52,7 +53,7 @@ tri_t tri_new(vert_t a, vert_t b, vert_t c) /* * Create a new triangle on the heap. */ -__fast__ +INLINE_MAYBE tri_t* tri_alloc(vert_t a, vert_t b, vert_t c) { tri_t* t = (tri_t*)mem_alloc(sizeof(tri_t)); @@ -64,7 +65,7 @@ tri_t* tri_alloc(vert_t a, vert_t b, vert_t c) /* * Apply a transformation matrix to alter the triangle geometry. */ -__fast__ +INLINE_MAYBE tri_t tri_transform(tri_t t, mat_t m) { t.a.v = mat_apply(m, t.a.v); @@ -73,6 +74,45 @@ tri_t tri_transform(tri_t t, mat_t m) return t; } +/* + * Perform a homogeneous divide on the geometry. + */ +INLINE_MAYBE +tri_t tri_homodiv(tri_t t) +{ + t.a.v = vec_homodiv(t.a.v); + t.b.v = vec_homodiv(t.b.v); + t.c.v = vec_homodiv(t.c.v); + return t; +} + + +/* + * Calculate a normal vector. + */ +INLINE_MAYBE +vec_t tri_normal(tri_t t) +{ + return vec_cross(vec_sub(t.b.v, t.a.v), vec_sub(t.c.v, t.a.v)); +} + + +/* + * Calculate the AABB for the triangle. + */ +INLINE_MAYBE +aabb_t tri_aabb(tri_t t) +{ + aabb_t b; + b.min = vec_new(scal_min2(t.a.v.x, t.b.v.x, t.c.v.x), + scal_min2(t.a.v.y, t.b.v.y, t.c.v.y), + scal_min2(t.a.v.z, t.b.v.z, t.c.v.z)); + b.max = vec_new(scal_max2(t.a.v.x, t.b.v.x, t.c.v.x), + scal_max2(t.a.v.y, t.b.v.y, t.c.v.y), + scal_max2(t.a.v.z, t.b.v.z, t.c.v.z)); + return b; +} + /* * Get the barycentric coordinates of a vector against a triangle. The @@ -81,8 +121,52 @@ tri_t tri_transform(tri_t t, mat_t m) * to check if they really are barycentric coordinates, meaning the point * vector v is inside the triangle, ignoring the Z components. */ -vec_t tri_barycentric(const tri_t* t, vec_t v); +INLINE_MAYBE +bool tri_barycentric(tri_t t, scal_t* b, vec_t v) +{ + scal_t denom = (t.b.v.y - t.c.v.y) * (t.a.v.x - t.c.v.x) + (t.c.v.x - t.b.v.x) * (t.a.v.y - t.c.v.y); + b[0] = ((t.b.v.y - t.c.v.y) * (v.x - t.c.v.x) + (t.c.v.x - t.b.v.x) * (v.y - t.c.v.y)) / denom; + b[1] = ((t.c.v.y - t.a.v.y) * (v.x - t.c.v.x) + (t.a.v.x - t.c.v.x) * (v.y - t.c.v.y)) / denom; + b[2] = S(1.0) - b[0] - b[1]; + if (S(0.0) <= b[0] && b[0] <= S(1.0) && + S(0.0) <= b[1] && b[1] <= S(1.0) && + S(0.0) <= b[2] && b[2] <= S(1.0)) { + return true; + } + return false; +} + + +/* + * Get an interpolated z-value at the barycentric coordinates. + */ +INLINE_MAYBE +scal_t tri_z(tri_t t, scal_t b[3]) +{ + return t.a.v.z * b[0] + t.b.v.z * b[1] + t.c.v.z * b[2]; +} + +/* + * Find the midpoint of the triangle. + */ +INLINE_MAYBE +vec_t tri_midpoint(tri_t t) +{ + return vec_new((t.a.v.x + t.b.v.x + t.c.v.x) * S(0.333), + (t.a.v.y + t.b.v.y + t.c.v.y) * S(0.333), + (t.a.v.z + t.b.v.z + t.c.v.z) * S(0.333)); +} + +/* + * Get the average color of the triangle. + */ +INLINE_MAYBE +color_t tri_color(tri_t t) +{ + scal_t b[] = {S(0.333), S(0.333), S(0.333)}; + return color_interp2(t.a.c, t.b.c, t.c.c, b); +} -#endif // __TRI_H__ +#endif // _TRI_H_