add support for 3d scenes, depth testing, lighting
[chaz/rasterize] / tri.h
diff --git a/tri.h b/tri.h
index 7170d4a3db3d3a399b04ccf172c10534d017c35e..de36ae66a8988a3ddd78492e1093e9b6f3d2445e 100644 (file)
--- 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_
 
This page took 0.025046 seconds and 4 git commands to generate.