2024-09-16 06:07:01 +00:00
|
|
|
#ifndef TWN_VEC_H
|
|
|
|
#define TWN_VEC_H
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
|
|
/* a point in some space (integer) */
|
2024-09-23 17:43:16 +00:00
|
|
|
typedef struct Vec2i {
|
2024-07-29 12:21:39 +00:00
|
|
|
_Alignas(8)
|
|
|
|
int32_t x;
|
|
|
|
int32_t y;
|
2024-09-23 17:43:16 +00:00
|
|
|
} Vec2i;
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* a point in some space (floating point) */
|
2024-09-23 17:43:16 +00:00
|
|
|
typedef struct Vec2 {
|
2024-07-29 12:21:39 +00:00
|
|
|
_Alignas(8)
|
|
|
|
float x;
|
|
|
|
float y;
|
2024-09-23 17:43:16 +00:00
|
|
|
} Vec2;
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* a point in some three dimension space (floating point) */
|
|
|
|
/* y goes up, x goes to the right */
|
2024-09-23 17:43:16 +00:00
|
|
|
typedef struct Vec3 {
|
2024-07-29 12:21:39 +00:00
|
|
|
_Alignas(16)
|
|
|
|
float x;
|
|
|
|
float y;
|
|
|
|
float z;
|
2024-09-23 17:43:16 +00:00
|
|
|
} Vec3;
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* a point in some three dimension space (floating point) */
|
|
|
|
/* y goes up, x goes to the right */
|
2024-09-23 17:43:16 +00:00
|
|
|
typedef struct Vec4 {
|
2024-07-29 12:21:39 +00:00
|
|
|
_Alignas(16)
|
|
|
|
float x;
|
|
|
|
float y;
|
|
|
|
float z;
|
|
|
|
float w;
|
2024-09-23 17:43:16 +00:00
|
|
|
} Vec4;
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* a point in some space (short) */
|
2024-09-23 17:43:16 +00:00
|
|
|
typedef struct Vec2sh {
|
2024-07-29 12:21:39 +00:00
|
|
|
_Alignas(4)
|
|
|
|
int16_t x;
|
|
|
|
int16_t y;
|
2024-09-23 17:43:16 +00:00
|
|
|
} Vec2sh;
|
2024-07-29 12:21:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* aren't macros to prevent double evaluation with side effects */
|
|
|
|
/* maybe could be inlined? i hope LTO will resolve this */
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec2 vec2_from_vec2i(Vec2i vec) {
|
|
|
|
return (Vec2) {
|
2024-07-29 12:21:39 +00:00
|
|
|
.x = (float)vec.x,
|
|
|
|
.y = (float)vec.y,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec2 vec2_from_vec2sh(Vec2sh vec) {
|
|
|
|
return (Vec2) {
|
2024-07-29 12:21:39 +00:00
|
|
|
.x = (float)vec.x,
|
|
|
|
.y = (float)vec.y,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_add(Vec3 a, Vec3 b) {
|
|
|
|
return (Vec3) { a.x + b.x, a.y + b.y, a.z + b.z };
|
2024-07-30 21:05:28 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_sub(Vec3 a, Vec3 b) {
|
|
|
|
return (Vec3) { a.x - b.x, a.y - b.y, a.z - b.z };
|
2024-07-29 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec2 vec2_div(Vec2 a, Vec2 b) {
|
|
|
|
return (Vec2) { a.x / b.x, a.y / b.y };
|
2024-07-31 21:52:15 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec2 vec2_scale(Vec2 a, float s) {
|
|
|
|
return (Vec2) { a.x * s, a.y * s };
|
2024-07-30 16:36:59 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_scale(Vec3 a, float s) {
|
|
|
|
return (Vec3) { a.x * s, a.y * s, a.z * s };
|
2024-07-29 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline float vec3_dot(Vec3 a, Vec3 b) {
|
2024-07-30 18:56:23 +00:00
|
|
|
return a.x * b.x + a.y * b.y + a.z * b.z;
|
2024-07-29 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_cross(Vec3 a, Vec3 b) {
|
|
|
|
return (Vec3) {
|
2024-07-29 12:21:39 +00:00
|
|
|
a.y * b.z - a.z * b.y,
|
|
|
|
a.z * b.x - a.x * b.z,
|
|
|
|
a.x * b.y - a.y * b.x,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: fast_sqrt version? */
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_norm(Vec3 a) {
|
|
|
|
const float n = sqrtf(vec3_dot(a, a));
|
2024-07-29 12:21:39 +00:00
|
|
|
/* TODO: do we need truncating over epsilon as cglm does? */
|
2024-09-23 17:43:16 +00:00
|
|
|
return vec3_scale(a, 1.0f / n);
|
2024-07-29 12:21:39 +00:00
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
static inline Vec3 vec3_rotate(Vec3 v, float angle, Vec3 axis) {
|
2024-07-30 21:05:28 +00:00
|
|
|
/* from cglm */
|
2024-09-23 17:43:16 +00:00
|
|
|
Vec3 v1, v2, k;
|
2024-07-30 21:05:28 +00:00
|
|
|
float c, s;
|
|
|
|
|
|
|
|
c = cosf(angle);
|
|
|
|
s = sinf(angle);
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
k = vec3_norm(axis);
|
2024-07-30 21:05:28 +00:00
|
|
|
|
|
|
|
/* Right Hand, Rodrigues' rotation formula:
|
|
|
|
v = v*cos(t) + (kxv)sin(t) + k*(k.v)(1 - cos(t))
|
|
|
|
*/
|
2024-09-23 17:43:16 +00:00
|
|
|
v1 = vec3_scale(v, c);
|
2024-07-30 21:05:28 +00:00
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
v2 = vec3_cross(k, v);
|
|
|
|
v2 = vec3_scale(v2, s);
|
2024-07-30 21:05:28 +00:00
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
v1 = vec3_add(v1, v2);
|
2024-07-30 21:05:28 +00:00
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
v2 = vec3_scale(k, vec3_dot(k, v) * (1.0f - c));
|
|
|
|
v = vec3_add(v1, v2);
|
2024-07-30 21:05:28 +00:00
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
#define m_vec2_from(p_any_vec2) (_Generic((p_any_vec2), \
|
|
|
|
Vec2i: vec2_from_vec2i, \
|
|
|
|
Vec2sh: vec2_from_vec2sh \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec2))
|
|
|
|
|
|
|
|
#define m_vec_sub(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
2024-09-23 17:43:16 +00:00
|
|
|
Vec3: vec3_sub \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec0, p_any_vec1))
|
|
|
|
|
2024-07-31 21:52:15 +00:00
|
|
|
#define m_vec_div(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
2024-09-23 17:43:16 +00:00
|
|
|
Vec2: vec2_div \
|
2024-07-31 21:52:15 +00:00
|
|
|
)(p_any_vec0, p_any_vec1))
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
#define m_vec_scale(p_any_vec, p_any_scalar) (_Generic((p_any_vec), \
|
|
|
|
Vec2: vec2_scale, \
|
|
|
|
Vec3: vec3_scale \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec, p_any_scalar))
|
|
|
|
|
|
|
|
#define m_vec_dot(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
2024-09-23 17:43:16 +00:00
|
|
|
Vec3: vec3_dot \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec0, p_any_vec1))
|
|
|
|
|
2024-09-23 17:43:16 +00:00
|
|
|
#define m_vec_cross(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \
|
|
|
|
Vec3: vec3_cross \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec0, p_any_vec1))
|
|
|
|
|
|
|
|
#define m_vec_norm(p_any_vec) (_Generic((p_any_vec), \
|
2024-09-23 17:43:16 +00:00
|
|
|
Vec3: vec3_norm \
|
2024-07-29 12:21:39 +00:00
|
|
|
)(p_any_vec))
|
|
|
|
|
|
|
|
#endif
|