+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;
+}
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * 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];
+}
+
+/*
+ * Calculate an interpolated point.
+ */
+INLINE_MAYBE
+vec_t tri_point(tri_t t, scal_t b[3])
+{
+ return vec_interp(t.a.v, t.b.v, t.c.v, b);
+}
+
+/*
+ * Calculate an interpolated normal.
+ */
+INLINE_MAYBE
+vec_t tri_normal2(tri_t t, scal_t b[3])
+{
+ return vec_normalize(vec_interp(t.a.n, t.b.n, t.c.n, b));
+}
+
+/*
+ * Calculate an interpolated texture coordinate.
+ */
+INLINE_MAYBE
+vec_t tri_tcoord(tri_t t, scal_t b[3])
+{
+#if PERSPECTIVE_FIX
+ return vec_tinterp(t.a.t, t.b.t, t.c.t, b);
+#else
+ return vec_interp(t.a.t, t.b.t, t.c.t, b);
+#endif
+}
+
+/*
+ * Calculate an entirely new vertex within the triangle based on barycentric
+ * coordinates.
+ */
+INLINE_MAYBE
+vert_t tri_interp(tri_t t, scal_t b[3])
+{
+ vert_t v = vert_new(tri_point(t, b));
+ v.c = color_interp2(t.a.c, t.b.c, t.c.c, b);
+ v.n = tri_normal2(t, b);
+ v.t = tri_tcoord(t, b);
+ return v;
+}