diff --git a/CREDITS b/CREDITS
index 7272ddc..a159edf 100644
--- a/CREDITS
+++ b/CREDITS
@@ -61,3 +61,7 @@ https://forums.khronos.org/showthread.php/10264-Animations-in-1-4-1-release-note
https://forums.khronos.org/showthread.php/10644-Animation-Bezier-interpolation
https://forums.khronos.org/showthread.php/10387-2D-Tangents-in-Bezier-Splines?p=34164&viewfull=1#post34164
https://forums.khronos.org/showthread.php/10651-Animation-TCB-Spline-Interpolation-in-COLLADA?highlight=bezier
+
+12. vec2 cross product
+http://allenchou.net/2013/07/cross-product-of-2d-vectors/
+
diff --git a/Makefile.am b/Makefile.am
index f755b65..371dd29 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,7 +42,10 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/io.h \
include/cglm/mat4.h \
include/cglm/mat3.h \
+ include/cglm/mat2.h \
include/cglm/affine.h \
+ include/cglm/vec2.h \
+ include/cglm/vec2-ext.h \
include/cglm/vec3.h \
include/cglm/vec3-ext.h \
include/cglm/vec4.h \
@@ -65,6 +68,8 @@ cglm_HEADERS = include/cglm/version.h \
cglm_calldir=$(includedir)/cglm/call
cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/mat3.h \
+ include/cglm/call/mat2.h \
+ include/cglm/call/vec2.h \
include/cglm/call/vec3.h \
include/cglm/call/vec4.h \
include/cglm/call/affine.h \
@@ -102,6 +107,8 @@ cglm_simd_neon_HEADERS = include/cglm/simd/neon/mat4.h
cglm_structdir=$(includedir)/cglm/struct
cglm_struct_HEADERS = include/cglm/struct/mat4.h \
include/cglm/struct/mat3.h \
+ include/cglm/struct/vec2.h \
+ include/cglm/struct/vec2-ext.h \
include/cglm/struct/vec3.h \
include/cglm/struct/vec3-ext.h \
include/cglm/struct/vec4.h \
@@ -125,8 +132,10 @@ libcglm_la_SOURCES=\
src/io.c \
src/quat.c \
src/cam.c \
+ src/vec2.c \
src/vec3.c \
src/vec4.c \
+ src/mat2.c \
src/mat3.c \
src/mat4.c \
src/plane.c \
diff --git a/include/cglm/call.h b/include/cglm/call.h
index 7cbd501..87ecea5 100644
--- a/include/cglm/call.h
+++ b/include/cglm/call.h
@@ -12,10 +12,12 @@ extern "C" {
#endif
#include "cglm.h"
+#include "call/vec2.h"
#include "call/vec3.h"
#include "call/vec4.h"
-#include "call/mat4.h"
+#include "call/mat2.h"
#include "call/mat3.h"
+#include "call/mat4.h"
#include "call/affine.h"
#include "call/cam.h"
#include "call/quat.h"
diff --git a/include/cglm/call/mat2.h b/include/cglm/call/mat2.h
new file mode 100644
index 0000000..91234a3
--- /dev/null
+++ b/include/cglm/call/mat2.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglmc_mat2_h
+#define cglmc_mat2_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../cglm.h"
+
+CGLM_EXPORT
+void
+glmc_mat2_copy(mat2 mat, mat2 dest);
+
+CGLM_EXPORT
+void
+glmc_mat2_identity(mat2 mat);
+
+CGLM_EXPORT
+void
+glmc_mat2_identity_array(mat2 * __restrict mat, size_t count);
+
+CGLM_EXPORT
+void
+glmc_mat2_zero(mat2 mat);
+
+CGLM_EXPORT
+void
+glmc_mat2_mul(mat2 m1, mat2 m2, mat2 dest);
+
+CGLM_EXPORT
+void
+glmc_mat2_transpose_to(mat2 m, mat2 dest);
+
+CGLM_EXPORT
+void
+glmc_mat2_transpose(mat2 m);
+
+CGLM_EXPORT
+void
+glmc_mat2_mulv(mat2 m, vec2 v, vec2 dest);
+
+CGLM_EXPORT
+float
+glmc_mat2_trace(mat2 m);
+
+CGLM_EXPORT
+void
+glmc_mat2_scale(mat2 m, float s);
+
+CGLM_EXPORT
+float
+glmc_mat2_det(mat2 mat);
+
+CGLM_EXPORT
+void
+glmc_mat2_inv(mat2 mat, mat2 dest);
+
+CGLM_EXPORT
+void
+glmc_mat2_swap_col(mat2 mat, int col1, int col2);
+
+CGLM_EXPORT
+void
+glmc_mat2_swap_row(mat2 mat, int row1, int row2);
+
+CGLM_EXPORT
+float
+glmc_mat2_rmc(vec2 r, mat2 m, vec2 c);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* cglmc_mat2_h */
diff --git a/include/cglm/call/vec2.h b/include/cglm/call/vec2.h
new file mode 100644
index 0000000..d4d3396
--- /dev/null
+++ b/include/cglm/call/vec2.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglmc_vec2_h
+#define cglmc_vec2_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../cglm.h"
+
+CGLM_EXPORT
+void
+glmc_vec2(float * __restrict v, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_copy(vec2 a, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_zero(vec2 v);
+
+CGLM_EXPORT
+void
+glmc_vec2_one(vec2 v);
+
+CGLM_EXPORT
+float
+glmc_vec2_dot(vec2 a, vec2 b);
+
+CGLM_EXPORT
+float
+glmc_vec2_cross(vec2 a, vec2 b);
+
+CGLM_EXPORT
+float
+glmc_vec2_norm2(vec2 v);
+
+CGLM_EXPORT
+float
+glmc_vec2_norm(vec2 v);
+
+CGLM_EXPORT
+void
+glmc_vec2_add(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_adds(vec2 v, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_sub(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_subs(vec2 v, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_mul(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_scale(vec2 v, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_scale_as(vec2 v, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_div(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_divs(vec2 v, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_addadd(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_subadd(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_muladd(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_muladds(vec2 a, float s, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_maxadd(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_minadd(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_negate_to(vec2 v, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_negate(vec2 v);
+
+CGLM_EXPORT
+void
+glmc_vec2_normalize(vec2 v);
+
+CGLM_EXPORT
+void
+glmc_vec2_normalize_to(vec2 v, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_rotate(vec2 v, float angle, vec2 dest);
+
+CGLM_EXPORT
+float
+glmc_vec2_distance2(vec2 a, vec2 b);
+
+CGLM_EXPORT
+float
+glmc_vec2_distance(vec2 a, vec2 b);
+
+CGLM_EXPORT
+void
+glmc_vec2_maxv(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_minv(vec2 a, vec2 b, vec2 dest);
+
+CGLM_EXPORT
+void
+glmc_vec2_clamp(vec2 v, float minval, float maxval);
+
+CGLM_EXPORT
+void
+glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* cglmc_vec2_h */
diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h
index 7c301bf..cbd2952 100644
--- a/include/cglm/cglm.h
+++ b/include/cglm/cglm.h
@@ -9,10 +9,12 @@
#define cglm_h
#include "common.h"
+#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
#include "mat3.h"
+#include "mat2.h"
#include "affine.h"
#include "cam.h"
#include "frustum.h"
diff --git a/include/cglm/io.h b/include/cglm/io.h
index ac0bfeb..c714400 100644
--- a/include/cglm/io.h
+++ b/include/cglm/io.h
@@ -83,6 +83,36 @@ glm_mat3_print(mat3 matrix,
#undef n
}
+CGLM_INLINE
+void
+glm_mat2_print(mat2 matrix,
+ FILE * __restrict ostream) {
+ int i;
+ int j;
+
+#define m 2
+#define n 2
+
+ fprintf(ostream, "Matrix (float%dx%d):\n", m, n);
+
+ for (i = 0; i < m; i++) {
+ fprintf(ostream, "\t|");
+ for (j = 0; j < n; j++) {
+ fprintf(ostream, "%0.4f", matrix[j][i]);;
+
+ if (j != n - 1)
+ fprintf(ostream, "\t");
+ }
+
+ fprintf(ostream, "|\n");
+ }
+
+ fprintf(ostream, "\n");
+
+#undef m
+#undef n
+}
+
CGLM_INLINE
void
glm_vec4_print(vec4 vec,
@@ -149,6 +179,28 @@ glm_ivec3_print(ivec3 vec,
#undef m
}
+CGLM_INLINE
+void
+glm_vec2_print(vec2 vec,
+ FILE * __restrict ostream) {
+ int i;
+
+#define m 2
+
+ fprintf(ostream, "Vector (float%d):\n\t|", m);
+
+ for (i = 0; i < m; i++) {
+ fprintf(ostream, "%0.4f", vec[i]);
+
+ if (i != m - 1)
+ fprintf(ostream, "\t");
+ }
+
+ fprintf(ostream, "|\n\n");
+
+#undef m
+}
+
CGLM_INLINE
void
glm_versor_print(versor vec,
diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h
new file mode 100644
index 0000000..69d27d3
--- /dev/null
+++ b/include/cglm/mat2.h
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Macros:
+ GLM_MAT2_IDENTITY_INIT
+ GLM_MAT2_ZERO_INIT
+ GLM_MAT2_IDENTITY
+ GLM_MAT2_ZERO
+
+ Functions:
+ CGLM_INLINE void glm_mat2_copy(mat2 mat, mat2 dest)
+ CGLM_INLINE void glm_mat2_identity(mat2 mat)
+ CGLM_INLINE void glm_mat2_identity_array(mat2 * restrict mat, size_t count)
+ CGLM_INLINE void glm_mat2_zero(mat2 mat)
+ CGLM_INLINE void glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest)
+ CGLM_INLINE void glm_mat2_transpose_to(mat2 m, mat2 dest)
+ CGLM_INLINE void glm_mat2_transpose(mat2 m)
+ CGLM_INLINE void glm_mat2_mulv(mat2 m, vec2 v, vec2 dest)
+ CGLM_INLINE float glm_mat2_trace(mat2 m)
+ CGLM_INLINE void glm_mat2_scale(mat2 m, float s)
+ CGLM_INLINE float glm_mat2_det(mat2 mat)
+ CGLM_INLINE void glm_mat2_inv(mat2 mat, mat2 dest)
+ CGLM_INLINE void glm_mat2_swap_col(mat2 mat, int col1, int col2)
+ CGLM_INLINE void glm_mat2_swap_row(mat2 mat, int row1, int row2)
+ CGLM_INLINE float glm_mat2_rmc(vec2 r, mat2 m, vec2 c)
+ */
+
+#ifndef cglm_mat2_h
+#define cglm_mat2_h
+
+#include "common.h"
+#include "vec2.h"
+
+#ifdef CGLM_SSE_FP
+# include "simd/sse2/mat2.h"
+#endif
+
+#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}}
+#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}}
+
+/* for C only */
+#define GLM_MAT2_IDENTITY ((mat2)GLM_MAT2_IDENTITY_INIT)
+#define GLM_MAT2_ZERO ((mat2)GLM_MAT2_ZERO_INIT)
+
+/*!
+ * @brief copy all members of [mat] to [dest]
+ *
+ * @param[in] mat source
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_mat2_copy(mat2 mat, mat2 dest) {
+ glm_vec4_copy(mat[0], dest[0]);
+}
+
+/*!
+ * @brief make given matrix identity. It is identical with below,
+ * but it is more easy to do that with this func especially for members
+ * e.g. glm_mat2_identity(aStruct->aMatrix);
+ *
+ * @code
+ * glm_mat2_copy(GLM_MAT2_IDENTITY, mat); // C only
+ *
+ * // or
+ * mat2 mat = GLM_MAT2_IDENTITY_INIT;
+ * @endcode
+ *
+ * @param[in, out] mat destination
+ */
+CGLM_INLINE
+void
+glm_mat2_identity(mat2 mat) {
+ CGLM_ALIGN_MAT mat2 t = GLM_MAT2_IDENTITY_INIT;
+ glm_mat2_copy(t, mat);
+}
+
+/*!
+ * @brief make given matrix array's each element identity matrix
+ *
+ * @param[in, out] mat matrix array (must be aligned (16)
+ * if alignment is not disabled)
+ *
+ * @param[in] count count of matrices
+ */
+CGLM_INLINE
+void
+glm_mat2_identity_array(mat2 * __restrict mat, size_t count) {
+ CGLM_ALIGN_MAT mat2 t = GLM_MAT2_IDENTITY_INIT;
+ size_t i;
+
+ for (i = 0; i < count; i++) {
+ glm_mat2_copy(t, mat[i]);
+ }
+}
+
+/*!
+ * @brief make given matrix zero.
+ *
+ * @param[in, out] mat matrix
+ */
+CGLM_INLINE
+void
+glm_mat2_zero(mat2 mat) {
+ CGLM_ALIGN_MAT mat2 t = GLM_MAT2_ZERO_INIT;
+ glm_mat2_copy(t, mat);
+}
+
+/*!
+ * @brief multiply m1 and m2 to dest
+ *
+ * m1, m2 and dest matrices can be same matrix, it is possible to write this:
+ *
+ * @code
+ * mat2 m = GLM_MAT2_IDENTITY_INIT;
+ * glm_mat2_mul(m, m, m);
+ * @endcode
+ *
+ * @param[in] m1 left matrix
+ * @param[in] m2 right matrix
+ * @param[out] dest destination matrix
+ */
+CGLM_INLINE
+void
+glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
+#if defined( __SSE__ ) || defined( __SSE2__ )
+ glm_mat2_mul_sse2(m1, m2, dest);
+#else
+ float a00 = m1[0][0], a01 = m1[0][1],
+ a10 = m1[1][0], a11 = m1[1][1],
+ b00 = m2[0][0], b01 = m2[0][1],
+ b10 = m2[1][0], b11 = m2[1][1];
+
+ dest[0][0] = a00 * b00 + a10 * b01;
+ dest[0][1] = a01 * b00 + a11 * b01;
+ dest[1][0] = a00 * b10 + a10 * b11;
+ dest[1][1] = a01 * b10 + a11 * b11;
+#endif
+}
+
+/*!
+ * @brief transpose mat2 and store in dest
+ *
+ * source matrix will not be transposed unless dest is m
+ *
+ * @param[in] m matrix
+ * @param[out] dest result
+ */
+CGLM_INLINE
+void
+glm_mat2_transpose_to(mat2 m, mat2 dest) {
+#if defined( __SSE__ ) || defined( __SSE2__ )
+ glm_mat2_transp_sse2(m, dest);
+#else
+ dest[0][0] = m[0][0];
+ dest[0][1] = m[1][0];
+ dest[1][0] = m[0][1];
+ dest[1][1] = m[1][1];
+#endif
+}
+
+/*!
+ * @brief tranpose mat2 and store result in same matrix
+ *
+ * @param[in, out] m source and dest
+ */
+CGLM_INLINE
+void
+glm_mat2_transpose(mat2 m) {
+ float tmp;
+ tmp = m[0][1];
+ m[0][1] = m[1][0];
+ m[1][0] = tmp;
+}
+
+/*!
+ * @brief multiply mat2 with vec2 (column vector) and store in dest vector
+ *
+ * @param[in] m mat2 (left)
+ * @param[in] v vec2 (right, column vector)
+ * @param[out] dest vec2 (result, column vector)
+ */
+CGLM_INLINE
+void
+glm_mat2_mulv(mat2 m, vec2 v, vec2 dest) {
+ dest[0] = m[0][0] * v[0] + m[1][0] * v[1];
+ dest[1] = m[0][1] * v[0] + m[1][1] * v[1];
+}
+
+/*!
+ * @brief trace of matrix
+ *
+ * sum of the elements on the main diagonal from upper left to the lower right
+ *
+ * @param[in] m matrix
+ */
+CGLM_INLINE
+float
+glm_mat2_trace(mat2 m) {
+ return m[0][0] + m[1][1];
+}
+
+/*!
+ * @brief scale (multiply with scalar) matrix
+ *
+ * multiply matrix with scalar
+ *
+ * @param[in, out] m matrix
+ * @param[in] s scalar
+ */
+CGLM_INLINE
+void
+glm_mat2_scale(mat2 m, float s) {
+ glm_vec4_scale(m[0], s, m[0]);
+}
+
+/*!
+ * @brief mat2 determinant
+ *
+ * @param[in] mat matrix
+ *
+ * @return determinant
+ */
+CGLM_INLINE
+float
+glm_mat2_det(mat2 mat) {
+ return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];
+}
+
+/*!
+ * @brief inverse mat2 and store in dest
+ *
+ * @param[in] mat matrix
+ * @param[out] dest inverse matrix
+ */
+CGLM_INLINE
+void
+glm_mat2_inv(mat2 mat, mat2 dest) {
+ float det;
+ float a = mat[0][0], b = mat[0][1],
+ c = mat[1][0], d = mat[1][1];
+
+ det = 1.0f / (a * d - b * c);
+
+ dest[0][0] = d * det;
+ dest[0][1] = -b * det;
+ dest[1][0] = -c * det;
+ dest[1][1] = a * det;
+}
+
+/*!
+ * @brief swap two matrix columns
+ *
+ * @param[in,out] mat matrix
+ * @param[in] col1 col1
+ * @param[in] col2 col2
+ */
+CGLM_INLINE
+void
+glm_mat2_swap_col(mat2 mat, int col1, int col2) {
+ float a, b;
+
+ a = mat[col1][0];
+ b = mat[col1][1];
+
+ mat[col1][0] = mat[col2][0];
+ mat[col1][1] = mat[col2][1];
+
+ mat[col2][0] = a;
+ mat[col2][1] = b;
+}
+
+/*!
+ * @brief swap two matrix rows
+ *
+ * @param[in,out] mat matrix
+ * @param[in] row1 row1
+ * @param[in] row2 row2
+ */
+CGLM_INLINE
+void
+glm_mat2_swap_row(mat2 mat, int row1, int row2) {
+ float a, b;
+
+ a = mat[0][row1];
+ b = mat[1][row1];
+
+ mat[0][row1] = mat[0][row2];
+ mat[1][row1] = mat[1][row2];
+
+ mat[0][row2] = a;
+ mat[1][row2] = b;
+}
+
+/*!
+ * @brief helper for R (row vector) * M (matrix) * C (column vector)
+ *
+ * rmc stands for Row * Matrix * Column
+ *
+ * the result is scalar because R * M = Matrix1x2 (row vector),
+ * then Matrix1x2 * Vec2 (column vector) = Matrix1x1 (Scalar)
+ *
+ * @param[in] r row vector or matrix1x2
+ * @param[in] m matrix2x2
+ * @param[in] c column vector or matrix2x1
+ *
+ * @return scalar value e.g. Matrix1x1
+ */
+CGLM_INLINE
+float
+glm_mat2_rmc(vec2 r, mat2 m, vec2 c) {
+ vec2 tmp;
+ glm_mat2_mulv(m, c, tmp);
+ return glm_vec2_dot(r, tmp);
+}
+
+#endif /* cglm_mat2_h */
diff --git a/include/cglm/simd/sse2/mat2.h b/include/cglm/simd/sse2/mat2.h
new file mode 100644
index 0000000..b3b4d97
--- /dev/null
+++ b/include/cglm/simd/sse2/mat2.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglm_mat2_sse_h
+#define cglm_mat2_sse_h
+#if defined( __SSE__ ) || defined( __SSE2__ )
+
+#include "../../common.h"
+#include "../intrin.h"
+
+CGLM_INLINE
+void
+glm_mat2_mul_sse2(mat2 m1, mat2 m2, mat2 dest) {
+ __m128 x0, x1, x2;
+
+ x1 = glmm_load(m1[0]); /* d c b a */
+ x2 = glmm_load(m2[0]); /* h g f e */
+
+ /*
+ dest[0][0] = a * e + c * f;
+ dest[0][1] = b * e + d * f;
+ dest[1][0] = a * g + c * h;
+ dest[1][1] = b * g + d * h;
+ */
+ x0 = _mm_mul_ps(_mm_movelh_ps(x1, x1), glmm_shuff1(x2, 2, 2, 0, 0));
+ x1 = _mm_mul_ps(_mm_movehl_ps(x1, x1), glmm_shuff1(x2, 3, 3, 1, 1));
+ x1 = _mm_add_ps(x0, x1);
+
+ glmm_store(dest[0], x1);
+}
+
+CGLM_INLINE
+void
+glm_mat2_transp_sse2(mat2 m, mat2 dest) {
+ /* d c b a */
+ /* d b c a */
+ glmm_store(dest[0], glmm_shuff1(glmm_load(m[0]), 3, 1, 2, 0));
+}
+
+#endif
+#endif /* cglm_mat2_sse_h */
diff --git a/include/cglm/struct.h b/include/cglm/struct.h
index 66a0e9b..654a1d4 100644
--- a/include/cglm/struct.h
+++ b/include/cglm/struct.h
@@ -13,8 +13,10 @@ extern "C" {
#include "cglm.h"
#include "types-struct.h"
+#include "struct/vec2.h"
#include "struct/vec3.h"
#include "struct/vec4.h"
+#include "struct/mat2.h"
#include "struct/mat3.h"
#include "struct/mat4.h"
#include "struct/affine.h"
diff --git a/include/cglm/struct/mat2.h b/include/cglm/struct/mat2.h
new file mode 100644
index 0000000..c73f13c
--- /dev/null
+++ b/include/cglm/struct/mat2.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Macros:
+ GLM_MAT2_IDENTITY_INIT
+ GLM_MAT2_ZERO_INIT
+ GLM_MAT2_IDENTITY
+ GLM_MAT2_ZERO
+
+ Functions:
+ CGLM_INLINE void glms_mat2_identity(mat2 mat)
+ CGLM_INLINE void glms_mat2_identity_array(mat2 * restrict mat, size_t count)
+ CGLM_INLINE void glms_mat2_zero(mat2 mat)
+ CGLM_INLINE void glms_mat2_mul(mat2 m1, mat2 m2, mat2 dest)
+ CGLM_INLINE void glms_mat2_transpose_to(mat2 m, mat2 dest)
+ CGLM_INLINE void glms_mat2_transpose(mat2 m)
+ CGLM_INLINE void glms_mat2_mulv(mat2 m, vec2 v, vec2 dest)
+ CGLM_INLINE float glms_mat2_trace(mat2 m)
+ CGLM_INLINE void glms_mat2_scale(mat2 m, float s)
+ CGLM_INLINE float glms_mat2_det(mat2 mat)
+ CGLM_INLINE void glms_mat2_inv(mat2 mat, mat2 dest)
+ CGLM_INLINE void glms_mat2_swap_col(mat2 mat, int col1, int col2)
+ CGLM_INLINE void glms_mat2_swap_row(mat2 mat, int row1, int row2)
+ CGLM_INLINE float glms_mat2_rmc(vec2 r, mat2 m, vec2 c)
+ */
+
+#ifndef cglms_mat2_h
+#define cglms_mat2_h
+
+#include "../common.h"
+#include "../types-struct.h"
+#include "../mat2.h"
+
+#define GLMS_MAT2_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 1.0f}
+#define GLMS_MAT2_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f}
+
+/* for C only */
+#define GLMS_MAT2_IDENTITY ((mat3s)GLMS_MAT2_IDENTITY_INIT)
+#define GLMS_MAT2_ZERO ((mat3s)GLMS_MAT2_ZERO_INIT)
+
+/*!
+ * @brief make given matrix identity. It is identical with below,
+ * but it is more easy to do that with this func especially for members
+ * e.g. glm_mat2_identity(aStruct->aMatrix);
+ *
+ * @code
+ * glm_mat2_copy(GLM_MAT2_IDENTITY, mat); // C only
+ *
+ * // or
+ * mat2 mat = GLM_MAT2_IDENTITY_INIT;
+ * @endcode
+ *
+ * @returns identity matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_identity(void) {
+ mat2s r;
+ glm_mat2_identity(r.raw);
+ return r;
+}
+
+/*!
+ * @brief make given matrix array's each element identity matrix
+ *
+ * @param[in, out] mat matrix array (must be aligned (16)
+ * if alignment is not disabled)
+ *
+ * @param[in] count count of matrices
+ */
+CGLM_INLINE
+void
+glms_mat2_identity_array(mat2s * __restrict mat, size_t count) {
+ CGLM_ALIGN_MAT mat2s t = GLMS_MAT2_IDENTITY_INIT;
+ size_t i;
+
+ for (i = 0; i < count; i++) {
+ glm_mat2_copy(t.raw, mat[i].raw);
+ }
+}
+
+/*!
+ * @brief make given matrix zero.
+ *
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_zero(void) {
+ mat2s r;
+ glm_mat2_zero(r.raw);
+ return r;
+}
+
+/*!
+ * @brief multiply m1 and m2 to dest
+ *
+ * m1, m2 and dest matrices can be same matrix, it is possible to write this:
+ *
+ * @code
+ * mat2 m = GLM_MAT2_IDENTITY_INIT;
+ * glm_mat2_mul(m, m, m);
+ * @endcode
+ *
+ * @param[in] m1 left matrix
+ * @param[in] m2 right matrix
+ *
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_mul(mat2s m1, mat2s m2) {
+ mat2s r;
+ glm_mat2_mul(m1.raw, m2.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief transpose mat2
+ *
+ * @param[in] m matrix to transpose
+ *
+ * @returns transposed matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_transpose(mat2s m) {
+ glm_mat2_transpose(m.raw);
+ return m;
+}
+
+/*!
+ * @brief multiply mat2 with vec2 (column vector) and store in dest vector
+ *
+ * @param[in] m mat2 (left)
+ * @param[in] v vec2 (right, column vector)
+ * @returns vec2 (result, column vector)
+ */
+CGLM_INLINE
+vec2s
+glms_mat2_mulv(mat2s m, vec2s v) {
+ vec2s r;
+ glm_mat2_mulv(m.raw, v.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief trace of matrix
+ *
+ * sum of the elements on the main diagonal from upper left to the lower right
+ *
+ * @param[in] m matrix
+ */
+CGLM_INLINE
+float
+glms_mat2_trace(mat2s m) {
+ return glm_mat2_trace(m.raw);
+}
+
+/*!
+ * @brief scale (multiply with scalar) matrix
+ *
+ * multiply matrix with scalar
+ *
+ * @param[in, out] m matrix
+ * @param[in] s scalar
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_scale(mat2s m, float s) {
+ glm_mat2_scale(m.raw, s);
+ return m;
+}
+
+/*!
+ * @brief mat2 determinant
+ *
+ * @param[in] mat matrix
+ *
+ * @return determinant
+ */
+CGLM_INLINE
+float
+glms_mat2_det(mat2s mat) {
+ return glm_mat2_det(mat.raw);
+}
+
+/*!
+ * @brief inverse mat2 and store in dest
+ *
+ * @param[in] mat matrix
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_inv(mat2s mat) {
+ mat2s r;
+ glm_mat2_inv(mat.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief swap two matrix columns
+ *
+ * @param[in] mat matrix
+ * @param[in] col1 col1
+ * @param[in] col2 col2
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_swap_col(mat2s mat, int col1, int col2) {
+ glm_mat2_swap_col(mat.raw, col1, col2);
+ return mat;
+}
+
+/*!
+ * @brief swap two matrix rows
+ *
+ * @param[in] mat matrix
+ * @param[in] row1 row1
+ * @param[in] row2 row2
+ * @returns matrix
+ */
+CGLM_INLINE
+mat2s
+glms_mat2_swap_row(mat2s mat, int row1, int row2) {
+ glm_mat2_swap_row(mat.raw, row1, row2);
+ return mat;
+}
+
+/*!
+ * @brief helper for R (row vector) * M (matrix) * C (column vector)
+ *
+ * rmc stands for Row * Matrix * Column
+ *
+ * the result is scalar because R * M = Matrix1x2 (row vector),
+ * then Matrix1x2 * Vec2 (column vector) = Matrix1x1 (Scalar)
+ *
+ * @param[in] r row vector or matrix1x2
+ * @param[in] m matrix2x2
+ * @param[in] c column vector or matrix2x1
+ *
+ * @return scalar value e.g. Matrix1x1
+ */
+CGLM_INLINE
+float
+glms_mat2_rmc(vec2s r, mat2s m, vec2s c) {
+ return glm_mat2_rmc(r.raw, m.raw, c.raw);
+}
+
+#endif /* cglms_mat2_h */
diff --git a/include/cglm/struct/vec2-ext.h b/include/cglm/struct/vec2-ext.h
new file mode 100644
index 0000000..d77debe
--- /dev/null
+++ b/include/cglm/struct/vec2-ext.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*!
+ * @brief SIMD like functions
+ */
+
+/*
+ Functions:
+ CGLM_INLINE vec2s glms_vec2_fill(float val)
+ CGLM_INLINE bool glms_vec2_eq(vec2s v, float val)
+ CGLM_INLINE bool glms_vec2_eq_eps(vec2s v, float val)
+ CGLM_INLINE bool glms_vec2_eq_all(vec2s v)
+ CGLM_INLINE bool glms_vec2_eqv(vec2s a, vec2s b)
+ CGLM_INLINE bool glms_vec2_eqv_eps(vec2s a, vec2s b)
+ CGLM_INLINE float glms_vec2_max(vec2s v)
+ CGLM_INLINE float glms_vec2_min(vec2s v)
+ CGLM_INLINE bool glms_vec2_isnan(vec2s v)
+ CGLM_INLINE bool glms_vec2_isinf(vec2s v)
+ CGLM_INLINE bool glms_vec2_isvalid(vec2s v)
+ CGLM_INLINE vec2s glms_vec2_sign(vec2s v)
+ CGLM_INLINE vec2s glms_vec2_sqrt(vec2s v)
+ */
+
+#ifndef cglms_vec2s_ext_h
+#define cglms_vec2s_ext_h
+
+#include "../common.h"
+#include "../types-struct.h"
+#include "../util.h"
+#include "../vec2-ext.h"
+
+/*!
+ * @brief fill a vector with specified value
+ *
+ * @param[in] val value
+ * @returns dest
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_fill(float val) {
+ vec2s r;
+ glm_vec2_fill(r.raw, val);
+ return r;
+}
+
+/*!
+ * @brief check if vector is equal to value (without epsilon)
+ *
+ * @param[in] v vector
+ * @param[in] val value
+ */
+CGLM_INLINE
+bool
+glms_vec2_eq(vec2s v, float val) {
+ return glm_vec2_eq(v.raw, val);
+}
+
+/*!
+ * @brief check if vector is equal to value (with epsilon)
+ *
+ * @param[in] v vector
+ * @param[in] val value
+ */
+CGLM_INLINE
+bool
+glms_vec2_eq_eps(vec2s v, float val) {
+ return glm_vec2_eq_eps(v.raw, val);
+}
+
+/*!
+ * @brief check if vectors members are equal (without epsilon)
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_eq_all(vec2s v) {
+ return glm_vec2_eq_all(v.raw);
+}
+
+/*!
+ * @brief check if vector is equal to another (without epsilon)
+ *
+ * @param[in] a vector
+ * @param[in] b vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_eqv(vec2s a, vec2s b) {
+ return glm_vec2_eqv(a.raw, b.raw);
+}
+
+/*!
+ * @brief check if vector is equal to another (with epsilon)
+ *
+ * @param[in] a vector
+ * @param[in] b vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_eqv_eps(vec2s a, vec2s b) {
+ return glm_vec2_eqv_eps(a.raw, b.raw);
+}
+
+/*!
+ * @brief max value of vector
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+float
+glms_vec2_max(vec2s v) {
+ return glm_vec2_max(v.raw);
+}
+
+/*!
+ * @brief min value of vector
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+float
+glms_vec2_min(vec2s v) {
+ return glm_vec2_min(v.raw);
+}
+
+/*!
+ * @brief check if all items are NaN (not a number)
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_isnan(vec2s v) {
+ return glm_vec2_isnan(v.raw);
+}
+
+/*!
+ * @brief check if all items are INFINITY
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_isinf(vec2s v) {
+ return glm_vec2_isinf(v.raw);
+}
+
+/*!
+ * @brief check if all items are valid number
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glms_vec2_isvalid(vec2s v) {
+ return glm_vec2_isvalid(v.raw);
+}
+
+/*!
+ * @brief get sign of 32 bit float as +1, -1, 0
+ *
+ * Important: It returns 0 for zero/NaN input
+ *
+ * @param v vector
+ * @returns sign vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_sign(vec2s v) {
+ vec2s r;
+ glm_vec2_sign(v.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief square root of each vector item
+ *
+ * @param[in] v vector
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_sqrt(vec2s v) {
+ vec2s r;
+ glm_vec2_sqrt(v.raw, r.raw);
+ return r;
+}
+
+#endif /* cglms_vec2s_ext_h */
diff --git a/include/cglm/struct/vec2.h b/include/cglm/struct/vec2.h
new file mode 100644
index 0000000..e6ea945
--- /dev/null
+++ b/include/cglm/struct/vec2.h
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Macros:
+ GLMS_VEC2_ONE_INIT
+ GLMS_VEC2_ZERO_INIT
+ GLMS_VEC2_ONE
+ GLMS_VEC2_ZERO
+
+ Functions:
+ CGLM_INLINE vec2s glms_vec2(vec3s v3)
+ CGLM_INLINE void glms_vec2_pack(vec2s dst[], vec2 src[], size_t len)
+ CGLM_INLINE void glms_vec2_unpack(vec2 dst[], vec2s src[], size_t len)
+ CGLM_INLINE vec2s glms_vec2_zero(void)
+ CGLM_INLINE vec2s glms_vec2_one(void)
+ CGLM_INLINE float glms_vec2_dot(vec2s a, vec2s b)
+ CGLM_INLINE float glms_vec2_cross(vec2s a, vec2s b)
+ CGLM_INLINE float glms_vec2_norm2(vec2s v)
+ CGLM_INLINE float glms_vec2_norm(vec2s v)
+ CGLM_INLINE vec2s glms_vec2_add(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_adds(vec2s a, float s)
+ CGLM_INLINE vec2s glms_vec2_sub(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_subs(vec2s a, float s)
+ CGLM_INLINE vec2s glms_vec2_mul(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_scale(vec2s v, float s)
+ CGLM_INLINE vec2s glms_vec2_scale_as(vec2s v, float s)
+ CGLM_INLINE vec2s glms_vec2_div(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_divs(vec2s a, float s)
+ CGLM_INLINE vec2s glms_vec2_addadd(vec2s a, vec2s b, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_subadd(vec2s a, vec2s b, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_muladd(vec2s a, vec2s b, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_muladds(vec2s a, float s, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_maxadd(vec2s a, vec2s b, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_minadd(vec2s a, vec2s b, vec2s dest)
+ CGLM_INLINE vec2s glms_vec2_negate(vec2s v)
+ CGLM_INLINE vec2s glms_vec2_normalize(vec2s v)
+ CGLM_INLINE vec2s glms_vec2_rotate(vec2s v, float angle, vec2s axis)
+ CGLM_INLINE float glms_vec2_distance(vec2s a, vec2s b)
+ CGLM_INLINE float glms_vec2_distance2(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_maxv(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_minv(vec2s a, vec2s b)
+ CGLM_INLINE vec2s glms_vec2_clamp(vec2s v, float minVal, float maxVal)
+ CGLM_INLINE vec2s glms_vec2_lerp(vec2s from, vec2s to, float t)
+ */
+
+#ifndef cglms_vec2s_h
+#define cglms_vec2s_h
+
+#include "../common.h"
+#include "../types-struct.h"
+#include "../util.h"
+#include "../vec2.h"
+#include "vec2-ext.h"
+
+#define GLMS_VEC2_ONE_INIT {GLM_VEC2_ONE_INIT}
+#define GLMS_VEC2_ZERO_INIT {GLM_VEC2_ZERO_INIT}
+
+#define GLMS_VEC2_ONE ((vec2s)GLMS_VEC2_ONE_INIT)
+#define GLMS_VEC2_ZERO ((vec2s)GLMS_VEC2_ZERO_INIT)
+
+/*!
+ * @brief init vec2 using vec2
+ *
+ * @param[in] v4 vector3
+ * @returns destination
+ */
+CGLM_INLINE
+vec2s
+glms_vec2(vec3s v3) {
+ vec2s r;
+ glm_vec2(v3.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief pack an array of vec2 into an array of vec2s
+ *
+ * @param[out] dst array of vec2
+ * @param[in] src array of vec2s
+ * @param[in] len number of elements
+ */
+CGLM_INLINE
+void
+glms_vec2_pack(vec2s dst[], vec2 src[], size_t len) {
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ glm_vec2_copy(src[i], dst[i].raw);
+ }
+}
+
+/*!
+ * @brief unpack an array of vec2s into an array of vec2
+ *
+ * @param[out] dst array of vec2s
+ * @param[in] src array of vec2
+ * @param[in] len number of elements
+ */
+CGLM_INLINE
+void
+glms_vec2_unpack(vec2 dst[], vec2s src[], size_t len) {
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ glm_vec2_copy(src[i].raw, dst[i]);
+ }
+}
+
+/*!
+ * @brief make vector zero
+ *
+ * @returns zero vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_zero(void) {
+ vec2s r;
+ glm_vec2_zero(r.raw);
+ return r;
+}
+
+/*!
+ * @brief make vector one
+ *
+ * @returns one vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_one(void) {
+ vec2s r;
+ glm_vec2_one(r.raw);
+ return r;
+}
+
+/*!
+ * @brief vec2 dot product
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return dot product
+ */
+CGLM_INLINE
+float
+glms_vec2_dot(vec2s a, vec2s b) {
+ return glm_vec2_dot(a.raw, b.raw);
+}
+
+/*!
+ * @brief vec2 cross product
+ *
+ * REF: http://allenchou.net/2013/07/cross-product-of-2d-vectors/
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return Z component of cross product
+ */
+CGLM_INLINE
+float
+glms_vec2_cross(vec2s a, vec2s b) {
+ return glm_vec2_cross(a.raw, b.raw);
+}
+
+/*!
+ * @brief norm * norm (magnitude) of vec
+ *
+ * we can use this func instead of calling norm * norm, because it would call
+ * sqrtf fuction twice but with this func we can avoid func call, maybe this is
+ * not good name for this func
+ *
+ * @param[in] v vector
+ *
+ * @return norm * norm
+ */
+CGLM_INLINE
+float
+glms_vec2_norm2(vec2s v) {
+ return glm_vec2_norm2(v.raw);
+}
+
+/*!
+ * @brief norm (magnitude) of vec2
+ *
+ * @param[in] v vector
+ *
+ * @return norm
+ */
+CGLM_INLINE
+float
+glms_vec2_norm(vec2s v) {
+ return glm_vec2_norm(v.raw);
+}
+
+/*!
+ * @brief add a vector to b vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_add(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_add(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief add scalar to v vector store result in dest (d = v + s)
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_adds(vec2s a, float s) {
+ vec2s r;
+ glm_vec2_adds(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief subtract b vector from a vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_sub(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_sub(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief subtract scalar from v vector store result in dest (d = v - s)
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_subs(vec2s a, float s) {
+ vec2s r;
+ glm_vec2_subs(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief multiply two vector (component-wise multiplication)
+ *
+ * @param a vector1
+ * @param b vector2
+ * @returns v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_mul(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_mul(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief multiply/scale vec2 vector with scalar: result = v * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_scale(vec2s v, float s) {
+ vec2s r;
+ glm_vec2_scale(v.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief make vec2 vector scale as specified: result = unit(v) * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @returns destination vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_scale_as(vec2s v, float s) {
+ vec2s r;
+ glm_vec2_scale_as(v.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief div vector with another component-wise division: d = a / b
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns result = (a[0]/b[0], a[1]/b[1], a[2]/b[2])
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_div(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_div(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief div vector with scalar: d = v / s
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns result = (a[0]/s, a[1]/s, a[2]/s)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_divs(vec2s a, float s) {
+ vec2s r;
+ glm_vec2_divs(a.raw, s, r.raw);
+ return r;
+}
+
+/*!
+ * @brief add two vectors and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a + b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_addadd(vec2s a, vec2s b, vec2s dest) {
+ glm_vec2_addadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief sub two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a + b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_subadd(vec2s a, vec2s b, vec2s dest) {
+ glm_vec2_subadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += (a * b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_muladd(vec2s a, vec2s b, vec2s dest) {
+ glm_vec2_muladd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief mul vector with scalar and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @returns dest += (a * b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_muladds(vec2s a, float s, vec2s dest) {
+ glm_vec2_muladds(a.raw, s, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief add max of two vector to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += max(a, b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_maxadd(vec2s a, vec2s b, vec2s dest) {
+ glm_vec2_maxadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief add min of two vector to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @returns dest += min(a, b)
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_minadd(vec2s a, vec2s b, vec2s dest) {
+ glm_vec2_minadd(a.raw, b.raw, dest.raw);
+ return dest;
+}
+
+/*!
+ * @brief negate vector components
+ *
+ * @param[in] v vector
+ * @returns negated vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_negate(vec2s v) {
+ glm_vec2_negate(v.raw);
+ return v;
+}
+
+/*!
+ * @brief normalize vec2 and store result in same vec
+ *
+ * @param[in] v vector
+ * @returns normalized vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_normalize(vec2s v) {
+ glm_vec2_normalize(v.raw);
+ return v;
+}
+
+/*!
+ * @brief rotate vec2 around axis by angle using Rodrigues' rotation formula
+ *
+ * @param[in] v vector
+ * @param[in] axis axis vector (must be unit vector)
+ * @param[in] angle angle by radians
+ * @returns rotated vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_rotate(vec2s v, float angle, vec2s axis) {
+ glm_vec2_rotate(v.raw, angle, axis.raw);
+ return v;
+}
+
+/**
+ * @brief distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return distance
+ */
+CGLM_INLINE
+float
+glms_vec2_distance(vec2s a, vec2s b) {
+ return glm_vec2_distance(a.raw, b.raw);
+}
+
+/**
+ * @brief squared distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return squared distance (distance * distance)
+ */
+CGLM_INLINE
+float
+glms_vec2_distance2(vec2s a, vec2s b) {
+ return glm_vec2_distance2(a.raw, b.raw);
+}
+
+/*!
+ * @brief max values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_maxv(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_maxv(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief min values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @returns destination
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_minv(vec2s a, vec2s b) {
+ vec2s r;
+ glm_vec2_minv(a.raw, b.raw, r.raw);
+ return r;
+}
+
+/*!
+ * @brief clamp vector's individual members between min and max values
+ *
+ * @param[in] v vector
+ * @param[in] minVal minimum value
+ * @param[in] maxVal maximum value
+ * @returns clamped vector
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_clamp(vec2s v, float minVal, float maxVal) {
+ glm_vec2_clamp(v.raw, minVal, maxVal);
+ return v;
+}
+
+/*!
+ * @brief linear interpolation between two vectors
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount)
+ * @returns destination
+ */
+CGLM_INLINE
+vec2s
+glms_vec2_lerp(vec2s from, vec2s to, float t) {
+ vec2s r;
+ glm_vec2_lerp(from.raw, to.raw, t, r.raw);
+ return r;
+}
+
+#endif /* cglms_vec2s_h */
diff --git a/include/cglm/types-struct.h b/include/cglm/types-struct.h
index 6af55ed..f211e0a 100644
--- a/include/cglm/types-struct.h
+++ b/include/cglm/types-struct.h
@@ -101,8 +101,19 @@ typedef union CGLM_ALIGN_IF(16) versors {
#endif
} versors;
+typedef union mat2s {
+ mat2 raw;
+ vec2s col[2];
+#if CGLM_USE_ANONYMOUS_STRUCT
+ struct {
+ float m00, m01;
+ float m10, m11;
+ };
+#endif
+} mat2s;
+
typedef union mat3s {
- mat3 raw;
+ mat3 raw;
vec3s col[3];
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
@@ -114,7 +125,7 @@ typedef union mat3s {
} mat3s;
typedef union CGLM_ALIGN_MAT mat4s {
- mat4 raw;
+ mat4 raw;
vec4s col[4];
#if CGLM_USE_ANONYMOUS_STRUCT
struct {
diff --git a/include/cglm/types.h b/include/cglm/types.h
index f2bc7c1..60eb538 100644
--- a/include/cglm/types.h
+++ b/include/cglm/types.h
@@ -38,7 +38,8 @@ typedef int ivec3[3];
typedef CGLM_ALIGN_IF(16) float vec4[4];
typedef vec4 versor; /* |x, y, z, w| -> w is the last */
typedef vec3 mat3[3];
-typedef CGLM_ALIGN_MAT vec4 mat4[4];
+typedef CGLM_ALIGN_IF(16) vec2 mat2[2];
+typedef CGLM_ALIGN_MAT vec4 mat4[4];
/*
Important: cglm stores quaternion as [x, y, z, w] in memory since v0.4.0
diff --git a/include/cglm/vec2-ext.h b/include/cglm/vec2-ext.h
new file mode 100644
index 0000000..da5ba65
--- /dev/null
+++ b/include/cglm/vec2-ext.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Functions:
+ CGLM_INLINE void glm_vec2_fill(vec2 v, float val)
+ CGLM_INLINE bool glm_vec2_eq(vec2 v, float val);
+ CGLM_INLINE bool glm_vec2_eq_eps(vec2 v, float val);
+ CGLM_INLINE bool glm_vec2_eq_all(vec2 v);
+ CGLM_INLINE bool glm_vec2_eqv(vec2 a, vec2 b);
+ CGLM_INLINE bool glm_vec2_eqv_eps(vec2 a, vec2 b);
+ CGLM_INLINE float glm_vec2_max(vec2 v);
+ CGLM_INLINE float glm_vec2_min(vec2 v);
+ CGLM_INLINE bool glm_vec2_isnan(vec2 v);
+ CGLM_INLINE bool glm_vec2_isinf(vec2 v);
+ CGLM_INLINE bool glm_vec2_isvalid(vec2 v);
+ CGLM_INLINE void glm_vec2_sign(vec2 v, vec2 dest);
+ CGLM_INLINE void glm_vec2_sqrt(vec2 v, vec2 dest);
+ */
+
+#ifndef cglm_vec2_ext_h
+#define cglm_vec2_ext_h
+
+#include "common.h"
+#include "util.h"
+
+/*!
+ * @brief fill a vector with specified value
+ *
+ * @param[out] v dest
+ * @param[in] val value
+ */
+CGLM_INLINE
+void
+glm_vec2_fill(vec2 v, float val) {
+ v[0] = v[1] = val;
+}
+
+/*!
+ * @brief check if vector is equal to value (without epsilon)
+ *
+ * @param[in] v vector
+ * @param[in] val value
+ */
+CGLM_INLINE
+bool
+glm_vec2_eq(vec2 v, float val) {
+ return v[0] == val && v[0] == v[1];
+}
+
+/*!
+ * @brief check if vector is equal to value (with epsilon)
+ *
+ * @param[in] v vector
+ * @param[in] val value
+ */
+CGLM_INLINE
+bool
+glm_vec2_eq_eps(vec2 v, float val) {
+ return fabsf(v[0] - val) <= FLT_EPSILON
+ && fabsf(v[1] - val) <= FLT_EPSILON;
+}
+
+/*!
+ * @brief check if vectors members are equal (without epsilon)
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_eq_all(vec2 v) {
+ return v[0] == v[1];
+}
+
+/*!
+ * @brief check if vector is equal to another (without epsilon)
+ *
+ * @param[in] a vector
+ * @param[in] b vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_eqv(vec2 a, vec2 b) {
+ return a[0] == b[0] && a[1] == b[1];
+}
+
+/*!
+ * @brief check if vector is equal to another (with epsilon)
+ *
+ * @param[in] a vector
+ * @param[in] b vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_eqv_eps(vec2 a, vec2 b) {
+ return fabsf(a[0] - b[0]) <= FLT_EPSILON
+ && fabsf(a[1] - b[1]) <= FLT_EPSILON;
+}
+
+/*!
+ * @brief max value of vector
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+float
+glm_vec2_max(vec2 v) {
+ return glm_max(v[0], v[1]);
+}
+
+/*!
+ * @brief min value of vector
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+float
+glm_vec2_min(vec2 v) {
+ return glm_min(v[0], v[1]);
+}
+
+/*!
+ * @brief check if all items are NaN (not a number)
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_isnan(vec2 v) {
+ return isnan(v[0]) || isnan(v[1]);
+}
+
+/*!
+ * @brief check if all items are INFINITY
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_isinf(vec2 v) {
+ return isinf(v[0]) || isinf(v[1]);
+}
+
+/*!
+ * @brief check if all items are valid number
+ * you should only use this in DEBUG mode or very critical asserts
+ *
+ * @param[in] v vector
+ */
+CGLM_INLINE
+bool
+glm_vec2_isvalid(vec2 v) {
+ return !glm_vec2_isnan(v) && !glm_vec2_isinf(v);
+}
+
+/*!
+ * @brief get sign of 32 bit float as +1, -1, 0
+ *
+ * Important: It returns 0 for zero/NaN input
+ *
+ * @param v vector
+ */
+CGLM_INLINE
+void
+glm_vec2_sign(vec2 v, vec2 dest) {
+ dest[0] = glm_signf(v[0]);
+ dest[1] = glm_signf(v[1]);
+}
+
+/*!
+ * @brief square root of each vector item
+ *
+ * @param[in] v vector
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_sqrt(vec2 v, vec2 dest) {
+ dest[0] = sqrtf(v[0]);
+ dest[1] = sqrtf(v[1]);
+}
+
+#endif /* cglm_vec2_ext_h */
diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h
new file mode 100644
index 0000000..73ecea9
--- /dev/null
+++ b/include/cglm/vec2.h
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+/*
+ Macros:
+ GLM_VEC2_ONE_INIT
+ GLM_VEC2_ZERO_INIT
+ GLM_VEC2_ONE
+ GLM_VEC2_ZERO
+
+ Functions:
+ CGLM_INLINE void glm_vec2(float * __restrict v, vec2 dest)
+ CGLM_INLINE void glm_vec2_copy(vec2 a, vec2 dest)
+ CGLM_INLINE void glm_vec2_zero(vec2 v)
+ CGLM_INLINE void glm_vec2_one(vec2 v)
+ CGLM_INLINE float glm_vec2_dot(vec2 a, vec2 b)
+ CGLM_INLINE float glm_vec2_cross(vec2 a, vec2 b)
+ CGLM_INLINE float glm_vec2_norm2(vec2 v)
+ CGLM_INLINE float glm_vec2_norm(vec2 vec)
+ CGLM_INLINE void glm_vec2_add(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_adds(vec2 v, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_sub(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_subs(vec2 v, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_mul(vec2 a, vec2 b, vec2 d)
+ CGLM_INLINE void glm_vec2_scale(vec2 v, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_scale_as(vec2 v, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_div(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_divs(vec2 v, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_addadd(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_subadd(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_muladd(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_muladds(vec2 a, float s, vec2 dest)
+ CGLM_INLINE void glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_minadd(vec2 a, vec2 b, vec2 dest)
+ CGLM_INLINE void glm_vec2_negate_to(vec2 v, vec2 dest)
+ CGLM_INLINE void glm_vec2_negate(vec2 v)
+ CGLM_INLINE void glm_vec2_normalize(vec2 v)
+ CGLM_INLINE void glm_vec2_normalize_to(vec2 vec, vec2 dest)
+ CGLM_INLINE void glm_vec2_rotate(vec2 v, float angle, vec2 dest)
+ CGLM_INLINE float glm_vec2_distance2(vec2 a, vec2 b)
+ CGLM_INLINE float glm_vec2_distance(vec2 a, vec2 b)
+ CGLM_INLINE void glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest)
+ CGLM_INLINE void glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest)
+ CGLM_INLINE void glm_vec2_clamp(vec2 v, float minVal, float maxVal)
+ CGLM_INLINE void glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest)
+
+ */
+
+#ifndef cglm_vec2_h
+#define cglm_vec2_h
+
+#include "common.h"
+#include "util.h"
+#include "vec2-ext.h"
+
+#define GLM_VEC2_ONE_INIT {1.0f, 1.0f}
+#define GLM_VEC2_ZERO_INIT {0.0f, 0.0f}
+
+#define GLM_VEC2_ONE ((vec2)GLM_VEC2_ONE_INIT)
+#define GLM_VEC2_ZERO ((vec2)GLM_VEC2_ZERO_INIT)
+
+/*!
+ * @brief init vec2 using another vector
+ *
+ * @param[in] v a vector
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2(float * __restrict v, vec2 dest) {
+ dest[0] = v[0];
+ dest[1] = v[1];
+}
+
+/*!
+ * @brief copy all members of [a] to [dest]
+ *
+ * @param[in] a source
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2_copy(vec2 a, vec2 dest) {
+ dest[0] = a[0];
+ dest[1] = a[1];
+}
+
+/*!
+ * @brief make vector zero
+ *
+ * @param[in, out] v vector
+ */
+CGLM_INLINE
+void
+glm_vec2_zero(vec2 v) {
+ v[0] = v[1] = 0.0f;
+}
+
+/*!
+ * @brief make vector one
+ *
+ * @param[in, out] v vector
+ */
+CGLM_INLINE
+void
+glm_vec2_one(vec2 v) {
+ v[0] = v[1] = 1.0f;
+}
+
+/*!
+ * @brief vec2 dot product
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return dot product
+ */
+CGLM_INLINE
+float
+glm_vec2_dot(vec2 a, vec2 b) {
+ return a[0] * b[0] + a[1] * b[1];
+}
+
+/*!
+ * @brief vec2 cross product
+ *
+ * REF: http://allenchou.net/2013/07/cross-product-of-2d-vectors/
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ *
+ * @return Z component of cross product
+ */
+CGLM_INLINE
+float
+glm_vec2_cross(vec2 a, vec2 b) {
+ /* just calculate the z-component */
+ return a[0] * b[1] - a[1] * b[0];
+}
+
+/*!
+ * @brief norm * norm (magnitude) of vec
+ *
+ * we can use this func instead of calling norm * norm, because it would call
+ * sqrtf fuction twice but with this func we can avoid func call, maybe this is
+ * not good name for this func
+ *
+ * @param[in] v vector
+ *
+ * @return norm * norm
+ */
+CGLM_INLINE
+float
+glm_vec2_norm2(vec2 v) {
+ return glm_vec2_dot(v, v);
+}
+
+/*!
+ * @brief norm (magnitude) of vec2
+ *
+ * @param[in] vec vector
+ *
+ * @return norm
+ */
+CGLM_INLINE
+float
+glm_vec2_norm(vec2 vec) {
+ return sqrtf(glm_vec2_norm2(vec));
+}
+
+/*!
+ * @brief add a vector to b vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_add(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = a[0] + b[0];
+ dest[1] = a[1] + b[1];
+}
+
+/*!
+ * @brief add scalar to v vector store result in dest (d = v + s)
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_adds(vec2 v, float s, vec2 dest) {
+ dest[0] = v[0] + s;
+ dest[1] = v[1] + s;
+}
+
+/*!
+ * @brief subtract b vector from a vector store result in dest
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_sub(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = a[0] - b[0];
+ dest[1] = a[1] - b[1];
+}
+
+/*!
+ * @brief subtract scalar from v vector store result in dest (d = v - s)
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_subs(vec2 v, float s, vec2 dest) {
+ dest[0] = v[0] - s;
+ dest[1] = v[1] - s;
+}
+
+/*!
+ * @brief multiply two vector (component-wise multiplication)
+ *
+ * @param a v1
+ * @param b v2
+ * @param dest v3 = (a[0] * b[0], a[1] * b[1])
+ */
+CGLM_INLINE
+void
+glm_vec2_mul(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = a[0] * b[0];
+ dest[1] = a[1] * b[1];
+}
+
+/*!
+ * @brief multiply/scale vector with scalar: result = v * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_scale(vec2 v, float s, vec2 dest) {
+ dest[0] = v[0] * s;
+ dest[1] = v[1] * s;
+}
+
+/*!
+ * @brief scale as vector specified: result = unit(v) * s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_scale_as(vec2 v, float s, vec2 dest) {
+ float norm;
+ norm = glm_vec2_norm(v);
+
+ if (norm == 0.0f) {
+ glm_vec2_zero(dest);
+ return;
+ }
+
+ glm_vec2_scale(v, s / norm, dest);
+}
+
+/*!
+ * @brief div vector with another component-wise division: d = a / b
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest result = (a[0]/b[0], a[1]/b[1])
+ */
+CGLM_INLINE
+void
+glm_vec2_div(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = a[0] / b[0];
+ dest[1] = a[1] / b[1];
+}
+
+/*!
+ * @brief div vector with scalar: d = v / s
+ *
+ * @param[in] v vector
+ * @param[in] s scalar
+ * @param[out] dest result = (a[0]/s, a[1]/s)
+ */
+CGLM_INLINE
+void
+glm_vec2_divs(vec2 v, float s, vec2 dest) {
+ dest[0] = v[0] / s;
+ dest[1] = v[1] / s;
+}
+
+/*!
+ * @brief add two vectors and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest dest += (a + b)
+ */
+CGLM_INLINE
+void
+glm_vec2_addadd(vec2 a, vec2 b, vec2 dest) {
+ dest[0] += a[0] + b[0];
+ dest[1] += a[1] + b[1];
+}
+
+/*!
+ * @brief sub two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest dest += (a + b)
+ */
+CGLM_INLINE
+void
+glm_vec2_subadd(vec2 a, vec2 b, vec2 dest) {
+ dest[0] += a[0] - b[0];
+ dest[1] += a[1] - b[1];
+}
+
+/*!
+ * @brief mul two vectors and add result to dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest dest += (a * b)
+ */
+CGLM_INLINE
+void
+glm_vec2_muladd(vec2 a, vec2 b, vec2 dest) {
+ dest[0] += a[0] * b[0];
+ dest[1] += a[1] * b[1];
+}
+
+/*!
+ * @brief mul vector with scalar and add result to sum
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector
+ * @param[in] s scalar
+ * @param[out] dest dest += (a * b)
+ */
+CGLM_INLINE
+void
+glm_vec2_muladds(vec2 a, float s, vec2 dest) {
+ dest[0] += a[0] * s;
+ dest[1] += a[1] * s;
+}
+
+/*!
+ * @brief add max of two vector to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest dest += max(a, b)
+ */
+CGLM_INLINE
+void
+glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest) {
+ dest[0] += glm_max(a[0], b[0]);
+ dest[1] += glm_max(a[1], b[1]);
+}
+
+/*!
+ * @brief add min of two vector to result/dest
+ *
+ * it applies += operator so dest must be initialized
+ *
+ * @param[in] a vector 1
+ * @param[in] b vector 2
+ * @param[out] dest dest += min(a, b)
+ */
+CGLM_INLINE
+void
+glm_vec2_minadd(vec2 a, vec2 b, vec2 dest) {
+ dest[0] += glm_min(a[0], b[0]);
+ dest[1] += glm_min(a[1], b[1]);
+}
+
+/*!
+ * @brief negate vector components and store result in dest
+ *
+ * @param[in] v vector
+ * @param[out] dest result vector
+ */
+CGLM_INLINE
+void
+glm_vec2_negate_to(vec2 v, vec2 dest) {
+ dest[0] = -v[0];
+ dest[1] = -v[1];
+}
+
+/*!
+ * @brief negate vector components
+ *
+ * @param[in, out] v vector
+ */
+CGLM_INLINE
+void
+glm_vec2_negate(vec2 v) {
+ glm_vec2_negate_to(v, v);
+}
+
+/*!
+ * @brief normalize vector and store result in same vec
+ *
+ * @param[in, out] v vector
+ */
+CGLM_INLINE
+void
+glm_vec2_normalize(vec2 v) {
+ float norm;
+
+ norm = glm_vec2_norm(v);
+
+ if (norm == 0.0f) {
+ v[0] = v[1] = 0.0f;
+ return;
+ }
+
+ glm_vec2_scale(v, 1.0f / norm, v);
+}
+
+/*!
+ * @brief normalize vector to dest
+ *
+ * @param[in] v source
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2_normalize_to(vec2 v, vec2 dest) {
+ float norm;
+
+ norm = glm_vec2_norm(v);
+
+ if (norm == 0.0f) {
+ glm_vec2_zero(dest);
+ return;
+ }
+
+ glm_vec2_scale(v, 1.0f / norm, dest);
+}
+
+/*!
+ * @brief rotate vec2 around origin by angle (CCW: counterclockwise)
+ *
+ * Formula:
+ * 𝑥2 = cos(a)𝑥1 − sin(a)𝑦1
+ * 𝑦2 = sin(a)𝑥1 + cos(a)𝑦1
+ *
+ * @param[in] v vector to rotate
+ * @param[in] angle angle by radians
+ * @param[out] dest destination vector
+ */
+CGLM_INLINE
+void
+glm_vec2_rotate(vec2 v, float angle, vec2 dest) {
+ float c, s, x1, y1;
+
+ c = cosf(angle);
+ s = sinf(angle);
+
+ x1 = v[0];
+ y1 = v[1];
+
+ dest[0] = c * x1 - s * y1;
+ dest[1] = s * x1 + c * y1;
+}
+
+/**
+ * @brief squared distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return returns squared distance (distance * distance)
+ */
+CGLM_INLINE
+float
+glm_vec2_distance2(vec2 a, vec2 b) {
+ return glm_pow2(b[0] - a[0]) + glm_pow2(b[1] - a[1]);
+}
+
+/**
+ * @brief distance between two vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @return returns distance
+ */
+CGLM_INLINE
+float
+glm_vec2_distance(vec2 a, vec2 b) {
+ return sqrtf(glm_vec2_distance2(a, b));
+}
+
+/*!
+ * @brief max values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2_maxv(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = glm_max(a[0], b[0]);
+ dest[1] = glm_max(a[1], b[1]);
+}
+
+/*!
+ * @brief min values of vectors
+ *
+ * @param[in] a vector1
+ * @param[in] b vector2
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2_minv(vec2 a, vec2 b, vec2 dest) {
+ dest[0] = glm_min(a[0], b[0]);
+ dest[1] = glm_min(a[1], b[1]);
+}
+
+/*!
+ * @brief clamp vector's individual members between min and max values
+ *
+ * @param[in, out] v vector
+ * @param[in] minval minimum value
+ * @param[in] maxval maximum value
+ */
+CGLM_INLINE
+void
+glm_vec2_clamp(vec2 v, float minval, float maxval) {
+ v[0] = glm_clamp(v[0], minval, maxval);
+ v[1] = glm_clamp(v[1], minval, maxval);
+}
+
+/*!
+ * @brief linear interpolation between two vector
+ *
+ * formula: from + s * (to - from)
+ *
+ * @param[in] from from value
+ * @param[in] to to value
+ * @param[in] t interpolant (amount) clamped between 0 and 1
+ * @param[out] dest destination
+ */
+CGLM_INLINE
+void
+glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) {
+ vec2 s, v;
+
+ /* from + s * (to - from) */
+ glm_vec2_fill(s, glm_clamp_zo(t));
+ glm_vec2_sub(to, from, v);
+ glm_vec2_mul(s, v, v);
+ glm_vec2_add(from, v, dest);
+}
+
+#endif /* cglm_vec2_h */
diff --git a/src/mat2.c b/src/mat2.c
new file mode 100644
index 0000000..99a282d
--- /dev/null
+++ b/src/mat2.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#include "../include/cglm/cglm.h"
+#include "../include/cglm/call.h"
+
+CGLM_EXPORT
+void
+glmc_mat2_copy(mat2 mat, mat2 dest) {
+ glm_mat2_copy(mat, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_identity(mat2 mat) {
+ glm_mat2_identity(mat);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_identity_array(mat2 * __restrict mat, size_t count) {
+ glm_mat2_identity_array(mat, count);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_zero(mat2 mat) {
+ glm_mat2_zero(mat);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
+ glm_mat2_mul(m1, m2, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_transpose_to(mat2 m, mat2 dest) {
+ glm_mat2_transpose_to(m, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_transpose(mat2 m) {
+ glm_mat2_transpose(m);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_mulv(mat2 m, vec2 v, vec2 dest) {
+ glm_mat2_mulv(m, v, dest);
+}
+
+CGLM_EXPORT
+float
+glmc_mat2_trace(mat2 m) {
+ return glm_mat2_trace(m);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_scale(mat2 m, float s) {
+ glm_mat2_scale(m, s);
+}
+
+CGLM_EXPORT
+float
+glmc_mat2_det(mat2 mat) {
+ return glm_mat2_det(mat);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_inv(mat2 mat, mat2 dest) {
+ glm_mat2_inv(mat, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_swap_col(mat2 mat, int col1, int col2) {
+ glm_mat2_swap_col(mat, col1, col2);
+}
+
+CGLM_EXPORT
+void
+glmc_mat2_swap_row(mat2 mat, int row1, int row2) {
+ glm_mat2_swap_row(mat, row1, row2);
+}
+
+CGLM_EXPORT
+float
+glmc_mat2_rmc(vec2 r, mat2 m, vec2 c) {
+ return glm_mat2_rmc(r, m, c);
+}
diff --git a/src/vec2.c b/src/vec2.c
new file mode 100644
index 0000000..3048688
--- /dev/null
+++ b/src/vec2.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#include "../include/cglm/cglm.h"
+#include "../include/cglm/call.h"
+
+CGLM_EXPORT
+void
+glmc_vec2(float * __restrict v, vec2 dest) {
+ glm_vec2(v, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_copy(vec2 a, vec2 dest) {
+ glm_vec2_copy(a, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_zero(vec2 v) {
+ glm_vec2_zero(v);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_one(vec2 v) {
+ glm_vec2_one(v);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_dot(vec2 a, vec2 b) {
+ return glm_vec2_dot(a, b);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_cross(vec2 a, vec2 b) {
+ return glm_vec2_cross(a, b);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_norm2(vec2 v) {
+ return glm_vec2_norm2(v);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_norm(vec2 v) {
+ return glm_vec2_norm(v);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_add(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_add(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_adds(vec2 v, float s, vec2 dest) {
+ glm_vec2_adds(v, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_sub(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_sub(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_subs(vec2 v, float s, vec2 dest) {
+ glm_vec2_subs(v, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_mul(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_mul(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_scale(vec2 v, float s, vec2 dest) {
+ glm_vec2_scale(v, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_scale_as(vec2 v, float s, vec2 dest) {
+ glm_vec2_scale_as(v, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_div(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_div(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_divs(vec2 v, float s, vec2 dest) {
+ glm_vec2_divs(v, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_addadd(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_addadd(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_subadd(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_subadd(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_muladd(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_muladd(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_muladds(vec2 a, float s, vec2 dest) {
+ glm_vec2_muladds(a, s, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_maxadd(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_maxadd(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_minadd(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_minadd(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_negate_to(vec2 v, vec2 dest) {
+ glm_vec2_negate_to(v, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_negate(vec2 v) {
+ glm_vec2_negate(v);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_normalize(vec2 v) {
+ glm_vec2_normalize(v);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_normalize_to(vec2 v, vec2 dest) {
+ glm_vec2_normalize_to(v, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_rotate(vec2 v, float angle, vec2 dest) {
+ glm_vec2_rotate(v, angle, dest);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_distance2(vec2 a, vec2 b) {
+ return glm_vec2_distance2(a, b);
+}
+
+CGLM_EXPORT
+float
+glmc_vec2_distance(vec2 a, vec2 b) {
+ return glm_vec2_distance(a, b);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_maxv(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_maxv(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_minv(vec2 a, vec2 b, vec2 dest) {
+ glm_vec2_minv(a, b, dest);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_clamp(vec2 v, float minval, float maxval) {
+ glm_vec2_clamp(v, minval, maxval);
+}
+
+CGLM_EXPORT
+void
+glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) {
+ glm_vec2_lerp(from, to, t, dest);
+}
diff --git a/test/src/test_affine.h b/test/src/test_affine.h
index 0487716..2199a43 100644
--- a/test/src/test_affine.h
+++ b/test/src/test_affine.h
@@ -571,7 +571,7 @@ TEST_IMPL(GLM_PREFIX, decompose_rs) {
glm_mat4_mul(m2, r, m2);
glm_scale(m2, s1);
- ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001));
+ ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f));
TEST_SUCCESS
}
@@ -607,7 +607,7 @@ TEST_IMPL(GLM_PREFIX, decompose) {
glm_mat4_mul(m2, r, m2);
glm_scale(m2, s);
- ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001));
+ ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f));
glm_mat4_identity(m1);
glm_translate(m1, (vec3){56.0f, 13.0f, 90.0f});
@@ -628,7 +628,7 @@ TEST_IMPL(GLM_PREFIX, decompose) {
glm_translate(m2, t);
glm_mat4_mul(m2, r, m2);
glm_scale(m2, s);
- ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001));
+ ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f));
TEST_SUCCESS
}
diff --git a/test/src/test_common.c b/test/src/test_common.c
index 2f177fd..46b6e63 100644
--- a/test/src/test_common.c
+++ b/test/src/test_common.c
@@ -14,10 +14,10 @@ test_rand_mat4(mat4 dest) {
dest[3][0] = drand48();
dest[3][1] = drand48();
dest[3][2] = drand48();
-
+
/* random rotatation around random axis with random angle */
glm_rotate(dest, drand48(), (vec3){drand48(), drand48(), drand48()});
-
+
/* random scale */
/* glm_scale(dest, (vec3){drand48(), drand48(), drand48()}); */
}
@@ -31,6 +31,14 @@ test_rand_mat3(mat3 dest) {
glm_mat4_pick3(m4, dest);
}
+void
+test_rand_mat2(mat2 dest) {
+ dest[0][0] = drand48();
+ dest[0][1] = drand48();
+ dest[1][0] = drand48();
+ dest[1][1] = drand48();
+}
+
void
test_rand_vec3(vec3 dest) {
dest[0] = drand48();
@@ -39,7 +47,7 @@ test_rand_vec3(vec3 dest) {
}
vec3s
-test_rand_vec3s() {
+test_rand_vec3s(void) {
vec3s r;
test_rand_vec3(r.raw);
return r;
@@ -54,7 +62,7 @@ test_rand_vec4(vec4 dest) {
}
vec4s
-test_rand_vec4s() {
+test_rand_vec4s(void) {
vec4s r;
test_rand_vec4(r.raw);
return r;
@@ -73,68 +81,119 @@ test_rand_quat(versor q) {
test_status_t
test_assert_mat4_eq(mat4 m1, mat4 m2) {
- int i, j, k;
+ int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- for (k = 0; k < 4; k++)
- ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009)
+ ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009)
}
}
-
+
TEST_SUCCESS
}
test_status_t
test_assert_mat4_eqt(mat4 m1, mat4 m2) {
- int i, j, k;
+ int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- for (k = 0; k < 4; k++)
- ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009)
+ ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009)
}
}
-
+
TEST_SUCCESS
}
test_status_t
test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps) {
- int i, j, k;
-
+ int i, j;
+
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- for (k = 0; k < 4; k++)
- ASSERT(fabsf(m1[i][j] - m2[i][j]) <= eps);
+ ASSERT(fabsf(m1[i][j] - m2[i][j]) <= eps);
}
}
-
+
+ TEST_SUCCESS
+}
+
+test_status_t
+test_assert_mat2_eqt(mat2 m1, mat2 m2) {
+ int i, j;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009);
+ }
+ }
+
+ TEST_SUCCESS
+}
+
+test_status_t
+test_assert_mat2_eq(mat2 m1, mat2 m2) {
+ int i, j;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009);
+ }
+ }
+
+ TEST_SUCCESS
+}
+
+test_status_t
+test_assert_mat2_eq_identity(mat2 m2) {
+ int i, j;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ if (i == j) {
+ ASSERT(test_eq(m2[i][j], 1.0f))
+ } else {
+ ASSERT(test_eq(m2[i][j], 0.0f))
+ }
+ }
+ }
+
+ TEST_SUCCESS
+}
+
+test_status_t
+test_assert_mat2_eq_zero(mat2 m2) {
+ int i, j;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ ASSERT(test_eq(m2[i][j], 0.0f))
+ }
+ }
+
TEST_SUCCESS
}
test_status_t
test_assert_mat3_eq(mat3 m1, mat3 m2) {
- int i, j, k;
+ int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
- for (k = 0; k < 3; k++)
- ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009);
+ ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009);
}
}
-
+
TEST_SUCCESS
}
test_status_t
test_assert_mat3_eqt(mat3 m1, mat3 m2) {
- int i, j, k;
+ int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
- for (k = 0; k < 3; k++)
- ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009);
+ ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009);
}
}
@@ -204,7 +263,15 @@ test_assert_mat4_eq_zero(mat4 m4) {
test_status_t
test_assert_eqf(float a, float b) {
ASSERT(fabsf(a - b) <= 0.000009); /* rounding errors */
-
+
+ TEST_SUCCESS
+}
+
+test_status_t
+test_assert_vec2_eq(vec2 v1, vec2 v2) {
+ ASSERT(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */
+ ASSERT(fabsf(v1[1] - v2[1]) <= 0.000009);
+
TEST_SUCCESS
}
@@ -213,14 +280,14 @@ test_assert_vec3_eq(vec3 v1, vec3 v2) {
ASSERT(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */
ASSERT(fabsf(v1[1] - v2[1]) <= 0.000009);
ASSERT(fabsf(v1[2] - v2[2]) <= 0.000009);
-
+
TEST_SUCCESS
}
test_status_t
test_assert_vec3s_eq(vec3s v1, vec3s v2) {
test_assert_vec3_eq(v1.raw, v2.raw);
-
+
TEST_SUCCESS
}
@@ -230,14 +297,14 @@ test_assert_vec4_eq(vec4 v1, vec4 v2) {
ASSERT(fabsf(v1[1] - v2[1]) <= 0.000009);
ASSERT(fabsf(v1[2] - v2[2]) <= 0.000009);
ASSERT(fabsf(v1[3] - v2[3]) <= 0.000009);
-
+
TEST_SUCCESS
}
test_status_t
test_assert_vec4s_eq(vec4s v1, vec4s v2) {
test_assert_vec4_eq(v1.raw, v2.raw);
-
+
TEST_SUCCESS
}
@@ -247,7 +314,7 @@ test_assert_quat_eq_abs(versor v1, versor v2) {
ASSERT(fabsf(fabsf(v1[1]) - fabsf(v2[1])) <= 0.0009);
ASSERT(fabsf(fabsf(v1[2]) - fabsf(v2[2])) <= 0.0009);
ASSERT(fabsf(fabsf(v1[3]) - fabsf(v2[3])) <= 0.0009);
-
+
TEST_SUCCESS
}
@@ -257,7 +324,7 @@ test_assert_quat_eq(versor v1, versor v2) {
ASSERT(fabsf(v1[1] - v2[1]) <= 0.000009);
ASSERT(fabsf(v1[2] - v2[2]) <= 0.000009);
ASSERT(fabsf(v1[3] - v2[3]) <= 0.000009);
-
+
TEST_SUCCESS
}
diff --git a/test/src/test_common.h b/test/src/test_common.h
index 8443ec3..86801b6 100644
--- a/test/src/test_common.h
+++ b/test/src/test_common.h
@@ -16,6 +16,9 @@ test_rand_mat4(mat4 dest);
void
test_rand_mat3(mat3 dest);
+void
+test_rand_mat2(mat2 dest);
+
test_status_t
test_assert_eqf(float a, float b);
@@ -34,9 +37,24 @@ test_assert_mat4_eq_identity(mat4 m4);
test_status_t
test_assert_mat4_eq_zero(mat4 m4);
+test_status_t
+test_assert_mat2_eqt(mat2 m1, mat2 m2);
+
+test_status_t
+test_assert_mat2_eq(mat2 m1, mat2 m2);
+
+test_status_t
+test_assert_mat2_eq_identity(mat2 m2);
+
+test_status_t
+test_assert_mat2_eq_zero(mat2 m2);
+
test_status_t
test_assert_mat3_eq(mat3 m1, mat3 m2);
+test_status_t
+test_assert_vec2_eq(vec2 v1, vec2 v2);
+
test_status_t
test_assert_mat3_eqt(mat3 m1, mat3 m2);
diff --git a/test/src/test_mat2.h b/test/src/test_mat2.h
new file mode 100644
index 0000000..9141caf
--- /dev/null
+++ b/test/src/test_mat2.h
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#include "test_common.h"
+
+#define A_MATRIX2x2 {{1,2},{5,6}}
+
+#ifndef CGLM_TEST_MAT2_ONCE
+#define CGLM_TEST_MAT2_ONCE
+
+TEST_IMPL(MACRO_GLM_MAT2_IDENTITY_INIT) {
+ mat2 m = GLM_MAT2_IDENTITY_INIT;
+
+ ASSERT(test_eq(m[0][0], 1.0f))
+ ASSERT(test_eq(m[0][1], 0.0f))
+ ASSERT(test_eq(m[1][0], 0.0f))
+ ASSERT(test_eq(m[1][1], 1.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_MAT2_ZERO_INIT) {
+ mat2 m = GLM_MAT2_ZERO_INIT;
+
+ ASSERT(test_eq(m[0][0], 0.0f))
+ ASSERT(test_eq(m[0][1], 0.0f))
+ ASSERT(test_eq(m[1][0], 0.0f))
+ ASSERT(test_eq(m[1][1], 0.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_MAT2_IDENTITY) {
+ ASSERT(test_eq(GLM_MAT2_IDENTITY[0][0], 1.0f))
+ ASSERT(test_eq(GLM_MAT2_IDENTITY[0][1], 0.0f))
+ ASSERT(test_eq(GLM_MAT2_IDENTITY[1][0], 0.0f))
+ ASSERT(test_eq(GLM_MAT2_IDENTITY[1][1], 1.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_MAT2_ZERO) {
+ ASSERT(test_eq(GLM_MAT2_ZERO[0][0], 0.0f))
+ ASSERT(test_eq(GLM_MAT2_ZERO[0][1], 0.0f))
+ ASSERT(test_eq(GLM_MAT2_ZERO[1][0], 0.0f))
+ ASSERT(test_eq(GLM_MAT2_ZERO[1][1], 0.0f))
+
+ TEST_SUCCESS
+}
+
+#endif /* CGLM_TEST_MAT2_ONCE */
+
+TEST_IMPL(GLM_PREFIX, mat2_copy) {
+ mat2 m1 = A_MATRIX2x2;
+ mat2 m2 = GLM_MAT2_IDENTITY_INIT;
+
+ GLM(mat2_copy)(m1, m2);
+
+ test_assert_mat2_eq(m1, m2);
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_identity) {
+ mat2 m1 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m2 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m3;
+
+ GLM(mat2_identity)(m3);
+
+ ASSERTIFY(test_assert_mat2_eq_identity(m1))
+ ASSERTIFY(test_assert_mat2_eq_identity(m2))
+ ASSERTIFY(test_assert_mat2_eq_identity(m3))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_identity_array) {
+ int i, count;
+ mat2 matrices[4] = {
+ A_MATRIX2x2,
+ A_MATRIX2x2,
+ A_MATRIX2x2,
+ A_MATRIX2x2
+ };
+
+ count = 4;
+
+ GLM(mat2_identity_array)(matrices, count);
+
+ for (i = 0; i < count; i++) {
+ ASSERTIFY(test_assert_mat2_eq_identity(matrices[i]))
+ }
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_zero) {
+ mat2 m1 = GLM_MAT2_ZERO_INIT;
+ mat2 m2 = GLM_MAT2_ZERO_INIT;
+ mat2 m3;
+
+ GLM(mat2_zero)(m3);
+
+ ASSERTIFY(test_assert_mat2_eq_zero(m1))
+ ASSERTIFY(test_assert_mat2_eq_zero(m2))
+ ASSERTIFY(test_assert_mat2_eq_zero(m3))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_mul) {
+ mat2 m1 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m2 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m3;
+ mat2 m4 = GLM_MAT2_ZERO_INIT;
+ int i, j, k;
+
+ /* test random matrices */
+ /* random matrices */
+ test_rand_mat2(m1);
+ test_rand_mat2(m2);
+
+ GLM(mat2_mul)(m1, m2, m3);
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ for (k = 0; k < 2; k++)
+ /* column-major */
+ m4[i][j] += m1[k][j] * m2[i][k];
+ }
+ }
+
+ ASSERTIFY(test_assert_mat2_eq(m3, m4))
+
+ /* test pre compiled */
+ GLM(mat2_mul)(m1, m2, m3);
+ ASSERTIFY(test_assert_mat2_eq(m3, m4))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_transpose_to) {
+ mat2 mat = A_MATRIX2x2;
+ mat2 m1;
+
+ GLM(mat2_transpose_to)(mat, m1);
+
+ ASSERTIFY(test_assert_mat2_eqt(mat, m1))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_transpose) {
+ mat2 mat = A_MATRIX2x2;
+ mat2 m1;
+
+ GLM(mat2_copy)(mat, m1);
+ GLM(mat2_transpose)(m1);
+
+ ASSERTIFY(test_assert_mat2_eqt(mat, m1))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_mulv) {
+ vec2 res;
+ mat2 mat = A_MATRIX2x2;
+ vec2 v = {11.0f, 21.0f};
+ int i;
+
+ GLM(mat2_mulv)(mat, v, res);
+
+ for (i = 0; i < 2; i++) {
+ ASSERT(test_eq(res[i], v[0] * mat[0][i] + v[1] * mat[1][i]))
+ }
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_trace) {
+ mat2 mat = A_MATRIX2x2;
+ float trace;
+
+ trace = GLM(mat2_trace)(mat);
+
+ ASSERT(test_eq(trace, mat[0][0] + mat[1][1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_scale) {
+ mat2 m1 = A_MATRIX2x2;
+ mat2 m2 = A_MATRIX2x2;
+ int i, j, scale;
+
+ scale = rand() % 100;
+
+ GLM(mat2_scale)(m1, (float)scale);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++) {
+ ASSERT(test_eq(m1[i][j], m2[i][j] * scale))
+ }
+ }
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_det) {
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_inv) {
+ mat2 m1 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m2 = GLM_MAT2_IDENTITY_INIT;
+ mat2 m3;
+ int i;
+
+ m1[0][0] = 41.0f;
+ m1[0][1] = 0.0f;
+ m1[1][0] = 0.0f;
+ m1[1][1] = 70.0f;
+
+ for (i = 0; i < 10000; i++) {
+ /* test inverse precise */
+ GLM(mat2_inv)(m1, m2);
+ GLM(mat2_inv)(m2, m3);
+
+ ASSERTIFY(test_assert_mat2_eq(m1, m3))
+ }
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_swap_col) {
+ mat2 m1 = A_MATRIX2x2;
+ mat2 m2 = A_MATRIX2x2;
+
+ GLM(mat2_swap_col)(m1, 0, 1);
+
+ ASSERTIFY(test_assert_vec2_eq(m1[0], m2[1]))
+ ASSERTIFY(test_assert_vec2_eq(m1[1], m2[0]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_swap_row) {
+ mat2 m1 = A_MATRIX2x2;
+ mat2 m2 = A_MATRIX2x2;
+
+ GLM(mat2_swap_row)(m1, 0, 1);
+
+ ASSERT(test_eq(m1[0][0], m2[0][1]))
+ ASSERT(test_eq(m1[0][1], m2[0][0]))
+
+ ASSERT(test_eq(m1[1][0], m2[1][1]))
+ ASSERT(test_eq(m1[1][1], m2[1][0]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, mat2_rmc) {
+ mat2 mat = A_MATRIX2x2;
+ vec2 v = {11.0f, 12.0f};
+ vec2 v1;
+ float r1, r2;
+ int i;
+
+ r1 = GLM(mat2_rmc)(v, mat, v);
+
+ for (i = 0; i < 2; i++) {
+ v1[i] = v[0] * mat[i][0] + v[1] * mat[i][1];
+ }
+
+ r2 = v[0] * v1[0] + v[1] * v1[1];
+
+ ASSERT(test_eq(r1, r2))
+
+ TEST_SUCCESS
+}
+
+#undef A_MATRIX2x2
diff --git a/test/src/test_vec2.h b/test/src/test_vec2.h
new file mode 100644
index 0000000..5f04c49
--- /dev/null
+++ b/test/src/test_vec2.h
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#include "test_common.h"
+
+#ifndef CGLM_TEST_VEC2_ONCE
+#define CGLM_TEST_VEC2_ONCE
+
+/* Macros */
+
+TEST_IMPL(MACRO_GLM_VEC2_ONE_INIT) {
+ vec2 v = GLM_VEC2_ONE_INIT;
+
+ ASSERT(test_eq(v[0], 1.0f))
+ ASSERT(test_eq(v[1], 1.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_VEC2_ZERO_INIT) {
+ vec2 v = GLM_VEC2_ZERO_INIT;
+
+ ASSERT(test_eq(v[0], 0.0f))
+ ASSERT(test_eq(v[1], 0.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_VEC2_ONE) {
+ ASSERT(test_eq(GLM_VEC2_ONE[0], 1.0f))
+ ASSERT(test_eq(GLM_VEC2_ONE[1], 1.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(MACRO_GLM_VEC2_ZERO) {
+ ASSERT(test_eq(GLM_VEC2_ZERO[0], 0.0f))
+ ASSERT(test_eq(GLM_VEC2_ZERO[0], 0.0f))
+
+ TEST_SUCCESS
+}
+
+#endif /* CGLM_TEST_VEC2_ONCE */
+
+TEST_IMPL(GLM_PREFIX, vec2) {
+ vec4 v4 = {10.0f, 9.0f, 8.0f, 7.0f};
+ vec3 v3 = {11.0f, 12.0f, 13.0f};
+ vec2 v2;
+
+ GLM(vec2)(v4, v2);
+ ASSERT(test_eq(v2[0], v4[0]))
+ ASSERT(test_eq(v2[1], v4[1]))
+
+ GLM(vec2)(v3, v2);
+ ASSERT(test_eq(v2[0], v3[0]))
+ ASSERT(test_eq(v2[1], v3[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_copy) {
+ vec2 v1 = {10.0f, 9.0f};
+ vec2 v2 = {1.0f, 2.0f};
+
+ GLM(vec2_copy)(v1, v2);
+
+ ASSERTIFY(test_assert_vec2_eq(v1, v2))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_zero) {
+ vec2 v1 = {10.0f, 9.0f};
+ vec2 v2 = {1.0f, 2.0f};
+
+ GLM(vec2_zero)(v1);
+ GLM(vec2_zero)(v2);
+
+ ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ZERO))
+ ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ZERO))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_one) {
+ vec2 v1 = {10.0f, 9.0f};
+ vec2 v2 = {1.0f, 2.0f};
+
+ GLM(vec2_one)(v1);
+ GLM(vec2_one)(v2);
+
+ ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ONE))
+ ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ONE))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_dot) {
+ vec2 a = {10.0f, 9.0f};
+ vec2 b = {1.0f, 2.0f};
+ float dot1, dot2;
+
+ dot1 = GLM(vec2_dot)(a, b);
+ dot2 = a[0] * b[0] + a[1] * b[1];
+
+ ASSERT(test_eq(dot1, dot2))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_cross) {
+ vec2 a = {10.0f, 9.0f};
+ vec2 b = {1.0f, 2.0f};
+ float cprod;
+
+ cprod = a[0] * b[1] - a[1] * b[0];
+
+ ASSERT(test_eq(glm_vec2_cross(a, b), cprod))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_norm2) {
+ vec2 a = {10.0f, 9.0f};
+ float n1, n2;
+
+ n1 = GLM(vec2_norm2)(a);
+ n2 = a[0] * a[0] + a[1] * a[1];
+
+ ASSERT(test_eq(n1, n2))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_norm) {
+ vec2 a = {10.0f, 9.0f};
+ float n1, n2;
+
+ n1 = GLM(vec2_norm)(a);
+ n2 = sqrtf(a[0] * a[0] + a[1] * a[1]);
+
+ ASSERT(test_eq(n1, n2))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_add) {
+ vec2 a = {-10.0f, 9.0f};
+ vec2 b = {12.0f, 19.0f};
+ vec2 c, d;
+
+ c[0] = a[0] + b[0];
+ c[1] = a[1] + b[1];
+
+ GLM(vec2_add)(a, b, d);
+
+ ASSERTIFY(test_assert_vec2_eq(c, d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_adds) {
+ vec4 a = {-10.0f, 9.0f};
+ vec4 c, d;
+ float s = 7.0f;
+
+ c[0] = a[0] + s;
+ c[1] = a[1] + s;
+
+ GLM(vec2_adds)(a, s, d);
+
+ ASSERTIFY(test_assert_vec2_eq(c, d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_sub) {
+ vec2 a = {-10.0f, 9.0f};
+ vec2 b = {12.0f, 19.0f};
+ vec2 c, d;
+
+ c[0] = a[0] - b[0];
+ c[1] = a[1] - b[1];
+
+ GLM(vec2_sub)(a, b, d);
+
+ ASSERTIFY(test_assert_vec2_eq(c, d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_subs) {
+ vec2 a = {-10.0f, 9.0f};
+ vec2 c, d;
+ float s = 7.0f;
+
+ c[0] = a[0] - s;
+ c[1] = a[1] - s;
+
+ GLM(vec2_subs)(a, s, d);
+
+ ASSERTIFY(test_assert_vec2_eq(c, d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_mul) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3;
+
+ GLM(vec2_mul)(v1, v2, v3);
+
+ ASSERT(test_eq(v1[0] * v2[0], v3[0]))
+ ASSERT(test_eq(v1[1] * v2[1], v3[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_scale) {
+ vec2 v1 = {2.0f, -3.0f}, v2;
+ float s = 7.0f;
+
+ GLM(vec2_scale)(v1, s, v2);
+
+ ASSERT(test_eq(v1[0] * s, v2[0]))
+ ASSERT(test_eq(v1[1] * s, v2[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_scale_as) {
+ vec2 v1 = {2.0f, -3.0f}, v2;
+ float s = 7.0f;
+ float norm;
+
+ GLM(vec2_scale_as)(v1, s, v2);
+
+ norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
+ if (norm == 0.0f) {
+ ASSERT(test_eq(v1[0], 0.0f))
+ ASSERT(test_eq(v1[1], 0.0f))
+
+ TEST_SUCCESS
+ }
+
+ norm = s / norm;
+
+ ASSERT(test_eq(v1[0] * norm, v2[0]))
+ ASSERT(test_eq(v1[1] * norm, v2[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_div) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3;
+
+ GLM(vec2_div)(v1, v2, v3);
+
+ ASSERT(test_eq(v1[0] / v2[0], v3[0]))
+ ASSERT(test_eq(v1[1] / v2[1], v3[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_divs) {
+ vec2 v1 = {2.0f, -3.0f}, v2;
+ float s = 7.0f;
+
+ GLM(vec2_divs)(v1, s, v2);
+
+ ASSERT(test_eq(v1[0] / s, v2[0]))
+ ASSERT(test_eq(v1[1] / s, v2[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_addadd) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {1.0f, 2.0f},
+ v4 = {1.0f, 2.0f};
+
+ GLM(vec2_addadd)(v1, v2, v4);
+
+ ASSERT(test_eq(v3[0] + v1[0] + v2[0], v4[0]))
+ ASSERT(test_eq(v3[1] + v1[1] + v2[1], v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_subadd) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {1.0f, 2.0f},
+ v4 = {1.0f, 2.0f};
+
+ GLM(vec2_subadd)(v1, v2, v4);
+
+ ASSERT(test_eq(v3[0] + v1[0] - v2[0], v4[0]))
+ ASSERT(test_eq(v3[1] + v1[1] - v2[1], v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_muladd) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {1.0f, 2.0f},
+ v4 = {1.0f, 2.0f};
+
+ GLM(vec2_muladd)(v1, v2, v4);
+
+ ASSERT(test_eq(v3[0] + v1[0] * v2[0], v4[0]))
+ ASSERT(test_eq(v3[1] + v1[1] * v2[1], v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_muladds) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {1.0f, 2.0f},
+ v3 = {1.0f, 2.0f};
+ float s = 9.0f;
+
+ GLM(vec2_muladds)(v1, s, v3);
+
+ ASSERT(test_eq(v2[0] + v1[0] * s, v3[0]))
+ ASSERT(test_eq(v2[1] + v1[1] * s, v3[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_maxadd) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {1.0f, 2.0f},
+ v4 = {1.0f, 2.0f};
+
+ GLM(vec2_maxadd)(v1, v2, v4);
+
+ ASSERT(test_eq(v3[0] + glm_max(v1[0], v2[0]), v4[0]))
+ ASSERT(test_eq(v3[1] + glm_max(v1[1], v2[1]), v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_minadd) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {1.0f, 2.0f},
+ v4 = {1.0f, 2.0f};
+
+ GLM(vec2_minadd)(v1, v2, v4);
+
+ ASSERT(test_eq(v3[0] + glm_min(v1[0], v2[0]), v4[0]))
+ ASSERT(test_eq(v3[1] + glm_min(v1[1], v2[1]), v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_negate_to) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3, v4;
+
+ GLM(vec2_negate_to)(v1, v3);
+ GLM(vec2_negate_to)(v2, v4);
+
+ ASSERT(test_eq(-v1[0], v3[0]))
+ ASSERT(test_eq(-v1[1], v3[1]))
+
+ ASSERT(test_eq(-v2[0], v4[0]))
+ ASSERT(test_eq(-v2[1], v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_negate) {
+ vec2 v1 = {2.0f, -3.0f},
+ v2 = {-3.0f, 4.0f},
+ v3 = {2.0f, -3.0f},
+ v4 = {-3.0f, 4.0f};
+
+ GLM(vec2_negate)(v1);
+ GLM(vec2_negate)(v2);
+
+ ASSERT(test_eq(-v1[0], v3[0]))
+ ASSERT(test_eq(-v1[1], v3[1]))
+
+ ASSERT(test_eq(-v2[0], v4[0]))
+ ASSERT(test_eq(-v2[1], v4[1]))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_normalize) {
+ vec2 v1 = {2.0f, -3.0f}, v2 = {2.0f, -3.0f};
+ float s = 1.0f;
+ float norm;
+
+ GLM(vec2_normalize)(v2);
+
+ norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
+ if (norm == 0.0f) {
+ ASSERT(test_eq(v1[0], 0.0f))
+ ASSERT(test_eq(v1[1], 0.0f))
+
+ TEST_SUCCESS
+ }
+
+ norm = s / norm;
+
+ ASSERT(test_eq(v1[0] * norm, v2[0]))
+ ASSERT(test_eq(v1[1] * norm, v2[1]))
+
+ glm_vec2_zero(v1);
+ GLM(vec2_normalize)(v1);
+ ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ZERO))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_normalize_to) {
+ vec2 v1 = {2.0f, -3.0f}, v2;
+ float s = 1.0f;
+ float norm;
+
+ GLM(vec2_normalize_to)(v1, v2);
+
+ norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]);
+ if (norm == 0.0f) {
+ ASSERT(test_eq(v1[0], 0.0f))
+ ASSERT(test_eq(v1[1], 0.0f))
+
+ TEST_SUCCESS
+ }
+
+ norm = s / norm;
+
+ ASSERT(test_eq(v1[0] * norm, v2[0]))
+ ASSERT(test_eq(v1[1] * norm, v2[1]))
+
+ glm_vec2_zero(v1);
+ GLM(vec2_normalize_to)(v1, v2);
+ ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ZERO))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_rotate) {
+ vec2 v1 = {1.0f, 0.0f};
+
+ GLM(vec2_rotate)(v1, GLM_PI_2f, v1);
+
+ ASSERT(test_eq(v1[0], 0.0f))
+ ASSERT(test_eq(v1[1], 1.0f))
+
+ GLM(vec2_rotate)(v1, GLM_PI_2f, v1);
+
+ ASSERT(test_eq(v1[0], -1.0f))
+ ASSERT(test_eq(v1[1], 0.0f))
+
+ GLM(vec2_rotate)(v1, GLM_PI_2f, v1);
+
+ ASSERT(test_eq(v1[0], 0.0f))
+ ASSERT(test_eq(v1[1], -1.0f))
+
+ GLM(vec2_rotate)(v1, GLM_PI_2f, v1);
+
+ ASSERT(test_eq(v1[0], 1.0f))
+ ASSERT(test_eq(v1[1], 0.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_distance2) {
+ vec2 v1 = {30.0f, 0.0f},
+ v2 = {0.0f, 0.0f},
+ v3 = {3.0f, 10.0f},
+ v4 = {0.46f, 4.0f};
+ float d;
+
+ d = GLM(vec2_distance2)(v1, v2);
+ ASSERT(test_eq(d, 30.0f * 30.0f))
+
+ d = GLM(vec2_distance2)(v3, v4);
+ ASSERT(test_eq(powf(v3[0] - v4[0], 2.0f)
+ + powf(v3[1] - v4[1], 2.0f), d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_distance) {
+ vec2 v1 = {30.0f, 0.0f},
+ v2 = {0.0f, 0.0f},
+ v3 = {3.0f, 10.0f},
+ v4 = {0.46f, 4.0f};
+ float d;
+
+ d = GLM(vec2_distance)(v1, v2);
+ ASSERT(test_eq(d, 30.0f))
+
+ d = GLM(vec2_distance)(v3, v4);
+ ASSERT(test_eq(sqrtf(powf(v3[0] - v4[0], 2.0f)
+ + powf(v3[1] - v4[1], 2.0f)), d))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_maxv) {
+ vec2 v1, v2, v3;
+ vec2 v5 = {-1.456f, -1.456f};
+ vec2 v6 = {11.0f, 11.0f};
+ vec2 v7 = {78.0f, -78.0f};
+
+ GLM(vec2_maxv)(v5, v6, v1);
+ GLM(vec2_maxv)(v5, v7, v2);
+ GLM(vec2_maxv)(v6, v7, v3);
+
+ ASSERT(test_eq(v1[0], 11.0f))
+ ASSERT(test_eq(v1[1], 11.0f))
+
+ ASSERT(test_eq(v2[0], 78.0f))
+ ASSERT(test_eq(v2[1], -1.456f))
+
+ ASSERT(test_eq(v3[0], 78.0f))
+ ASSERT(test_eq(v3[1], 11.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_minv) {
+ vec2 v1, v2, v3;
+ vec2 v5 = {-1.456f, -1.456f};
+ vec2 v6 = {11.0f, 11.0f};
+ vec2 v7 = {78.0f, -78.0f};
+
+ GLM(vec2_minv)(v5, v6, v1);
+ GLM(vec2_minv)(v5, v7, v2);
+ GLM(vec2_minv)(v6, v7, v3);
+
+ ASSERT(test_eq(v1[0], -1.456f))
+ ASSERT(test_eq(v1[1], -1.456f))
+
+ ASSERT(test_eq(v2[0], -1.456f))
+ ASSERT(test_eq(v2[1], -78.0f))
+
+ ASSERT(test_eq(v3[0], 11.0f))
+ ASSERT(test_eq(v3[1], -78.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_clamp) {
+ vec2 v1 = {-1.456f, -11.456f};
+ vec2 v2 = {0.110f, 111.0f};
+ vec2 v3 = {78.0f, 32.0f};
+
+ GLM(vec2_clamp)(v1, -1.03f, 30.0f);
+ GLM(vec2_clamp)(v2, 0.11f, 111.0f);
+ GLM(vec2_clamp)(v3, -88.0f, 70.0f);
+
+ ASSERT(test_eq(v1[0], -1.03f))
+ ASSERT(test_eq(v1[1], -1.03f))
+
+ ASSERT(test_eq(v2[0], 0.11f))
+ ASSERT(test_eq(v2[1], 111.0f))
+
+ ASSERT(test_eq(v3[0], 70.0f))
+ ASSERT(test_eq(v3[1], 32.0f))
+
+ TEST_SUCCESS
+}
+
+TEST_IMPL(GLM_PREFIX, vec2_lerp) {
+ vec2 v1 = {-100.0f, -200.0f};
+ vec2 v2 = {100.0f, 200.0f};
+ vec2 v3;
+
+ GLM(vec2_lerp)(v1, v2, 0.5f, v3);
+ ASSERT(test_eq(v3[0], 0.0f))
+ ASSERT(test_eq(v3[1], 0.0f))
+
+ GLM(vec2_lerp)(v1, v2, 0.75f, v3);
+ ASSERT(test_eq(v3[0], 50.0f))
+ ASSERT(test_eq(v3[1], 100.0f))
+
+ TEST_SUCCESS
+}
diff --git a/test/src/test_vec3.h b/test/src/test_vec3.h
index 0b6dc4d..4fa1d25 100644
--- a/test/src/test_vec3.h
+++ b/test/src/test_vec3.h
@@ -233,7 +233,7 @@ TEST_IMPL(GLM_PREFIX, vec3_zero) {
GLM(vec3_zero)(v2);
ASSERTIFY(test_assert_vec3_eq(v1, GLM_VEC3_ZERO))
- ASSERTIFY(test_assert_vec3_eq(v1, GLM_VEC3_ZERO))
+ ASSERTIFY(test_assert_vec3_eq(v2, GLM_VEC3_ZERO))
TEST_SUCCESS
}
@@ -335,9 +335,9 @@ TEST_IMPL(GLM_PREFIX, vec3_norm_inf) {
}
TEST_IMPL(GLM_PREFIX, vec3_add) {
- vec4 a = {-10.0f, 9.0f, -8.0f};
- vec4 b = {12.0f, 19.0f, -18.0f};
- vec4 c, d;
+ vec3 a = {-10.0f, 9.0f, -8.0f};
+ vec3 b = {12.0f, 19.0f, -18.0f};
+ vec3 c, d;
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
@@ -351,8 +351,8 @@ TEST_IMPL(GLM_PREFIX, vec3_add) {
}
TEST_IMPL(GLM_PREFIX, vec3_adds) {
- vec4 a = {-10.0f, 9.0f, -8.0f};
- vec4 c, d;
+ vec3 a = {-10.0f, 9.0f, -8.0f};
+ vec3 c, d;
float s = 7.0f;
c[0] = a[0] + s;
@@ -367,9 +367,9 @@ TEST_IMPL(GLM_PREFIX, vec3_adds) {
}
TEST_IMPL(GLM_PREFIX, vec3_sub) {
- vec4 a = {-10.0f, 9.0f, -8.0f};
- vec4 b = {12.0f, 19.0f, -18.0f};
- vec4 c, d;
+ vec3 a = {-10.0f, 9.0f, -8.0f};
+ vec3 b = {12.0f, 19.0f, -18.0f};
+ vec3 c, d;
c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
@@ -383,8 +383,8 @@ TEST_IMPL(GLM_PREFIX, vec3_sub) {
}
TEST_IMPL(GLM_PREFIX, vec3_subs) {
- vec4 a = {-10.0f, 9.0f, -8.0f};
- vec4 c, d;
+ vec3 a = {-10.0f, 9.0f, -8.0f};
+ vec3 c, d;
float s = 7.0f;
c[0] = a[0] - s;
@@ -928,7 +928,6 @@ TEST_IMPL(GLM_PREFIX, vec3_rotate_m4) {
TEST_SUCCESS
}
-
TEST_IMPL(GLM_PREFIX, vec3_rotate_m3) {
vec3 v1 = {1.0f, 0.0f, 0.0f}, v2 = {1.0f, 1.0f, 1.0f};
mat4 x0, y0, z0;
diff --git a/test/src/test_vec4.h b/test/src/test_vec4.h
index 5e20c63..abb882f 100644
--- a/test/src/test_vec4.h
+++ b/test/src/test_vec4.h
@@ -217,7 +217,7 @@ TEST_IMPL(GLM_PREFIX, vec4_zero) {
GLM(vec4_zero)(v2);
ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ZERO))
- ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ZERO))
+ ASSERTIFY(test_assert_vec4_eq(v2, GLM_VEC4_ZERO))
TEST_SUCCESS
}
@@ -230,7 +230,7 @@ TEST_IMPL(GLM_PREFIX, vec4_one) {
GLM(vec4_one)(v2);
ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ONE))
- ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ONE))
+ ASSERTIFY(test_assert_vec4_eq(v2, GLM_VEC4_ONE))
TEST_SUCCESS
}
diff --git a/test/src/tests.c b/test/src/tests.c
index ee7c488..669b33c 100644
--- a/test/src/tests.c
+++ b/test/src/tests.c
@@ -12,8 +12,10 @@
#define GLM_PREFIX glm_
#define GLM(X) (glm_ ## X)
+#include "test_vec2.h"
#include "test_vec3.h"
#include "test_vec4.h"
+#include "test_mat2.h"
#include "test_mat3.h"
#include "test_mat4.h"
#include "test_quat.h"
@@ -31,8 +33,10 @@
#define GLM_PREFIX glmc_
#define GLM(X) (glmc_ ## X)
+#include "test_vec2.h"
#include "test_vec3.h"
#include "test_vec4.h"
+#include "test_mat2.h"
#include "test_mat3.h"
#include "test_mat4.h"
#include "test_quat.h"
diff --git a/test/tests.h b/test/tests.h
index e4933e9..4c9a552 100644
--- a/test/tests.h
+++ b/test/tests.h
@@ -159,6 +159,42 @@ TEST_DECLARE(glmc_mat3_swap_col)
TEST_DECLARE(glmc_mat3_swap_row)
TEST_DECLARE(glmc_mat3_rmc)
+TEST_DECLARE(MACRO_GLM_MAT2_IDENTITY_INIT)
+TEST_DECLARE(MACRO_GLM_MAT2_ZERO_INIT)
+TEST_DECLARE(MACRO_GLM_MAT2_IDENTITY)
+TEST_DECLARE(MACRO_GLM_MAT2_ZERO)
+TEST_DECLARE(glm_mat2_copy)
+TEST_DECLARE(glm_mat2_identity)
+TEST_DECLARE(glm_mat2_identity_array)
+TEST_DECLARE(glm_mat2_zero)
+TEST_DECLARE(glm_mat2_mul)
+TEST_DECLARE(glm_mat2_transpose_to)
+TEST_DECLARE(glm_mat2_transpose)
+TEST_DECLARE(glm_mat2_mulv)
+TEST_DECLARE(glm_mat2_trace)
+TEST_DECLARE(glm_mat2_scale)
+TEST_DECLARE(glm_mat2_det)
+TEST_DECLARE(glm_mat2_inv)
+TEST_DECLARE(glm_mat2_swap_col)
+TEST_DECLARE(glm_mat2_swap_row)
+TEST_DECLARE(glm_mat2_rmc)
+
+TEST_DECLARE(glmc_mat2_copy)
+TEST_DECLARE(glmc_mat2_identity)
+TEST_DECLARE(glmc_mat2_identity_array)
+TEST_DECLARE(glmc_mat2_zero)
+TEST_DECLARE(glmc_mat2_mul)
+TEST_DECLARE(glmc_mat2_transpose_to)
+TEST_DECLARE(glmc_mat2_transpose)
+TEST_DECLARE(glmc_mat2_mulv)
+TEST_DECLARE(glmc_mat2_trace)
+TEST_DECLARE(glmc_mat2_scale)
+TEST_DECLARE(glmc_mat2_det)
+TEST_DECLARE(glmc_mat2_inv)
+TEST_DECLARE(glmc_mat2_swap_col)
+TEST_DECLARE(glmc_mat2_swap_row)
+TEST_DECLARE(glmc_mat2_rmc)
+
/* camera */
TEST_DECLARE(camera_lookat)
TEST_DECLARE(camera_decomp)
@@ -261,6 +297,85 @@ TEST_DECLARE(glmc_quat_rotate_atm)
/* bezier */
TEST_DECLARE(bezier)
+
+/* Macros */
+
+TEST_DECLARE(MACRO_GLM_VEC2_ONE_INIT)
+TEST_DECLARE(MACRO_GLM_VEC2_ZERO_INIT)
+TEST_DECLARE(MACRO_GLM_VEC2_ONE)
+TEST_DECLARE(MACRO_GLM_VEC2_ZERO)
+
+TEST_DECLARE(glm_vec2)
+TEST_DECLARE(glm_vec2_copy)
+TEST_DECLARE(glm_vec2_zero)
+TEST_DECLARE(glm_vec2_one)
+TEST_DECLARE(glm_vec2_dot)
+TEST_DECLARE(glm_vec2_cross)
+TEST_DECLARE(glm_vec2_norm2)
+TEST_DECLARE(glm_vec2_norm)
+TEST_DECLARE(glm_vec2_add)
+TEST_DECLARE(glm_vec2_adds)
+TEST_DECLARE(glm_vec2_sub)
+TEST_DECLARE(glm_vec2_subs)
+TEST_DECLARE(glm_vec2_mul)
+TEST_DECLARE(glm_vec2_scale)
+TEST_DECLARE(glm_vec2_scale_as)
+TEST_DECLARE(glm_vec2_div)
+TEST_DECLARE(glm_vec2_divs)
+TEST_DECLARE(glm_vec2_addadd)
+TEST_DECLARE(glm_vec2_subadd)
+TEST_DECLARE(glm_vec2_muladd)
+TEST_DECLARE(glm_vec2_muladds)
+TEST_DECLARE(glm_vec2_maxadd)
+TEST_DECLARE(glm_vec2_minadd)
+TEST_DECLARE(glm_vec2_negate_to)
+TEST_DECLARE(glm_vec2_negate)
+TEST_DECLARE(glm_vec2_normalize)
+TEST_DECLARE(glm_vec2_normalize_to)
+TEST_DECLARE(glm_vec2_rotate)
+TEST_DECLARE(glm_vec2_distance2)
+TEST_DECLARE(glm_vec2_distance)
+TEST_DECLARE(glm_vec2_maxv)
+TEST_DECLARE(glm_vec2_minv)
+TEST_DECLARE(glm_vec2_clamp)
+TEST_DECLARE(glm_vec2_lerp)
+
+
+TEST_DECLARE(glmc_vec2)
+TEST_DECLARE(glmc_vec2_copy)
+TEST_DECLARE(glmc_vec2_zero)
+TEST_DECLARE(glmc_vec2_one)
+TEST_DECLARE(glmc_vec2_dot)
+TEST_DECLARE(glmc_vec2_cross)
+TEST_DECLARE(glmc_vec2_norm2)
+TEST_DECLARE(glmc_vec2_norm)
+TEST_DECLARE(glmc_vec2_add)
+TEST_DECLARE(glmc_vec2_adds)
+TEST_DECLARE(glmc_vec2_sub)
+TEST_DECLARE(glmc_vec2_subs)
+TEST_DECLARE(glmc_vec2_mul)
+TEST_DECLARE(glmc_vec2_scale)
+TEST_DECLARE(glmc_vec2_scale_as)
+TEST_DECLARE(glmc_vec2_div)
+TEST_DECLARE(glmc_vec2_divs)
+TEST_DECLARE(glmc_vec2_addadd)
+TEST_DECLARE(glmc_vec2_subadd)
+TEST_DECLARE(glmc_vec2_muladd)
+TEST_DECLARE(glmc_vec2_muladds)
+TEST_DECLARE(glmc_vec2_maxadd)
+TEST_DECLARE(glmc_vec2_minadd)
+TEST_DECLARE(glmc_vec2_negate_to)
+TEST_DECLARE(glmc_vec2_negate)
+TEST_DECLARE(glmc_vec2_normalize)
+TEST_DECLARE(glmc_vec2_normalize_to)
+TEST_DECLARE(glmc_vec2_rotate)
+TEST_DECLARE(glmc_vec2_distance2)
+TEST_DECLARE(glmc_vec2_distance)
+TEST_DECLARE(glmc_vec2_maxv)
+TEST_DECLARE(glmc_vec2_minv)
+TEST_DECLARE(glmc_vec2_clamp)
+TEST_DECLARE(glmc_vec2_lerp)
+
/* vec3 */
TEST_DECLARE(MACRO_GLM_VEC3_ONE_INIT)
TEST_DECLARE(MACRO_GLM_VEC3_ZERO_INIT)
@@ -696,7 +811,6 @@ TEST_LIST {
TEST_ENTRY(glmc_mat4_swap_row)
TEST_ENTRY(glmc_mat4_rmc)
-
/* mat3 */
TEST_ENTRY(glm_mat3_copy)
TEST_ENTRY(glm_mat3_identity)
@@ -732,6 +846,42 @@ TEST_LIST {
TEST_ENTRY(glmc_mat3_swap_row)
TEST_ENTRY(glmc_mat3_rmc)
+ TEST_ENTRY(MACRO_GLM_MAT2_IDENTITY_INIT)
+ TEST_ENTRY(MACRO_GLM_MAT2_ZERO_INIT)
+ TEST_ENTRY(MACRO_GLM_MAT2_IDENTITY)
+ TEST_ENTRY(MACRO_GLM_MAT2_ZERO)
+ TEST_ENTRY(glm_mat2_copy)
+ TEST_ENTRY(glm_mat2_identity)
+ TEST_ENTRY(glm_mat2_identity_array)
+ TEST_ENTRY(glm_mat2_zero)
+ TEST_ENTRY(glm_mat2_mul)
+ TEST_ENTRY(glm_mat2_transpose_to)
+ TEST_ENTRY(glm_mat2_transpose)
+ TEST_ENTRY(glm_mat2_mulv)
+ TEST_ENTRY(glm_mat2_trace)
+ TEST_ENTRY(glm_mat2_scale)
+ TEST_ENTRY(glm_mat2_det)
+ TEST_ENTRY(glm_mat2_inv)
+ TEST_ENTRY(glm_mat2_swap_col)
+ TEST_ENTRY(glm_mat2_swap_row)
+ TEST_ENTRY(glm_mat2_rmc)
+
+ TEST_ENTRY(glmc_mat2_copy)
+ TEST_ENTRY(glmc_mat2_identity)
+ TEST_ENTRY(glmc_mat2_identity_array)
+ TEST_ENTRY(glmc_mat2_zero)
+ TEST_ENTRY(glmc_mat2_mul)
+ TEST_ENTRY(glmc_mat2_transpose_to)
+ TEST_ENTRY(glmc_mat2_transpose)
+ TEST_ENTRY(glmc_mat2_mulv)
+ TEST_ENTRY(glmc_mat2_trace)
+ TEST_ENTRY(glmc_mat2_scale)
+ TEST_ENTRY(glmc_mat2_det)
+ TEST_ENTRY(glmc_mat2_inv)
+ TEST_ENTRY(glmc_mat2_swap_col)
+ TEST_ENTRY(glmc_mat2_swap_row)
+ TEST_ENTRY(glmc_mat2_rmc)
+
/* camera */
TEST_ENTRY(camera_lookat)
TEST_ENTRY(camera_decomp)
@@ -834,6 +984,83 @@ TEST_LIST {
/* bezier */
TEST_ENTRY(bezier)
+ /* Macros */
+
+ TEST_ENTRY(MACRO_GLM_VEC2_ONE_INIT)
+ TEST_ENTRY(MACRO_GLM_VEC2_ZERO_INIT)
+ TEST_ENTRY(MACRO_GLM_VEC2_ONE)
+ TEST_ENTRY(MACRO_GLM_VEC2_ZERO)
+
+ TEST_ENTRY(glm_vec2)
+ TEST_ENTRY(glm_vec2_copy)
+ TEST_ENTRY(glm_vec2_zero)
+ TEST_ENTRY(glm_vec2_one)
+ TEST_ENTRY(glm_vec2_dot)
+ TEST_ENTRY(glm_vec2_cross)
+ TEST_ENTRY(glm_vec2_norm2)
+ TEST_ENTRY(glm_vec2_norm)
+ TEST_ENTRY(glm_vec2_add)
+ TEST_ENTRY(glm_vec2_adds)
+ TEST_ENTRY(glm_vec2_sub)
+ TEST_ENTRY(glm_vec2_subs)
+ TEST_ENTRY(glm_vec2_mul)
+ TEST_ENTRY(glm_vec2_scale)
+ TEST_ENTRY(glm_vec2_scale_as)
+ TEST_ENTRY(glm_vec2_div)
+ TEST_ENTRY(glm_vec2_divs)
+ TEST_ENTRY(glm_vec2_addadd)
+ TEST_ENTRY(glm_vec2_subadd)
+ TEST_ENTRY(glm_vec2_muladd)
+ TEST_ENTRY(glm_vec2_muladds)
+ TEST_ENTRY(glm_vec2_maxadd)
+ TEST_ENTRY(glm_vec2_minadd)
+ TEST_ENTRY(glm_vec2_negate_to)
+ TEST_ENTRY(glm_vec2_negate)
+ TEST_ENTRY(glm_vec2_normalize)
+ TEST_ENTRY(glm_vec2_normalize_to)
+ TEST_ENTRY(glm_vec2_rotate)
+ TEST_ENTRY(glm_vec2_distance2)
+ TEST_ENTRY(glm_vec2_distance)
+ TEST_ENTRY(glm_vec2_maxv)
+ TEST_ENTRY(glm_vec2_minv)
+ TEST_ENTRY(glm_vec2_clamp)
+ TEST_ENTRY(glm_vec2_lerp)
+
+ TEST_ENTRY(glmc_vec2)
+ TEST_ENTRY(glmc_vec2_copy)
+ TEST_ENTRY(glmc_vec2_zero)
+ TEST_ENTRY(glmc_vec2_one)
+ TEST_ENTRY(glmc_vec2_dot)
+ TEST_ENTRY(glmc_vec2_cross)
+ TEST_ENTRY(glmc_vec2_norm2)
+ TEST_ENTRY(glmc_vec2_norm)
+ TEST_ENTRY(glmc_vec2_add)
+ TEST_ENTRY(glmc_vec2_adds)
+ TEST_ENTRY(glmc_vec2_sub)
+ TEST_ENTRY(glmc_vec2_subs)
+ TEST_ENTRY(glmc_vec2_mul)
+ TEST_ENTRY(glmc_vec2_scale)
+ TEST_ENTRY(glmc_vec2_scale_as)
+ TEST_ENTRY(glmc_vec2_div)
+ TEST_ENTRY(glmc_vec2_divs)
+ TEST_ENTRY(glmc_vec2_addadd)
+ TEST_ENTRY(glmc_vec2_subadd)
+ TEST_ENTRY(glmc_vec2_muladd)
+ TEST_ENTRY(glmc_vec2_muladds)
+ TEST_ENTRY(glmc_vec2_maxadd)
+ TEST_ENTRY(glmc_vec2_minadd)
+ TEST_ENTRY(glmc_vec2_negate_to)
+ TEST_ENTRY(glmc_vec2_negate)
+ TEST_ENTRY(glmc_vec2_normalize)
+ TEST_ENTRY(glmc_vec2_normalize_to)
+ TEST_ENTRY(glmc_vec2_rotate)
+ TEST_ENTRY(glmc_vec2_distance2)
+ TEST_ENTRY(glmc_vec2_distance)
+ TEST_ENTRY(glmc_vec2_maxv)
+ TEST_ENTRY(glmc_vec2_minv)
+ TEST_ENTRY(glmc_vec2_clamp)
+ TEST_ENTRY(glmc_vec2_lerp)
+
/* vec3 */
/* Macros */
diff --git a/win/cglm-test.vcxproj b/win/cglm-test.vcxproj
index f7ccc91..1c0916d 100644
--- a/win/cglm-test.vcxproj
+++ b/win/cglm-test.vcxproj
@@ -30,11 +30,16 @@
+
+
+
+
+
diff --git a/win/cglm-test.vcxproj.filters b/win/cglm-test.vcxproj.filters
index 66691ff..c81dc11 100644
--- a/win/cglm-test.vcxproj.filters
+++ b/win/cglm-test.vcxproj.filters
@@ -64,5 +64,20 @@
src
+
+ src
+
+
+ src
+
+
+ src
+
+
+ src
+
+
+ src
+
\ No newline at end of file
diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj
index b5249d7..4f0c332 100644
--- a/win/cglm.vcxproj
+++ b/win/cglm.vcxproj
@@ -28,18 +28,21 @@
+
+
+
@@ -52,12 +55,14 @@
+
+
@@ -69,6 +74,7 @@
+
@@ -94,12 +100,15 @@
+
+
+
@@ -107,6 +116,8 @@
+
+
diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters
index 21c554c..42f116b 100644
--- a/win/cglm.vcxproj.filters
+++ b/win/cglm.vcxproj.filters
@@ -1,4 +1,4 @@
-
+
@@ -86,6 +86,12 @@
src
+
+ src
+
+
+ src
+
@@ -253,6 +259,9 @@
include\cglm\call
+
+ include\cglm
+
include\cglm\struct
@@ -313,5 +322,29 @@
include\cglm
+
+ include\cglm\call
+
+
+ include\cglm\call
+
+
+ include\cglm\struct
+
+
+ include\cglm
+
+
+ include\cglm
+
+
+ include\cglm
+
+
+ include\cglm\struct
+
+
+ include\cglm\struct
+
\ No newline at end of file