#include #include #include #define VEC_ABS(x) ((x) > 0 ? (x) : -(x)) struct vec2i { union { struct { ssize_t x, y; }; ssize_t dims[2]; }; }; struct vec3i { union { struct { ssize_t x, y, z; }; ssize_t dims[3]; }; }; struct vec2f { union { struct { double x, y; }; double dims[2]; }; }; struct vec3f { union { struct { double x, y, z; }; double dims[3]; }; }; #define DEFINE_VEC_SET(name, type, dims) \ static inline void name(type *dst, const type *src) { \ memcpy(dst, src, sizeof(type)); \ } #define DEFINE_VEC_ADD(name, type, n) \ static inline void name(type *dst, const type *a, const type *b) { \ for (int i = 0; i < n; i++) \ dst->dims[i] = a->dims[i] + b->dims[i]; \ } #define DEFINE_VEC_SUB(name, type, n) \ static inline void name(type *dst, const type *a, const type *b) { \ for (int i = 0; i < n; i++) \ dst->dims[i] = a->dims[i] - b->dims[i]; \ } #define DEFINE_VEC_MUL(name, type, prim, n) \ static inline void name(type *dst, const type *a, prim b) { \ for (int i = 0; i < n; i++) \ dst->dims[i] = a->dims[i] * b; \ } #define DEFINE_VEC_EQL(name, type, n) \ static inline bool name(const type *a, const type *b) { \ for (int i = 0; i < n; i++) \ if (a->dims[i] != b->dims[i]) return false; \ return true; \ } DEFINE_VEC_SET(vec2i_set, struct vec2i, 2); DEFINE_VEC_ADD(vec2i_add, struct vec2i, 2); DEFINE_VEC_SUB(vec2i_sub, struct vec2i, 2); DEFINE_VEC_MUL(vec2i_mul, struct vec2i, ssize_t, 2); DEFINE_VEC_EQL(vec2i_eql, struct vec2i, 2); static inline void vec2i_setv(struct vec2i *dst, ssize_t x, ssize_t y) { dst->x = x; dst->y = y; } static inline ssize_t vec2i_len(struct vec2i *a) { return VEC_ABS(a->x) + VEC_ABS(a->y); } DEFINE_VEC_SET(vec3i_set, struct vec3i, 3); DEFINE_VEC_ADD(vec3i_add, struct vec3i, 3); DEFINE_VEC_SUB(vec3i_sub, struct vec3i, 3); DEFINE_VEC_MUL(vec3i_mul, struct vec3i, ssize_t, 3); DEFINE_VEC_EQL(vec3i_eql, struct vec3i, 3); static inline void vec3i_setv(struct vec3i *dst, ssize_t x, ssize_t y, ssize_t z) { dst->x = x; dst->y = y; dst->z = z; } DEFINE_VEC_SET(vec2f_set, struct vec2f, 2); DEFINE_VEC_ADD(vec2f_add, struct vec2f, 2); DEFINE_VEC_SUB(vec2f_sub, struct vec2f, 2); DEFINE_VEC_MUL(vec2f_mul, struct vec2f, double, 2); static inline void vec2f_setv(struct vec2f *dst, double x, double y) { dst->x = x; dst->y = y; } DEFINE_VEC_SET(vec3f_set, struct vec3f, 3); DEFINE_VEC_ADD(vec3f_add, struct vec3f, 3); DEFINE_VEC_SUB(vec3f_sub, struct vec3f, 3); DEFINE_VEC_MUL(vec3f_mul, struct vec3f, double, 3); static inline void vec3f_setv(struct vec3f *dst, double x, double y, double z) { dst->x = x; dst->y = y; dst->z = z; } static inline void vec3i_add_2i(struct vec3i *dst, const struct vec3i *a, const struct vec2i *b) { dst->x = a->x + b->x; dst->y = a->y + b->y; dst->z = a->z; } #undef DEFINE_VEC_SET #undef DEFINE_VEC_ADD #undef DEFINE_VEC_SUB #undef DEFINE_VEC_MUL