diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ad397a..f136fda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ add_library(${PROJECT_NAME} src/curve.c src/bezier.c src/ray.c + src/affine2d.c ) set_target_properties(${PROJECT_NAME} PROPERTIES diff --git a/Makefile.am b/Makefile.am index cc9c692..0fdebff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,6 +23,7 @@ checkLDFLAGS = -L./.libs \ checkCFLAGS = $(AM_CFLAGS) \ -std=gnu11 \ -O3 \ + -DCGLM_DEFINE_PRINTS \ -I./include check_PROGRAMS = test/tests @@ -65,7 +66,8 @@ cglm_HEADERS = include/cglm/version.h \ include/cglm/curve.h \ include/cglm/bezier.h \ include/cglm/applesimd.h \ - include/cglm/ray.h + include/cglm/ray.h \ + include/cglm/affine2d.h cglm_calldir=$(includedir)/cglm/call cglm_call_HEADERS = include/cglm/call/mat4.h \ @@ -87,7 +89,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \ include/cglm/call/ease.h \ include/cglm/call/curve.h \ include/cglm/call/bezier.h \ - include/cglm/call/ray.h + include/cglm/call/ray.h \ + include/cglm/call/affine2d.h cglm_simddir=$(includedir)/cglm/simd cglm_simd_HEADERS = include/cglm/simd/intrin.h \ @@ -151,7 +154,8 @@ libcglm_la_SOURCES=\ src/ease.c \ src/curve.c \ src/bezier.c \ - src/ray.c + src/ray.c \ + src/affine2d.c test_tests_SOURCES=\ test/runner.c \ diff --git a/docs/source/affine-mat.rst b/docs/source/affine-mat.rst index 43740cf..d0065e9 100644 --- a/docs/source/affine-mat.rst +++ b/docs/source/affine-mat.rst @@ -1,6 +1,6 @@ .. default-domain:: C -affine transform matrix (specialized functions) +3D Affine Transform Matrix (specialized functions) ================================================================================ Header: cglm/affine-mat.h diff --git a/docs/source/affine.rst b/docs/source/affine.rst index 8ded38d..df2dcb7 100644 --- a/docs/source/affine.rst +++ b/docs/source/affine.rst @@ -1,6 +1,6 @@ .. default-domain:: C -affine transforms +3D Affine Transforms ================================================================================ Header: cglm/affine.h @@ -45,6 +45,8 @@ The implementation would be: glm_rotate(m, angle, axis); glm_translate(m, pivotInv); /* pivotInv = -pivot */ +.. _TransformsOrder: + Transforms Order ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/affine2d.rst b/docs/source/affine2d.rst new file mode 100644 index 0000000..f12cd59 --- /dev/null +++ b/docs/source/affine2d.rst @@ -0,0 +1,140 @@ +.. default-domain:: C + +2D Affine Transforms +================================================================================ + +Header: cglm/affine2d.h + +2D Transforms uses `2d` suffix for naming. If there is no 2D suffix it is 3D function. + +Initialize Transform Matrices +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Functions with **_make** prefix expect you don't have a matrix and they create +a matrix for you. You don't need to pass identity matrix. + +But other functions expect you have a matrix and you want to transform them. If +you didn't have any existing matrix you have to initialize matrix to identity +before sending to transfrom functions. + +Transforms Order +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See :ref:`TransformsOrder` to read similar section. + + +Table of contents (click to go): +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Functions: + +1. :c:func:`glm_translate2d` +#. :c:func:`glm_translate2d_to` +#. :c:func:`glm_translate2d_x` +#. :c:func:`glm_translate2d_y` +#. :c:func:`glm_translate2d_make` +#. :c:func:`glm_scale2d_to` +#. :c:func:`glm_scale2d_make` +#. :c:func:`glm_scale2d` +#. :c:func:`glm_scale2d_uni` +#. :c:func:`glm_rotate2d_make` +#. :c:func:`glm_rotate2d` +#. :c:func:`glm_rotate2d_to` + +.. c:function:: void glm_translate2d(mat3 m, vec2 v) + + translate existing 2d transform matrix by *v* vector and stores result in same matrix + + Parameters: + | *[in, out]* **m** 2d affine transfrom + | *[in]* **v** translate vector [x, y] + +.. c:function:: void glm_translate2d_to(mat3 m, vec2 v, mat3 dest) + + translate existing 2d transform matrix by *v* vector and store result in dest + + Parameters: + | *[in]* **m** 2d affine transfrom + | *[in]* **v** translate vector [x, y] + | *[out]* **dest** translated matrix + +.. c:function:: void glm_translate2d_x(mat3 m, float x) + + translate existing 2d transform matrix by x factor + + Parameters: + | *[in, out]* **m** 2d affine transfrom + | *[in]* **x** x factor + +.. c:function:: void glm_translate2d_y(mat3 m, float y) + + translate existing 2d transform matrix by y factor + + Parameters: + | *[in, out]* **m** 2d affine transfrom + | *[in]* **y** y factor + +.. c:function:: void glm_translate2d_make(mat3 m, vec2 v) + + creates NEW translate 2d transform matrix by *v* vector + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **v** translate vector [x, y] + +.. c:function:: void glm_scale2d_to(mat3 m, vec2 v, mat3 dest) + + scale existing 2d transform matrix by *v* vector and store result in dest + + Parameters: + | *[in]* **m** affine transfrom + | *[in]* **v** scale vector [x, y] + | *[out]* **dest** scaled matrix + +.. c:function:: void glm_scale2d_make(mat3 m, vec2 v) + + creates NEW 2d scale matrix by *v* vector + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **v** scale vector [x, y] + +.. c:function:: void glm_scale2d(mat3 m, vec2 v) + + scales existing 2d transform matrix by *v* vector and stores result in same matrix + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **v** translate vector [x, y] + +.. c:function:: void glm_scale2d_uni(mat3 m, float s) + + applies uniform scale to existing 2d transform matrix v = [s, s] and stores result in same matrix + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **s** scale factor + +.. c:function:: void glm_rotate2d_make(mat3 m, float angle) + + creates NEW rotation matrix by angle around *Z* axis + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **angle** angle (radians) + +.. c:function:: void glm_rotate2d(mat3 m, float angle) + + rotate existing 2d transform matrix around *Z* axis by angle and store result in same matrix + + Parameters: + | *[in, out]* **m** affine transfrom + | *[in]* **angle** angle (radians) + +.. c:function:: void glm_rotate2d_to(mat3 m, float angle, mat3 dest) + + rotate existing 2d transform matrix around *Z* axis by angle and store result in dest + + Parameters: + | *[in]* **m** affine transfrom + | *[in]* **angle** angle (radians) + | *[out]* **dest** rotated matrix \ No newline at end of file diff --git a/docs/source/api.rst b/docs/source/api.rst index 717b61c..67e0fb0 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -28,6 +28,7 @@ Follow the :doc:`build` documentation for this affine affine-mat + affine2d cam frustum box diff --git a/include/cglm/affine2d.h b/include/cglm/affine2d.h new file mode 100644 index 0000000..bb66289 --- /dev/null +++ b/include/cglm/affine2d.h @@ -0,0 +1,268 @@ +/* + * 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_translate2d(mat3 m, vec2 v) + CGLM_INLINE void glm_translate2d_to(mat3 m, vec2 v, mat3 dest) + CGLM_INLINE void glm_translate2d_x(mat3 m, float x) + CGLM_INLINE void glm_translate2d_y(mat3 m, float y) + CGLM_INLINE void glm_translate2d_make(mat3 m, vec2 v) + CGLM_INLINE void glm_scale2d_to(mat3 m, vec2 v, mat3 dest) + CGLM_INLINE void glm_scale2d_make(mat3 m, vec2 v) + CGLM_INLINE void glm_scale2d(mat3 m, vec2 v) + CGLM_INLINE void glm_scale2d_uni(mat3 m, float s) + CGLM_INLINE void glm_rotate2d_make(mat3 m, float angle) + CGLM_INLINE void glm_rotate2d(mat3 m, float angle) + CGLM_INLINE void glm_rotate2d_to(mat3 m, float angle, mat3 dest) + */ + +#ifndef cglm_affine2d_h +#define cglm_affine2d_h + +#include "common.h" +#include "util.h" +#include "vec2.h" +#include "mat3.h" + +/*! + * @brief translate existing 2d transform matrix by v vector + * and stores result in same matrix + * + * @param[in, out] m affine transfrom + * @param[in] v translate vector [x, y] + */ +CGLM_INLINE +void +glm_translate2d(mat3 m, vec2 v) { + m[2][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0]; + m[2][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1]; + m[2][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2]; +} + +/*! + * @brief translate existing 2d transform matrix by v vector + * and store result in dest + * + * source matrix will remain same + * + * @param[in] m affine transfrom + * @param[in] v translate vector [x, y] + * @param[out] dest translated matrix + */ +CGLM_INLINE +void +glm_translate2d_to(mat3 m, vec2 v, mat3 dest) { + glm_mat3_copy(m, dest); + glm_translate2d(dest, v); +} + +/*! + * @brief translate existing 2d transform matrix by x factor + * + * @param[in, out] m affine transfrom + * @param[in] x x factor + */ +CGLM_INLINE +void +glm_translate2d_x(mat3 m, float x) { + m[2][0] = m[0][0] * x + m[2][0]; + m[2][1] = m[0][1] * x + m[2][1]; + m[2][2] = m[0][2] * x + m[2][2]; +} + +/*! + * @brief translate existing 2d transform matrix by y factor + * + * @param[in, out] m affine transfrom + * @param[in] y y factor + */ +CGLM_INLINE +void +glm_translate2d_y(mat3 m, float y) { + m[2][0] = m[1][0] * y + m[2][0]; + m[2][1] = m[1][1] * y + m[2][1]; + m[2][2] = m[1][2] * y + m[2][2]; +} + +/*! + * @brief creates NEW translate 2d transform matrix by v vector + * + * @param[out] m affine transfrom + * @param[in] v translate vector [x, y] + */ +CGLM_INLINE +void +glm_translate2d_make(mat3 m, vec2 v) { + glm_mat3_identity(m); + m[2][0] = v[0]; + m[2][1] = v[1]; +} + +/*! + * @brief scale existing 2d transform matrix by v vector + * and store result in dest + * + * @param[in] m affine transfrom + * @param[in] v scale vector [x, y] + * @param[out] dest scaled matrix + */ +CGLM_INLINE +void +glm_scale2d_to(mat3 m, vec2 v, mat3 dest) { + dest[0][0] = m[0][0] * v[0]; + dest[0][1] = m[0][1] * v[0]; + dest[0][2] = m[0][2] * v[0]; + + dest[1][0] = m[1][0] * v[1]; + dest[1][1] = m[1][1] * v[1]; + dest[1][2] = m[1][2] * v[1]; + + dest[2][0] = m[2][0]; + dest[2][1] = m[2][1]; + dest[2][2] = m[2][2]; +} + +/*! + * @brief creates NEW 2d scale matrix by v vector + * + * @param[out] m affine transfrom + * @param[in] v scale vector [x, y] + */ +CGLM_INLINE +void +glm_scale2d_make(mat3 m, vec2 v) { + glm_mat3_identity(m); + m[0][0] = v[0]; + m[1][1] = v[1]; +} + +/*! + * @brief scales existing 2d transform matrix by v vector + * and stores result in same matrix + * + * @param[in, out] m affine transfrom + * @param[in] v scale vector [x, y] + */ +CGLM_INLINE +void +glm_scale2d(mat3 m, vec2 v) { + m[0][0] = m[0][0] * v[0]; + m[0][1] = m[0][1] * v[0]; + m[0][2] = m[0][2] * v[0]; + + m[1][0] = m[1][0] * v[1]; + m[1][1] = m[1][1] * v[1]; + m[1][2] = m[1][2] * v[1]; +} + +/*! + * @brief applies uniform scale to existing 2d transform matrix v = [s, s] + * and stores result in same matrix + * + * @param[in, out] m affine transfrom + * @param[in] s scale factor + */ +CGLM_INLINE +void +glm_scale2d_uni(mat3 m, float s) { + m[0][0] = m[0][0] * s; + m[0][1] = m[0][1] * s; + m[0][2] = m[0][2] * s; + + m[1][0] = m[1][0] * s; + m[1][1] = m[1][1] * s; + m[1][2] = m[1][2] * s; +} + +/*! + * @brief creates NEW rotation matrix by angle around Z axis + * + * @param[out] m affine transfrom + * @param[in] angle angle (radians) + */ +CGLM_INLINE +void +glm_rotate2d_make(mat3 m, float angle) { + float c, s; + + s = sinf(angle); + c = cosf(angle); + + m[0][0] = c; + m[0][1] = s; + m[0][2] = 0; + + m[1][0] = -s; + m[1][1] = c; + m[1][2] = 0; + + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; +} + +/*! + * @brief rotate existing 2d transform matrix around Z axis by angle + * and store result in same matrix + * + * @param[in, out] m affine transfrom + * @param[in] angle angle (radians) + */ +CGLM_INLINE +void +glm_rotate2d(mat3 m, float angle) { + float m00 = m[0][0], m10 = m[1][0], + m01 = m[0][1], m11 = m[1][1], + m02 = m[0][2], m12 = m[1][2]; + float c, s; + + s = sinf(angle); + c = cosf(angle); + + m[0][0] = m00 * c + m10 * s; + m[0][1] = m01 * c + m11 * s; + m[0][2] = m02 * c + m12 * s; + + m[1][0] = m00 * -s + m10 * c; + m[1][1] = m01 * -s + m11 * c; + m[1][2] = m02 * -s + m12 * c; +} + +/*! + * @brief rotate existing 2d transform matrix around Z axis by angle + * and store result in dest + * + * @param[in] m affine transfrom + * @param[in] angle angle (radians) + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_rotate2d_to(mat3 m, float angle, mat3 dest) { + float m00 = m[0][0], m10 = m[1][0], + m01 = m[0][1], m11 = m[1][1], + m02 = m[0][2], m12 = m[1][2]; + float c, s; + + s = sinf(angle); + c = cosf(angle); + + dest[0][0] = m00 * c + m10 * s; + dest[0][1] = m01 * c + m11 * s; + dest[0][2] = m02 * c + m12 * s; + + dest[1][0] = m00 * -s + m10 * c; + dest[1][1] = m01 * -s + m11 * c; + dest[1][2] = m02 * -s + m12 * c; + + dest[2][0] = m[2][0]; + dest[2][1] = m[2][1]; + dest[2][2] = m[2][2]; +} + +#endif /* cglm_affine2d_h */ diff --git a/include/cglm/call.h b/include/cglm/call.h index b51b731..ffb3532 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -32,6 +32,7 @@ extern "C" { #include "call/curve.h" #include "call/bezier.h" #include "call/ray.h" +#include "call/affine2d.h" #ifdef __cplusplus } diff --git a/include/cglm/call/affine2d.h b/include/cglm/call/affine2d.h new file mode 100644 index 0000000..e1b9462 --- /dev/null +++ b/include/cglm/call/affine2d.h @@ -0,0 +1,67 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_affine2d_h +#define cglmc_affine2d_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +void +glmc_translate2d_make(mat3 m, vec2 v); + +CGLM_EXPORT +void +glmc_translate2d_to(mat3 m, vec2 v, mat3 dest); + +CGLM_EXPORT +void +glmc_translate2d(mat3 m, vec2 v); + +CGLM_EXPORT +void +glmc_translate2d_x(mat3 m, float to); + +CGLM_EXPORT +void +glmc_translate2d_y(mat3 m, float to); + +CGLM_EXPORT +void +glmc_scale2d_to(mat3 m, vec2 v, mat3 dest); + +CGLM_EXPORT +void +glmc_scale2d_make(mat3 m, vec2 v); + +CGLM_EXPORT +void +glmc_scale2d(mat3 m, vec2 v); + +CGLM_EXPORT +void +glmc_scale2d_uni(mat3 m, float s); + +CGLM_EXPORT +void +glmc_rotate2d_make(mat3 m, float angle); + +CGLM_EXPORT +void +glmc_rotate2d(mat3 m, float angle); + +CGLM_EXPORT +void +glmc_rotate2d_to(mat3 m, float angle, mat3 dest); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_affine2d_h */ diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index afc7f99..5ff3421 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -31,5 +31,6 @@ #include "curve.h" #include "bezier.h" #include "ray.h" +#include "affine2d.h" #endif /* cglm_h */ diff --git a/include/cglm/struct.h b/include/cglm/struct.h index 654a1d4..871525a 100644 --- a/include/cglm/struct.h +++ b/include/cglm/struct.h @@ -31,6 +31,7 @@ extern "C" { #include "struct/project.h" #include "struct/sphere.h" #include "struct/curve.h" +#include "struct/affine2d.h" #ifdef __cplusplus } diff --git a/include/cglm/struct/affine2d.h b/include/cglm/struct/affine2d.h new file mode 100644 index 0000000..412bd47 --- /dev/null +++ b/include/cglm/struct/affine2d.h @@ -0,0 +1,177 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + Functions: + CGLM_INLINE mat3s glms_translate2d(mat3 m, vec2 v) + CGLM_INLINE mat3s glms_translate2d_x(mat3s m, float x) + CGLM_INLINE mat3s glms_translate2d_y(mat3s m, float y) + CGLM_INLINE mat3s glms_translate2d_make(vec2s v) + CGLM_INLINE mat3s glms_scale2d_make(vec2s v) + CGLM_INLINE mat3s glms_scale2d(mat3s m, vec2s v) + CGLM_INLINE mat3s glms_scale2d_uni(mat3s m, float s) + CGLM_INLINE mat3s glms_rotate2d_make(float angle) + CGLM_INLINE mat3s glms_rotate2d(mat3s m, float angle) + CGLM_INLINE mat3s glms_rotate2d_to(mat3s m, float angle) + */ + +#ifndef cglms_affine2ds_h +#define cglms_affine2ds_h + +#include "../common.h" +#include "../types-struct.h" +#include "../affine2d.h" +#include "vec3.h" +#include "mat3.h" + +/*! + * @brief translate existing 2d transform matrix by v vector + * and stores result in same matrix + * + * @param[in] m affine transfrom + * @param[in] v translate vector [x, y] + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_translate2d(mat3s m, vec2s v) { + glm_translate2d(m.raw, v.raw); + return m; +} + +/*! + * @brief translate existing 2d transform matrix by x factor + * + * @param[in] m affine transfrom + * @param[in] x x factor + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_translate2d_x(mat3s m, float x) { + glm_translate2d_x(m.raw, x); + return m; +} + +/*! + * @brief translate existing 2d transform matrix by y factor + * + * @param[in] m affine transfrom + * @param[in] y y factor + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_translate2d_y(mat3s m, float y) { + glm_translate2d_y(m.raw, y); + return m; +} + +/*! + * @brief creates NEW translate 2d transform matrix by v vector + * + * @param[in] v translate vector [x, y] + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_translate2d_make(vec2s v) { + mat3s m; + glm_translate2d_make(m.raw, v.raw); + return m; +} + +/*! + * @brief creates NEW 2d scale matrix by v vector + * + * @param[in] v scale vector [x, y] + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_scale2d_make(vec2s v) { + mat3s m; + glm_scale2d_make(m.raw, v.raw); + return m; +} + +/*! + * @brief scales existing 2d transform matrix by v vector + * and stores result in same matrix + * + * @param[in] m affine transfrom + * @param[in] v scale vector [x, y, z] + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_scale2d(mat3s m, vec2s v) { + mat3s r; + glm_scale2d_to(m.raw, v.raw, r.raw); + return r; +} + +/*! + * @brief applies uniform scale to existing 2d transform matrix v = [s, s, s] + * and stores result in same matrix + * + * @param[in] m affine transfrom + * @param[in] s scale factor + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_scale2d_uni(mat3s m, float s) { + glm_scale2d_uni(m.raw, s); + return m; +} + +/*! + * @brief creates NEW 2d rotation matrix by angle and axis + * + * axis will be normalized so you don't need to normalize it + * + * @param[in] angle angle (radians) + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_rotate2d_make(float angle) { + mat3s m; + glm_rotate2d_make(m.raw, angle); + return m; +} + +/*! + * @brief rotate existing 2d transform matrix around given axis by angle + * + * @param[in] m affine transfrom + * @param[in] angle angle (radians) + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_rotate2d(mat3s m, float angle) { + glm_rotate2d(m.raw, angle); + return m; +} + +/*! + * @brief rotate existing 2d transform matrix around given axis by angle + * + * @param[in] m affine transfrom + * @param[in] angle angle (radians) + * @returns affine transfrom + */ +CGLM_INLINE +mat3s +glms_rotate2d_to(mat3s m, float angle) { + glm_rotate2d(m.raw, angle); + return m; +} + +#endif /* cglms_affine2ds_h */ diff --git a/src/affine2d.c b/src/affine2d.c new file mode 100644 index 0000000..6e5913e --- /dev/null +++ b/src/affine2d.c @@ -0,0 +1,81 @@ +/* + * 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_translate2d_make(mat3 m, vec2 v) { + glm_translate2d_make(m, v); +} + +CGLM_EXPORT +void +glmc_translate2d_to(mat3 m, vec2 v, mat3 dest) { + glm_translate2d_to(m, v, dest); +} + +CGLM_EXPORT +void +glmc_translate2d(mat3 m, vec2 v) { + glm_translate2d(m, v); +} + +CGLM_EXPORT +void +glmc_translate2d_x(mat3 m, float to) { + glm_translate2d_x(m, to); +} + +CGLM_EXPORT +void +glmc_translate2d_y(mat3 m, float to) { + glm_translate2d_y(m, to); +} + +CGLM_EXPORT +void +glmc_scale2d_to(mat3 m, vec2 v, mat3 dest) { + glm_scale2d_to(m, v, dest); +} + +CGLM_EXPORT +void +glmc_scale2d_make(mat3 m, vec2 v) { + glm_scale2d_make(m, v); +} + +CGLM_EXPORT +void +glmc_scale2d(mat3 m, vec2 v) { + glm_scale2d(m, v); +} + +CGLM_EXPORT +void +glmc_scale2d_uni(mat3 m, float s) { + glm_scale2d_uni(m, s); +} + +CGLM_EXPORT +void +glmc_rotate2d_make(mat3 m, float angle) { + glm_rotate2d_make(m, angle); +} + +CGLM_EXPORT +void +glmc_rotate2d(mat3 m, float angle) { + glm_rotate2d(m, angle); +} + +CGLM_EXPORT +void +glmc_rotate2d_to(mat3 m, float angle, mat3 dest) { + glm_rotate2d_to(m, angle, dest); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fb2c288..59096e4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -16,6 +16,7 @@ set(TEST_MAIN tests) set(TEST_RUNNER_PARAMS "") add_executable(${TEST_MAIN} ${TESTFILES}) +target_compile_definitions(${TEST_MAIN} PRIVATE CGLM_DEFINE_PRINTS=1) target_link_libraries(${TEST_MAIN} PRIVATE cglm m) target_include_directories(${TEST_MAIN} PRIVATE diff --git a/test/src/test_affine2d.h b/test/src/test_affine2d.h new file mode 100644 index 0000000..8828661 --- /dev/null +++ b/test/src/test_affine2d.h @@ -0,0 +1,310 @@ +/* + * 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" + +TEST_IMPL(GLM_PREFIX, translate2d) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(translate2d)(m1, (vec2){13.0f, 11.0f}); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 15.0f)) + ASSERT(test_eq(v2[1], 14.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(translate2d)(m1, (vec2){1.0f, -1.0f}); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], 16.0f)) + ASSERT(test_eq(v2[1], 13.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, translate2d_to) { + mat3 m1, m2; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(translate2d_to)(m1, (vec2){13.0f, 11.0f}, m2); + glm_mat3_mulv(m2, v1, v2); + + ASSERT(test_eq(v2[0], 15.0f)) + ASSERT(test_eq(v2[1], 14.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(translate2d_to)(m1, (vec2){1.0f, -1.0f}, m2); + glm_mat3_mulv(m2, v2, v2); + + ASSERT(test_eq(v2[0], 16.0f)) + ASSERT(test_eq(v2[1], 13.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, translate2d_x) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(translate2d_x)(m1, 13.0f); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 15.0f)) + ASSERT(test_eq(v2[1], 3.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(translate2d_x)(m1, -1.0f); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], 14.0f)) + ASSERT(test_eq(v2[1], 3.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, translate2d_y) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(translate2d_y)(m1, 11.0f); + glm_mat3_mulv(m1, v1, v2); + + + ASSERT(test_eq(v2[0], 2.0f)) + ASSERT(test_eq(v2[1], 14.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(translate2d_y)(m1, -1.0f); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], 2.0f)) + ASSERT(test_eq(v2[1], 13.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, translate2d_make) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(translate2d_make)(m1, (vec2){13.0f, 11.0f}); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 15.0f)) + ASSERT(test_eq(v2[1], 14.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(translate2d_make)(m1, (vec2){-1.0f, -5.0f}); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], 14.0f)) + ASSERT(test_eq(v2[1], 9.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, scale2d_to) { + mat3 m1, m2; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(scale2d_to)(m1, (vec2){13.0f, 11.0f}, m2); + glm_mat3_mulv(m2, v1, v2); + + ASSERT(test_eq(v2[0], 26.0f)) + ASSERT(test_eq(v2[1], 33.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(scale2d_to)(m1, (vec2){-1.0f, -5.0f}, m2); + glm_mat3_mulv(m2, v2, v2); + + ASSERT(test_eq(v2[0], -26.0f)) + ASSERT(test_eq(v2[1], -165.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, scale2d_make) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + GLM(scale2d_make)(m1, (vec2){13.0f, 11.0f}); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 26.0f)) + ASSERT(test_eq(v2[1], 33.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + GLM(scale2d_make)(m1, (vec3){-1.0f, -5.0f}); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], -26.0f)) + ASSERT(test_eq(v2[1], -165.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, scale2d) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(scale2d)(m1, (vec2){13.0f, 11.0f}); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 26.0f)) + ASSERT(test_eq(v2[1], 33.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(scale2d)(m1, (vec2){-1.0f, -5.0f}); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], -26.0f)) + ASSERT(test_eq(v2[1], -165.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, scale2d_uni) { + mat3 m1; + vec3 v1 = {2.0f, 3.0f, 1.0f}, v2; + + glm_mat3_identity(m1); + GLM(scale2d_uni)(m1, 13.0f); + glm_mat3_mulv(m1, v1, v2); + + ASSERT(test_eq(v2[0], 26.0f)) + ASSERT(test_eq(v2[1], 39.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + glm_mat3_identity(m1); + GLM(scale2d_uni)(m1, -5.0f); + glm_mat3_mulv(m1, v2, v2); + + ASSERT(test_eq(v2[0], -130.0f)) + ASSERT(test_eq(v2[1], -195.0f)) + ASSERT(test_eq(v2[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, rotate2d_make) { + mat3 m1 = GLM_MAT3_IDENTITY_INIT; + vec3 v1 = {0.0f, 1.0f, 1.0f}, v2 = {0.0f, 1.0f, 1.0f}; + + GLM(rotate2d_make)(m1, GLM_PI_2f); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], -1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d_make)(m1, -GLM_PI_2f); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], 1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d_make)(m1, GLM_PIf); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], -1.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, rotate2d) { + mat3 m1 = GLM_MAT3_IDENTITY_INIT; + vec3 v1 = {0.0f, 1.0f, 1.0f}, v2 = {0.0f, 1.0f, 1.0f}; + + GLM(rotate2d)(m1, GLM_PI_2f); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], -1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d)(m1, GLM_PI_2f); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], -1.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d)(m1, GLM_PI_2f); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], 1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, rotate2d_to) { + mat3 m1 = GLM_MAT3_IDENTITY_INIT, m2; + vec3 v1 = {0.0f, 1.0f, 1.0f}, v2 = {0.0f, 1.0f, 1.0f}; + + GLM(rotate2d_to)(m1, GLM_PI_2f, m1); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], -1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d_to)(m1, GLM_PI_2f, m2); + glm_mat3_mulv(m2, v1, v1); + + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], -1.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + glm_vec3_copy(v2, v1); + + GLM(rotate2d_to)(m2, GLM_PI_2f, m1); + glm_mat3_mulv(m1, v1, v1); + + ASSERT(test_eq(v1[0], 1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + ASSERT(test_eq(v1[2], 1.0f)) + + TEST_SUCCESS +} diff --git a/test/src/tests.c b/test/src/tests.c index 2ea66c3..1cfc378 100644 --- a/test/src/tests.c +++ b/test/src/tests.c @@ -22,6 +22,7 @@ #include "test_project.h" #include "test_plane.h" #include "test_affine.h" +#include "test_affine2d.h" #include "test_affine_mat.h" #include "test_ray.h" #include "test_camera.h" @@ -45,6 +46,7 @@ #include "test_project.h" #include "test_plane.h" #include "test_affine.h" +#include "test_affine2d.h" #include "test_affine_mat.h" #include "test_ray.h" #include "test_camera.h" diff --git a/test/tests.h b/test/tests.h index 6ccfc91..2fe9fc6 100644 --- a/test/tests.h +++ b/test/tests.h @@ -70,6 +70,33 @@ TEST_DECLARE(glmc_uniscaled) TEST_DECLARE(glmc_decompose_rs) TEST_DECLARE(glmc_decompose) +/* affine 2d */ +TEST_DECLARE(glm_translate2d) +TEST_DECLARE(glm_translate2d_to) +TEST_DECLARE(glm_translate2d_x) +TEST_DECLARE(glm_translate2d_y) +TEST_DECLARE(glm_translate2d_make) +TEST_DECLARE(glm_scale2d_to) +TEST_DECLARE(glm_scale2d_make) +TEST_DECLARE(glm_scale2d) +TEST_DECLARE(glm_scale2d_uni) +TEST_DECLARE(glm_rotate2d_make) +TEST_DECLARE(glm_rotate2d) +TEST_DECLARE(glm_rotate2d_to) + +TEST_DECLARE(glmc_translate2d) +TEST_DECLARE(glmc_translate2d_to) +TEST_DECLARE(glmc_translate2d_x) +TEST_DECLARE(glmc_translate2d_y) +TEST_DECLARE(glmc_translate2d_make) +TEST_DECLARE(glmc_scale2d_to) +TEST_DECLARE(glmc_scale2d_make) +TEST_DECLARE(glmc_scale2d) +TEST_DECLARE(glmc_scale2d_uni) +TEST_DECLARE(glmc_rotate2d_make) +TEST_DECLARE(glmc_rotate2d) +TEST_DECLARE(glmc_rotate2d_to) + /* mat4 */ TEST_DECLARE(glm_mat4_ucopy) TEST_DECLARE(glm_mat4_copy) @@ -764,7 +791,34 @@ TEST_LIST { TEST_ENTRY(glmc_uniscaled) TEST_ENTRY(glmc_decompose_rs) TEST_ENTRY(glmc_decompose) + + /* affine 2d */ + TEST_ENTRY(glm_translate2d) + TEST_ENTRY(glm_translate2d_to) + TEST_ENTRY(glm_translate2d_x) + TEST_ENTRY(glm_translate2d_y) + TEST_ENTRY(glm_translate2d_make) + TEST_ENTRY(glm_scale2d_to) + TEST_ENTRY(glm_scale2d_make) + TEST_ENTRY(glm_scale2d) + TEST_ENTRY(glm_scale2d_uni) + TEST_ENTRY(glm_rotate2d_make) + TEST_ENTRY(glm_rotate2d) + TEST_ENTRY(glm_rotate2d_to) + TEST_ENTRY(glmc_translate2d) + TEST_ENTRY(glmc_translate2d_to) + TEST_ENTRY(glmc_translate2d_x) + TEST_ENTRY(glmc_translate2d_y) + TEST_ENTRY(glmc_translate2d_make) + TEST_ENTRY(glmc_scale2d_to) + TEST_ENTRY(glmc_scale2d_make) + TEST_ENTRY(glmc_scale2d) + TEST_ENTRY(glmc_scale2d_uni) + TEST_ENTRY(glmc_rotate2d_make) + TEST_ENTRY(glmc_rotate2d) + TEST_ENTRY(glmc_rotate2d_to) + /* mat4 */ TEST_ENTRY(glm_mat4_ucopy) TEST_ENTRY(glm_mat4_copy)