diff options
Diffstat (limited to 'v3f.h')
-rw-r--r-- | v3f.h | 117 |
1 files changed, 86 insertions, 31 deletions
@@ -14,81 +14,132 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* + * 3D vector operations header + * + * Variants prefixed with _ return a result vector struct by value. + * + * Variants missing the _ prefix for vector result operations return a pointer + * and must be either supplied the result memory as the first "res" argument + * which is then returned after being populated with the result's value, or + * NULL to allocate space for the result and that pointer is resturned after being + * populated with its value. When supplying NULL result pointers the functions + * must allocate memory and thus may return NULL on OOM, so callers should + * check for NULL returns when supplying NULL for res. + * + * Example: + * v3f_t foo, *foop; + * + * foo = _v3f_mult(&(v3f_t){1.f,1.f,1.f}, &(v3f_t){2.f,2.f,2.f}); + * + * is equivalent to: + * + * v3f_mult(&foo, &(v3f_t){1.f,1.f,1.f}, &(v3f_t){2.f,2.f,2.f}); + * + * or dynamically allocated: + * + * foop = v3f_mult(NULL, &(v3f_t){1.f,1.f,1.f}, &(v3f_t){2.f,2.f,2.f}); + * free(foop); + * + * is equivalent to: + * + * foop = malloc(sizeof(v3f_t)); + * v3f_mult(foop, &(v3f_t){1.f,1.f,1.f}, &(v3f_t){2.f,2.f,2.f}); + * free(foop); + */ + #ifndef _V3F_H #define _V3F_H + #include <math.h> +#include <stdlib.h> + typedef struct v3f_t { float x, y, z; } v3f_t; -static inline v3f_t v3f_add(const v3f_t *a, const v3f_t *b) +static inline v3f_t * _v3f_allocated(v3f_t **ptr) +{ + if (!*ptr) + *ptr = malloc(sizeof(v3f_t)); + + return *ptr; +} + + +static inline v3f_t _v3f_add(const v3f_t *a, const v3f_t *b) { return (v3f_t){a->x + b->x, a->y + b->y, a->z + b->z}; } -static inline v3f_t * pv3f_add(const v3f_t *a, const v3f_t *b, v3f_t *res) +static inline v3f_t * v3f_add(v3f_t *res, const v3f_t *a, const v3f_t *b) { - *res = v3f_add(a, b); + if (_v3f_allocated(&res)) + *res = _v3f_add(a, b); return res; } -static inline v3f_t v3f_sub(const v3f_t *a, const v3f_t *b) +static inline v3f_t _v3f_sub(const v3f_t *a, const v3f_t *b) { return (v3f_t){a->x - b->x, a->y - b->y, a->z - b->z}; } -static inline v3f_t * pv3f_sub(const v3f_t *a, const v3f_t *b, v3f_t *res) +static inline v3f_t * v3f_sub(v3f_t *res, const v3f_t *a, const v3f_t *b) { - *res = v3f_sub(a, b); + if (_v3f_allocated(&res)) + *res = _v3f_sub(a, b); return res; } -static inline v3f_t v3f_mult(const v3f_t *a, const v3f_t *b) +static inline v3f_t _v3f_mult(const v3f_t *a, const v3f_t *b) { return (v3f_t){a->x * b->x, a->y * b->y, a->z * b->z}; } -static inline v3f_t * pv3f_mult(const v3f_t *a, const v3f_t *b, v3f_t *res) +static inline v3f_t * v3f_mult(v3f_t *res, const v3f_t *a, const v3f_t *b) { - *res = v3f_mult(a, b); + if (_v3f_allocated(&res)) + *res = _v3f_mult(a, b); return res; } -static inline v3f_t v3f_mult_scalar(const v3f_t *v, float scalar) +static inline v3f_t _v3f_mult_scalar(const v3f_t *v, float scalar) { return (v3f_t){v->x * scalar, v->y * scalar, v->z * scalar}; } -static inline v3f_t * pv3f_mult_scalar(const v3f_t *v, float scalar, v3f_t *res) +static inline v3f_t * v3f_mult_scalar(v3f_t *res, const v3f_t *v, float scalar) { - *res = v3f_mult_scalar(v, scalar); + if (_v3f_allocated(&res)) + *res = _v3f_mult_scalar(v, scalar); return res; } -static inline v3f_t v3f_div_scalar(const v3f_t *v, float scalar) +static inline v3f_t _v3f_div_scalar(const v3f_t *v, float scalar) { - return v3f_mult_scalar(v, 1.f / scalar); + return _v3f_mult_scalar(v, 1.f / scalar); } -static inline v3f_t * pv3f_div_scalar(const v3f_t *v, float scalar, v3f_t *res) +static inline v3f_t * v3f_div_scalar(v3f_t *res, const v3f_t *v, float scalar) { - *res = v3f_div_scalar(v, scalar); + if (_v3f_allocated(&res)) + *res = _v3f_div_scalar(v, scalar); return res; } @@ -106,52 +157,56 @@ static inline float v3f_length(const v3f_t *v) } -static inline v3f_t v3f_normalize(const v3f_t *v) +static inline v3f_t _v3f_normalize(const v3f_t *v) { - return v3f_mult_scalar(v, 1.0f / v3f_length(v)); + return _v3f_mult_scalar(v, 1.0f / v3f_length(v)); } -static inline v3f_t * pv3f_normalize(const v3f_t *v, v3f_t *res) +static inline v3f_t * v3f_normalize(v3f_t *res, const v3f_t *v) { - *res = v3f_normalize(v); + if (_v3f_allocated(&res)) + *res = _v3f_normalize(v); return res; } -static inline v3f_t v3f_lerp(const v3f_t *a, const v3f_t *b, float t) +static inline v3f_t _v3f_lerp(const v3f_t *a, const v3f_t *b, float t) { v3f_t lerp_a, lerp_b; - lerp_a = v3f_mult_scalar(a, 1.0f - t); - lerp_b = v3f_mult_scalar(b, t); + lerp_a = _v3f_mult_scalar(a, 1.0f - t); + lerp_b = _v3f_mult_scalar(b, t); - return v3f_add(&lerp_a, &lerp_b); + return _v3f_add(&lerp_a, &lerp_b); } -static inline v3f_t * pv3f_lerp(const v3f_t *a, const v3f_t *b, float t, v3f_t *res) +static inline v3f_t * v3f_lerp(v3f_t *res, const v3f_t *a, const v3f_t *b, float t) { - *res = v3f_lerp(a, b, t); + if (_v3f_allocated(&res)) + *res = _v3f_lerp(a, b, t); return res; } -static inline v3f_t v3f_nlerp(const v3f_t *a, const v3f_t *b, float t) +static inline v3f_t _v3f_nlerp(const v3f_t *a, const v3f_t *b, float t) { - v3f_t lerp = v3f_lerp(a, b, t); + v3f_t lerp = _v3f_lerp(a, b, t); - return v3f_normalize(&lerp); + return _v3f_normalize(&lerp); } -static inline v3f_t * pv3f_nlerp(const v3f_t *a, const v3f_t *b, float t, v3f_t *res) +static inline v3f_t * v3f_nlerp(v3f_t *res, const v3f_t *a, const v3f_t *b, float t) { - *res = v3f_nlerp(a, b, t); + if (_v3f_allocated(&res)) + *res = _v3f_nlerp(a, b, t); return res; } + #endif |