* mcgarvey@eng.utah.edu
*/
-#ifndef __VEC_H__
-#define __VEC_H__
+#ifndef _VEC_H_
+#define _VEC_H_
#include "common.h"
/*
* 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;
/*
* 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;
* 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));
#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;
/*
* Add two vectors together.
*/
-__fast__
+INLINE_MAYBE
vec_t vec_add(vec_t a, vec_t b)
{
a.x += b.x;
/*
* Subtract a vector from another vector.
*/
-__fast__
+INLINE_MAYBE
vec_t vec_sub(vec_t a, vec_t b)
{
a.x -= b.x;
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_