summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge <[email protected]>2020-04-19 14:52:39 +0200
committerTyge <[email protected]>2020-04-19 14:57:19 +0200
commit76c8cc6e95e630fab87941f4366a46fb6587d7f5 (patch)
tree7f494ef800875ae7280d901913feae0c58622113
parentd7f49e5c1815a2b5ab75c32378d6d7739c5c0495 (diff)
downloadSTC-modified-76c8cc6e95e630fab87941f4366a46fb6587d7f5.tar.gz
STC-modified-76c8cc6e95e630fab87941f4366a46fb6587d7f5.zip
Moved gl math to glm folder
Added clist - single linked list with fast sorting. Refactoring.
-rw-r--r--glm/mat3.h (renamed from stc/cmat3.h)80
-rw-r--r--glm/mat4.h (renamed from stc/cmat4.h)94
-rw-r--r--glm/quat.h206
-rw-r--r--glm/transform.h148
-rw-r--r--glm/vec3.h219
-rw-r--r--glm/vec4.h190
-rw-r--r--stc/carray.h44
-rw-r--r--stc/cdefs.h51
-rw-r--r--stc/clist.h199
-rw-r--r--stc/cmap.h58
-rw-r--r--stc/copt.h108
-rw-r--r--stc/cquat.h206
-rw-r--r--stc/cstring.h56
-rw-r--r--stc/cvec3.h202
-rw-r--r--stc/cvec4.h170
-rw-r--r--stc/cvector.h58
16 files changed, 1241 insertions, 848 deletions
diff --git a/stc/cmat3.h b/glm/mat3.h
index 24903c02..ad9e03ea 100644
--- a/stc/cmat3.h
+++ b/glm/mat3.h
@@ -20,31 +20,31 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-#ifndef CMAT3__H__
-#define CMAT3__H__
+#ifndef GLM_MAT3__H__
+#define GLM_MAT3__H__
-#include "cvec3.h"
+#include "vec3.h"
-#define cmat3_identity_init {1, 0, 0, 0, 1, 0, 0, 0, 1}
-#define cmat3_zero_init {0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define glm_mat3_identity_init {1, 0, 0, 0, 1, 0, 0, 0, 1}
+#define glm_mat3_zero_init {0, 0, 0, 0, 0, 0, 0, 0, 0}
-#define cmat3f_identity ((CMat3f) cmat3_identity_init)
-#define cmat3d_identity ((CMat3d) cmat3_identity_init)
-#define cmat3f_zero ((CMat3f) cmat3_zero_init)
-#define cmat3d_zero ((CMat3d) cmat3_zero_init)
+#define glm_mat3f_identity ((glm_mat3f) glm_mat3_identity_init)
+#define glm_mat3d_identity ((glm_mat3d) glm_mat3_identity_init)
+#define glm_mat3f_zero ((glm_mat3f) glm_mat3_zero_init)
+#define glm_mat3d_zero ((glm_mat3d) glm_mat3_zero_init)
-#define declare_CMat3(tag, T) \
- typedef const T (*CMat3##tag##ConstRef)[3]; \
+#define declare_glm_mat3(tag, T) \
+ typedef const T (*glm_mat3##tag##m)[3]; \
\
- typedef union CMat3##tag { \
- CVec3##tag v[3]; \
+ typedef union glm_mat3##tag { \
+ glm_vec3##tag v[3]; \
T m[3][3], arr[3*3]; \
- } CMat3##tag; \
+ } glm_mat3##tag; \
\
- static inline CMat3##tag \
- cmat3##tag##_mult(CMat3##tag##ConstRef m1, CMat3##tag##ConstRef m2) { \
+ static inline glm_mat3##tag \
+ glm_mat3##tag##_mult(glm_mat3##tag##m m1, glm_mat3##tag##m m2) { \
const T *a = m1[0], *b = m2[0]; \
- return (CMat3##tag) { \
+ return (glm_mat3##tag) { \
a[0] * b[0] + a[3] * b[1] + a[6] * b[2], \
a[1] * b[0] + a[4] * b[1] + a[7] * b[2], \
a[2] * b[0] + a[5] * b[1] + a[8] * b[2], \
@@ -57,40 +57,40 @@
}; \
} \
\
- static inline CMat3##tag* \
- cmat3##tag##_scale(CMat3##tag* self, T s) { \
+ static inline glm_mat3##tag* \
+ glm_mat3##tag##_scale(glm_mat3##tag* self, T s) { \
T* a = self->arr; \
a[0] *= s, a[1] *= s, a[2] *= s, \
a[3] *= s, a[4] *= s, a[5] *= s, \
a[6] *= s, a[7] *= s, a[8] *= s; \
return self; \
} \
- static inline CMat3##tag \
- cmat3##tag##_scalarMult(CMat3##tag##ConstRef m, T s) { \
- CMat3##tag dst; \
+ static inline glm_mat3##tag \
+ glm_mat3##tag##_scalarMult(glm_mat3##tag##m m, T s) { \
+ glm_mat3##tag dst; \
T *c = dst.arr; const T *a = m[0]; \
for (int i = 0; i < 9; ++i) *c++ = *a++ * s; \
return dst; \
} \
- static inline CMat3##tag \
- cmat3##tag##_compMult(CMat3##tag##ConstRef m1, CMat3##tag##ConstRef m2) { \
- CMat3##tag dst; \
+ static inline glm_mat3##tag \
+ glm_mat3##tag##_compMult(glm_mat3##tag##m m1, glm_mat3##tag##m m2) { \
+ glm_mat3##tag dst; \
T *c = dst.arr; const T *a = m1[0], *b = m2[0]; \
for (int i = 0; i < 9; ++i) *c++ = *a++ * *b++; \
return dst; \
} \
- static inline CVec3##tag \
- cmat3##tag##_vecMult(CMat3##tag##ConstRef m, CVec3##tag v) { \
- return (CVec3##tag) { \
+ static inline glm_vec3##tag \
+ glm_mat3##tag##_vecMult(glm_mat3##tag##m m, glm_vec3##tag v) { \
+ return (glm_vec3##tag) { \
m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, \
m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, \
m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z, \
}; \
} \
\
- static inline CMat3##tag \
- cmat3##tag##_transpose(CMat3##tag##ConstRef m) { \
- return (CMat3##tag) { \
+ static inline glm_mat3##tag \
+ glm_mat3##tag##_transpose(glm_mat3##tag##m m) { \
+ return (glm_mat3##tag) { \
m[0][0], m[1][0], m[2][0], \
m[0][1], m[1][1], m[2][1], \
m[0][2], m[1][2], m[2][2], \
@@ -98,24 +98,24 @@
} \
\
static inline T \
- cmat3##tag##_trace(CMat3##tag##ConstRef m) { \
+ glm_mat3##tag##_trace(glm_mat3##tag##m m) { \
return m[0][0] + m[1][1] + m[2][2]; \
} \
\
\
static inline T \
- cmat3##tag##_determinant(CMat3##tag##ConstRef m) { \
+ glm_mat3##tag##_determinant(glm_mat3##tag##m m) { \
const T *a = m[0]; \
return a[0] * (a[4] * a[8] - a[7] * a[5]) \
- a[3] * (a[1] * a[8] - a[2] * a[7]) \
+ a[6] * (a[1] * a[5] - a[2] * a[4]); \
} \
\
- static inline CMat3##tag \
- cmat3##tag##_inverse(CMat3##tag##ConstRef m) { \
+ static inline glm_mat3##tag \
+ glm_mat3##tag##_inverse(glm_mat3##tag##m m) { \
const T *a = m[0]; \
- T k = 1.0f / cmat3##tag##_determinant(m); \
- return (CMat3##tag) { \
+ T k = 1.0f / glm_mat3##tag##_determinant(m); \
+ return (glm_mat3##tag) { \
(a[4] * a[8] - a[5] * a[7]) * k, \
-(a[1] * a[8] - a[7] * a[2]) * k, \
(a[1] * a[5] - a[4] * a[2]) * k, \
@@ -128,10 +128,10 @@
}; \
} \
\
- typedef T cmat3##tag##_value_t
+ typedef T glm_mat3##tag##_value_t
-declare_CMat3(d, double);
-declare_CMat3(f, float);
+declare_glm_mat3(d, double);
+declare_glm_mat3(f, float);
#endif
diff --git a/stc/cmat4.h b/glm/mat4.h
index 0fd5cbfe..34638ec5 100644
--- a/stc/cmat4.h
+++ b/glm/mat4.h
@@ -20,34 +20,34 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-#ifndef CMAT4__H__
-#define CMAT4__H__
+#ifndef GLM_MAT4__H__
+#define GLM_MAT4__H__
-#include "cmat3.h"
-#include "cvec4.h"
+#include "mat3.h"
+#include "vec4.h"
-#define cmat4_identity_init {1, 0, 0, 0, 0, 1, 0, 0, \
+#define glm_mat4_identity_init {1, 0, 0, 0, 0, 1, 0, 0, \
0, 0, 1, 0, 0, 0, 0, 1}
-#define cmat4_zero_init {0, 0, 0, 0, 0, 0, 0, 0, \
+#define glm_mat4_zero_init {0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0}
-#define cmat4f_identity ((CMat4f) cmat4_identity_init)
-#define cmat4d_identity ((CMat4d) cmat4_identity_init)
-#define cmat4f_zero ((CMat4f) cmat4_zero_init)
-#define cmat4d_zero ((CMat4d) cmat4_zero_init)
+#define glm_mat4f_identity ((glm_mat4f) glm_mat4_identity_init)
+#define glm_mat4d_identity ((glm_mat4d) glm_mat4_identity_init)
+#define glm_mat4f_zero ((glm_mat4f) glm_mat4_zero_init)
+#define glm_mat4d_zero ((glm_mat4d) glm_mat4_zero_init)
-#define declare_CMat4(tag, T) \
- typedef const T (*CMat4##tag##ConstRef)[4]; \
+#define declare_glm_mat4(tag, T) \
+ typedef const T (*glm_mat4##tag##m)[4]; \
\
- typedef union CMat4##tag { \
- CVec4##tag v[4]; \
+ typedef union glm_mat4##tag { \
+ glm_vec4##tag v[4]; \
T m[4][4], arr[4*4]; \
- } CMat4##tag; \
+ } glm_mat4##tag; \
\
- static inline CMat4##tag \
- cmat4##tag##_mult(CMat4##tag##ConstRef mat1, CMat4##tag##ConstRef mat2) { \
+ static inline glm_mat4##tag \
+ glm_mat4##tag##_mult(glm_mat4##tag##m mat1, glm_mat4##tag##m mat2) { \
const T *a = mat1[0], *b = mat2[0]; \
- return (CMat4##tag) { \
+ return (glm_mat4##tag) { \
a[ 0] * b[ 0] + a[ 4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b[ 3], \
a[ 1] * b[ 0] + a[ 5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b[ 3], \
a[ 2] * b[ 0] + a[ 6] * b[ 1] + a[10] * b[ 2] + a[14] * b[ 3], \
@@ -67,29 +67,29 @@
}; \
} \
\
- static inline CMat4##tag* \
- cmat4##tag##_scale(CMat4##tag* self, T s) { \
+ static inline glm_mat4##tag* \
+ glm_mat4##tag##_scale(glm_mat4##tag* self, T s) { \
T* a = self->arr; \
for (int i = 0; i < 16; ++i) *a++ *= s; \
return self; \
} \
- static inline CMat4##tag \
- cmat4##tag##_scalarMult(CMat4##tag##ConstRef m, T s) { \
- CMat4##tag dst; \
+ static inline glm_mat4##tag \
+ glm_mat4##tag##_scalarMult(glm_mat4##tag##m m, T s) { \
+ glm_mat4##tag dst; \
T *c = dst.arr; const T *a = m[0]; \
for (int i = 0; i < 16; ++i) *c++ = *a++ * s; \
return dst; \
} \
- static inline CMat4##tag \
- cmat4##tag##_compMult(CMat4##tag##ConstRef m1, CMat4##tag##ConstRef m2) { \
- CMat4##tag dst; \
+ static inline glm_mat4##tag \
+ glm_mat4##tag##_compMult(glm_mat4##tag##m m1, glm_mat4##tag##m m2) { \
+ glm_mat4##tag dst; \
T *c = dst.arr; const T *a = m1[0], *b = m2[0]; \
for (int i = 0; i < 16; ++i) *c++ = *a++ * *b++; \
return dst; \
} \
- static inline CVec4##tag \
- cmat4##tag##_vecMult(CMat4##tag##ConstRef m, CVec4##tag v) { \
- return (CVec4##tag) { \
+ static inline glm_vec4##tag \
+ glm_mat4##tag##_vecMult(glm_mat4##tag##m m, glm_vec4##tag v) { \
+ return (glm_vec4##tag) { \
m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, \
m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w, \
m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w, \
@@ -97,9 +97,9 @@
}; \
} \
\
- static inline CMat4##tag \
- cmat4##tag##_transpose(CMat4##tag##ConstRef m) { \
- return (CMat4##tag) { \
+ static inline glm_mat4##tag \
+ glm_mat4##tag##_transpose(glm_mat4##tag##m m) { \
+ return (glm_mat4##tag) { \
m[0][0], m[1][0], m[2][0], m[3][0], \
m[0][1], m[1][1], m[2][1], m[3][1], \
m[0][2], m[1][2], m[2][2], m[3][2], \
@@ -107,18 +107,18 @@
}; \
} \
\
- static inline CMat3##tag \
- cmat4##tag##_transpose3(CMat4##tag##ConstRef m) { \
- return (CMat3##tag) { \
+ static inline glm_mat3##tag \
+ glm_mat4##tag##_transpose3(glm_mat4##tag##m m) { \
+ return (glm_mat3##tag) { \
m[0][0], m[1][0], m[2][0], \
m[0][1], m[1][1], m[2][1], \
m[0][2], m[1][2], m[2][2], \
}; \
} \
\
- static inline CMat3##tag \
- cmat4##tag##_to3(CMat4##tag##ConstRef m) { \
- return (CMat3##tag) { \
+ static inline glm_mat3##tag \
+ glm_mat4##tag##_to3(glm_mat4##tag##m m) { \
+ return (glm_mat3##tag) { \
m[0][0], m[0][1], m[0][2], \
m[1][0], m[1][1], m[1][2], \
m[2][0], m[2][1], m[2][2], \
@@ -126,12 +126,12 @@
} \
\
static inline T \
- cmat4##tag##_trace(CMat4##tag##ConstRef m) { \
+ glm_mat4##tag##_trace(glm_mat4##tag##m m) { \
return m[0][0] + m[1][1] + m[2][2] + m[3][3]; \
} \
\
static inline T \
- cmat4##tag##_determinant(CMat4##tag##ConstRef mat) { \
+ glm_mat4##tag##_determinant(glm_mat4##tag##m mat) { \
const T *p = mat[0]; \
T a, b, c, d, e, f; \
a = p[10] * p[15] - p[14] * p[11], \
@@ -147,9 +147,9 @@
} \
\
\
- static inline CMat4##tag \
- cmat4##tag##_inverse(CMat4##tag##ConstRef mat) { \
- CMat4##tag dst; \
+ static inline glm_mat4##tag \
+ glm_mat4##tag##_inverse(glm_mat4##tag##m mat) { \
+ glm_mat4##tag dst; \
const T *p = mat[0]; \
T a, b, c, d, e, f, det; \
a = p[10] * p[15] - p[14] * p[11], \
@@ -192,13 +192,13 @@
\
det = p[0] * dst.m[0][0] + p[1] * dst.m[1][0] \
+ p[2] * dst.m[2][0] + p[3] * dst.m[3][0]; \
- return *cmat4##tag##_scale(&dst, 1.0f / det); \
+ return *glm_mat4##tag##_scale(&dst, 1.0f / det); \
} \
\
- typedef T cmat4##tag##_value_t
+ typedef T glm_mat4##tag##_value_t
-declare_CMat4(d, double);
-declare_CMat4(f, float);
+declare_glm_mat4(d, double);
+declare_glm_mat4(f, float);
#endif
diff --git a/glm/quat.h b/glm/quat.h
new file mode 100644
index 00000000..40124eff
--- /dev/null
+++ b/glm/quat.h
@@ -0,0 +1,206 @@
+// MIT License
+//
+// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#ifndef GLM_QUAT__H__
+#define GLM_QUAT__H__
+
+#include "mat4.h"
+
+#define glm_quat_arr(q) (&(q).x)
+#define glm_quatf_identity ((glm_quatf) {0.f, 0.f, 0.f, 1.f})
+#define glm_quatd_identity ((glm_quatd) {0.0, 0.0, 0.0, 1.0})
+
+#define declare_glm_quat(tag, T) \
+ typedef glm_vec4##tag glm_quat##tag; \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_init(T x, T y, T z, T w) { return (glm_quat##tag) {x, y, z, w}; } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_unit(glm_quat##tag q) { \
+ T dot = _glm_vec4_DOT(q, q); \
+ if (dot <= 0.0f) return glm_quat##tag##_identity; \
+ return glm_vec4##tag##_mult(q, 1.0f / glm_sqrt_##tag(dot)); \
+ } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_fromAxis(T angle, glm_vec3##tag axis) { \
+ T a = angle * 0.5f, c = glm_cos_##tag(a), s = glm_sin_##tag(a); \
+ glm_vec3##tag u = glm_vec3##tag##_unit(axis); \
+ return (glm_quat##tag) {s * u.x, s * u.y, s * u.z, c}; \
+ } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_fromVectors(glm_vec3##tag u, glm_vec3##tag v) { \
+ T d = glm_sqrt_##tag(_glm_vec3_DOT(u, u) * _glm_vec3_DOT(v, v)); \
+ T real_part = d + _glm_vec3_DOT(u, v); \
+ glm_vec3##tag t; \
+ if (real_part < 1.e-6f * d) { \
+ /* If u and v are exactly opposite, rotate 180 degrees */ \
+ /* around an arbitrary orthogonal axis. */ \
+ real_part = 0; \
+ t = fabs(u.x) > fabs(u.z) ? (glm_vec3##tag) {-u.y, u.x, 0} : (glm_vec3##tag) {0, -u.z, u.y}; \
+ } else /* Build quaternion the standard way.*/ \
+ t = _glm_vec3_CROSS(u, v); \
+ glm_quat##tag q = (glm_quat##tag) {t.x, t.y, t.z, real_part}; \
+ return glm_quat##tag##_unit(q); \
+ } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_fromMat4(glm_mat4##tag##m m) { \
+ T trace = m[0][0] + m[1][1] + m[2][2], r, rinv; \
+ glm_quat##tag dst; \
+ if (trace >= 0.0f) { \
+ r = glm_sqrt_##tag(1.0f + trace); \
+ rinv = 0.5f / r; \
+ dst.x = rinv * (m[1][2] - m[2][1]); \
+ dst.y = rinv * (m[2][0] - m[0][2]); \
+ dst.z = rinv * (m[0][1] - m[1][0]); \
+ dst.w = r * 0.5f; \
+ } else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) { \
+ r = glm_sqrt_##tag(1.0f + m[0][0] - m[1][1] - m[2][2]); \
+ rinv = 0.5f / r; \
+ dst.x = r * 0.5f; \
+ dst.y = rinv * (m[0][1] + m[1][0]); \
+ dst.z = rinv * (m[0][2] + m[2][0]); \
+ dst.w = rinv * (m[1][2] - m[2][1]); \
+ } else if (m[1][1] >= m[2][2]) { \
+ r = glm_sqrt_##tag(1.0f - m[0][0] + m[1][1] - m[2][2]); \
+ rinv = 0.5f / r; \
+ dst.x = rinv * (m[0][1] + m[1][0]); \
+ dst.y = r * 0.5f; \
+ dst.z = rinv * (m[1][2] + m[2][1]); \
+ dst.w = rinv * (m[2][0] - m[0][2]); \
+ } else { \
+ r = glm_sqrt_##tag(1.0f - m[0][0] - m[1][1] + m[2][2]); \
+ rinv = 0.5f / r; \
+ dst.x = rinv * (m[0][2] + m[2][0]); \
+ dst.y = rinv * (m[1][2] + m[2][1]); \
+ dst.z = r * 0.5f; \
+ dst.w = rinv * (m[0][1] - m[1][0]); \
+ } \
+ return dst; \
+ } \
+ \
+ static inline glm_mat4##tag \
+ glm_quat##tag##_toMat4(glm_quat##tag q) { \
+ glm_mat4##tag dst; \
+ T norm = glm_quat##tag##_length(q), \
+ s = norm > 0.0f ? 2.0f / norm : 0.0f, \
+ xx = s * q.x * q.x, xy = s * q.x * q.y, wx = s * q.w * q.x, \
+ yy = s * q.y * q.y, yz = s * q.y * q.z, wy = s * q.w * q.y, \
+ zz = s * q.z * q.z, xz = s * q.x * q.z, wz = s * q.w * q.z; \
+ \
+ dst.m[0][0] = 1.0f - yy - zz; \
+ dst.m[1][1] = 1.0f - xx - zz; \
+ dst.m[2][2] = 1.0f - xx - yy; \
+ dst.m[0][1] = xy + wz; \
+ dst.m[1][2] = yz + wx; \
+ dst.m[2][0] = xz + wy; \
+ dst.m[1][0] = xy - wz; \
+ dst.m[2][1] = yz - wx; \
+ dst.m[0][2] = xz - wy; \
+ dst.m[0][3] = dst.m[1][3] = dst.m[2][3] = 0.0f; \
+ dst.m[3][0] = dst.m[3][1] = dst.m[3][2] = 0.0f; \
+ dst.m[3][3] = 1.0f; \
+ return dst; \
+ } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_conjugate(glm_quat##tag q) { \
+ q.x = -q.x, q.y = -q.y, q.z = -q.z; \
+ return q; \
+ } \
+ \
+ static inline glm_quat##tag \
+ glm_quat##tag##_cross(glm_quat##tag p, glm_quat##tag q) { \
+ return (glm_quat##tag) {p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y, \
+ p.w * q.y - p.x * q.z + p.y * q.w + p.z * q.x, \
+ p.w * q.z + p.x * q.y - p.y * q.x + p.z * q.w, \
+ p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z}; \
+ } \
+ static inline glm_quat##tag \
+ glm_quat##tag##_inverse(glm_quat##tag q) { \
+ q.x = -q.x, q.y = -q.y, q.z = -q.z; \
+ return glm_vec4##tag##_mult(q, 1.0f / _glm_vec4_DOT(q, q)); \
+ } \
+ static inline T \
+ glm_quat##tag##_angle(glm_quat##tag q) { \
+ /* sin(theta / 2) = length(x*x + y*y + z*z) */ \
+ /* cos(theta / 2) = w */ \
+ /* theta = 2 * atan(sin(theta / 2) / cos(theta / 2)) */ \
+ return 2.0f * glm_atan2_##tag(glm_sqrt_##tag(_glm_vec3_DOT(q, q)), q.w); \
+ } \
+ static inline T \
+ glm_quat##tag##_imagLength(glm_quat##tag q) { \
+ return glm_sqrt_##tag(_glm_vec3_DOT(q, q)); \
+ } \
+ typedef T glm_quat##tag##_value_t
+
+#define glm_quatf_fromArray(arr) glm_vec4f_fromArray(arr)
+#define glm_quatd_fromArray(arr) glm_vec4d_fromArray(arr)
+
+#define glm_quatf_assign(q, x, y, z, w) glm_vec4f_assign(q, x, y, z, w)
+#define glm_quatd_assign(q, x, y, z, w) glm_vec4d_assign(q, x, y, z, w)
+
+#define glm_quatf_assignArray(q, arr) glm_vec4f_assignArray(q, arr)
+#define glm_quatd_assignArray(q, arr) glm_vec4d_assignArray(q, arr)
+
+#define glm_quatf_length(q) glm_vec4f_length(q)
+#define glm_quatd_length(q) glm_vec4d_length(q)
+
+#define glm_quatf_length2(q) glm_vec4f_length2(q)
+#define glm_quatd_length2(q) glm_vec4d_length2(q)
+
+#define glm_quatf_dot(p, q) glm_vec4f_dot(p, q)
+#define glm_quatd_dot(p, q) glm_vec4d_dot(p, q)
+
+#define glm_quatf_lerp(p, q, t) glm_vec4f_lerp(p, q, t)
+#define glm_quatd_lerp(p, q, t) glm_vec4d_lerp(p, q, t)
+
+#define glm_quatf_swizzle(q, swz) glm_vec4f_swizzle(q, swz)
+#define glm_quatd_swizzle(q, swz) glm_vec4d_swizzle(q, swz)
+
+#define glm_quatf_equals(p, q) glm_vec4f_equals(p, q)
+#define glm_quatd_equals(p, q) glm_vec4d_equals(p, q)
+
+#define glm_quatf_compare(p, q) glm_vec4f_compare(p, q)
+#define glm_quatd_compare(p, q) glm_vec4d_compare(p, q)
+
+#define glm_quatf_imag(q) glm_vec4f_to3(q)
+#define glm_quatd_imag(q) glm_vec4d_to3(q)
+
+#define glm_quatf_real(q) ((float) (q).w)
+#define glm_quatd_real(q) ((double) (q).w)
+
+declare_glm_quat(f, float);
+declare_glm_quat(d, double);
+
+
+static inline glm_quatd glm_quatf_tod(glm_quatf v) {
+ return (glm_quatd) {v.x, v.y, v.z, v.w};
+}
+static inline glm_quatf glm_quatd_tof(glm_quatd v) {
+ return (glm_quatf) {(float) v.x, (float) v.y, (float) v.z, (float) v.w};
+}
+
+#endif
diff --git a/glm/transform.h b/glm/transform.h
new file mode 100644
index 00000000..a301b4f8
--- /dev/null
+++ b/glm/transform.h
@@ -0,0 +1,148 @@
+#include "mat4.h"
+
+#define declare_mat4_transform(tag, T) \
+ /* right handed, opengl spec functions */ \
+ \
+ static inline glm_mat4##tag glm_mat4##tag_##ortho(T left, T right, T bottom, T top, T zNear, T zFar) \
+ { \
+ glm_mat4##tag dst = glm_mat4##tag##_identity; \
+ dst.m[0][0] = 2.0f / (right - left); \
+ dst.m[1][1] = 2.0f / (top - bottom); \
+ dst.m[2][2] = - 2.0f / (zFar - zNear); \
+ dst.m[3][0] = - (right + left) / (right - left); \
+ dst.m[3][1] = - (top + bottom) / (top - bottom); \
+ dst.m[3][2] = - (zFar + zNear) / (zFar - zNear); \
+ return dst; \
+ } \
+ \
+ static inline glm_mat4##tag glm_mat4##tag_##frustum(T left, T right, T bottom, T top, T nearVal, T farVal) \
+ { \
+ glm_mat4##tag dst = glm_mat4##tag##_zero; \
+ dst.m[0][0] = (2.0f * nearVal) / (right - left); \
+ dst.m[1][1] = (2.0f * nearVal) / (top - bottom); \
+ dst.m[2][0] = (right + left) / (right - left); \
+ dst.m[2][1] = (top + bottom) / (top - bottom); \
+ dst.m[2][2] = - (farVal + nearVal) / (farVal - nearVal); \
+ dst.m[2][3] = - 1.0f; \
+ dst.m[3][2] = - (2.0f * farVal * nearVal) / (farVal - nearVal); \
+ return dst; \
+ } \
+ \
+ static inline glm_mat4##tag glm_mat4##tag##_perspective(T fovy, T aspect, T zNear, T zFar) \
+ { \
+ const T tanHalfFovy = glm_tan_##tag(fovy / 2.0f); \
+ \
+ glm_mat4##tag dst = glm_mat4##tag##_zero; \
+ dst.m[0][0] = 1.0f / (aspect * tanHalfFovy); \
+ dst.m[1][1] = 1.0f / (tanHalfFovy); \
+ dst.m[2][2] = - (zFar + zNear) / (zFar - zNear); \
+ dst.m[2][3] = - 1.0f; \
+ dst.m[3][2] = - (2.0f * zFar * zNear) / (zFar - zNear); \
+ return dst; \
+ } \
+ \
+ static inline glm_mat4##tag glm_mat4##tag_##perspectiveFov(T fov, T width, T height, T zNear, T zFar) \
+ { \
+ const T rad = fov; \
+ const T h = glm_cos_##tag(0.5f * rad) / glm_sin_##tag(0.5f * rad); \
+ const T w = h * height / width; /* todo max(width , Height) / min(width , Height)? */ \
+ \
+ glm_mat4##tag dst = glm_mat4##tag##_zero; \
+ dst.m[0][0] = w; \
+ dst.m[1][1] = h; \
+ dst.m[2][2] = - (zFar + zNear) / (zFar - zNear); \
+ dst.m[2][3] = - 1.0f; \
+ dst.m[3][2] = - (2.0f * zFar * zNear) / (zFar - zNear); \
+ return dst; \
+ } \
+ \
+ static inline glm_mat4##tag glm_mat4##tag_##infinitePerspective(T fovy, T aspect, T zNear) \
+ { \
+ const T range = glm_tan_##tag(fovy / 2.0f) * zNear; \
+ const T left = -range * aspect; \
+ const T right = range * aspect; \
+ const T bottom = -range; \
+ const T top = range; \
+ \
+ glm_mat4##tag dst = glm_mat4##tag##_zero; \
+ dst.m[0][0] = (2.0f * zNear) / (right - left); \
+ dst.m[1][1] = (2.0f * zNear) / (top - bottom); \
+ dst.m[2][2] = - 1.0f; \
+ dst.m[2][3] = - 1.0f; \
+ dst.m[3][2] = - 2.0f * zNear; \
+ return dst; \
+ }
+
+// ------------
+
+ static inline glm_mat4##tag translate(const glm_mat4##tag##m m, glm_vec3##tag v)
+ {
+ glm_mat4##tag dst = *(const glm_mat4##tag *) m;
+ dst.m[3] = m[0] * v[0] + m[1] * v.y + m[2] * v.z + m[3];
+ return dst;
+ }
+
+ static inline glm_mat4##tag rotate(glm_mat4##tag##m m, T angle, glm_vec3##tag v)
+ {
+ const T a = angle;
+ const T c = cos(a);
+ const T s = sin(a);
+
+ glm_vec3##tag axis(normalize(v));
+ glm_vec3##tag temp((T(1) - c) * axis);
+
+ glm_mat4##tag rot;
+ rot.m[0][0] = c + temp[0] * axis[0];
+ rot.m[0][1] = temp[0] * axis[1] + s * axis[2];
+ rot.m[0][2] = temp[0] * axis[2] - s * axis[1];
+
+ rot.m[1][0] = temp[1] * axis[0] - s * axis[2];
+ rot.m[1][1] = c + temp[1] * axis[1];
+ rot.m[1][2] = temp[1] * axis[2] + s * axis[0];
+
+ rot.m[2][0] = temp[2] * axis[0] + s * axis[1];
+ rot.m[2][1] = temp[2] * axis[1] - s * axis[0];
+ rot.m[2][2] = c + temp[2] * axis[2];
+
+ glm_mat4##tag dst;
+ dst.m[0] = m[0] * rot.m[0][0] + m[1] * rot.m[0][1] + m[2] * rot.m[0][2];
+ dst.m[1] = m[0] * rot.m[1][0] + m[1] * rot.m[1][1] + m[2] * rot.m[1][2];
+ dst.m[2] = m[0] * rot.m[2][0] + m[1] * rot.m[2][1] + m[2] * rot.m[2][2];
+ dst.m[3] = m[3];
+ return dst;
+ }
+
+
+ static inline glm_mat4##tag scale(glm_mat4##tag##m m, glm_vec3##tag v)
+ {
+ glm_mat4##tag dst;
+ dst.m[0] = m[0] * v[0];
+ dst.m[1] = m[1] * v[1];
+ dst.m[2] = m[2] * v[2];
+ dst.m[3] = m[3];
+ return dst;
+ }
+
+ static inline glm_mat4##tag lookAtRH(glm_vec3##tag eye, glm_vec3##tag center, glm_vec3##tag up)
+ {
+ const glm_vec3##tag f(normalize(center - eye));
+ const glm_vec3##tag s(normalize(cross(f, up)));
+ const glm_vec3##tag u(cross(s, f));
+
+ glm_mat4##tag dst(1);
+ dst.m[0][0] = s.x;
+ dst.m[1][0] = s.y;
+ dst.m[2][0] = s.z;
+ dst.m[0][1] = u.x;
+ dst.m[1][1] = u.y;
+ dst.m[2][1] = u.z;
+ dst.m[0][2] =-f.x;
+ dst.m[1][2] =-f.y;
+ dst.m[2][2] =-f.z;
+ dst.m[3][0] =-dot(s, eye);
+ dst.m[3][1] =-dot(u, eye);
+ dst.m[3][2] = dot(f, eye);
+ return dst;
+ }
+
+}//namespace glm
diff --git a/glm/vec3.h b/glm/vec3.h
new file mode 100644
index 00000000..fb66ce42
--- /dev/null
+++ b/glm/vec3.h
@@ -0,0 +1,219 @@
+// MIT License
+//
+// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#ifndef GLM_VEC3__H__
+#define GLM_VEC3__H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <math.h>
+
+#define glm_sqrt_f(x) sqrtf(x)
+#define glm_sqrt_d(x) sqrt(x)
+#define glm_sin_f(x) sinf(x)
+#define glm_sin_d(x) sin(x)
+#define glm_cos_f(x) cosf(x)
+#define glm_cos_d(x) cos(x)
+#define glm_atan2_f(x, y) atan2f(x, y)
+#define glm_atan2_d(x, y) atan2(x, y)
+
+#ifdef GLM_NO_ANONYMOUS_STRUCT
+#define _glm_VEC3(tag, T) struct glm_vec3##tag { T x, y, z; }
+#else
+#define _glm_VEC3(tag, T) union glm_vec3##tag { struct { T x, y, z; }; T arr[3]; }
+#endif
+
+#define glm_vec3_arr(v) (&(v).x)
+#define glm_vec3f_zero ((glm_vec3f) {0.f, 0.f, 0.f})
+#define glm_vec3d_zero ((glm_vec3d) {0.0, 0.0, 0.0})
+
+#define declare_glm_vec3(tag, T) \
+ typedef _glm_VEC3(tag, T) glm_vec3##tag; \
+ static glm_vec3##tag \
+ glm_vec3##tag##_axis[3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; \
+ \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_init(T x, T y, T z) { return (glm_vec3##tag) {x, y, z}; } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_fromArray(const T* a) { return (glm_vec3##tag) {a[0], a[1], a[2]}; } \
+ \
+ static inline glm_vec3##tag* \
+ glm_vec3##tag##_assign(glm_vec3##tag* self, T x, T y, T z) { \
+ self->x = x, self->y = y, self->z = z; return self; \
+ } \
+ static inline glm_vec3##tag* \
+ glm_vec3##tag##_assignArray(glm_vec3##tag* self, const T* a) { \
+ self->x = a[0], self->y = a[1], self->z = a[2]; return self; \
+ } \
+ static inline glm_vec3##tag* \
+ glm_vec3##tag##_add(glm_vec3##tag* self, glm_vec3##tag v) { \
+ self->x += v.x, self->y += v.y, self->z += v.z; return self; \
+ } \
+ static inline glm_vec3##tag* \
+ glm_vec3##tag##_sub(glm_vec3##tag* self, glm_vec3##tag v) { \
+ self->x -= v.x, self->y -= v.y, self->z -= v.z; return self; \
+ } \
+ static inline glm_vec3##tag* \
+ glm_vec3##tag##_scale(glm_vec3##tag* self, T s) { \
+ self->x *= s, self->y *= s, self->z *= s; return self; \
+ } \
+ static inline T \
+ glm_vec3##tag##_length(glm_vec3##tag v) { \
+ return glm_sqrt_##tag(_glm_vec3_DOT(v, v)); \
+ } \
+ static inline T \
+ glm_vec3##tag##_length2(glm_vec3##tag v) { \
+ return _glm_vec3_DOT(v, v); \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_plus(glm_vec3##tag u, glm_vec3##tag v) { \
+ u.x += v.x, u.y += v.y, u.z += v.z; return u; \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_minus(glm_vec3##tag u, glm_vec3##tag v) { \
+ u.x -= v.x, u.y -= v.y, u.z -= v.z; return u; \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_mult(glm_vec3##tag v, T s) { \
+ v.x *= s, v.y *= s, v.z *= s; return v; \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_neg(glm_vec3##tag v) { \
+ v.x = -v.x, v.y = -v.y, v.z = -v.z; return v; \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_unit(glm_vec3##tag v) { \
+ T s = 1.0f / glm_sqrt_##tag(_glm_vec3_DOT(v, v)); \
+ s; v.x *= s, v.y *= s, v.z *= s; \
+ return v; \
+ } \
+ static inline T \
+ glm_vec3##tag##_dot(glm_vec3##tag u, glm_vec3##tag v) { \
+ return _glm_vec3_DOT(u, v); \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_cross(glm_vec3##tag u, glm_vec3##tag v) { \
+ return (glm_vec3##tag) {_glm_vec3_CROSS(u, v)}; \
+ } \
+ static inline T \
+ glm_vec3##tag##_triple(glm_vec3##tag u, glm_vec3##tag v, glm_vec3##tag w) { \
+ glm_vec3##tag cross = {_glm_vec3_CROSS(u, v)}; \
+ return _glm_vec3_DOT(cross, w); \
+ } \
+ /* Reflect u on plane with given normal vector pn */ \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_reflect(glm_vec3##tag u, glm_vec3##tag pn) { \
+ T dot2 = 2.0f * _glm_vec3_DOT(u, pn); \
+ u.x -= dot2 * pn.x, u.y -= dot2 * pn.y, u.z -= dot2 * pn.z; \
+ return u; \
+ } \
+ /* Refract u incident on plane with given normal vector pn */ \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_refract(glm_vec3##tag u, glm_vec3##tag pn, T eta) { \
+ T dot = _glm_vec3_DOT(pn, u); \
+ T k = 1.0f - eta * eta * (1.0f - dot * dot); \
+ if (k < 0.0f) return glm_vec3##tag##_zero; \
+ glm_vec3##tag##_scale(&u, eta); \
+ glm_vec3##tag##_scale(&pn, eta * dot + glm_sqrt_##tag(k)); \
+ return *glm_vec3##tag##_sub(&u, pn); \
+ } \
+ static inline T \
+ glm_vec3##tag##_distance(glm_vec3##tag u, glm_vec3##tag v) { \
+ u.x -= v.x, u.y -= v.y, u.z -= v.z; \
+ return glm_sqrt_##tag(_glm_vec3_DOT(u, u)); \
+ } \
+ /* Signed distance between point u and a plane (pp, pn), pn normalized. */ \
+ static inline T \
+ glm_vec3##tag##_distanceToPlane(glm_vec3##tag u, glm_vec3##tag pp, glm_vec3##tag pn) { \
+ u.x -= pp.x, u.y -= pp.y, u.z -= pp.z; \
+ return _glm_vec3_DOT(u, pn); \
+ } \
+ /* Linear interpolation */ \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_lerp(glm_vec3##tag u, glm_vec3##tag v, T t) { \
+ T s = 1.0f - t; \
+ u.x = s*u.x + t*v.x, u.y = s*u.y + t*v.y, u.z = s*u.z + t*v.z; \
+ return u; \
+ } \
+ /* Swizzle */ \
+ glm_vec3##tag##_xzy(glm_vec3##tag u) { \
+ return (glm_vec3##tag) {u.x, u.z, u.y}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_yxz(glm_vec3##tag u) { \
+ return (glm_vec3##tag) {u.y, u.x, u.z}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_yzx(glm_vec3##tag u) { \
+ return (glm_vec3##tag) {u.y, u.z, u.x}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_zxy(glm_vec3##tag u) { \
+ return (glm_vec3##tag) {u.z, u.x, u.y}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_zyx(glm_vec3##tag u) { \
+ return (glm_vec3##tag) {u.z, u.y, u.x}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec3##tag##_swizzle(glm_vec3##tag u, const char* swz) { \
+ T* a = glm_vec3_arr(u); \
+ return (glm_vec3##tag) {a[swz[0] - 'x'], a[swz[1] - 'x'], a[swz[2] - 'x']}; \
+ } \
+ static inline bool \
+ glm_vec3##tag##_rayPlaneIntersection(glm_vec3##tag* out, glm_vec3##tag u, glm_vec3##tag dir, \
+ glm_vec3##tag pp, glm_vec3##tag pn) { \
+ T d = _glm_vec3_DOT(dir, pn); if (d == 0) return false; \
+ T t = (_glm_vec3_DOT(pp, pn) - _glm_vec3_DOT(u, pn)) / d; \
+ if (t < 0) return false; \
+ u.x += dir.x*t, u.y += dir.y*t, u.z += dir.z*t; \
+ *out = u; return true; \
+ } \
+ static inline bool \
+ glm_vec3##tag##_equals(glm_vec3##tag u, glm_vec3##tag v) { \
+ if (u.x != v.x) return false; \
+ if (u.y != v.y) return false; \
+ return u.z == v.z; \
+ } \
+ static inline int \
+ glm_vec3##tag##_compare(glm_vec3##tag* u, glm_vec3##tag* v) { \
+ if (u->x != v->x) return 1 - ((u->x < v->x)<<1); \
+ if (u->y != v->y) return 1 - ((u->y < v->y)<<1); \
+ return u->z == v->z ? 0 : 1 - ((u->z < v->z)<<1); \
+ } \
+ typedef T glm_vec3##tag##_value_t
+
+#define _glm_vec3_DOT(u, v) (u.x*v.x + u.y*v.y + u.z*v.z)
+#define _glm_vec3_SUB(u, v) u.x - v.x, u.y - v.y, u.z - v.z
+#define _glm_vec3_CROSS(u, v) u.y*v.z - v.y*u.z, u.z*v.x - v.z*u.x, u.x*v.y - u.y*v.x
+
+declare_glm_vec3(d, double);
+declare_glm_vec3(f, float);
+
+static inline glm_vec3f glm_vec3d_tof(glm_vec3d v) {
+ return (glm_vec3f) {(float) v.x, (float) v.y, (float) v.z};
+}
+static inline glm_vec3d glm_vec3f_tod(glm_vec3f v) {
+ return (glm_vec3d) {v.x, v.y, v.z};
+}
+
+#endif
diff --git a/glm/vec4.h b/glm/vec4.h
new file mode 100644
index 00000000..2ef0d2ea
--- /dev/null
+++ b/glm/vec4.h
@@ -0,0 +1,190 @@
+// MIT License
+//
+// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#ifndef GLM_VEC4__H__
+#define GLM_VEC4__H__
+
+#include "vec3.h"
+
+#ifdef GLM_NO_ANONYMOUS_STRUCT
+#define _glm_VEC4(tag, T) struct glm_vec4##tag { T x, y, z, w; }
+#else
+#define _glm_VEC4(tag, T) union glm_vec4##tag { struct { T x, y, z, w; }; T arr[4]; }
+#endif
+
+#define glm_vec4_arr(v) (&(v).x)
+#define glm_vec4f_zero ((glm_vec4f) {0.f, 0.f, 0.f, 0.f})
+#define glm_vec4d_zero ((glm_vec4d) {0.0, 0.0, 0.0, 0.0})
+
+#define declare_glm_vec4(tag, T) \
+ typedef _glm_VEC4(tag, T) glm_vec4##tag; \
+ static glm_vec4##tag glm_vec4##tag##_axis[4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; \
+ \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_init(T x, T y, T z, T w) { return (glm_vec4##tag) {x, y, z, w}; } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_fromArray(const T* a) { return (glm_vec4##tag) {a[0], a[1], a[2], a[3]}; } \
+ \
+ static inline glm_vec4##tag* \
+ glm_vec4##tag##_assign(glm_vec4##tag* self, T x, T y, T z, T w) { \
+ self->x = x, self->y = y, self->z = z, self->z = z, self->w = w; return self; \
+ } \
+ static inline glm_vec4##tag* \
+ glm_vec4##tag##_assignArray(glm_vec4##tag* self, const T* a) { \
+ self->x = a[0], self->y = a[1], self->z = a[2], self->w = a[3]; return self; \
+ } \
+ static inline glm_vec4##tag* \
+ glm_vec4##tag##_add(glm_vec4##tag* self, glm_vec4##tag v) { \
+ self->x += v.x, self->y += v.y, self->z += v.z, self->w += v.w; return self; \
+ } \
+ static inline glm_vec4##tag* \
+ glm_vec4##tag##_sub(glm_vec4##tag* self, glm_vec4##tag v) { \
+ self->x -= v.x, self->y -= v.y, self->z -= v.z, self->w -= v.w; return self; \
+ } \
+ static inline glm_vec4##tag* \
+ glm_vec4##tag##_scale(glm_vec4##tag* self, T s) { \
+ self->x *= s, self->y *= s, self->z *= s, self->w *= s; return self; \
+ } \
+ static inline T \
+ glm_vec4##tag##_length(glm_vec4##tag v) { \
+ return glm_sqrt_##tag(_glm_vec4_DOT(v, v)); \
+ } \
+ static inline T \
+ glm_vec4##tag##_length2(glm_vec4##tag v) { \
+ return _glm_vec4_DOT(v, v); \
+ } \
+ static inline T \
+ glm_vec4##tag##_distance(glm_vec4##tag u, glm_vec4##tag v) { \
+ u.x -= v.x, u.y -= v.y, u.z -= v.z, u.w -= v.w; \
+ return glm_sqrt_##tag(_glm_vec4_DOT(u, u)); \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_plus(glm_vec4##tag u, glm_vec4##tag v) { \
+ u.x += v.x, u.y += v.y, u.z += v.z, u.w += v.w; return u; \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_minus(glm_vec4##tag u, glm_vec4##tag v) { \
+ u.x -= v.x, u.y -= v.y, u.z -= v.z, u.w -= v.w; return u; \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_mult(glm_vec4##tag v, T s) { \
+ v.x *= s, v.y *= s, v.z *= s, v.w *= s; return v; \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_neg(glm_vec4##tag v) { \
+ v.x = -v.x, v.y = -v.y, v.z = -v.z, v.w = -v.w; return v; \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_unit(glm_vec4##tag v) { \
+ T s = glm_sqrt_##tag(_glm_vec4_DOT(v, v)); \
+ if (s < 1e-8) return glm_vec4##tag##_zero; \
+ s = 1.0f / s; v.x *= s, v.y *= s, v.z *= s, v.w *= s; \
+ return v; \
+ } \
+ static inline T \
+ glm_vec4##tag##_dot(glm_vec4##tag u, glm_vec4##tag v) { \
+ return _glm_vec4_DOT(u, v); \
+ } \
+ static inline glm_vec4##tag \
+ glm_vec3##tag##_xyzw(glm_vec3##tag u, T w) { \
+ return (glm_vec4##tag) {u.x, u.y, u.z, w}; \
+ } \
+ /* Swizzle */ \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_xyz(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.x, u.y, u.z}; \
+ }; \
+ glm_vec4##tag##_xzy(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.x, u.z, u.y}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_yxz(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.y, u.x, u.z}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_yzx(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.y, u.z, u.x}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_zxy(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.z, u.x, u.y}; \
+ }; \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_zyx(glm_vec4##tag u) { \
+ return (glm_vec3##tag) {u.z, u.y, u.x}; \
+ }; \
+ \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_swizzle(glm_vec4##tag u, const char* swz) { \
+ const T* a = glm_vec4_arr(u); \
+ return (glm_vec4##tag) {a[(swz[0] - 'x') & 3], \
+ a[(swz[1] - 'x') & 3], \
+ a[(swz[2] - 'x') & 3], \
+ a[(swz[3] - 'x') & 3]}; \
+ } \
+ static inline glm_vec3##tag \
+ glm_vec4##tag##_swizzle3(glm_vec4##tag u, const char* swz) { \
+ const T* a = glm_vec4_arr(u); \
+ return (glm_vec3##tag) {a[(swz[0] - 'x') & 3], \
+ a[(swz[1] - 'x') & 3], \
+ a[(swz[2] - 'x') & 3]}; \
+ } \
+ /* Linear interpolation */ \
+ static inline glm_vec4##tag \
+ glm_vec4##tag##_lerp(glm_vec4##tag u, glm_vec4##tag v, T t) { \
+ T s = 1.0f - t; \
+ u.x = s*u.x + t*v.x, u.y = s*u.y + t*v.y, \
+ u.z = s*u.z + t*v.z, u.w = s*u.w + t*v.w; \
+ return u; \
+ } \
+ static inline bool \
+ glm_vec4##tag##_equals(glm_vec4##tag u, glm_vec4##tag v) { \
+ if (u.x != v.x) return false; \
+ if (u.y != v.y) return false; \
+ if (u.z != v.z) return false; \
+ return u.w == v.w; \
+ } \
+ static inline int \
+ glm_vec4##tag##_compare(glm_vec4##tag* u, glm_vec4##tag* v) { \
+ if (u->x != v->x) return 1 - ((u->x < v->x)<<1); \
+ if (u->y != v->y) return 1 - ((u->y < v->y)<<1); \
+ if (u->z != v->z) return 1 - ((u->z < v->z)<<1); \
+ return u->w == v->w ? 0 : 1 - ((u->w < v->w)<<1); \
+ } \
+ typedef T glm_vec4##tag##_value_t
+
+#define _glm_vec4_DOT(u, v) (u.x*v.x + u.y*v.y + u.z*v.z + u.w*v.w)
+#define _glm_vec4_SUB(u, v) u.x - v.x, u.y - v.y, u.z - v.z, u.w - v.w
+
+declare_glm_vec4(d, double);
+declare_glm_vec4(f, float);
+
+static inline glm_vec4d
+glm_vec4f_tod(glm_vec4f v) {
+ return (glm_vec4d) {v.x, v.y, v.z, v.w};
+}
+static inline glm_vec4f
+glm_vec4d_tof(glm_vec4d v) {
+ return (glm_vec4f) {(float) v.x, (float) v.y, (float) v.z, (float) v.w};
+}
+
+#endif
diff --git a/stc/carray.h b/stc/carray.h
index bb70c856..c2151875 100644
--- a/stc/carray.h
+++ b/stc/carray.h
@@ -1,25 +1,25 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#ifndef CARRAY__H__
#define CARRAY__H__
diff --git a/stc/cdefs.h b/stc/cdefs.h
index f58eeeee..fa127c28 100644
--- a/stc/cdefs.h
+++ b/stc/cdefs.h
@@ -1,32 +1,32 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#ifndef CDEFS__H__
#define CDEFS__H__
#include <stdint.h>
#include <stdbool.h>
-// Macro overloading feature support: https://rextester.com/ONP80107
+/* Macro overloading feature support: https://rextester.com/ONP80107 */
#define c_CAT( A, B ) A ## B
#define c_EXPAND(...) __VA_ARGS__
#define c_VA_ARG_SIZE(...) c_EXPAND(c_APPLY_ARG_N((__VA_ARGS__, c_RSEQ_N)))
@@ -48,6 +48,7 @@
#define c_defaultInitRaw(x) (x)
#define c_defaultGetRaw(x) (x)
+#define c_noCompare(x, y) 0
#define c_defaultCompare(x, y) (*(x) == *(y) ? 0 : *(x) < *(y) ? -1 : 1)
#define c_defaultEquals(x, y) (memcmp(x, y, sizeof(*(y))) == 0)
#define c_defaultDestroy(p) ((void)0)
@@ -55,7 +56,7 @@
#define c_foreach(it, ctag, con) \
for (ctag##_iter_t it = ctag##_begin(con); it.item != ctag##_end(con).item; it = ctag##_next(it))
-// One-byte-at-a-time hash based on Murmur's mix
+/* One-byte-at-a-time hash based on Murmur's mix */
static inline uint32_t c_defaultHash(const void *data, size_t len) {
const uint8_t *key = (const uint8_t *) data;
uint32_t x = UINT32_C(0xc613fc15);
@@ -67,7 +68,7 @@ static inline uint32_t c_defaultHash(const void *data, size_t len) {
return x;
}
-// https://nullprogram.com/blog/2018/07/31/: assume len positive multiple of 4
+/* https://nullprogram.com/blog/2018/07/31/: assume len positive multiple of 4 */
static inline uint32_t c_lowbias32Hash(const void *data, size_t len) {
const uint32_t *key = (const uint32_t *) data; uint32_t x = *key;
do {
diff --git a/stc/clist.h b/stc/clist.h
new file mode 100644
index 00000000..34858b86
--- /dev/null
+++ b/stc/clist.h
@@ -0,0 +1,199 @@
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef CLIST__H__
+#define CLIST__H__
+
+#include "cdefs.h"
+
+/* Circular Singly-linked Lists */
+
+#define clist_init {NULL, 0}
+#define clist_size(list) ((size_t) (list).size)
+
+#define declare_CList(...) c_MACRO_OVERLOAD(declare_CList, __VA_ARGS__)
+
+#define declare_CList_2(tag, Value) \
+ declare_CList_3(tag, Value, c_defaultDestroy)
+#define declare_CList_3(tag, Value, valueDestroy) \
+ declare_CList_4(tag, Value, valueDestroy, c_defaultCompare)
+#define declare_CList_4(tag, Value, valueDestroy, valueCompare) \
+ declare_CList_6(tag, Value, valueDestroy, valueCompare, Value, c_defaultGetRaw)
+#define declare_CList_string(tag) \
+ declare_CList_6(tag, CString, cstring_destroy, cstring_compareRaw, const char*, cstring_getRaw)
+
+
+#define declare_CListTypes(tag, Value) \
+ c_struct (CListNode_##tag) { \
+ CListNode_##tag *next; \
+ Value value; \
+ }; \
+ \
+ c_struct (CList_##tag) { \
+ CListNode_##tag* last; \
+ size_t size; \
+ }; \
+ \
+ c_struct (clist_##tag##_iter_t) { \
+ CListNode_##tag *item, *head; \
+ }
+
+
+#define declare_CList_6(tag, Value, valueDestroy, valueCompare, ValueRaw, valueGetRaw) \
+ \
+ declare_CListTypes(tag, Value); \
+ \
+ static inline void \
+ clist_##tag##_pushFront(CList_##tag* self, Value value) { \
+ _clist_pushAfter(tag, self->last, value); \
+ if (!self->last) self->last = entry; \
+ } \
+ static inline void \
+ clist_##tag##_pushBack(CList_##tag* self, Value value) { \
+ _clist_pushAfter(tag, self->last, value); \
+ self->last = entry; \
+ } \
+ static inline void \
+ clist_##tag##_pushAfter(CList_##tag* self, clist_##tag##_iter_t pos, Value value) { \
+ _clist_pushAfter(tag, pos.item, value); \
+ if (!self->last || pos.item == self->last) self->last = entry; \
+ } \
+ \
+ static inline void \
+ clist_##tag##_popFront(CList_##tag* self) { \
+ CListNode_##tag* del = self->last->next, *next = del->next; \
+ --self->size; \
+ if (next == del) self->last = NULL; \
+ else self->last->next = next; \
+ valueDestroy(&del->value); \
+ free(del); \
+ } \
+ \
+ static inline void \
+ clist_##tag##_destroy(CList_##tag* self) { \
+ while (clist_size(*self)) \
+ clist_##tag##_popFront(self); \
+ } \
+ \
+ static inline clist_##tag##_iter_t \
+ clist_##tag##_begin(CList_##tag lst) { \
+ CListNode_##tag *head = lst.last ? lst.last->next : NULL; \
+ return (clist_##tag##_iter_t) {head, head}; \
+ } \
+ \
+ static inline clist_##tag##_iter_t \
+ clist_##tag##_next(clist_##tag##_iter_t it) { \
+ CListNode_##tag *next = it.item->next; \
+ it.item = next != it.head ? next : NULL; \
+ return it; \
+ } \
+ \
+ static inline clist_##tag##_iter_t \
+ clist_##tag##_end(CList_##tag lst) { \
+ return (clist_##tag##_iter_t) {NULL}; \
+ } \
+ \
+ static inline int \
+ clist_##tag##_sortCompare(const void* x, const void* y) { \
+ CListNode_##tag *a = (CListNode_##tag *)x, *b = (CListNode_##tag *)y; \
+ return valueCompare(valueGetRaw(&a->value), valueGetRaw(&b->value)); \
+ } \
+ \
+ static inline void \
+ clist_##tag##_sort(CList_##tag* self) { \
+ CListNode__i* last = clist_sort((CListNode__i *) self->last, clist_##tag##_sortCompare); \
+ self->last = (CListNode_##tag *) last; \
+ } \
+ \
+ typedef Value clist_##tag##_value_t
+
+
+#define _clist_pushAfter(tag, node, val) \
+ CListNode_##tag *entry = c_new_1(CListNode_##tag), \
+ *next = self->last ? node->next : entry; \
+ entry->value = val; \
+ entry->next = next; \
+ ++self->size; \
+ if (node) node->next = entry
+
+
+declare_CListTypes(_i, int);
+
+/*
+ * Singly linked list Mergesort implementation by Simon Tatham. O(n*log(n)).
+ * https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
+ */
+static CListNode__i *
+clist_sort(CListNode__i *list, int (*cmp)(const void*, const void*)) {
+ CListNode__i *p, *q, *e, *tail, *oldhead;
+ int insize = 1, nmerges, psize, qsize, i;
+ if (!list) return NULL;
+
+ while (1) {
+ p = list;
+ oldhead = list;
+ list = tail = NULL;
+ nmerges = 0;
+
+ while (p) {
+ ++nmerges;
+ q = p;
+ psize = 0;
+ for (i = 0; i < insize; ++i) {
+ ++psize;
+ q = (q->next == oldhead ? NULL : q->next);
+ if (!q) break;
+ }
+ qsize = insize;
+
+ while (psize > 0 || (qsize > 0 && q)) {
+ if (psize == 0) {
+ e = q; q = q->next; --qsize;
+ if (q == oldhead) q = NULL;
+ } else if (qsize == 0 || !q) {
+ e = p; p = p->next; --psize;
+ if (p == oldhead) p = NULL;
+ } else if (cmp(p, q) <= 0) {
+ e = p; p = p->next; --psize;
+ if (p == oldhead) p = NULL;
+ } else {
+ e = q; q = q->next; --qsize;
+ if (q == oldhead) q = NULL;
+ }
+ if (tail)
+ tail->next = e;
+ else
+ list = e;
+ tail = e;
+ }
+ p = q;
+ }
+ tail->next = list;
+
+ if (nmerges <= 1)
+ return tail;
+
+ insize *= 2;
+ }
+}
+
+#endif
diff --git a/stc/cmap.h b/stc/cmap.h
index 576a01d3..f547922e 100644
--- a/stc/cmap.h
+++ b/stc/cmap.h
@@ -1,27 +1,27 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#ifndef CMAP_H_
-#define CMAP_H_
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef CMAP__H__
+#define CMAP__H__
#include "cvector.h"
@@ -31,7 +31,7 @@
#define cmap_bucketCount(map) cvector_capacity((map)._table)
-// CMapEntry:
+/* CMapEntry: */
#define declare_CMapEntry(tag, Key, Value, valueDestroy, keyDestroy) \
struct CMapEntry_##tag { \
Key key; \
@@ -55,7 +55,7 @@ enum {cmapentry_HASH=0x7fff, cmapentry_USED=0x8000};
#define cmapentry_noCompare(x, y) (0)
-// CMap:
+/* CMap: */
#define declare_CMap(...) c_MACRO_OVERLOAD(declare_CMap, __VA_ARGS__)
#define declare_CMap_3(tag, Key, Value) \
@@ -72,7 +72,7 @@ enum {cmapentry_HASH=0x7fff, cmapentry_USED=0x8000};
Key, c_defaultGetRaw, c_defaultInitRaw)
-// CMap<CString, Value>:
+/* CMap<CString, Value>: */
#define declare_CMap_stringkey(...) c_MACRO_OVERLOAD(declare_CMap_stringkey, __VA_ARGS__)
#define declare_CMap_stringkey_2(tag, Value) \
@@ -83,7 +83,7 @@ enum {cmapentry_HASH=0x7fff, cmapentry_USED=0x8000};
const char* const, cstring_getRaw, cstring_make)
-// CMap full:
+/* CMap full: */
#define declare_CMap_10(tag, Key, Value, valueDestroy, keyHashRaw, keyEqualsRaw, keyDestroy, \
RawKey, keyGetRaw, keyInitRaw) \
declare_CMapEntry(tag, Key, Value, valueDestroy, keyDestroy); \
@@ -269,7 +269,7 @@ typedef Key cmap_##tag##_key_t; \
typedef Value cmap_##tag##_value_t
-// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
+/* https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction */
static inline uint32_t cmap_reduce(uint32_t x, uint32_t N) {
return ((uint64_t) x * (uint64_t) N) >> 32 ;
}
diff --git a/stc/copt.h b/stc/copt.h
index 5c512698..3dda284f 100644
--- a/stc/copt.h
+++ b/stc/copt.h
@@ -1,28 +1,30 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
-// Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c
-// Fixed major bugs with option arguments (both long and short), and shows a useful demo of the features.
-// Has a more consistent API, added arg->bad output field, written in C99.
+/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c
+ * Fixed major bugs with option arguments (both long and short), and shows a useful demo of the features.
+ * Has a more consistent API, added arg->bad output field, written in C99.
+ */
#ifndef COPT__H__
#define COPT__H__
@@ -36,11 +38,11 @@ enum {
copt_optional_argument = 2
};
typedef struct {
- int ind; // equivalent to optind
- int opt; // equivalent to optopt
- char *arg; // equivalent to optarg
- char *bad; // points to the faulty option
- int longindex; // idx of long option; or -1 if short
+ int ind; /* equivalent to optind */
+ int opt; /* equivalent to optopt */
+ char *arg; /* equivalent to optarg */
+ char *bad; /* points to the faulty option */
+ int longindex; /* idx of long option; or -1 if short */
int _i, _pos, _nargs;
char _bad[4];
} copt_t;
@@ -53,7 +55,7 @@ struct copt_option {
static const copt_t copt_init = {1, 0, NULL, NULL, -1, 1, 0, 0, {'-', 0, 0, 0}};
-static void _copt_permute(char *argv[], int j, int n) { // move argv[j] over n elements to the left
+static void _copt_permute(char *argv[], int j, int n) { /* move argv[j] over n elements to the left */
int k;
char *p = argv[j];
for (k = 0; k < n; ++k)
@@ -62,21 +64,21 @@ static void _copt_permute(char *argv[], int j, int n) { // move argv[j] over n e
}
-// Parse command-line options and arguments
-//
-// This fuction has a similar interface to GNU's getopt_long(). Each call
-// parses one option and returns the option name. opt->arg points to the option
-// argument if present. The function returns -1 when all command-line arguments
-// are parsed. In this case, opt->ind is the index of the first non-option
-// argument.
-//
-// @param opt output; must be initialized to copt_init on first call
-// @param posixly_correct if true, do not move options ahead of non-option arguments,
-// instead stop option processing on first nonoption argument.
-// @return ASCII val for a short option; longopt.val for a long option;
-// -1 if argv[] is fully processed; '?' for an unknown option or
-// an ambiguous long option; ':' if an option argument is missing
-//
+/* Parse command-line options and arguments
+ *
+ * This fuction has a similar interface to GNU's getopt_long(). Each call
+ * parses one option and returns the option name. opt->arg points to the option
+ * argument if present. The function returns -1 when all command-line arguments
+ * are parsed. In this case, opt->ind is the index of the first non-option
+ * argument.
+ *
+ * @param opt output; must be initialized to copt_init on first call
+ * @param posixly_correct if true, do not move options ahead of non-option arguments,
+ * instead stop option processing on first nonoption argument.
+ * @return ASCII val for a short option; longopt.val for a long option;
+ * -1 if argv[] is fully processed; '?' for an unknown option or
+ * an ambiguous long option; ':' if an option argument is missing
+ */
static int copt_getopt(copt_t *opt, int argc, char *argv[],
const char *shortopts, const struct copt_option *longopts,
bool posixly_correct) {
@@ -90,17 +92,17 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[],
opt->ind = opt->_i - opt->_nargs;
return -1;
}
- if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { // "--" or a long option
- if (argv[opt->_i][2] == '\0') { // a bare "--"
+ if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */
+ if (argv[opt->_i][2] == '\0') { /* a bare "--" */
_copt_permute(argv, opt->_i, opt->_nargs);
++opt->_i, opt->ind = opt->_i - opt->_nargs;
return -1;
}
opt->opt = 0, optc = '?', opt->_pos = -1;
- if (longopts) { // parse long options
+ if (longopts) { /* parse long options */
int k, n_exact = 0, n_partial = 0;
const struct copt_option *o = 0, *o_exact = 0, *o_partial = 0;
- for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} // find the end of the option name
+ for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} /* find the end of the option name */
for (k = 0; longopts[k].name != 0; ++k)
if (strncmp(&argv[opt->_i][2], longopts[k].name, j - 2) == 0) {
if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k];
@@ -118,18 +120,18 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[],
argv[opt->_i + 1][0] != '-'))
opt->arg = argv[++opt->_i];
else if (o->has_arg == copt_required_argument)
- optc = ':'; // missing option argument
+ optc = ':'; /* missing option argument */
}
}
}
- } else { // a short option
+ } else { /* a short option */
const char *p;
if (opt->_pos == 0) opt->_pos = 1;
optc = opt->opt = argv[opt->_i][opt->_pos++];
opt->_bad[1] = optc, opt->bad = opt->_bad;
p = strchr((char *) shortopts, optc);
if (p == 0) {
- optc = '?'; // unknown option
+ optc = '?'; /* unknown option */
} else if (p[1] == ':') {
if (argv[opt->_i][opt->_pos] != '\0')
opt->arg = &argv[opt->_i][opt->_pos];
@@ -142,7 +144,7 @@ static int copt_getopt(copt_t *opt, int argc, char *argv[],
}
if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) {
++opt->_i, opt->_pos = 0;
- if (opt->_nargs > 0) // permute
+ if (opt->_nargs > 0) /* permute */
for (j = i0; j < opt->_i; ++j)
_copt_permute(argv, j, opt->_nargs);
}
diff --git a/stc/cquat.h b/stc/cquat.h
deleted file mode 100644
index 928d475a..00000000
--- a/stc/cquat.h
+++ /dev/null
@@ -1,206 +0,0 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#ifndef CQUAT__H__
-#define CQUAT__H__
-
-#include "cmat4.h"
-
-#define cquat_arr(q) (&(q).x)
-#define cquatf_identity ((CQuatf) {0.f, 0.f, 0.f, 1.f})
-#define cquatd_identity ((CQuatd) {0.0, 0.0, 0.0, 1.0})
-
-#define declare_CQuat(tag, T) \
- typedef CVec4##tag CQuat##tag; \
- \
- static inline CQuat##tag \
- cquat##tag(T x, T y, T z, T w) { return (CQuat##tag) {x, y, z, w}; } \
- \
- static inline CQuat##tag \
- cquat##tag##_unit(CQuat##tag q) { \
- T dot = _cvec4_DOT(q, q); \
- if (dot <= 0.0f) return cquat##tag##_identity; \
- return cvec4##tag##_mult(q, 1.0f / c_sqrt_##tag(dot)); \
- } \
- \
- static inline CQuat##tag \
- cquat##tag##_fromAxis(T angle, CVec3##tag axis) { \
- T a = angle * 0.5f, c = c_cos_##tag(a), s = c_sin_##tag(a); \
- CVec3##tag u = cvec3##tag##_unit(axis); \
- return (CQuat##tag) {s * u.x, s * u.y, s * u.z, c}; \
- } \
- \
- static inline CQuat##tag \
- cquat##tag##_fromVectors(CVec3##tag u, CVec3##tag v) { \
- T d = c_sqrt_##tag(_cvec3_DOT(u, u) * _cvec3_DOT(v, v)); \
- T real_part = d + _cvec3_DOT(u, v); \
- CVec3##tag t; \
- if (real_part < 1.e-6f * d) { \
- /* If u and v are exactly opposite, rotate 180 degrees */ \
- /* around an arbitrary orthogonal axis. */ \
- real_part = 0; \
- t = fabs(u.x) > fabs(u.z) ? (CVec3##tag) {-u.y, u.x, 0} : (CVec3##tag) {0, -u.z, u.y}; \
- } else /* Build quaternion the standard way.*/ \
- t = _cvec3_CROSS(u, v); \
- CQuat##tag q = (CQuat##tag) {t.x, t.y, t.z, real_part}; \
- return cquat##tag##_unit(q); \
- } \
- \
- static inline CQuat##tag \
- cquat##tag##_fromMat4(CMat4##tag##ConstRef m) { \
- T trace = m[0][0] + m[1][1] + m[2][2], r, rinv; \
- CQuat##tag dst; \
- if (trace >= 0.0f) { \
- r = c_sqrt_##tag(1.0f + trace); \
- rinv = 0.5f / r; \
- dst.x = rinv * (m[1][2] - m[2][1]); \
- dst.y = rinv * (m[2][0] - m[0][2]); \
- dst.z = rinv * (m[0][1] - m[1][0]); \
- dst.w = r * 0.5f; \
- } else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) { \
- r = c_sqrt_##tag(1.0f + m[0][0] - m[1][1] - m[2][2]); \
- rinv = 0.5f / r; \
- dst.x = r * 0.5f; \
- dst.y = rinv * (m[0][1] + m[1][0]); \
- dst.z = rinv * (m[0][2] + m[2][0]); \
- dst.w = rinv * (m[1][2] - m[2][1]); \
- } else if (m[1][1] >= m[2][2]) { \
- r = c_sqrt_##tag(1.0f - m[0][0] + m[1][1] - m[2][2]); \
- rinv = 0.5f / r; \
- dst.x = rinv * (m[0][1] + m[1][0]); \
- dst.y = r * 0.5f; \
- dst.z = rinv * (m[1][2] + m[2][1]); \
- dst.w = rinv * (m[2][0] - m[0][2]); \
- } else { \
- r = c_sqrt_##tag(1.0f - m[0][0] - m[1][1] + m[2][2]); \
- rinv = 0.5f / r; \
- dst.x = rinv * (m[0][2] + m[2][0]); \
- dst.y = rinv * (m[1][2] + m[2][1]); \
- dst.z = r * 0.5f; \
- dst.w = rinv * (m[0][1] - m[1][0]); \
- } \
- return dst; \
- } \
- \
- static inline CMat4##tag \
- cquat##tag##_toMat4(CQuat##tag q) { \
- CMat4##tag dst; \
- T norm = cquat##tag##_length(q), \
- s = norm > 0.0f ? 2.0f / norm : 0.0f, \
- xx = s * q.x * q.x, xy = s * q.x * q.y, wx = s * q.w * q.x, \
- yy = s * q.y * q.y, yz = s * q.y * q.z, wy = s * q.w * q.y, \
- zz = s * q.z * q.z, xz = s * q.x * q.z, wz = s * q.w * q.z; \
- \
- dst.m[0][0] = 1.0f - yy - zz; \
- dst.m[1][1] = 1.0f - xx - zz; \
- dst.m[2][2] = 1.0f - xx - yy; \
- dst.m[0][1] = xy + wz; \
- dst.m[1][2] = yz + wx; \
- dst.m[2][0] = xz + wy; \
- dst.m[1][0] = xy - wz; \
- dst.m[2][1] = yz - wx; \
- dst.m[0][2] = xz - wy; \
- dst.m[0][3] = dst.m[1][3] = dst.m[2][3] = 0.0f; \
- dst.m[3][0] = dst.m[3][1] = dst.m[3][2] = 0.0f; \
- dst.m[3][3] = 1.0f; \
- return dst; \
- } \
- \
- static inline CQuat##tag \
- cquat##tag##_conjugate(CQuat##tag q) { \
- q.x = -q.x, q.y = -q.y, q.z = -q.z; \
- return q; \
- } \
- \
- static inline CQuat##tag \
- cquat##tag##_cross(CQuat##tag p, CQuat##tag q) { \
- return (CQuat##tag) {p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y, \
- p.w * q.y - p.x * q.z + p.y * q.w + p.z * q.x, \
- p.w * q.z + p.x * q.y - p.y * q.x + p.z * q.w, \
- p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z}; \
- } \
- static inline CQuat##tag \
- cquat##tag##_inverse(CQuat##tag q) { \
- q.x = -q.x, q.y = -q.y, q.z = -q.z; \
- return cvec4##tag##_mult(q, 1.0f / _cvec4_DOT(q, q)); \
- } \
- static inline T \
- cquat##tag##_angle(CQuat##tag q) { \
- /* sin(theta / 2) = length(x*x + y*y + z*z) */ \
- /* cos(theta / 2) = w */ \
- /* theta = 2 * atan(sin(theta / 2) / cos(theta / 2)) */ \
- return 2.0f * c_atan2_##tag(c_sqrt_##tag(_cvec3_DOT(q, q)), q.w); \
- } \
- static inline T \
- cquat##tag##_imagLength(CQuat##tag q) { \
- return c_sqrt_##tag(_cvec3_DOT(q, q)); \
- } \
- typedef T cquat##tag##_value_t
-
-#define cquatf_fromArray(arr) cvec4f_fromArray(arr)
-#define cquatd_fromArray(arr) cvec4d_fromArray(arr)
-
-#define cquatf_assign(q, x, y, z, w) cvec4f_assign(q, x, y, z, w)
-#define cquatd_assign(q, x, y, z, w) cvec4d_assign(q, x, y, z, w)
-
-#define cquatf_assignArray(q, arr) cvec4f_assignArray(q, arr)
-#define cquatd_assignArray(q, arr) cvec4d_assignArray(q, arr)
-
-#define cquatf_length(q) cvec4f_length(q)
-#define cquatd_length(q) cvec4d_length(q)
-
-#define cquatf_length2(q) cvec4f_length2(q)
-#define cquatd_length2(q) cvec4d_length2(q)
-
-#define cquatf_dot(p, q) cvec4f_dot(p, q)
-#define cquatd_dot(p, q) cvec4d_dot(p, q)
-
-#define cquatf_lerp(p, q, t) cvec4f_lerp(p, q, t)
-#define cquatd_lerp(p, q, t) cvec4d_lerp(p, q, t)
-
-#define cquatf_swizzle(q, swz) cvec4f_swizzle(q, swz)
-#define cquatd_swizzle(q, swz) cvec4d_swizzle(q, swz)
-
-#define cquatf_equals(p, q) cvec4f_equals(p, q)
-#define cquatd_equals(p, q) cvec4d_equals(p, q)
-
-#define cquatf_compare(p, q) cvec4f_compare(p, q)
-#define cquatd_compare(p, q) cvec4d_compare(p, q)
-
-#define cquatf_imag(q) cvec4f_to3(q)
-#define cquatd_imag(q) cvec4d_to3(q)
-
-#define cquatf_real(q) ((float) (q).w)
-#define cquatd_real(q) ((double) (q).w)
-
-declare_CQuat(f, float);
-declare_CQuat(d, double);
-
-
-static inline CQuatd cquatf_tod(CQuatf v) {
- return (CQuatd) {v.x, v.y, v.z, v.w};
-}
-static inline CQuatf cquatd_tof(CQuatd v) {
- return (CQuatf) {(float) v.x, (float) v.y, (float) v.z, (float) v.w};
-}
-
-#endif
diff --git a/stc/cstring.h b/stc/cstring.h
index 344e56aa..454ff48c 100644
--- a/stc/cstring.h
+++ b/stc/cstring.h
@@ -1,25 +1,25 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#ifndef CSTRING__H__
#define CSTRING__H__
@@ -239,9 +239,14 @@ cstring_equalsS(CString cs1, CString cs2) {
return strcmp(cs1.str, cs2.str) == 0;
}
+static inline int
+cstring_compare(const void* cs1, const void* cs2) {
+ return strcmp(((const CString*)cs1)->str, ((const CString*)cs2)->str);
+}
+
static inline char*
cstring_strnstr(CString cs, size_t pos, const char* needle, size_t n) {
- char *x = cs.str + pos, // haystack
+ char *x = cs.str + pos, /* haystack */
*z = cs.str + cstring_size(cs) - n + 1;
if (x >= z)
return NULL;
@@ -281,17 +286,16 @@ cstring_splitNext(const char* delimiters) {
static inline CString
cstring_temp(const char* str) {
- // May only be used for accessing .str
+ /* May only be used for accessing .str */
CString temp = {(char *) str};
return temp;
}
-// CVector / CMap API functions:
+/* CVector / CMap API functions: */
#define cstring_getRaw(x) (&(x)->str)
#define cstring_compareRaw(x, y) strcmp(*(x), *(y))
#define cstring_equalsRaw(x, y) (strcmp(*(x), *(y)) == 0)
static inline uint32_t cstring_hashRaw(const char* const* str, size_t ignored) { return c_defaultHash(*str, strlen(*str)); }
-
#endif
diff --git a/stc/cvec3.h b/stc/cvec3.h
deleted file mode 100644
index 4c1bb7a7..00000000
--- a/stc/cvec3.h
+++ /dev/null
@@ -1,202 +0,0 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#ifndef CVEC3__H__
-#define CVEC3__H__
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <math.h>
-
-#define c_sqrt_f(x) sqrtf(x)
-#define c_sqrt_d(x) sqrt(x)
-#define c_sin_f(x) sinf(x)
-#define c_sin_d(x) sin(x)
-#define c_cos_f(x) cosf(x)
-#define c_cos_d(x) cos(x)
-#define c_atan2_f(x, y) atan2f(x, y)
-#define c_atan2_d(x, y) atan2(x, y)
-
-#ifdef c_NO_ANONYMOUS_STRUCT
-#define CVEC3_DEF(tag, T) struct CVec3##tag { T x, y, z; }
-#else
-#define CVEC3_DEF(tag, T) union CVec3##tag { struct { T x, y, z; }; T arr[3]; }
-#endif
-
-#define cvec3_arr(v) (&(v).x)
-#define cvec3f_zero ((CVec3f) {0.f, 0.f, 0.f})
-#define cvec3d_zero ((CVec3d) {0.0, 0.0, 0.0})
-
-
-#define declare_CVec3(tag, T) \
- typedef CVEC3_DEF(tag, T) CVec3##tag; \
- static CVec3##tag \
- cvec3##tag##_axis[3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; \
- \
- static inline CVec3##tag \
- cvec3##tag(T x, T y, T z) { return (CVec3##tag) {x, y, z}; } \
- static inline CVec3##tag \
- cvec3##tag##_fromArray(const T* a) { return (CVec3##tag) {a[0], a[1], a[2]}; } \
- \
- static inline CVec3##tag* \
- cvec3##tag##_assign(CVec3##tag* self, T x, T y, T z) { \
- self->x = x, self->y = y, self->z = z; return self; \
- } \
- static inline CVec3##tag* \
- cvec3##tag##_assignArray(CVec3##tag* self, const T* a) { \
- self->x = a[0], self->y = a[1], self->z = a[2]; return self; \
- } \
- static inline CVec3##tag* \
- cvec3##tag##_add(CVec3##tag* self, CVec3##tag v) { \
- self->x += v.x, self->y += v.y, self->z += v.z; return self; \
- } \
- static inline CVec3##tag* \
- cvec3##tag##_sub(CVec3##tag* self, CVec3##tag v) { \
- self->x -= v.x, self->y -= v.y, self->z -= v.z; return self; \
- } \
- static inline CVec3##tag* \
- cvec3##tag##_scale(CVec3##tag* self, T s) { \
- self->x *= s, self->y *= s, self->z *= s; return self; \
- } \
- static inline T \
- cvec3##tag##_length(CVec3##tag v) { \
- return c_sqrt_##tag(_cvec3_DOT(v, v)); \
- } \
- static inline T \
- cvec3##tag##_length2(CVec3##tag v) { \
- return _cvec3_DOT(v, v); \
- } \
- static inline CVec3##tag \
- cvec3##tag##_plus(CVec3##tag u, CVec3##tag v) { \
- u.x += v.x, u.y += v.y, u.z += v.z; return u; \
- } \
- static inline CVec3##tag \
- cvec3##tag##_minus(CVec3##tag u, CVec3##tag v) { \
- u.x -= v.x, u.y -= v.y, u.z -= v.z; return u; \
- } \
- static inline CVec3##tag \
- cvec3##tag##_mult(CVec3##tag v, T s) { \
- v.x *= s, v.y *= s, v.z *= s; return v; \
- } \
- static inline CVec3##tag \
- cvec3##tag##_neg(CVec3##tag v) { \
- v.x = -v.x, v.y = -v.y, v.z = -v.z; return v; \
- } \
- static inline CVec3##tag \
- cvec3##tag##_unit(CVec3##tag v) { \
- T s = c_sqrt_##tag(_cvec3_DOT(v, v)); \
- if (s < 1e-8) return cvec3##tag##_zero; \
- s = 1.0f / s; v.x *= s, v.y *= s, v.z *= s; \
- return v; \
- } \
- static inline T \
- cvec3##tag##_dot(CVec3##tag u, CVec3##tag v) { \
- return _cvec3_DOT(u, v); \
- } \
- static inline CVec3##tag \
- cvec3##tag##_cross(CVec3##tag u, CVec3##tag v) { \
- return (CVec3##tag) {_cvec3_CROSS(u, v)}; \
- } \
- static inline T \
- cvec3##tag##_triple(CVec3##tag u, CVec3##tag v, CVec3##tag w) { \
- CVec3##tag cross = {_cvec3_CROSS(u, v)}; \
- return _cvec3_DOT(cross, w); \
- } \
- /* Reflect u on plane with given normal vector pn */ \
- static inline CVec3##tag \
- cvec3##tag##_reflect(CVec3##tag u, CVec3##tag pn) { \
- T dot2 = 2.0f * _cvec3_DOT(u, pn); \
- u.x -= dot2 * pn.x, u.y -= dot2 * pn.y, u.z -= dot2 * pn.z; \
- return u; \
- } \
- /* Refract u incident on plane with given normal vector pn */ \
- static inline CVec3##tag \
- cvec3##tag##_refract(CVec3##tag u, CVec3##tag pn, T eta) { \
- T dot = _cvec3_DOT(pn, u); \
- T k = 1.0f - eta * eta * (1.0f - dot * dot); \
- if (k < 0.0f) return cvec3##tag##_zero; \
- cvec3##tag##_scale(&u, eta); \
- cvec3##tag##_scale(&pn, eta * dot + c_sqrt_##tag(k)); \
- return *cvec3##tag##_sub(&u, pn); \
- } \
- static inline T \
- cvec3##tag##_distance(CVec3##tag u, CVec3##tag v) { \
- u.x -= v.x, u.y -= v.y, u.z -= v.z; \
- return c_sqrt_##tag(_cvec3_DOT(u, u)); \
- } \
- /* Signed distance between point u and a plane (pp, pn), pn normalized. */ \
- static inline T \
- cvec3##tag##_distanceToPlane(CVec3##tag u, CVec3##tag pp, CVec3##tag pn) { \
- u.x -= pp.x, u.y -= pp.y, u.z -= pp.z; \
- return _cvec3_DOT(u, pn); \
- } \
- /* Linear interpolation */ \
- static inline CVec3##tag \
- cvec3##tag##_lerp(CVec3##tag u, CVec3##tag v, T t) { \
- T s = 1.0f - t; \
- u.x = s*u.x + t*v.x, u.y = s*u.y + t*v.y, u.z = s*u.z + t*v.z; \
- return u; \
- } \
- /* Swizzle */ \
- static inline CVec3##tag \
- cvec3##tag##_swizzle(CVec3##tag u, const char* swz) { \
- T* a = cvec3_arr(u); \
- return (CVec3##tag) {a[swz[0] - 'x'], a[swz[1] - 'x'], a[swz[2] - 'x']}; \
- } \
- static inline bool \
- cvec3##tag##_rayPlaneIntersection(CVec3##tag* out, CVec3##tag u, CVec3##tag dir, \
- CVec3##tag pp, CVec3##tag pn) { \
- T d = _cvec3_DOT(dir, pn); if (d == 0) return false; \
- T t = (_cvec3_DOT(pp, pn) - _cvec3_DOT(u, pn)) / d; \
- if (t < 0) return false; \
- u.x += dir.x*t, u.y += dir.y*t, u.z += dir.z*t; \
- *out = u; return true; \
- } \
- static inline bool \
- cvec3##tag##_equals(CVec3##tag u, CVec3##tag v) { \
- if (u.x != v.x) return false; \
- if (u.y != v.y) return false; \
- return u.z == v.z; \
- } \
- static inline int \
- cvec3##tag##_compare(CVec3##tag* u, CVec3##tag* v) { \
- if (u->x != v->x) return 1 - ((u->x < v->x)<<1); \
- if (u->y != v->y) return 1 - ((u->y < v->y)<<1); \
- return u->z == v->z ? 0 : 1 - ((u->z < v->z)<<1); \
- } \
- typedef T cvec3##tag##_value_t
-
-#define _cvec3_DOT(u, v) (u.x*v.x + u.y*v.y + u.z*v.z)
-#define _cvec3_SUB(u, v) u.x - v.x, u.y - v.y, u.z - v.z
-#define _cvec3_CROSS(u, v) u.y*v.z - v.y*u.z, u.z*v.x - v.z*u.x, u.x*v.y - u.y*v.x
-
-declare_CVec3(d, double);
-declare_CVec3(f, float);
-
-static inline CVec3f cvec3d_tof(CVec3d v) {
- return (CVec3f) {(float) v.x, (float) v.y, (float) v.z};
-}
-static inline CVec3d cvec3f_tod(CVec3f v) {
- return (CVec3d) {v.x, v.y, v.z};
-}
-
-#endif
diff --git a/stc/cvec4.h b/stc/cvec4.h
deleted file mode 100644
index b8daf4a0..00000000
--- a/stc/cvec4.h
+++ /dev/null
@@ -1,170 +0,0 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#ifndef CVEC4__H__
-#define CVEC4__H__
-
-#include "cvec3.h"
-
-#ifdef c_NO_ANONYMOUS_STRUCT
-#define CVEC4_DEF(tag, T) struct CVec4##tag { T x, y, z, w; }
-#else
-#define CVEC4_DEF(tag, T) union CVec4##tag { struct { T x, y, z, w; }; T arr[4]; }
-#endif
-
-#define cvec4_arr(v) (&(v).x)
-#define cvec4f_zero ((CVec4f) {0.f, 0.f, 0.f, 0.f})
-#define cvec4d_zero ((CVec4d) {0.0, 0.0, 0.0, 0.0})
-
-#define declare_CVec4(tag, T) \
- typedef CVEC4_DEF(tag, T) CVec4##tag; \
- static CVec4##tag cvec4##tag##_axis[4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; \
- \
- static inline CVec4##tag \
- cvec4##tag(T x, T y, T z, T w) { return (CVec4##tag) {x, y, z, w}; } \
- static inline CVec4##tag \
- cvec4##tag##_fromArray(const T* a) { return (CVec4##tag) {a[0], a[1], a[2], a[3]}; } \
- \
- static inline CVec4##tag* \
- cvec4##tag##_assign(CVec4##tag* self, T x, T y, T z, T w) { \
- self->x = x, self->y = y, self->z = z, self->z = z, self->w = w; return self; \
- } \
- static inline CVec4##tag* \
- cvec4##tag##_assignArray(CVec4##tag* self, const T* a) { \
- self->x = a[0], self->y = a[1], self->z = a[2], self->w = a[3]; return self; \
- } \
- static inline CVec4##tag* \
- cvec4##tag##_add(CVec4##tag* self, CVec4##tag v) { \
- self->x += v.x, self->y += v.y, self->z += v.z, self->w += v.w; return self; \
- } \
- static inline CVec4##tag* \
- cvec4##tag##_sub(CVec4##tag* self, CVec4##tag v) { \
- self->x -= v.x, self->y -= v.y, self->z -= v.z, self->w -= v.w; return self; \
- } \
- static inline CVec4##tag* \
- cvec4##tag##_scale(CVec4##tag* self, T s) { \
- self->x *= s, self->y *= s, self->z *= s, self->w *= s; return self; \
- } \
- static inline T \
- cvec4##tag##_length(CVec4##tag v) { \
- return c_sqrt_##tag(_cvec4_DOT(v, v)); \
- } \
- static inline T \
- cvec4##tag##_length2(CVec4##tag v) { \
- return _cvec4_DOT(v, v); \
- } \
- static inline T \
- cvec4##tag##_distance(CVec4##tag u, CVec4##tag v) { \
- u.x -= v.x, u.y -= v.y, u.z -= v.z, u.w -= v.w; \
- return c_sqrt_##tag(_cvec4_DOT(u, u)); \
- } \
- static inline CVec4##tag \
- cvec4##tag##_plus(CVec4##tag u, CVec4##tag v) { \
- u.x += v.x, u.y += v.y, u.z += v.z, u.w += v.w; return u; \
- } \
- static inline CVec4##tag \
- cvec4##tag##_minus(CVec4##tag u, CVec4##tag v) { \
- u.x -= v.x, u.y -= v.y, u.z -= v.z, u.w -= v.w; return u; \
- } \
- static inline CVec4##tag \
- cvec4##tag##_mult(CVec4##tag v, T s) { \
- v.x *= s, v.y *= s, v.z *= s, v.w *= s; return v; \
- } \
- static inline CVec4##tag \
- cvec4##tag##_neg(CVec4##tag v) { \
- v.x = -v.x, v.y = -v.y, v.z = -v.z, v.w = -v.w; return v; \
- } \
- static inline CVec4##tag \
- cvec4##tag##_unit(CVec4##tag v) { \
- T s = c_sqrt_##tag(_cvec4_DOT(v, v)); \
- if (s < 1e-8) return cvec4##tag##_zero; \
- s = 1.0f / s; v.x *= s, v.y *= s, v.z *= s, v.w *= s; \
- return v; \
- } \
- static inline T \
- cvec4##tag##_dot(CVec4##tag u, CVec4##tag v) { \
- return _cvec4_DOT(u, v); \
- } \
- static inline CVec3##tag \
- cvec4##tag##_to3(CVec4##tag u) { \
- return (CVec3##tag) {u.x, u.y, u.z}; \
- } \
- static inline CVec4##tag \
- cvec3##tag##_to4(CVec3##tag u, T w) { \
- return (CVec4##tag) {u.x, u.y, u.z, w}; \
- } \
- /* Swizzle */ \
- static inline CVec4##tag \
- cvec4##tag##_swizzle(CVec4##tag u, const char* swz) { \
- const T* a = cvec4_arr(u); \
- return (CVec4##tag) {a[(swz[0] - 'x') & 3], \
- a[(swz[1] - 'x') & 3], \
- a[(swz[2] - 'x') & 3], \
- a[(swz[3] - 'x') & 3]}; \
- } \
- static inline CVec3##tag \
- cvec4##tag##_swizzle3(CVec4##tag u, const char* swz) { \
- const T* a = cvec4_arr(u); \
- return (CVec3##tag) {a[(swz[0] - 'x') & 3], \
- a[(swz[1] - 'x') & 3], \
- a[(swz[2] - 'x') & 3]}; \
- } \
- /* Linear interpolation */ \
- static inline CVec4##tag \
- cvec4##tag##_lerp(CVec4##tag u, CVec4##tag v, T t) { \
- T s = 1.0f - t; \
- u.x = s*u.x + t*v.x, u.y = s*u.y + t*v.y, \
- u.z = s*u.z + t*v.z, u.w = s*u.w + t*v.w; \
- return u; \
- } \
- static inline bool \
- cvec4##tag##_equals(CVec4##tag u, CVec4##tag v) { \
- if (u.x != v.x) return false; \
- if (u.y != v.y) return false; \
- if (u.z != v.z) return false; \
- return u.w == v.w; \
- } \
- static inline int \
- cvec4##tag##_compare(CVec4##tag* u, CVec4##tag* v) { \
- if (u->x != v->x) return 1 - ((u->x < v->x)<<1); \
- if (u->y != v->y) return 1 - ((u->y < v->y)<<1); \
- if (u->z != v->z) return 1 - ((u->z < v->z)<<1); \
- return u->w == v->w ? 0 : 1 - ((u->w < v->w)<<1); \
- } \
- typedef T cvec4##tag##_value_t
-
-#define _cvec4_DOT(u, v) (u.x*v.x + u.y*v.y + u.z*v.z + u.w*v.w)
-#define _cvec4_SUB(u, v) u.x - v.x, u.y - v.y, u.z - v.z, u.w - v.w
-
-declare_CVec4(d, double);
-declare_CVec4(f, float);
-
-static inline CVec4d
-cvec4f_tod(CVec4f v) {
- return (CVec4d) {v.x, v.y, v.z, v.w};
-}
-static inline CVec4f
-cvec4d_tof(CVec4d v) {
- return (CVec4f) {(float) v.x, (float) v.y, (float) v.z, (float) v.w};
-}
-
-#endif
diff --git a/stc/cvector.h b/stc/cvector.h
index 68eddbfb..d46905e4 100644
--- a/stc/cvector.h
+++ b/stc/cvector.h
@@ -1,25 +1,25 @@
-// MIT License
-//
-// Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
+/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
#ifndef CVECTOR__H__
#define CVECTOR__H__
@@ -44,10 +44,14 @@ extern void qsort(void *base, size_t nitems, size_t size, int (*compar)(const vo
#define declare_CVector_string(tag) \
declare_CVector_6(tag, CString, cstring_destroy, cstring_compareRaw, const char*, cstring_getRaw)
+
+
#define declare_CVector_6(tag, Value, valueDestroy, valueCompare, ValueRaw, valueGetRaw) \
+ \
typedef struct CVector_##tag { \
Value* data; \
} CVector_##tag; \
+ \
static const CVector_##tag cvector_##tag##_init = cvector_init; \
\
static inline void \
@@ -83,7 +87,7 @@ cvector_##tag##_clear(CVector_##tag* self) { \
\
\
static inline void \
-cvector_##tag##_push(CVector_##tag* self, Value value) { \
+cvector_##tag##_pushBack(CVector_##tag* self, Value value) { \
size_t len = cvector_size(*self); \
if (len == cvector_capacity(*self)) \
cvector_##tag##_reserve(self, 7 + len * 5 / 3); \
@@ -139,7 +143,7 @@ cvector_##tag##_back(CVector_##tag cv) { \
} \
\
static inline void \
-cvector_##tag##_pop(CVector_##tag* self) { \
+cvector_##tag##_popBack(CVector_##tag* self) { \
valueDestroy(&self->data[_cvector_size(*self) - 1]); \
--_cvector_size(*self); \
} \
@@ -151,8 +155,7 @@ typedef struct cvector_##tag##_iter_t { \
\
static inline cvector_##tag##_iter_t \
cvector_##tag##_begin(CVector_##tag vec) { \
- cvector_##tag##_iter_t it = {vec.data}; \
- return it; \
+ return (cvector_##tag##_iter_t) {vec.data}; \
} \
\
static inline cvector_##tag##_iter_t \
@@ -163,8 +166,7 @@ cvector_##tag##_next(cvector_##tag##_iter_t it) { \
\
static inline cvector_##tag##_iter_t \
cvector_##tag##_end(CVector_##tag vec) { \
- cvector_##tag##_iter_t it = {vec.data + cvector_size(vec)}; \
- return it; \
+ return (cvector_##tag##_iter_t) {vec.data + cvector_size(vec)}; \
} \
typedef Value cvector_##tag##_value_t