aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2025-08-04 16:08:22 +0000
committerbonmas14 <bonmas14@gmail.com>2025-08-04 16:08:22 +0000
commitb16ca14911ad5df44ae499eed2d90c3ca2da4eb0 (patch)
tree685d64ea40f66b72c994bcfd3de0c5015a9cf36a /src
parented1cab483e49e29396178a33dea51773aa770855 (diff)
downloadungrateful-b16ca14911ad5df44ae499eed2d90c3ca2da4eb0.tar.gz
ungrateful-b16ca14911ad5df44ae499eed2d90c3ca2da4eb0.zip
Vecs and tests
Diffstat (limited to 'src')
-rw-r--r--src/un_math.c6
-rw-r--r--src/un_splines.c85
-rw-r--r--src/un_vec.c87
-rw-r--r--src/un_vecd.c307
-rw-r--r--src/un_vecr.c353
-rw-r--r--src/ungrateful.c5
-rw-r--r--src/ungrateful.h192
7 files changed, 955 insertions, 80 deletions
diff --git a/src/un_math.c b/src/un_math.c
index 772ef70..42a1c4b 100644
--- a/src/un_math.c
+++ b/src/un_math.c
@@ -6,7 +6,7 @@ real un_m_lerpr(real a, real b, real t) {
real un_m_ease_isiner(real t) {
#if defined(UN_DOUBLE_PRECISION)
- return 1.0 - cos((t * PI) / 2.0);
+ return 1.0 - cos((t * PI_D) / 2.0);
#else
return 1.0 - cosf((t * PI) / 2.0);
#endif
@@ -14,7 +14,7 @@ real un_m_ease_isiner(real t) {
real un_m_ease_iosiner(real t) {
#if defined(UN_DOUBLE_PRECISION)
- return sin((t * PI) / 2.0f);
+ return sin((t * PI_D) / 2.0f);
#else
return sinf((t * PI) / 2.0f);
#endif
@@ -22,7 +22,7 @@ real un_m_ease_iosiner(real t) {
real un_m_ease_osiner(real t) {
#if defined(UN_DOUBLE_PRECISION)
- return -(cos(t * PI) - 1.0) / 2.0;
+ return -(cos(t * PI_D) - 1.0) / 2.0;
#else
return -(cosf(t * PI) - 1.0) / 2.0;
#endif
diff --git a/src/un_splines.c b/src/un_splines.c
index 7b27ee0..c6d2844 100644
--- a/src/un_splines.c
+++ b/src/un_splines.c
@@ -1,40 +1,93 @@
-real un_m_bezierr(real a, real q0, real q1, real b, real t) {
- real i0, i1, i2, p1, p2;
+void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t) {
+ real i0, i1, i2, p0, p1;
i0 = un_m_lerpr(a, q0, t);
i1 = un_m_lerpr(q0, q1, t);
i2 = un_m_lerpr(q1, b, t);
- p1 = un_m_lerpr(i0, i1, t);
- p2 = un_m_lerpr(i1, i2, t);
+ p0 = un_m_lerpr(i0, i1, t);
+ p1 = un_m_lerpr(i1, i2, t);
- return un_m_lerpr(p1, p2, t);
+ *v = un_m_lerpr(p0, p1, t);
}
-f32 un_m_bezierf(f32 a, f32 q0, f32 q1, f32 b, f32 t) {
- f32 i0, i1, i2, p1, p2;
+void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t) {
+ f32 i0, i1, i2, p0, p1;
i0 = un_m_lerpf(a, q0, t);
i1 = un_m_lerpf(q0, q1, t);
i2 = un_m_lerpf(q1, b, t);
- p1 = un_m_lerpf(i0, i1, t);
- p2 = un_m_lerpf(i1, i2, t);
+ p0 = un_m_lerpf(i0, i1, t);
+ p1 = un_m_lerpf(i1, i2, t);
- return un_m_lerpf(p1, p2, t);
+ *v = un_m_lerpf(p0, p1, t);
}
-f64 un_m_bezierd(f64 a, f64 q0, f64 q1, f64 b, f64 t) {
- f64 i0, i1, i2, p1, p2;
+void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t) {
+ f64 i0, i1, i2, p0, p1;
i0 = un_m_lerpd(a, q0, t);
i1 = un_m_lerpd(q0, q1, t);
i2 = un_m_lerpd(q1, b, t);
- p1 = un_m_lerpd(i0, i1, t);
- p2 = un_m_lerpd(i1, i2, t);
+ p0 = un_m_lerpd(i0, i1, t);
+ p1 = un_m_lerpd(i1, i2, t);
- return un_m_lerpd(p1, p2, t);
+ *v = un_m_lerpd(p0, p1, t);
}
-// add v2-4 variants
+void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t) {
+ un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t) {
+ un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t) {
+ un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierr(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierf(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+
+void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierd(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
diff --git a/src/un_vec.c b/src/un_vec.c
index 1e1ccda..d6c984e 100644
--- a/src/un_vec.c
+++ b/src/un_vec.c
@@ -1,31 +1,3 @@
-
-
-
-/*
- *
- * vector from two vectors
- *
- * add
- * sub
- *
- * add scalar
- * sub scalar
- *
- * mul scalar
- * div scalar
- *
- * distance
- * discance sqr
- *
- * magnitude
- * magnitude sqr
- *
- * dot, cross, surface_cross, normalize, reflect, flatten, project
- *
- *
- *
- */
-
void un_m_add2f(f32 *v, f32 *a, f32 *b) {
v[0] = a[0] + b[0];
v[1] = a[1] + b[1];
@@ -199,6 +171,23 @@ void un_m_magnitude_sqr4f(f32 *v, f32 *a) {
*v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
}
+void un_m_distance2f(f32 *v, f32 *a, f32 *b) {
+ f32 f[2];
+ un_m_sub2f(f, b, a);
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1]);
+}
+
+void un_m_distance3f(f32 *v, f32 *a, f32 *b) {
+ f32 f[3];
+ un_m_sub3f(f, b, a);
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
+}
+
+void un_m_distance4f(f32 *v, f32 *a, f32 *b) {
+ f32 f[4];
+ un_m_sub4f(f, b, a);
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
+}
void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b) {
f32 f[2];
@@ -221,25 +210,25 @@ void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b) {
void un_m_normalize2f(f32 *v, f32 *a) {
f32 f;
un_m_magnitude2f(&f, a);
- v[0] /= f;
- v[1] /= f;
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
}
void un_m_normalize3f(f32 *v, f32 *a) {
f32 f;
un_m_magnitude3f(&f, a);
- v[0] /= f;
- v[1] /= f;
- v[2] /= f;
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
}
void un_m_normalize4f(f32 *v, f32 *a) {
f32 f;
un_m_magnitude4f(&f, a);
- v[0] /= f;
- v[1] /= f;
- v[2] /= f;
- v[3] /= f;
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
+ v[3] = a[3] / f;
}
void un_m_project2f(f32 *v, f32 *a, f32 *onto) {
@@ -292,3 +281,27 @@ void un_m_project4f(f32 *v, f32 *a, f32 *onto) {
v[2] = onto[2] * scale;
v[3] = onto[3] * scale;
}
+
+void un_m_reflect2f(f32 *v, f32 *a, f32 *normal) {
+ f32 dot;
+
+ un_m_dot2f(&dot, a, normal);
+ un_m_mul_scalar2f(v, normal, 2.0f * dot);
+ un_m_sub2f(v, v, a);
+}
+
+void un_m_reflect3f(f32 *v, f32 *a, f32 *normal) {
+ f32 dot;
+
+ un_m_dot3f(&dot, a, normal);
+ un_m_mul_scalar3f(v, normal, 2.0f * dot);
+ un_m_sub3f(v, v, a);
+}
+
+void un_m_reflect4f(f32 *v, f32 *a, f32 *normal) {
+ f32 dot;
+
+ un_m_dot4f(&dot, a, normal);
+ un_m_mul_scalar4f(v, normal, 2.0f * dot);
+ un_m_sub4f(v, v, a);
+}
diff --git a/src/un_vecd.c b/src/un_vecd.c
new file mode 100644
index 0000000..0d138a4
--- /dev/null
+++ b/src/un_vecd.c
@@ -0,0 +1,307 @@
+void un_m_add2d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+}
+
+void un_m_add3d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+ v[2] = a[2] + b[2];
+}
+
+void un_m_add4d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+ v[2] = a[2] + b[2];
+ v[3] = a[3] + b[3];
+}
+
+void un_m_sub2d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+}
+
+void un_m_sub3d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+ v[2] = a[2] - b[2];
+}
+
+void un_m_sub4d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+ v[2] = a[2] - b[2];
+ v[3] = a[3] - b[3];
+}
+
+void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+}
+
+void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+ v[2] = a[2] + scalar;
+}
+
+void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+ v[2] = a[2] + scalar;
+ v[3] = a[3] + scalar;
+}
+
+void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+}
+
+void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+ v[2] = a[2] - scalar;
+}
+
+void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+ v[2] = a[2] - scalar;
+ v[3] = a[3] - scalar;
+}
+
+void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+}
+
+void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+ v[2] = a[2] * scalar;
+}
+
+void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+ v[2] = a[2] * scalar;
+ v[3] = a[3] * scalar;
+}
+
+void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+}
+
+void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+ v[2] = a[2] / scalar;
+}
+
+void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+ v[2] = a[2] / scalar;
+ v[3] = a[3] / scalar;
+}
+
+void un_m_dot2d(f64 *v, f64 *a, f64 *b) {
+ *v = a[0] * b[0] + a[1] * b[1];
+}
+
+void un_m_dot3d(f64 *v, f64 *a, f64 *b) {
+ *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+void un_m_dot4d(f64 *v, f64 *a, f64 *b) {
+ *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+}
+
+void un_m_hadamard2d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+}
+
+void un_m_hadamard3d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+ v[2] = a[2] * b[2];
+}
+
+void un_m_hadamard4d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+ v[2] = a[2] * b[2];
+ v[3] = a[3] * b[3];
+}
+
+void un_m_cross2d(f64 *v, f64 *a) {
+ v[0] = a[1];
+ v[1] =-a[0];
+}
+
+void un_m_cross3d(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[1] * b[2] - a[2] * b[1];
+ v[1] = a[2] * b[0] - a[0] * b[2];
+ v[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+void un_m_magnitude2d(f64 *v, f64 *a) {
+ *v = sqrt(a[0] * a[0] + a[1] * a[1]);
+}
+
+void un_m_magnitude3d(f64 *v, f64 *a) {
+ *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+void un_m_magnitude4d(f64 *v, f64 *a) {
+ *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
+}
+
+void un_m_magnitude_sqr2d(f64 *v, f64 *a) {
+ *v = a[0] * a[0] + a[1] * a[1];
+}
+
+void un_m_magnitude_sqr3d(f64 *v, f64 *a) {
+ *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
+}
+
+void un_m_magnitude_sqr4d(f64 *v, f64 *a) {
+ *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
+}
+
+void un_m_distance2d(f64 *v, f64 *a, f64 *b) {
+ f64 f[2];
+ un_m_sub2d(f, b, a);
+ *v = sqrt(f[0] * f[0] + f[1] * f[1]);
+}
+
+void un_m_distance3d(f64 *v, f64 *a, f64 *b) {
+ f64 f[3];
+ un_m_sub3d(f, b, a);
+ *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
+}
+
+void un_m_distance4d(f64 *v, f64 *a, f64 *b) {
+ f64 f[4];
+ un_m_sub4d(f, b, a);
+ *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
+}
+
+void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b) {
+ f64 f[2];
+ un_m_sub2d(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1];
+}
+
+void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b) {
+ f64 f[3];
+ un_m_sub3d(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2];
+}
+
+void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b) {
+ f64 f[4];
+ un_m_sub4d(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3];
+}
+
+void un_m_normalize2d(f64 *v, f64 *a) {
+ f64 f;
+ un_m_magnitude2d(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+}
+
+void un_m_normalize3d(f64 *v, f64 *a) {
+ f64 f;
+ un_m_magnitude3d(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
+}
+
+void un_m_normalize4d(f64 *v, f64 *a) {
+ f64 f;
+ un_m_magnitude4d(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
+ v[3] = a[3] / f;
+}
+
+void un_m_project2d(f64 *v, f64 *a, f64 *onto) {
+ f64 dot, magn, scale;
+
+ un_m_dot2d(&dot, a, onto);
+ un_m_magnitude_sqr2d(&magn, onto);
+
+ if (magn < EPSILON) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+ return;
+ }
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+}
+
+void un_m_project3d(f64 *v, f64 *a, f64 *onto) {
+ f64 dot, magn, scale;
+
+ un_m_dot3d(&dot, a, onto);
+ un_m_magnitude_sqr3d(&magn, onto);
+
+ if (magn < EPSILON_D) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 3);
+ return;
+ }
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+ v[2] = onto[2] * scale;
+}
+
+void un_m_project4d(f64 *v, f64 *a, f64 *onto) {
+ f64 dot, magn, scale;
+
+ un_m_dot4d(&dot, a, onto);
+ un_m_magnitude_sqr4d(&magn, onto);
+
+ if (magn < EPSILON_D) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 4.0);
+ return;
+ }
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+ v[2] = onto[2] * scale;
+ v[3] = onto[3] * scale;
+}
+
+void un_m_reflect2d(f64 *v, f64 *a, f64 *normal) {
+ f64 dot;
+
+ un_m_dot2d(&dot, a, normal);
+ un_m_mul_scalar2d(v, normal, 2.0 * dot);
+ un_m_sub2d(v, v, a);
+}
+
+void un_m_reflect3d(f64 *v, f64 *a, f64 *normal) {
+ f64 dot;
+
+ un_m_dot3d(&dot, a, normal);
+ un_m_mul_scalar3d(v, normal, 2.0 * dot);
+ un_m_sub3d(v, v, a);
+}
+
+void un_m_reflect4d(f64 *v, f64 *a, f64 *normal) {
+ f64 dot;
+
+ un_m_dot4d(&dot, a, normal);
+ un_m_mul_scalar4d(v, normal, 2.0 * dot);
+ un_m_sub4d(v, v, a);
+}
diff --git a/src/un_vecr.c b/src/un_vecr.c
new file mode 100644
index 0000000..0fcf672
--- /dev/null
+++ b/src/un_vecr.c
@@ -0,0 +1,353 @@
+void un_m_add2r(real *v, real *a, real *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+}
+
+void un_m_add3r(real *v, real *a, real *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+ v[2] = a[2] + b[2];
+}
+
+void un_m_add4r(real *v, real *a, real *b) {
+ v[0] = a[0] + b[0];
+ v[1] = a[1] + b[1];
+ v[2] = a[2] + b[2];
+ v[3] = a[3] + b[3];
+}
+
+void un_m_sub2r(real *v, real *a, real *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+}
+
+void un_m_sub3r(real *v, real *a, real *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+ v[2] = a[2] - b[2];
+}
+
+void un_m_sub4r(real *v, real *a, real *b) {
+ v[0] = a[0] - b[0];
+ v[1] = a[1] - b[1];
+ v[2] = a[2] - b[2];
+ v[3] = a[3] - b[3];
+}
+
+void un_m_add_scalar2r(real *v, real *a, real scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+}
+
+void un_m_add_scalar3r(real *v, real *a, real scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+ v[2] = a[2] + scalar;
+}
+
+void un_m_add_scalar4r(real *v, real *a, real scalar) {
+ v[0] = a[0] + scalar;
+ v[1] = a[1] + scalar;
+ v[2] = a[2] + scalar;
+ v[3] = a[3] + scalar;
+}
+
+void un_m_sub_scalar2r(real *v, real *a, real scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+}
+
+void un_m_sub_scalar3r(real *v, real *a, real scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+ v[2] = a[2] - scalar;
+}
+
+void un_m_sub_scalar4r(real *v, real *a, real scalar) {
+ v[0] = a[0] - scalar;
+ v[1] = a[1] - scalar;
+ v[2] = a[2] - scalar;
+ v[3] = a[3] - scalar;
+}
+
+void un_m_mul_scalar2r(real *v, real *a, real scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+}
+
+void un_m_mul_scalar3r(real *v, real *a, real scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+ v[2] = a[2] * scalar;
+}
+
+void un_m_mul_scalar4r(real *v, real *a, real scalar) {
+ v[0] = a[0] * scalar;
+ v[1] = a[1] * scalar;
+ v[2] = a[2] * scalar;
+ v[3] = a[3] * scalar;
+}
+
+void un_m_div_scalar2r(real *v, real *a, real scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+}
+
+void un_m_div_scalar3r(real *v, real *a, real scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+ v[2] = a[2] / scalar;
+}
+
+void un_m_div_scalar4r(real *v, real *a, real scalar) {
+ v[0] = a[0] / scalar;
+ v[1] = a[1] / scalar;
+ v[2] = a[2] / scalar;
+ v[3] = a[3] / scalar;
+}
+
+void un_m_dot2r(real *v, real *a, real *b) {
+ *v = a[0] * b[0] + a[1] * b[1];
+}
+
+void un_m_dot3r(real *v, real *a, real *b) {
+ *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+void un_m_dot4r(real *v, real *a, real *b) {
+ *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+}
+
+void un_m_hadamard2r(real *v, real *a, real *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+}
+
+void un_m_hadamard3r(real *v, real *a, real *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+ v[2] = a[2] * b[2];
+}
+
+void un_m_hadamard4r(real *v, real *a, real *b) {
+ v[0] = a[0] * b[0];
+ v[1] = a[1] * b[1];
+ v[2] = a[2] * b[2];
+ v[3] = a[3] * b[3];
+}
+
+void un_m_cross2r(real *v, real *a) {
+ v[0] = a[1];
+ v[1] =-a[0];
+}
+
+void un_m_cross3r(real *v, real *a, real *b) {
+ v[0] = a[1] * b[2] - a[2] * b[1];
+ v[1] = a[2] * b[0] - a[0] * b[2];
+ v[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+void un_m_magnitude2r(real *v, real *a) {
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(a[0] * a[0] + a[1] * a[1]);
+#else
+ *v = sqrtf(a[0] * a[0] + a[1] * a[1]);
+#endif
+}
+
+void un_m_magnitude3r(real *v, real *a) {
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+#else
+ *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+#endif
+}
+
+void un_m_magnitude4r(real *v, real *a) {
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
+#else
+ *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
+#endif
+}
+
+void un_m_magnitude_sqr2r(real *v, real *a) {
+ *v = a[0] * a[0] + a[1] * a[1];
+}
+
+void un_m_magnitude_sqr3r(real *v, real *a) {
+ *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
+}
+
+void un_m_magnitude_sqr4r(real *v, real *a) {
+ *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
+}
+
+void un_m_distance2r(real *v, real *a, real *b) {
+ real f[2];
+ un_m_sub2r(f, b, a);
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(f[0] * f[0] + f[1] * f[1]);
+#else
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1]);
+#endif
+}
+
+void un_m_distance3r(real *v, real *a, real *b) {
+ real f[3];
+ un_m_sub3r(f, b, a);
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
+#else
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
+#endif
+}
+
+void un_m_distance4r(real *v, real *a, real *b) {
+ real f[4];
+ un_m_sub4r(f, b, a);
+#if defined(UN_DOUBLE_PRECISION)
+ *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
+#else
+ *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
+#endif
+}
+
+void un_m_distance_sqr2r(real *v, real *a, real *b) {
+ real f[2];
+ un_m_sub2r(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1];
+}
+
+void un_m_distance_sqr3r(real *v, real *a, real *b) {
+ real f[3];
+ un_m_sub3r(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2];
+}
+
+void un_m_distance_sqr4r(real *v, real *a, real *b) {
+ real f[4];
+ un_m_sub4r(f, b, a);
+ *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3];
+}
+
+void un_m_normalize2r(real *v, real *a) {
+ real f;
+ un_m_magnitude2r(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+}
+
+void un_m_normalize3r(real *v, real *a) {
+ real f;
+ un_m_magnitude3r(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
+}
+
+void un_m_normalize4r(real *v, real *a) {
+ real f;
+ un_m_magnitude4r(&f, a);
+ v[0] = a[0] / f;
+ v[1] = a[1] / f;
+ v[2] = a[2] / f;
+ v[3] = a[3] / f;
+}
+
+void un_m_project2r(real *v, real *a, real *onto) {
+ real dot, magn, scale;
+
+ un_m_dot2r(&dot, a, onto);
+ un_m_magnitude_sqr2r(&magn, onto);
+
+
+#if defined(UN_DOUBLE_PRECISION)
+ if (magn < EPSILON_D) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+ return;
+ }
+#else
+ if (magn < EPSILON) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 2);
+ return;
+ }
+#endif
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+}
+
+void un_m_project3r(real *v, real *a, real *onto) {
+ real dot, magn, scale;
+
+ un_m_dot3r(&dot, a, onto);
+ un_m_magnitude_sqr3r(&magn, onto);
+
+#if defined(UN_DOUBLE_PRECISION)
+ if (magn < EPSILON_D) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 3);
+ return;
+ }
+#else
+ if (magn < EPSILON) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 3);
+ return;
+ }
+#endif
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+ v[2] = onto[2] * scale;
+}
+
+void un_m_project4r(real *v, real *a, real *onto) {
+ real dot, magn, scale;
+
+ un_m_dot4r(&dot, a, onto);
+ un_m_magnitude_sqr4r(&magn, onto);
+
+#if defined(UN_DOUBLE_PRECISION)
+ if (magn < EPSILON_D) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 4);
+ return;
+ }
+#else
+ if (magn < EPSILON) {
+ un_memory_set((void*)v, 0, sizeof(*v) * 4);
+ return;
+ }
+#endif
+
+ scale = dot / magn;
+ v[0] = onto[0] * scale;
+ v[1] = onto[1] * scale;
+ v[2] = onto[2] * scale;
+ v[3] = onto[3] * scale;
+}
+
+void un_m_reflect2r(real *v, real *a, real *normal) {
+ real dot;
+
+ un_m_dot2r(&dot, a, normal);
+ un_m_mul_scalar2r(v, normal, 2.0 * dot);
+ un_m_sub2r(v, v, a);
+}
+
+void un_m_reflect3r(real *v, real *a, real *normal) {
+ real dot;
+
+ un_m_dot3r(&dot, a, normal);
+ un_m_mul_scalar3r(v, normal, 2.0 * dot);
+ un_m_sub3r(v, v, a);
+}
+
+void un_m_reflect4r(real *v, real *a, real *normal) {
+ real dot;
+
+ un_m_dot4r(&dot, a, normal);
+ un_m_mul_scalar4r(v, normal, 2.0 * dot);
+ un_m_sub4r(v, v, a);
+}
diff --git a/src/ungrateful.c b/src/ungrateful.c
index 6bfd381..61d8185 100644
--- a/src/ungrateful.c
+++ b/src/ungrateful.c
@@ -3,6 +3,11 @@
#include "un_memory.c"
#include "un_strings.c"
#include "un_list.c"
+
#include "un_math.c"
+
#include "un_vec.c"
+#include "un_vecd.c"
+#include "un_vecr.c"
+
#include "un_splines.c"
diff --git a/src/ungrateful.h b/src/ungrateful.h
index ff8c24b..bbbea47 100644
--- a/src/ungrateful.h
+++ b/src/ungrateful.h
@@ -97,45 +97,47 @@ typedef int8_t b8;
typedef float f32;
typedef double f64;
-#if defined(UN_DOUBLE_PRECISION)
-typedef double real;
-
#ifndef PI
-# define PI 3.14159265358979323846
+# define PI 3.14159265358979323846f
#endif
#ifndef EPSILON
-# define EPSILON 0.000001
+# define EPSILON 0.000001f
#endif
#ifndef DEG2RAD
-# define DEG2RAD (PI/180.0)
+# define DEG2RAD (PI/180.0f)
#endif
#ifndef RAD2DEG
-# define RAD2DEG (180.0/PI)
+# define RAD2DEG (180.0f/PI)
#endif
+#if defined(UN_DOUBLE_PRECISION)
+ typedef double real;
#else
-typedef float real;
+ typedef float real;
+#endif // UN_DOUBLE_PRECISION
-#ifndef PI
-# define PI 3.14159265358979323846f
+#ifndef PI_D
+# define PI_D 3.14159265358979323846
#endif
-#ifndef EPSILON
-# define EPSILON 0.000001f
+#ifndef EPSILON_D
+# define EPSILON_D 0.000000000000001
#endif
-#ifndef DEG2RAD
-# define DEG2RAD (PI/180.0f)
+#ifndef DEG2RAD_D
+# define DEG2RAD_D (PI/180.0)
#endif
-
-#ifndef RAD2DEG
-# define RAD2DEG (180.0f/PI)
+#ifndef RAD2DEG_D
+# define RAD2DEG_D (180.0/PI)
#endif
-#endif // UN_DOUBLE_PRECISION
+
+#define un_vec_unwrap2(vec) vec[0], vec[1]
+#define un_vec_unwrap3(vec) vec[0], vec[1], vec[2]
+#define un_vec_unwrap4(vec) vec[0], vec[1], vec[2], vec[3]
/* ---- Memory Allocators API ---- */
@@ -232,7 +234,7 @@ real un_m_lerpr(real a, real b, real t);
f32 un_m_lerpf(f32 a, f32 b, f32 t);
f64 un_m_lerpd(f64 a, f64 b, f64 t);
-/* 2d */
+/* 2d f32 */
void un_m_add2f(f32 *v, f32 *a, f32 *b);
void un_m_sub2f(f32 *v, f32 *a, f32 *b);
void un_m_add_scalar2f(f32 *v, f32 *a, f32 scalar);
@@ -243,14 +245,16 @@ void un_m_div_scalar2f(f32 *v, f32 *a, f32 scalar);
void un_m_dot2f(f32 *v, f32 *a, f32 *b);
void un_m_hadamard2f(f32 *v, f32 *a, f32 *b);
void un_m_project2f(f32 *v, f32 *a, f32 *onto);
+void un_m_reflect2f(f32 *v, f32 *a, f32 *normal);
void un_m_cross2f(f32 *v, f32 *a);
void un_m_normalize2f(f32 *v, f32 *a);
void un_m_magnitude2f(f32 *v, f32 *a);
void un_m_magnitude_sqr2f(f32 *v, f32 *a);
+void un_m_distance2f(f32 *v, f32 *a, f32 *b);
void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b);
-/* 3d */
+/* 3d f32 */
void un_m_add3f(f32 *v, f32 *a, f32 *b);
void un_m_sub3f(f32 *v, f32 *a, f32 *b);
void un_m_add_scalar3f(f32 *v, f32 *a, f32 scalar);
@@ -261,14 +265,16 @@ void un_m_div_scalar3f(f32 *v, f32 *a, f32 scalar);
void un_m_dot3f(f32 *v, f32 *a, f32 *b);
void un_m_hadamard3f(f32 *v, f32 *a, f32 *b);
void un_m_project3f(f32 *v, f32 *a, f32 *onto);
+void un_m_reflect3f(f32 *v, f32 *a, f32 *normal);
void un_m_cross3f(f32 *v, f32 *a, f32 *b);
void un_m_normalize3f(f32 *v, f32 *a);
void un_m_magnitude3f(f32 *v, f32 *a);
void un_m_magnitude_sqr3f(f32 *v, f32 *a);
+void un_m_distance3f(f32 *v, f32 *a, f32 *b);
void un_m_distance_sqr3f(f32 *v, f32 *a, f32 *b);
-/* 4d */
+/* 4d f32 */
void un_m_add4f(f32 *v, f32 *a, f32 *b);
void un_m_sub4f(f32 *v, f32 *a, f32 *b);
void un_m_add_scalar4f(f32 *v, f32 *a, f32 scalar);
@@ -279,17 +285,155 @@ void un_m_div_scalar4f(f32 *v, f32 *a, f32 scalar);
void un_m_dot4f(f32 *v, f32 *a, f32 *b);
void un_m_hadamard4f(f32 *v, f32 *a, f32 *b);
void un_m_project4f(f32 *v, f32 *a, f32 *onto);
+void un_m_reflect4f(f32 *v, f32 *a, f32 *normal);
void un_m_normalize4f(f32 *v, f32 *a);
void un_m_magnitude4f(f32 *v, f32 *a);
void un_m_magnitude_sqr4f(f32 *v, f32 *a);
+void un_m_distance4f(f32 *v, f32 *a, f32 *b);
void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b);
+
+/* 2d f64 */
+void un_m_add2d(f64 *v, f64 *a, f64 *b);
+void un_m_sub2d(f64 *v, f64 *a, f64 *b);
+
+void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar);
+void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar);
+void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar);
+void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar);
+
+void un_m_dot2d(f64 *v, f64 *a, f64 *b);
+void un_m_hadamard2d(f64 *v, f64 *a, f64 *b);
+void un_m_project2d(f64 *v, f64 *a, f64 *onto);
+void un_m_reflect2d(f64 *v, f64 *a, f64 *normal);
+void un_m_cross2d(f64 *v, f64 *a);
+
+void un_m_normalize2d(f64 *v, f64 *a);
+void un_m_magnitude2d(f64 *v, f64 *a);
+void un_m_magnitude_sqr2d(f64 *v, f64 *a);
+void un_m_distance2d(f64 *v, f64 *a, f64 *b);
+void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b);
+
+/* 3d f64 */
+void un_m_add3d(f64 *v, f64 *a, f64 *b);
+void un_m_sub3d(f64 *v, f64 *a, f64 *b);
+
+void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar);
+void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar);
+void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar);
+void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar);
+
+void un_m_dot3d(f64 *v, f64 *a, f64 *b);
+void un_m_hadamard3d(f64 *v, f64 *a, f64 *b);
+void un_m_project3d(f64 *v, f64 *a, f64 *onto);
+void un_m_reflect3d(f64 *v, f64 *a, f64 *normal);
+void un_m_cross3d(f64 *v, f64 *a, f64 *b);
+
+void un_m_normalize3d(f64 *v, f64 *a);
+void un_m_magnitude3d(f64 *v, f64 *a);
+void un_m_magnitude_sqr3d(f64 *v, f64 *a);
+void un_m_distance3d(f64 *v, f64 *a, f64 *b);
+void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b);
+
+/* 4d f64 */
+void un_m_add4d(f64 *v, f64 *a, f64 *b);
+void un_m_sub4d(f64 *v, f64 *a, f64 *b);
+
+void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar);
+void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar);
+void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar);
+void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar);
+
+void un_m_dot4d(f64 *v, f64 *a, f64 *b);
+void un_m_hadamard4d(f64 *v, f64 *a, f64 *b);
+void un_m_project4d(f64 *v, f64 *a, f64 *onto);
+void un_m_reflect4d(f64 *v, f64 *a, f64 *normal);
+
+void un_m_normalize4d(f64 *v, f64 *a);
+void un_m_magnitude4d(f64 *v, f64 *a);
+void un_m_magnitude_sqr4d(f64 *v, f64 *a);
+void un_m_distance4d(f64 *v, f64 *a, f64 *b);
+void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b);
+
+/* 2d real */
+void un_m_add2r(real *v, real *a, real *b);
+void un_m_sub2r(real *v, real *a, real *b);
+
+void un_m_add_scalar2r(real *v, real *a, real scalar);
+void un_m_sub_scalar2r(real *v, real *a, real scalar);
+void un_m_mul_scalar2r(real *v, real *a, real scalar);
+void un_m_div_scalar2r(real *v, real *a, real scalar);
+
+void un_m_dot2r(real *v, real *a, real *b);
+void un_m_hadamard2r(real *v, real *a, real *b);
+void un_m_project2r(real *v, real *a, real *onto);
+void un_m_reflect2r(real *v, real *a, real *normal);
+void un_m_cross2r(real *v, real *a);
+
+void un_m_normalize2r(real *v, real *a);
+void un_m_magnitude2r(real *v, real *a);
+void un_m_magnitude_sqr2r(real *v, real *a);
+void un_m_distance2r(real *v, real *a, real *b);
+void un_m_distance_sqr2r(real *v, real *a, real *b);
+
+/* 3d real */
+void un_m_add3r(real *v, real *a, real *b);
+void un_m_sub3r(real *v, real *a, real *b);
+
+void un_m_add_scalar3r(real *v, real *a, real scalar);
+void un_m_sub_scalar3r(real *v, real *a, real scalar);
+void un_m_mul_scalar3r(real *v, real *a, real scalar);
+void un_m_div_scalar3r(real *v, real *a, real scalar);
+
+void un_m_dot3r(real *v, real *a, real *b);
+void un_m_hadamard3r(real *v, real *a, real *b);
+void un_m_project3r(real *v, real *a, real *onto);
+void un_m_reflect3r(real *v, real *a, real *normal);
+void un_m_cross3r(real *v, real *a, real *b);
+
+void un_m_normalize3r(real *v, real *a);
+void un_m_magnitude3r(real *v, real *a);
+void un_m_magnitude_sqr3r(real *v, real *a);
+void un_m_distance3r(real *v, real *a, real *b);
+void un_m_distance_sqr3r(real *v, real *a, real *b);
+
+/* 4d real */
+void un_m_add4r(real *v, real *a, real *b);
+void un_m_sub4r(real *v, real *a, real *b);
+
+void un_m_add_scalar4r(real *v, real *a, real scalar);
+void un_m_sub_scalar4r(real *v, real *a, real scalar);
+void un_m_mul_scalar4r(real *v, real *a, real scalar);
+void un_m_div_scalar4r(real *v, real *a, real scalar);
+
+void un_m_dot4r(real *v, real *a, real *b);
+void un_m_hadamard4r(real *v, real *a, real *b);
+void un_m_project4r(real *v, real *a, real *onto);
+void un_m_reflect4r(real *v, real *a, real *normal);
+
+void un_m_normalize4r(real *v, real *a);
+void un_m_magnitude4r(real *v, real *a);
+void un_m_magnitude_sqr4r(real *v, real *a);
+void un_m_distance4r(real *v, real *a, real *b);
+void un_m_distance_sqr4r(real *v, real *a, real *b);
+
/* ---- splines ---- */
-real un_m_bezierr(real a, real q0, real q1, real b, real t);
-f32 un_m_bezierf(f32 a, f32 q0, f32 q1, f32 b, f32 t);
-f64 un_m_bezierd(f64 a, f64 q0, f64 q1, f64 b, f64 t);
+void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t);
+void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t);
+void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t);
+void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t);
+
+void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t);
+void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t);
+void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t);
+void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t);
+
+void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t);
+void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
+void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
+void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
/* ---- easing ---- */