/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #ifndef __VEC_H__ #define __VEC_H__ #include "common.h" /* * A simple vector class. */ struct vec { scal_t x; scal_t y; scal_t z; scal_t w; }; typedef struct vec vec_t; /* * Initialize a vector with four components. */ __fast__ void vec_init(vec_t* v, scal_t x, scal_t y, scal_t z, scal_t w) { v->x = x; v->y = y; v->z = z; v->w = w; } /* * Create a new vector with four components. */ __fast__ vec_t vec_new2(scal_t x, scal_t y, scal_t z, scal_t w) { vec_t v; vec_init(&v, x, y, z, w); return v; } /* * Create a new vector with three components. The fourth component is * initialized to one. */ __fast__ vec_t vec_new(scal_t x, scal_t y, scal_t z) { return vec_new2(x, y, z, S(1.0)); } #define VEC_ZERO vec_new(S(0.0), S(0.0), S(0.0)) #define VEC_ORTHO_X vec_new(S(1.0), S(0.0), S(0.0)) #define VEC_ORTHO_Y vec_new(S(0.0), S(1.0), S(0.0)) #define VEC_ORTHO_Z vec_new(S(0.0), S(0.0), S(1.0)) /* * Scale the vector with a scalar value. */ __fast__ vec_t vec_scale(vec_t v, scal_t s) { v.x *= s; v.y *= s; v.z *= s; return v; } /* * Add two vectors together. */ __fast__ vec_t vec_add(vec_t a, vec_t b) { a.x += b.x; a.y += b.y; a.z += b.z; return a; } /* * Subtract a vector from another vector. */ __fast__ vec_t vec_sub(vec_t a, vec_t b) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; } /* * Get the dot product of two vectors. */ __fast__ scal_t vec_dot(vec_t a, vec_t b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } /* * Get the dot product of two vectors, ignoring the last component. */ __fast__ scal_t vec_dot3(vec_t a, vec_t b) { return a.x * b.x + a.y * b.y + a.z * b.z; } /* * 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. */ __fast__ bool vec_is_barycentric(vec_t v) { /* * 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; } #endif // __VEC_H__