add support for 3d scenes, depth testing, lighting
[chaz/rasterize] / vec.h
diff --git a/vec.h b/vec.h
index f08945c444275218dbbd92ae0cedc8a8b3f36927..2c1269dccc88eb567e1962ecbcda2d8e5d082f56 100644 (file)
--- a/vec.h
+++ b/vec.h
@@ -5,8 +5,8 @@
  * mcgarvey@eng.utah.edu
  */
 
-#ifndef __VEC_H__
-#define __VEC_H__
+#ifndef _VEC_H_
+#define _VEC_H_
 
 #include "common.h"
 
@@ -26,7 +26,7 @@ typedef struct vec vec_t;
 /*
  * Initialize a vector with four components.
  */
-__fast__
+INLINE_MAYBE
 void vec_init(vec_t* v, scal_t x, scal_t y, scal_t z, scal_t w)
 {
     v->x = x;
@@ -39,7 +39,7 @@ void vec_init(vec_t* v, scal_t x, scal_t y, scal_t z, scal_t w)
 /*
  * Create a new vector with four components.
  */
-__fast__
+INLINE_MAYBE
 vec_t vec_new2(scal_t x, scal_t y, scal_t z, scal_t w)
 {
     vec_t v;
@@ -51,7 +51,7 @@ vec_t vec_new2(scal_t x, scal_t y, scal_t z, scal_t w)
  * Create a new vector with three components.  The fourth component is
  * initialized to one.
  */
-__fast__
+INLINE_MAYBE
 vec_t vec_new(scal_t x, scal_t y, scal_t z)
 {
     return vec_new2(x, y, z, S(1.0));
@@ -63,10 +63,63 @@ vec_t vec_new(scal_t x, scal_t y, scal_t z)
 #define VEC_ORTHO_Z vec_new(S(0.0), S(0.0), S(1.0))
 
 
+/*
+ * Print the vector to stdout.
+ */
+INLINE_MAYBE
+void vec_print(vec_t v)
+{
+#if (SCALAR_SIZE == 8)
+    const char* fmt = "[ %9.5lf %9.5lf %9.5lf %9.5lf ]";
+#else
+    const char* fmt = "[ %9.5f %9.5f %9.5f %9.5f ]";
+#endif
+    printf(fmt, v.x, v.y, v.z, v.w);
+}
+
+
+/*
+ * Calculate the magnitude of the vector, squared.
+ */
+INLINE_MAYBE
+scal_t vec_length2(vec_t v)
+{
+    return v.x * v.x + v.y * v.y + v.z * v.z;
+}
+
+/*
+ * Calculate the magnitude of the vector.
+ */
+INLINE_MAYBE
+scal_t vec_length(vec_t v)
+{
+    return scal_sqrt(vec_length2(v));
+}
+
+
+/*
+ * Determine whether or not two vectors are exactly equal.
+ */
+INLINE_MAYBE
+bool vec_isequal(vec_t a, vec_t b)
+{
+    return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w);
+}
+
+INLINE_MAYBE
+int vec_compare(vec_t a, vec_t b)
+{
+    if (vec_isequal(a, b)) {
+        return 0;
+    }
+    return vec_length2(a) < vec_length2(b) ? -1 : 1;
+}
+
+
 /*
  * Scale the vector with a scalar value.
  */
-__fast__
+INLINE_MAYBE
 vec_t vec_scale(vec_t v, scal_t s)
 {
     v.x *= s;
@@ -78,7 +131,7 @@ vec_t vec_scale(vec_t v, scal_t s)
 /*
  * Add two vectors together.
  */
-__fast__
+INLINE_MAYBE
 vec_t vec_add(vec_t a, vec_t b)
 {
     a.x += b.x;
@@ -90,7 +143,7 @@ vec_t vec_add(vec_t a, vec_t b)
 /*
  * Subtract a vector from another vector.
  */
-__fast__
+INLINE_MAYBE
 vec_t vec_sub(vec_t a, vec_t b)
 {
     a.x -= b.x;
@@ -99,46 +152,77 @@ vec_t vec_sub(vec_t a, vec_t b)
     return a;
 }
 
+/*
+ * Negate the vector.
+ */
+INLINE_MAYBE
+vec_t vec_neg(vec_t v)
+{
+    v.x = -v.x;
+    v.y = -v.y;
+    v.z = -v.z;
+    return v;
+}
+
 
 /*
- * Get the dot product of two vectors.
+ * Get a normalized (unit length) vector.
  */
-__fast__
-scal_t vec_dot(vec_t a, vec_t b)
+INLINE_MAYBE
+vec_t vec_normalize(vec_t v)
 {
-    return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+    scal_t l = vec_length(v);
+    if (l == S(0.0)) {
+        return VEC_ZERO;
+    }
+    return vec_scale(v, S(1.0) / l);
 }
 
+
 /*
  * Get the dot product of two vectors, ignoring the last component.
  */
-__fast__
-scal_t vec_dot3(vec_t a, vec_t b)
+INLINE_MAYBE
+scal_t vec_dot(vec_t a, vec_t b)
 {
     return a.x * b.x + a.y * b.y + a.z * b.z;
 }
 
+/*
+ * Get the dot product of two vectors.
+ */
+INLINE_MAYBE
+scal_t vec_dot2(vec_t a, vec_t b)
+{
+    return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+}
+
 
 /*
- * Check whether the values of the first three components could actually be
- * barycentric coordinates.  Note: The necessary condition of each component
- * adding up to one is assumed and not checked.
+ * Get the cross product of two vectors.
  */
-__fast__
-bool vec_is_barycentric(vec_t v)
+INLINE_MAYBE
+vec_t vec_cross(vec_t a, vec_t b)
 {
-    /*
-     * XXX: I'm fudging the bounds a little because horizontal edges (relative
-     * to the screen) are otherwise sometimes really jagged.  This probably
-     * isn't the best solution.
-     */
-    if (S(-0.000001) <= v.x && v.x <= S(1.000001) &&
-        S(-0.000001) <= v.y && v.y <= S(1.000001) &&
-        S(-0.000001) <= v.z && v.z <= S(1.000001)) {
-        return true;
-    }
-    return false;
+    return vec_new(a.y * b.z - a.z * b.y,
+                   a.z * b.x - a.x * b.z,
+                   a.x * b.y - a.y * b.x);
 }
 
-#endif // __VEC_H__
+
+/*
+ * Perform a homogeneous divide.
+ */
+INLINE_MAYBE
+vec_t vec_homodiv(vec_t v)
+{
+    v.x /= v.w;
+    v.y /= v.w;
+    v.z /= v.w;
+    v.w  = S(1.0);
+    return v;
+}
+
+
+#endif // _VEC_H_
 
This page took 0.026861 seconds and 4 git commands to generate.