summaryrefslogtreecommitdiff
path: root/libs/cglm/docs
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-06-14 00:06:42 -0500
committersanine <sanine.not@pm.me>2022-06-14 00:06:42 -0500
commit2f518e5e28d35ae24a5ac0e31000835e43b01972 (patch)
tree47fdeb9fa5b04e267702acb06424d3f87b37dd84 /libs/cglm/docs
parent034d5c965ff34cfdf4b153af9f32360a02e35684 (diff)
add cglm as 3rd-party library
Diffstat (limited to 'libs/cglm/docs')
-rw-r--r--libs/cglm/docs/make.bat36
-rw-r--r--libs/cglm/docs/source/affine-mat.rst99
-rw-r--r--libs/cglm/docs/source/affine.rst345
-rw-r--r--libs/cglm/docs/source/affine2d.rst140
-rw-r--r--libs/cglm/docs/source/api.rst59
-rw-r--r--libs/cglm/docs/source/bezier.rst89
-rw-r--r--libs/cglm/docs/source/box.rst181
-rw-r--r--libs/cglm/docs/source/build.rst153
-rw-r--r--libs/cglm/docs/source/call.rst19
-rw-r--r--libs/cglm/docs/source/cam.rst313
-rw-r--r--libs/cglm/docs/source/cglm-intro.pngbin0 -> 74053 bytes
-rw-r--r--libs/cglm/docs/source/color.rst34
-rw-r--r--libs/cglm/docs/source/conf.py203
-rw-r--r--libs/cglm/docs/source/curve.rst41
-rw-r--r--libs/cglm/docs/source/euler.rst182
-rw-r--r--libs/cglm/docs/source/features.rst28
-rw-r--r--libs/cglm/docs/source/frustum.rst168
-rw-r--r--libs/cglm/docs/source/getting_started.rst105
-rw-r--r--libs/cglm/docs/source/index.rst53
-rw-r--r--libs/cglm/docs/source/io.rst119
-rw-r--r--libs/cglm/docs/source/ivec2.rst163
-rw-r--r--libs/cglm/docs/source/ivec3.rst163
-rw-r--r--libs/cglm/docs/source/ivec4.rst163
-rw-r--r--libs/cglm/docs/source/mat2.rst179
-rw-r--r--libs/cglm/docs/source/mat3.rst189
-rw-r--r--libs/cglm/docs/source/mat4.rst304
-rw-r--r--libs/cglm/docs/source/opengl.rst61
-rw-r--r--libs/cglm/docs/source/opt.rst124
-rw-r--r--libs/cglm/docs/source/plane.rst33
-rw-r--r--libs/cglm/docs/source/project.rst102
-rw-r--r--libs/cglm/docs/source/quat.rst422
-rw-r--r--libs/cglm/docs/source/ray.rst31
-rw-r--r--libs/cglm/docs/source/sphere.rst74
-rw-r--r--libs/cglm/docs/source/troubleshooting.rst99
-rw-r--r--libs/cglm/docs/source/util.rst182
-rw-r--r--libs/cglm/docs/source/vec2-ext.rst134
-rw-r--r--libs/cglm/docs/source/vec2.rst375
-rw-r--r--libs/cglm/docs/source/vec3-ext.rst143
-rw-r--r--libs/cglm/docs/source/vec3.rst503
-rw-r--r--libs/cglm/docs/source/vec4-ext.rst138
-rw-r--r--libs/cglm/docs/source/vec4.rst408
-rw-r--r--libs/cglm/docs/source/version.rst15
42 files changed, 6372 insertions, 0 deletions
diff --git a/libs/cglm/docs/make.bat b/libs/cglm/docs/make.bat
new file mode 100644
index 0000000..f0aed6a
--- /dev/null
+++ b/libs/cglm/docs/make.bat
@@ -0,0 +1,36 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=python -msphinx
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+set SPHINXPROJ=cglm
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The Sphinx module was not found. Make sure you have Sphinx installed,
+ echo.then set the SPHINXBUILD environment variable to point to the full
+ echo.path of the 'sphinx-build' executable. Alternatively you may add the
+ echo.Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff --git a/libs/cglm/docs/source/affine-mat.rst b/libs/cglm/docs/source/affine-mat.rst
new file mode 100644
index 0000000..d0065e9
--- /dev/null
+++ b/libs/cglm/docs/source/affine-mat.rst
@@ -0,0 +1,99 @@
+.. default-domain:: C
+
+3D Affine Transform Matrix (specialized functions)
+================================================================================
+
+Header: cglm/affine-mat.h
+
+We mostly use glm_mat4_* for 4x4 general and transform matrices. **cglm**
+provides optimized version of some functions. Because affine transform matrix is
+a known format, for instance all last item of first three columns is zero.
+
+You should be careful when using these functions. For instance :c:func:`glm_mul`
+assumes matrix will be this format:
+
+.. code-block:: text
+
+ R R R X
+ R R R Y
+ R R R Z
+ 0 0 0 W
+
+if you override zero values here then use :c:func:`glm_mat4_mul` version.
+You cannot use :c:func:`glm_mul` anymore.
+
+Same is also true for :c:func:`glm_inv_tr` if you only have rotation and
+translation then it will work as expected, otherwise you cannot use that.
+
+In the future it may accept scale factors too but currectly it does not.
+
+Table of contents (click func go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_mul`
+#. :c:func:`glm_mul_rot`
+#. :c:func:`glm_inv_tr`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_mul(mat4 m1, mat4 m2, mat4 dest)
+
+ | this is similar to glm_mat4_mul but specialized to affine transform
+
+ Matrix format should be:
+
+ .. code-block:: text
+
+ R R R X
+ R R R Y
+ R R R Z
+ 0 0 0 W
+
+ this reduces some multiplications. It should be faster than mat4_mul.
+ if you are not sure about matrix format then DON'T use this! use mat4_mul
+
+ Parameters:
+ | *[in]* **m1** affine matrix 1
+ | *[in]* **m2** affine matrix 2
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_mul_rot(mat4 m1, mat4 m2, mat4 dest)
+
+ | this is similar to glm_mat4_mul but specialized to rotation matrix
+
+ Right Matrix format should be (left is free):
+
+ .. code-block:: text
+
+ R R R 0
+ R R R 0
+ R R R 0
+ 0 0 0 1
+
+ this reduces some multiplications. It should be faster than mat4_mul.
+ if you are not sure about matrix format then DON'T use this! use mat4_mul
+
+ Parameters:
+ | *[in]* **m1** affine matrix 1
+ | *[in]* **m2** affine matrix 2
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_inv_tr(mat4 mat)
+
+ | inverse orthonormal rotation + translation matrix (ridig-body)
+
+ .. code-block:: text
+
+ X = | R T | X' = | R' -R'T |
+ | 0 1 | | 0 1 |
+
+ use this if you only have rotation + translation, this should work faster
+ than :c:func:`glm_mat4_inv`
+
+ Don't use this if your matrix includes other things e.g. scale, shear...
+
+ Parameters:
+ | *[in,out]* **mat** affine matrix
diff --git a/libs/cglm/docs/source/affine.rst b/libs/cglm/docs/source/affine.rst
new file mode 100644
index 0000000..df2dcb7
--- /dev/null
+++ b/libs/cglm/docs/source/affine.rst
@@ -0,0 +1,345 @@
+.. default-domain:: C
+
+3D Affine Transforms
+================================================================================
+
+Header: cglm/affine.h
+
+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.
+
+There are also functions to decompose transform matrix. These functions can't
+decompose matrix after projected.
+
+Rotation Center
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Rotating functions uses origin as rotation center (pivot/anchor point),
+since scale factors are stored in rotation matrix, same may also true for scalling.
+cglm provides some functions for rotating around at given point e.g.
+**glm_rotate_at**, **glm_quat_rotate_at**. Use them or follow next section for algorihm ("Rotate or Scale around specific Point (Pivot Point / Anchor Point)").
+
+Rotate or Scale around specific Point (Anchor Point)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to rotate model around arbibtrary point follow these steps:
+
+1. Move model from pivot point to origin: **translate(-pivot.x, -pivot.y, -pivot.z)**
+2. Apply rotation (or scaling maybe)
+3. Move model back from origin to pivot (reverse of step-1): **translate(pivot.x, pivot.y, pivot.z)**
+
+**glm_rotate_at**, **glm_quat_rotate_at** and their helper functions works that way.
+
+The implementation would be:
+
+.. code-block:: c
+ :linenos:
+
+ glm_translate(m, pivot);
+ glm_rotate(m, angle, axis);
+ glm_translate(m, pivotInv); /* pivotInv = -pivot */
+
+.. _TransformsOrder:
+
+Transforms Order
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is important to understand this part especially if you call transform
+functions multiple times
+
+`glm_translate`, `glm_rotate`, `glm_scale` and `glm_quat_rotate` and their
+helpers functions works like this (cglm may provide reverse order too as alternative in the future):
+
+.. code-block:: c
+ :linenos:
+
+ TransformMatrix = TransformMatrix * TraslateMatrix; // glm_translate()
+ TransformMatrix = TransformMatrix * RotateMatrix; // glm_rotate(), glm_quat_rotate()
+ TransformMatrix = TransformMatrix * ScaleMatrix; // glm_scale()
+
+As you can see it is multipled as right matrix. For instance what will happen if you call `glm_translate` twice?
+
+.. code-block:: c
+ :linenos:
+
+ glm_translate(transform, translate1); /* transform = transform * translate1 */
+ glm_translate(transform, translate2); /* transform = transform * translate2 */
+ glm_rotate(transform, angle, axis) /* transform = transform * rotation */
+
+Now lets try to understand this:
+
+1. You call translate using `translate1` and you expect it will be first transform
+because you call it first, do you?
+
+Result will be **`transform = transform * translate1`**
+
+2. Then you call translate using `translate2` and you expect it will be second transform?
+
+Result will be **`transform = transform * translate2`**. Now lets expand transform,
+it was `transform * translate1` before second call.
+
+Now it is **`transform = transform * translate1 * translate2`**, now do you understand what I say?
+
+3. After last call transform will be:
+
+**`transform = transform * translate1 * translate2 * rotation`**
+
+The order will be; **rotation will be applied first**, then **translate2** then **translate1**
+
+It is all about matrix multiplication order. It is similar to MVP matrix:
+`MVP = Projection * View * Model`, model will be applied first, then view then projection.
+
+**Confused?**
+
+In the end the last function call applied first in shaders.
+
+As alternative way, you can create transform matrices individually then combine manually,
+but don't forget that `glm_translate`, `glm_rotate`, `glm_scale`... are optimized and should be faster (an smaller assembly output) than manual multiplication
+
+.. code-block:: c
+ :linenos:
+
+ mat4 transform1, transform2, transform3, finalTransform;
+
+ glm_translate_make(transform1, translate1);
+ glm_translate_make(transform2, translate2);
+ glm_rotate_make(transform3, angle, axis);
+
+ /* first apply transform1, then transform2, thentransform3 */
+ glm_mat4_mulN((mat4 *[]){&transform3, &transform2, &transform1}, 3, finalTransform);
+
+ /* if you don't want to use mulN, same as above */
+ glm_mat4_mul(transform3, transform2, finalTransform);
+ glm_mat4_mul(finalTransform, transform1, finalTransform);
+
+Now transform1 will be applied first, then transform2 then transform3
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_translate_to`
+#. :c:func:`glm_translate`
+#. :c:func:`glm_translate_x`
+#. :c:func:`glm_translate_y`
+#. :c:func:`glm_translate_z`
+#. :c:func:`glm_translate_make`
+#. :c:func:`glm_scale_to`
+#. :c:func:`glm_scale_make`
+#. :c:func:`glm_scale`
+#. :c:func:`glm_scale_uni`
+#. :c:func:`glm_rotate_x`
+#. :c:func:`glm_rotate_y`
+#. :c:func:`glm_rotate_z`
+#. :c:func:`glm_rotate_make`
+#. :c:func:`glm_rotate`
+#. :c:func:`glm_rotate_at`
+#. :c:func:`glm_rotate_atm`
+#. :c:func:`glm_decompose_scalev`
+#. :c:func:`glm_uniscaled`
+#. :c:func:`glm_decompose_rs`
+#. :c:func:`glm_decompose`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_translate_to(mat4 m, vec3 v, mat4 dest)
+
+ translate existing transform matrix by *v* vector and store result in dest
+
+ Parameters:
+ | *[in]* **m** affine transfrom
+ | *[in]* **v** translate vector [x, y, z]
+ | *[out]* **dest** translated matrix
+
+.. c:function:: void glm_translate(mat4 m, vec3 v)
+
+ translate existing transform matrix by *v* vector
+ and stores result in same matrix
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** translate vector [x, y, z]
+
+.. c:function:: void glm_translate_x(mat4 m, float x)
+
+ translate existing transform matrix by x factor
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** x factor
+
+.. c:function:: void glm_translate_y(mat4 m, float y)
+
+ translate existing transform matrix by *y* factor
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** y factor
+
+.. c:function:: void glm_translate_z(mat4 m, float z)
+
+ translate existing transform matrix by *z* factor
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** z factor
+
+.. c:function:: void glm_translate_make(mat4 m, vec3 v)
+
+ creates NEW translate transform matrix by *v* vector.
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** translate vector [x, y, z]
+
+.. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
+
+ scale existing transform matrix by *v* vector and store result in dest
+
+ Parameters:
+ | *[in]* **m** affine transfrom
+ | *[in]* **v** scale vector [x, y, z]
+ | *[out]* **dest** scaled matrix
+
+.. c:function:: void glm_scale_make(mat4 m, vec3 v)
+
+ creates NEW scale matrix by v vector
+
+ Parameters:
+ | *[out]* **m** affine transfrom
+ | *[in]* **v** scale vector [x, y, z]
+
+.. c:function:: void glm_scale(mat4 m, vec3 v)
+
+ scales existing transform matrix by v vector
+ and stores result in same matrix
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** scale vector [x, y, z]
+
+.. c:function:: void glm_scale_uni(mat4 m, float s)
+
+ applies uniform scale to existing transform matrix v = [s, s, s]
+ and stores result in same matrix
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **v** scale factor
+
+.. c:function:: void glm_rotate_x(mat4 m, float angle, mat4 dest)
+
+ rotate existing transform matrix around X axis by angle
+ and store result in dest
+
+ Parameters:
+ | *[in]* **m** affine transfrom
+ | *[in]* **angle** angle (radians)
+ | *[out]* **dest** rotated matrix
+
+.. c:function:: void glm_rotate_y(mat4 m, float angle, mat4 dest)
+
+ rotate existing transform matrix around Y axis by angle
+ and store result in dest
+
+ Parameters:
+ | *[in]* **m** affine transfrom
+ | *[in]* **angle** angle (radians)
+ | *[out]* **dest** rotated matrix
+
+.. c:function:: void glm_rotate_z(mat4 m, float angle, mat4 dest)
+
+ rotate existing 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
+
+.. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
+
+ creates NEW rotation matrix by angle and axis,
+ axis will be normalized so you don't need to normalize it
+
+ Parameters:
+ | *[out]* **m** affine transfrom
+ | *[in]* **axis** angle (radians)
+ | *[in]* **axis** axis
+
+.. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis)
+
+ rotate existing transform matrix around Z axis by angle and axis
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **angle** angle (radians)
+ | *[in]* **axis** axis
+
+.. c:function:: void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis)
+
+ rotate existing transform around given axis by angle at given pivot point (rotation center)
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **pivot** pivot, anchor point, rotation center
+ | *[in]* **angle** angle (radians)
+ | *[in]* **axis** axis
+
+.. c:function:: void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
+
+ | creates NEW rotation matrix by angle and axis at given point
+ | this creates rotation matrix, it assumes you don't have a matrix
+
+ | this should work faster than glm_rotate_at because it reduces one glm_translate.
+
+ Parameters:
+ | *[in, out]* **m** affine transfrom
+ | *[in]* **pivot** pivot, anchor point, rotation center
+ | *[in]* **angle** angle (radians)
+ | *[in]* **axis** axis
+
+.. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
+
+ decompose scale vector
+
+ Parameters:
+ | *[in]* **m** affine transform
+ | *[out]* **s** scale vector (Sx, Sy, Sz)
+
+.. c:function:: bool glm_uniscaled(mat4 m)
+
+ returns true if matrix is uniform scaled.
+ This is helpful for creating normal matrix.
+
+ Parameters:
+ | *[in]* **m** matrix
+
+.. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
+
+ decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
+ DON'T pass projected matrix here
+
+ Parameters:
+ | *[in]* **m** affine transform
+ | *[out]* **r** rotation matrix
+ | *[out]* **s** scale matrix
+
+.. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
+
+ decompose affine transform, TODO: extract shear factors.
+ DON'T pass projected matrix here
+
+ Parameters:
+ | *[in]* **m** affine transfrom
+ | *[out]* **t** translation vector
+ | *[out]* **r** rotation matrix (mat4)
+ | *[out]* **s** scaling vector [X, Y, Z]
diff --git a/libs/cglm/docs/source/affine2d.rst b/libs/cglm/docs/source/affine2d.rst
new file mode 100644
index 0000000..f12cd59
--- /dev/null
+++ b/libs/cglm/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/libs/cglm/docs/source/api.rst b/libs/cglm/docs/source/api.rst
new file mode 100644
index 0000000..7ffb823
--- /dev/null
+++ b/libs/cglm/docs/source/api.rst
@@ -0,0 +1,59 @@
+API documentation
+================================
+
+Some functions may exist twice,
+once for their namespace and once for global namespace
+to make easier to write very common functions
+
+For instance, in general we use :code:`glm_vec3_dot` to get dot product
+of two **vec3**. Now we can also do this with :code:`glm_dot`,
+same for *_cross* and so on...
+
+The original function stays where it is, the function in global namespace
+of same name is just an alias, so there is no call version of those functions.
+e.g there is no func like :code:`glmc_dot` because *glm_dot* is just alias for
+:code:`glm_vec3_dot`
+
+By including **cglm/cglm.h** header you will include all inline version
+of functions. Since functions in this header[s] are inline you don't need to
+build or link *cglm* against your project.
+
+But by including **cglm/call.h** header you will include all *non-inline*
+version of functions. You need to build *cglm* and link it.
+Follow the :doc:`build` documentation for this
+
+.. toctree::
+ :maxdepth: 1
+ :caption: API categories:
+
+ affine
+ affine-mat
+ affine2d
+ cam
+ frustum
+ box
+ quat
+ euler
+ mat2
+ mat3
+ mat4
+ vec2
+ vec2-ext
+ vec3
+ vec3-ext
+ vec4
+ vec4-ext
+ ivec2
+ ivec3
+ ivec4
+ color
+ plane
+ project
+ util
+ io
+ call
+ sphere
+ curve
+ bezier
+ version
+ ray
diff --git a/libs/cglm/docs/source/bezier.rst b/libs/cglm/docs/source/bezier.rst
new file mode 100644
index 0000000..8b29751
--- /dev/null
+++ b/libs/cglm/docs/source/bezier.rst
@@ -0,0 +1,89 @@
+.. default-domain:: C
+
+Bezier
+================================================================================
+
+Header: cglm/bezier.h
+
+Common helpers for cubic bezier and similar curves.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_bezier`
+2. :c:func:`glm_hermite`
+3. :c:func:`glm_decasteljau`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_bezier(float s, float p0, float c0, float c1, float p1)
+
+ | cubic bezier interpolation
+ | formula:
+
+ .. code-block:: text
+
+ B(s) = P0*(1-s)^3 + 3*C0*s*(1-s)^2 + 3*C1*s^2*(1-s) + P1*s^3
+
+ | similar result using matrix:
+
+ .. code-block:: text
+
+ B(s) = glm_smc(t, GLM_BEZIER_MAT, (vec4){p0, c0, c1, p1})
+
+ | glm_eq(glm_smc(...), glm_bezier(...)) should return TRUE
+
+ Parameters:
+ | *[in]* **s** parameter between 0 and 1
+ | *[in]* **p0** begin point
+ | *[in]* **c0** control point 1
+ | *[in]* **c1** control point 2
+ | *[in]* **p1** end point
+
+ Returns:
+ B(s)
+
+.. c:function:: float glm_hermite(float s, float p0, float t0, float t1, float p1)
+
+ | cubic hermite interpolation
+ | formula:
+
+ .. code-block:: text
+
+ H(s) = P0*(2*s^3 - 3*s^2 + 1) + T0*(s^3 - 2*s^2 + s) + P1*(-2*s^3 + 3*s^2) + T1*(s^3 - s^2)
+
+ | similar result using matrix:
+
+ .. code-block:: text
+
+ H(s) = glm_smc(t, GLM_HERMITE_MAT, (vec4){p0, p1, c0, c1})
+
+ | glm_eq(glm_smc(...), glm_hermite(...)) should return TRUE
+
+
+ Parameters:
+ | *[in]* **s** parameter between 0 and 1
+ | *[in]* **p0** begin point
+ | *[in]* **t0** tangent 1
+ | *[in]* **t1** tangent 2
+ | *[in]* **p1** end point
+
+ Returns:
+ B(s)
+
+.. c:function:: float glm_decasteljau(float prm, float p0, float c0, float c1, float p1)
+
+ | iterative way to solve cubic equation
+
+ Parameters:
+ | *[in]* **prm** parameter between 0 and 1
+ | *[in]* **p0** begin point
+ | *[in]* **c0** control point 1
+ | *[in]* **c1** control point 2
+ | *[in]* **p1** end point
+
+ Returns:
+ parameter to use in cubic equation
diff --git a/libs/cglm/docs/source/box.rst b/libs/cglm/docs/source/box.rst
new file mode 100644
index 0000000..7a388e2
--- /dev/null
+++ b/libs/cglm/docs/source/box.rst
@@ -0,0 +1,181 @@
+.. default-domain:: C
+
+axis aligned bounding box (AABB)
+================================================================================
+
+Header: cglm/box.h
+
+Some convenient functions provided for AABB.
+
+**Definition of box:**
+
+cglm defines box as two dimensional array of vec3.
+The first element is **min** point and the second one is **max** point.
+If you have another type e.g. struct or even another representation then you must
+convert it before and after call cglm box function.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_aabb_transform`
+#. :c:func:`glm_aabb_merge`
+#. :c:func:`glm_aabb_crop`
+#. :c:func:`glm_aabb_crop_until`
+#. :c:func:`glm_aabb_frustum`
+#. :c:func:`glm_aabb_invalidate`
+#. :c:func:`glm_aabb_isvalid`
+#. :c:func:`glm_aabb_size`
+#. :c:func:`glm_aabb_radius`
+#. :c:func:`glm_aabb_center`
+#. :c:func:`glm_aabb_aabb`
+#. :c:func:`glm_aabb_sphere`
+#. :c:func:`glm_aabb_point`
+#. :c:func:`glm_aabb_contains`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2])
+
+ | apply transform to Axis-Aligned Bounding Box
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[in]* **m** transform matrix
+ | *[out]* **dest** transformed bounding box
+
+.. c:function:: void glm_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2])
+
+ | merges two AABB bounding box and creates new one
+
+ two box must be in same space, if one of box is in different space then
+ you should consider to convert it's space by glm_box_space
+
+ Parameters:
+ | *[in]* **box1** bounding box 1
+ | *[in]* **box2** bounding box 2
+ | *[out]* **dest** merged bounding box
+
+.. c:function:: void glm_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2])
+
+ | crops a bounding box with another one.
+
+ this could be useful for gettng a bbox which fits with view frustum and
+ object bounding boxes. In this case you crop view frustum box with objects
+ box
+
+ Parameters:
+ | *[in]* **box** bounding box 1
+ | *[in]* **cropBox** crop box
+ | *[out]* **dest** cropped bounding box
+
+.. c:function:: void glm_aabb_crop_until(vec3 box[2], vec3 cropBox[2], vec3 clampBox[2], vec3 dest[2])
+
+ | crops a bounding box with another one.
+
+ this could be useful for gettng a bbox which fits with view frustum and
+ object bounding boxes. In this case you crop view frustum box with objects
+ box
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[in]* **cropBox** crop box
+ | *[in]* **clampBox** miniumum box
+ | *[out]* **dest** cropped bounding box
+
+.. c:function:: bool glm_aabb_frustum(vec3 box[2], vec4 planes[6])
+
+ | check if AABB intersects with frustum planes
+
+ this could be useful for frustum culling using AABB.
+
+ OPTIMIZATION HINT:
+ if planes order is similar to LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
+ then this method should run even faster because it would only use two
+ planes if object is not inside the two planes
+ fortunately cglm extracts planes as this order! just pass what you got!
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **planes** frustum planes
+
+.. c:function:: void glm_aabb_invalidate(vec3 box[2])
+
+ | invalidate AABB min and max values
+
+ | It fills *max* values with -FLT_MAX and *min* values with +FLT_MAX
+
+ Parameters:
+ | *[in, out]* **box** bounding box
+
+.. c:function:: bool glm_aabb_isvalid(vec3 box[2])
+
+ | check if AABB is valid or not
+
+ Parameters:
+ | *[in]* **box** bounding box
+
+ Returns:
+ returns true if aabb is valid otherwise false
+
+.. c:function:: float glm_aabb_size(vec3 box[2])
+
+ | distance between of min and max
+
+ Parameters:
+ | *[in]* **box** bounding box
+
+ Returns:
+ distance between min - max
+
+.. c:function:: float glm_aabb_radius(vec3 box[2])
+
+ | radius of sphere which surrounds AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+
+.. c:function:: void glm_aabb_center(vec3 box[2], vec3 dest)
+
+ | computes center point of AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **dest** center of bounding box
+
+.. c:function:: bool glm_aabb_aabb(vec3 box[2], vec3 other[2])
+
+ | check if two AABB intersects
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **other** other bounding box
+
+.. c:function:: bool glm_aabb_sphere(vec3 box[2], vec4 s)
+
+ | check if AABB intersects with sphere
+
+ | https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
+ | Solid Box - Solid Sphere test.
+
+ Parameters:
+ | *[in]* **box** solid bounding box
+ | *[out]* **s** solid sphere
+
+.. c:function:: bool glm_aabb_point(vec3 box[2], vec3 point)
+
+ | check if point is inside of AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **point** point
+
+.. c:function:: bool glm_aabb_contains(vec3 box[2], vec3 other[2])
+
+ | check if AABB contains other AABB
+
+ Parameters:
+ | *[in]* **box** bounding box
+ | *[out]* **other** other bounding box
diff --git a/libs/cglm/docs/source/build.rst b/libs/cglm/docs/source/build.rst
new file mode 100644
index 0000000..e2eb23d
--- /dev/null
+++ b/libs/cglm/docs/source/build.rst
@@ -0,0 +1,153 @@
+Build cglm
+================================
+
+| **cglm** does not have any external dependencies.
+
+**NOTE:**
+If you only need to inline versions, you don't need to build **cglm**, you don't need to link it to your program.
+Just import cglm to your project as dependency / external lib by copy-paste then use it as usual
+
+CMake (All platforms):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+ :linenos:
+
+ $ mkdir build
+ $ cd build
+ $ cmake .. # [Optional] -DCGLM_SHARED=ON
+ $ make
+ $ sudo make install # [Optional]
+
+**make** will build cglm to **build** folder.
+If you don't want to install **cglm** to your system's folder you can get static and dynamic libs in this folder.
+
+**CMake Options:**
+
+.. code-block:: CMake
+ :linenos:
+
+ option(CGLM_SHARED "Shared build" ON)
+ option(CGLM_STATIC "Static build" OFF)
+ option(CGLM_USE_C99 "" OFF) # C11
+ option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
+
+**Use as header-only library with your CMake project example**
+This requires no building or installation of cglm.
+
+.. code-block:: CMake
+ :linenos:
+
+ cmake_minimum_required(VERSION 3.8.2)
+
+ project(<Your Project Name>)
+
+ add_executable(${PROJECT_NAME} src/main.c)
+ target_link_libraries(${LIBRARY_NAME} PRIVATE
+ cglm_headers)
+
+ add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
+
+**Use with your CMake project example**
+
+.. code-block:: CMake
+ :linenos:
+
+ cmake_minimum_required(VERSION 3.8.2)
+
+ project(<Your Project Name>)
+
+ add_executable(${PROJECT_NAME} src/main.c)
+ target_link_libraries(${LIBRARY_NAME} PRIVATE
+ cglm)
+
+ add_subdirectory(external/cglm/)
+
+Meson (All platforms):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block::
+ :linenos:
+
+ $ meson build # [Optional] --default-library=static
+ $ cd build
+ $ ninja
+ $ sudo ninja install # [Optional]
+
+**Meson Options:**
+
+.. code-block::
+ :linenos:
+
+ c_std=c11
+ buildtype=release
+ default_library=shared
+ enable_tests=false # to run tests: ninja test
+
+
+**Use with your Meson project**
+
+.. code-block::
+ :linenos:
+
+ # Clone cglm or create a cglm.wrap under <source_root>/subprojects
+ project('name', 'c')
+
+ cglm_dep = dependency('cglm', fallback : 'cglm', 'cglm_dep')
+
+ executable('exe', 'src/main.c', dependencies : cglm_dep)
+
+
+Unix (Autotools):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: bash
+ :linenos:
+
+ $ sh autogen.sh
+ $ ./configure
+ $ make
+ $ make check # run tests (optional)
+ $ [sudo] make install # install to system (optional)
+
+**make** will build cglm to **.libs** sub folder in project folder.
+If you don't want to install **cglm** to your system's folder you can get static and dynamic libs in this folder.
+
+Windows (MSBuild):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Windows related build files, project files are located in `win` folder,
+make sure you are inside in cglm/win folder.
+
+Code Analysis are enabled, it may take awhile to build.
+
+.. code-block:: bash
+ :linenos:
+
+ $ cd win
+ $ .\build.bat
+
+if *msbuild* is not worked (because of multi versions of Visual Studio)
+then try to build with *devenv*:
+
+.. code-block:: bash
+ :linenos:
+
+ $ devenv cglm.sln /Build Release
+
+Currently tests are not available on Windows.
+
+Documentation (Sphinx):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**cglm** uses sphinx framework for documentation, it allows lot of formats for documentation. To see all options see sphinx build page:
+
+https://www.sphinx-doc.org/en/master/man/sphinx-build.html
+
+Example build:
+
+.. code-block:: bash
+ :linenos:
+
+ $ cd cglm/docs
+ $ sphinx-build source build
diff --git a/libs/cglm/docs/source/call.rst b/libs/cglm/docs/source/call.rst
new file mode 100644
index 0000000..f7765a7
--- /dev/null
+++ b/libs/cglm/docs/source/call.rst
@@ -0,0 +1,19 @@
+.. default-domain:: C
+
+precompiled functions (call)
+================================================================================
+
+All funcitons in **glm_** namespace are forced to **inline**.
+Most functions also have pre-compiled version.
+
+Precompiled versions are in **glmc_** namespace. *c* in the namespace stands for
+"call".
+
+Since precompiled functions are just wrapper for inline verisons,
+these functions are not documented individually.
+It would be duplicate documentation also it
+would be hard to sync documentation between inline and call verison for me.
+
+By including **clgm/cglm.h** you include all inline verisons. To get precompiled
+versions you need to include **cglm/call.h** header it also includes all
+call versions plus *clgm/cglm.h* (inline verisons)
diff --git a/libs/cglm/docs/source/cam.rst b/libs/cglm/docs/source/cam.rst
new file mode 100644
index 0000000..7afc5db
--- /dev/null
+++ b/libs/cglm/docs/source/cam.rst
@@ -0,0 +1,313 @@
+.. default-domain:: C
+
+camera
+======
+
+Header: cglm/cam.h
+
+There are many convenient functions for camera. For instance :c:func:`glm_look`
+is just wrapper for :c:func:`glm_lookat`. Sometimes you only have direction
+instead of target, so that makes easy to build view matrix using direction.
+There is also :c:func:`glm_look_anyup` function which can help build view matrix
+without providing UP axis. It uses :c:func:`glm_vec3_ortho` to get a UP axis and
+builds view matrix.
+
+You can also *_default* versions of ortho and perspective to build projection
+fast if you don't care specific projection values.
+
+*_decomp* means decompose; these function can help to decompose projection
+matrices.
+
+ **NOTE**: Be careful when working with high range (very small near, very large
+ far) projection matrices. You may not get exact value you gave.
+ **float** type cannot store very high precision so you will lose precision.
+ Also your projection matrix will be inaccurate due to losing precision
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_frustum`
+#. :c:func:`glm_ortho`
+#. :c:func:`glm_ortho_aabb`
+#. :c:func:`glm_ortho_aabb_p`
+#. :c:func:`glm_ortho_aabb_pz`
+#. :c:func:`glm_ortho_default`
+#. :c:func:`glm_ortho_default_s`
+#. :c:func:`glm_perspective`
+#. :c:func:`glm_persp_move_far`
+#. :c:func:`glm_perspective_default`
+#. :c:func:`glm_perspective_resize`
+#. :c:func:`glm_lookat`
+#. :c:func:`glm_look`
+#. :c:func:`glm_look_anyup`
+#. :c:func:`glm_persp_decomp`
+#. :c:func:`glm_persp_decompv`
+#. :c:func:`glm_persp_decomp_x`
+#. :c:func:`glm_persp_decomp_y`
+#. :c:func:`glm_persp_decomp_z`
+#. :c:func:`glm_persp_decomp_far`
+#. :c:func:`glm_persp_decomp_near`
+#. :c:func:`glm_persp_fovy`
+#. :c:func:`glm_persp_aspect`
+#. :c:func:`glm_persp_sizes`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_frustum(float left, float right, float bottom, float top, float nearVal, float farVal, mat4 dest)
+
+ | set up perspective peprojection matrix
+
+ Parameters:
+ | *[in]* **left** viewport.left
+ | *[in]* **right** viewport.right
+ | *[in]* **bottom** viewport.bottom
+ | *[in]* **top** viewport.top
+ | *[in]* **nearVal** near clipping plane
+ | *[in]* **farVal** far clipping plane
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_ortho(float left, float right, float bottom, float top, float nearVal, float farVal, mat4 dest)
+
+ | set up orthographic projection matrix
+
+ Parameters:
+ | *[in]* **left** viewport.left
+ | *[in]* **right** viewport.right
+ | *[in]* **bottom** viewport.bottom
+ | *[in]* **top** viewport.top
+ | *[in]* **nearVal** near clipping plane
+ | *[in]* **farVal** far clipping plane
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_ortho_aabb(vec3 box[2], mat4 dest)
+
+ | set up orthographic projection matrix using bounding box
+ | bounding box (AABB) must be in view space
+
+ Parameters:
+ | *[in]* **box** AABB
+ | *[in]* **dest** result matrix
+
+.. c:function:: void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
+
+ | set up orthographic projection matrix using bounding box
+ | bounding box (AABB) must be in view space
+
+ this version adds padding to box
+
+ Parameters:
+ | *[in]* **box** AABB
+ | *[in]* **padding** padding
+ | *[out]* **d** result matrix
+
+.. c:function:: void glm_ortho_aabb_pz(vec3 box[2], float padding, mat4 dest)
+
+ | set up orthographic projection matrix using bounding box
+ | bounding box (AABB) must be in view space
+
+ this version adds Z padding to box
+
+ Parameters:
+ | *[in]* **box** AABB
+ | *[in]* **padding** padding for near and far
+ | *[out]* **d** result matrix
+
+ Returns:
+ square of norm / magnitude
+
+.. c:function:: void glm_ortho_default(float aspect, mat4 dest)
+
+ | set up unit orthographic projection matrix
+
+ Parameters:
+ | *[in]* **aspect** aspect ration ( width / height )
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_ortho_default_s(float aspect, float size, mat4 dest)
+
+ | set up orthographic projection matrix with given CUBE size
+
+ Parameters:
+ | *[in]* **aspect** aspect ration ( width / height )
+ | *[in]* **size** cube size
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_perspective(float fovy, float aspect, float nearVal, float farVal, mat4 dest)
+
+ | set up perspective projection matrix
+
+ Parameters:
+ | *[in]* **fovy** field of view angle (in radians)
+ | *[in]* **aspect** aspect ratio ( width / height )
+ | *[in]* **nearVal** near clipping plane
+ | *[in]* **farVal** far clipping planes
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_persp_move_far(mat4 proj, float deltaFar)
+
+ | extend perspective projection matrix's far distance
+
+ | this function does not guarantee far >= near, be aware of that!
+
+ Parameters:
+ | *[in, out]* **proj** projection matrix to extend
+ | *[in]* **deltaFar** distance from existing far (negative to shink)
+
+.. c:function:: void glm_perspective_default(float aspect, mat4 dest)
+
+ | set up perspective projection matrix with default near/far
+ and angle values
+
+ Parameters:
+ | *[in]* **aspect** aspect aspect ratio ( width / height )
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_perspective_resize(float aspect, mat4 proj)
+
+ | resize perspective matrix by aspect ratio ( width / height )
+ this makes very easy to resize proj matrix when window / viewport reized
+
+ Parameters:
+ | *[in]* **aspect** aspect ratio ( width / height )
+ | *[in, out]* **proj** perspective projection matrix
+
+.. c:function:: void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest)
+
+ | set up view matrix
+
+ **NOTE:** The UP vector must not be parallel to the line of sight from the eye point to the reference point.
+
+ Parameters:
+ | *[in]* **eye** eye vector
+ | *[in]* **center** center vector
+ | *[in]* **up** up vector
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest)
+
+ | set up view matrix
+
+ convenient wrapper for :c:func:`glm_lookat`: if you only have direction not
+ target self then this might be useful. Because you need to get target
+ from direction.
+
+ **NOTE:** The UP vector must not be parallel to the line of sight from the eye point to the reference point.
+
+ Parameters:
+ | *[in]* **eye** eye vector
+ | *[in]* **dir** direction vector
+ | *[in]* **up** up vector
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_look_anyup(vec3 eye, vec3 dir, mat4 dest)
+
+ | set up view matrix
+
+ convenient wrapper for :c:func:`glm_look` if you only have direction
+ and if you don't care what UP vector is then this might be useful
+ to create view matrix
+
+ Parameters:
+ | *[in]* **eye** eye vector
+ | *[in]* **dir** direction vector
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_persp_decomp(mat4 proj, float *nearVal, float *farVal, float *top, float *bottom, float *left, float *right)
+
+ | decomposes frustum values of perspective projection.
+
+ Parameters:
+ | *[in]* **eye** perspective projection matrix
+ | *[out]* **nearVal** near
+ | *[out]* **farVal** far
+ | *[out]* **top** top
+ | *[out]* **bottom** bottom
+ | *[out]* **left** left
+ | *[out]* **right** right
+
+.. c:function:: void glm_persp_decompv(mat4 proj, float dest[6])
+
+ | decomposes frustum values of perspective projection.
+ | this makes easy to get all values at once
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **dest** array
+
+.. c:function:: void glm_persp_decomp_x(mat4 proj, float *left, float *right)
+
+ | decomposes left and right values of perspective projection.
+ | x stands for x axis (left / right axis)
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **left** left
+ | *[out]* **right** right
+
+.. c:function:: void glm_persp_decomp_y(mat4 proj, float *top, float *bottom)
+
+ | decomposes top and bottom values of perspective projection.
+ | y stands for y axis (top / botom axis)
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **top** top
+ | *[out]* **bottom** bottom
+
+.. c:function:: void glm_persp_decomp_z(mat4 proj, float *nearVal, float *farVal)
+
+ | decomposes near and far values of perspective projection.
+ | z stands for z axis (near / far axis)
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **nearVal** near
+ | *[out]* **farVal** far
+
+.. c:function:: void glm_persp_decomp_far(mat4 proj, float * __restrict farVal)
+
+ | decomposes far value of perspective projection.
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **farVal** far
+
+.. c:function:: void glm_persp_decomp_near(mat4 proj, float * __restrict nearVal)
+
+ | decomposes near value of perspective projection.
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[out]* **nearVal** near
+
+.. c:function:: float glm_persp_fovy(mat4 proj)
+
+ | returns field of view angle along the Y-axis (in radians)
+
+ if you need to degrees, use glm_deg to convert it or use this:
+ fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+
+ Returns:
+ | fovy in radians
+
+.. c:function:: float glm_persp_aspect(mat4 proj)
+
+ | returns aspect ratio of perspective projection
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+
+.. c:function:: void glm_persp_sizes(mat4 proj, float fovy, vec4 dest)
+
+ | returns sizes of near and far planes of perspective projection
+
+ Parameters:
+ | *[in]* **proj** perspective projection matrix
+ | *[in]* **fovy** fovy (see brief)
+ | *[out]* **dest** sizes order: [Wnear, Hnear, Wfar, Hfar]
diff --git a/libs/cglm/docs/source/cglm-intro.png b/libs/cglm/docs/source/cglm-intro.png
new file mode 100644
index 0000000..74ac74e
--- /dev/null
+++ b/libs/cglm/docs/source/cglm-intro.png
Binary files differ
diff --git a/libs/cglm/docs/source/color.rst b/libs/cglm/docs/source/color.rst
new file mode 100644
index 0000000..62a4dc1
--- /dev/null
+++ b/libs/cglm/docs/source/color.rst
@@ -0,0 +1,34 @@
+.. default-domain:: C
+
+color
+================================================================================
+
+Header: cglm/color.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_luminance`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_luminance(vec3 rgb)
+
+ | averages the color channels into one value
+
+ This function uses formula in COLLADA 1.5 spec which is
+
+ .. code-block:: text
+
+ luminance = (color.r * 0.212671) +
+ (color.g * 0.715160) +
+ (color.b * 0.072169)
+
+ It is based on the ISO/CIE color standards (see ITU-R Recommendation BT.709-4),
+ that averages the color channels into one value
+
+ Parameters:
+ | *[in]* **rgb** RGB color
diff --git a/libs/cglm/docs/source/conf.py b/libs/cglm/docs/source/conf.py
new file mode 100644
index 0000000..eaf48b4
--- /dev/null
+++ b/libs/cglm/docs/source/conf.py
@@ -0,0 +1,203 @@
+# -*- coding: utf-8 -*-
+#
+# cglm documentation build configuration file, created by
+# sphinx-quickstart on Tue Jun 6 20:31:05 2017.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '3.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.todo',
+ 'sphinx.ext.coverage',
+ 'sphinx.ext.mathjax',
+ 'sphinx.ext.ifconfig',
+ 'sphinx.ext.viewcode',
+ 'sphinx.ext.githubpages'
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'cglm'
+copyright = u'2017, Recep Aslantas'
+author = u'Recep Aslantas'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = u'0.8.6'
+# The full version, including alpha/beta/rc tags.
+release = u'0.8.6'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = []
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+html_theme_options = {
+ # 'github_banner': 'true',
+ # 'github_button': 'true',
+ # 'github_user': 'recp',
+ # 'github_repo': 'cglm',
+ # 'travis_button': 'true',
+ # 'show_related': 'true',
+ # 'fixed_sidebar': 'true'
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'cglmdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'cglm.tex', u'cglm Documentation',
+ u'Recep Aslantas', 'manual'),
+]
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'cglm', u'cglm Documentation',
+ [author], 1)
+]
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'cglm', u'cglm Documentation',
+ author, 'cglm', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# -- Options for Epub output -------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
+epub_author = author
+epub_publisher = author
+epub_copyright = copyright
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#
+# epub_identifier = ''
+
+# A unique identification for the text.
+#
+# epub_uid = ''
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+
+# -- Extension configuration -------------------------------------------------
+
+# -- Options for todo extension ----------------------------------------------
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+# -- Options for the C domain ------------------------------------------------
+
+c_id_attributes = ['__restrict']
diff --git a/libs/cglm/docs/source/curve.rst b/libs/cglm/docs/source/curve.rst
new file mode 100644
index 0000000..26c9b75
--- /dev/null
+++ b/libs/cglm/docs/source/curve.rst
@@ -0,0 +1,41 @@
+.. default-domain:: C
+
+Curve
+================================================================================
+
+Header: cglm/curve.h
+
+Common helpers for common curves. For specific curve see its header/doc
+e.g bezier
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_smc`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_smc(float s, mat4 m, vec4 c)
+
+ | helper function to calculate **S** * **M** * **C** multiplication for curves
+
+ | this function does not encourage you to use SMC, instead it is a helper if you use SMC.
+
+ | if you want to specify S as vector then use more generic glm_mat4_rmc() func.
+
+ | Example usage:
+
+ .. code-block:: c
+
+ Bs = glm_smc(s, GLM_BEZIER_MAT, (vec4){p0, c0, c1, p1})
+
+ Parameters:
+ | *[in]* **s** parameter between 0 and 1 (this will be [s3, s2, s, 1])
+ | *[in]* **m** basis matrix
+ | *[out]* **c** position/control vector
+
+ Returns:
+ scalar value e.g. Bs
diff --git a/libs/cglm/docs/source/euler.rst b/libs/cglm/docs/source/euler.rst
new file mode 100644
index 0000000..74ba4c2
--- /dev/null
+++ b/libs/cglm/docs/source/euler.rst
@@ -0,0 +1,182 @@
+.. default-domain:: C
+
+euler angles
+============
+
+Header: cglm/euler.h
+
+You may wonder what **glm_euler_sq** type ( **_sq** stands for sequence ) and
+:c:func:`glm_euler_by_order` do.
+I used them to convert euler angles in one coordinate system to another. For
+instance if you have **Z_UP** euler angles and if you want to convert it
+to **Y_UP** axis then :c:func:`glm_euler_by_order` is your friend. For more
+information check :c:func:`glm_euler_order` documentation
+
+You must pass arrays as array, if you use C compiler then you can use something
+like this:
+
+.. code-block:: c
+
+ float pitch, yaw, roll;
+ mat4 rot;
+
+ /* pitch = ...; yaw = ...; roll = ... */
+ glm_euler((vec3){pitch, yaw, roll}, rot);
+
+Rotation Conveniention
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Current *cglm*'s euler functions uses these convention:
+
+* Tait–Bryan angles (x-y-z convention)
+* Intrinsic rotations (pitch, yaw and roll).
+ This is reserve order of extrinsic (elevation, heading and bank) rotation
+* Right hand rule (actually all rotations in *cglm* use **RH**)
+* All angles used in *cglm* are **RADIANS** not degrees
+
+
+**NOTE**: The default :c:func:`glm_euler` function is the short name of
+:c:func:`glm_euler_xyz` this is why you can't see :c:func:`glm_euler_xyz`.
+When you see an euler function which doesn't have any X, Y, Z suffix then
+assume that uses **_xyz** (or instead it accept order as parameter).
+
+If rotation doesn't work properly, your options:
+
+1. If you use (or paste) degrees convert it to radians before calling an euler function
+
+.. code-block:: c
+
+ float pitch, yaw, roll;
+ mat4 rot;
+
+ /* pitch = degrees; yaw = degrees; roll = degrees */
+ glm_euler((vec3){glm_rad(pitch), glm_rad(yaw), glm_rad(roll)}, rot);
+
+2. Convention mismatch. You may have extrinsic angles,
+ if you do (if you must) then consider to use reverse order e.g if you have
+ **xyz** extrinsic then use **zyx**
+
+3. *cglm* may implemented it wrong, consider to create an issue to report it
+ or pull request to fix it
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Types:
+
+1. glm_euler_sq
+
+Functions:
+
+1. :c:func:`glm_euler_order`
+#. :c:func:`glm_euler_angles`
+#. :c:func:`glm_euler`
+#. :c:func:`glm_euler_xyz`
+#. :c:func:`glm_euler_zyx`
+#. :c:func:`glm_euler_zxy`
+#. :c:func:`glm_euler_xzy`
+#. :c:func:`glm_euler_yzx`
+#. :c:func:`glm_euler_yxz`
+#. :c:func:`glm_euler_by_order`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: glm_euler_sq glm_euler_order(int ord[3])
+
+ | packs euler angles order to glm_euler_sq enum.
+
+ To use :c:func:`glm_euler_by_order` function you need *glm_euler_sq*. You
+ can get it with this function.
+
+ You can build param like this:
+
+ | X = 0, Y = 1, Z = 2
+
+ if you have ZYX order then you pass this: [2, 1, 0] = ZYX.
+ if you have YXZ order then you pass this: [1, 0, 2] = YXZ
+
+ As you can see first item specifies which axis will be first then the
+ second one specifies which one will be next an so on.
+
+ Parameters:
+ | *[in]* **ord** euler angles order [Angle1, Angle2, Angle2]
+
+ Returns:
+ packed euler order
+
+.. c:function:: void glm_euler_angles(mat4 m, vec3 dest)
+
+ | extract euler angles (in radians) using xyz order
+
+ Parameters:
+ | *[in]* **m** affine transform
+ | *[out]* **dest** angles vector [x, y, z]
+
+.. c:function:: void glm_euler(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ this is alias of glm_euler_xyz function
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_xyz(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_zyx(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_zxy(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_xzy(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_yzx(vec3 angles, mat4 dest)
+
+ build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_yxz(vec3 angles, mat4 dest)
+
+ | build rotation matrix from euler angles
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **dest** rotation matrix
+
+.. c:function:: void glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest)
+
+ | build rotation matrix from euler angles with given euler order.
+
+ Use :c:func:`glm_euler_order` function to build *ord* parameter
+
+ Parameters:
+ | *[in]* **angles** angles as vector [Xangle, Yangle, Zangle]
+ | *[in]* **ord** euler order
+ | *[in]* **dest** rotation matrix
diff --git a/libs/cglm/docs/source/features.rst b/libs/cglm/docs/source/features.rst
new file mode 100644
index 0000000..8113f63
--- /dev/null
+++ b/libs/cglm/docs/source/features.rst
@@ -0,0 +1,28 @@
+Features
+================================================================================
+
+* **scalar** and **simd** (sse, avx, neon...) optimizations
+* option to use different clipspaces e.g. Left Handed, Zero-to-One... (currrently right handed negative-one is default)
+* array api and struct api, you can use arrays or structs.
+* general purpose matrix operations (mat4, mat3)
+* chain matrix multiplication (square only)
+* general purpose vector operations (cross, dot, rotate, proj, angle...)
+* affine transformations
+* matrix decomposition (extract rotation, scaling factor)
+* optimized affine transform matrices (mul, rigid-body inverse)
+* camera (lookat)
+* projections (ortho, perspective)
+* quaternions
+* euler angles / yaw-pitch-roll to matrix
+* extract euler angles
+* inline or pre-compiled function call
+* frustum (extract view frustum planes, corners...)
+* bounding box (AABB in Frustum (culling), crop, merge...)
+* bounding sphere
+* project, unproject
+* easing functions
+* curves
+* curve interpolation helpers (SMC, deCasteljau...)
+* helpers to convert cglm types to Apple's simd library to pass cglm types to Metal GL without packing them on both sides
+* ray intersection helpers
+* and others...
diff --git a/libs/cglm/docs/source/frustum.rst b/libs/cglm/docs/source/frustum.rst
new file mode 100644
index 0000000..b58913c
--- /dev/null
+++ b/libs/cglm/docs/source/frustum.rst
@@ -0,0 +1,168 @@
+.. default-domain:: C
+
+frustum
+=============
+
+Header: cglm/frustum.h
+
+cglm provides convenient functions to extract frustum planes, corners...
+All extracted corners are **vec4** so you must create array of **vec4**
+not **vec3**. If you want to store them to save space you msut convert them
+yourself.
+
+**vec4** is used to speed up functions need to corners. This is why frustum
+fucntions use *vec4* instead of *vec3*
+
+Currenty related-functions use [-1, 1] clip space configuration to extract
+corners but you can override it by prodiving **GLM_CUSTOM_CLIPSPACE** macro.
+If you provide it then you have to all bottom macros as *vec4*
+
+Current configuration:
+
+.. code-block:: c
+
+ /* near */
+ GLM_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
+ GLM_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
+ GLM_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
+ GLM_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
+
+ /* far */
+ GLM_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
+ GLM_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
+ GLM_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
+ GLM_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
+
+
+Explain of short names:
+ * **LBN**: left bottom near
+ * **LTN**: left top near
+ * **RTN**: right top near
+ * **RBN**: right bottom near
+ * **LBF**: left bottom far
+ * **LTF**: left top far
+ * **RTF**: right top far
+ * **RBF**: right bottom far
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+.. code-block:: c
+
+ GLM_LBN 0 /* left bottom near */
+ GLM_LTN 1 /* left top near */
+ GLM_RTN 2 /* right top near */
+ GLM_RBN 3 /* right bottom near */
+
+ GLM_LBF 4 /* left bottom far */
+ GLM_LTF 5 /* left top far */
+ GLM_RTF 6 /* right top far */
+ GLM_RBF 7 /* right bottom far */
+
+ GLM_LEFT 0
+ GLM_RIGHT 1
+ GLM_BOTTOM 2
+ GLM_TOP 3
+ GLM_NEAR 4
+ GLM_FAR 5
+
+Functions:
+
+1. :c:func:`glm_frustum_planes`
+#. :c:func:`glm_frustum_corners`
+#. :c:func:`glm_frustum_center`
+#. :c:func:`glm_frustum_box`
+#. :c:func:`glm_frustum_corners_at`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_frustum_planes(mat4 m, vec4 dest[6])
+
+ | extracts view frustum planes
+
+ planes' space:
+ - if m = proj: View Space
+ - if m = viewProj: World Space
+ - if m = MVP: Object Space
+
+ You probably want to extract planes in world space so use viewProj as m
+ Computing viewProj:
+
+ .. code-block:: c
+
+ glm_mat4_mul(proj, view, viewProj);
+
+ Exracted planes order: [left, right, bottom, top, near, far]
+
+ Parameters:
+ | *[in]* **m** matrix
+ | *[out]* **dest** exracted view frustum planes
+
+.. c:function:: void glm_frustum_corners(mat4 invMat, vec4 dest[8])
+
+ | extracts view frustum corners using clip-space coordinates
+
+ corners' space:
+ - if m = invViewProj: World Space
+ - if m = invMVP: Object Space
+
+ You probably want to extract corners in world space so use **invViewProj**
+ Computing invViewProj:
+
+ .. code-block:: c
+
+ glm_mat4_mul(proj, view, viewProj);
+ ...
+ glm_mat4_inv(viewProj, invViewProj);
+
+ if you have a near coord at **i** index,
+ you can get it's far coord by i + 4;
+ follow example below to understand that
+
+ For instance to find center coordinates between a near and its far coord:
+
+ .. code-block:: c
+
+ for (j = 0; j < 4; j++) {
+ glm_vec3_center(corners[i], corners[i + 4], centerCorners[i]);
+ }
+
+ corners[i + 4] is far of corners[i] point.
+
+ Parameters:
+ | *[in]* **invMat** matrix
+ | *[out]* **dest** exracted view frustum corners
+
+.. c:function:: void glm_frustum_center(vec4 corners[8], vec4 dest)
+
+ | finds center of view frustum
+
+ Parameters:
+ | *[in]* **corners** view frustum corners
+ | *[out]* **dest** view frustum center
+
+.. c:function:: void glm_frustum_box(vec4 corners[8], mat4 m, vec3 box[2])
+
+ | finds bounding box of frustum relative to given matrix e.g. view mat
+
+ Parameters:
+ | *[in]* **corners** view frustum corners
+ | *[in]* **m** matrix to convert existing conners
+ | *[out]* **box** bounding box as array [min, max]
+
+.. c:function:: void glm_frustum_corners_at(vec4 corners[8], float splitDist, float farDist, vec4 planeCorners[4])
+
+ | finds planes corners which is between near and far planes (parallel)
+
+ this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
+ find planes' corners but you will need to one more plane.
+ Actually you have it, it is near, far or created previously with this func ;)
+
+ Parameters:
+ | *[in]* **corners** frustum corners
+ | *[in]* **splitDist** split distance
+ | *[in]* **farDist** far distance (zFar)
+ | *[out]* **planeCorners** plane corners [LB, LT, RT, RB]
diff --git a/libs/cglm/docs/source/getting_started.rst b/libs/cglm/docs/source/getting_started.rst
new file mode 100644
index 0000000..bf2b8f3
--- /dev/null
+++ b/libs/cglm/docs/source/getting_started.rst
@@ -0,0 +1,105 @@
+Getting Started
+================================
+
+Types:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**cglm** uses **glm** prefix for all functions e.g. glm_lookat. You can see supported types in common header file:
+
+.. code-block:: c
+ :linenos:
+
+ typedef float vec2[2];
+ typedef float vec3[3];
+ typedef int ivec3[3];
+ typedef CGLM_ALIGN_IF(16) float vec4[4];
+ typedef vec4 versor;
+ typedef vec3 mat3[3];
+
+ #ifdef __AVX__
+ typedef CGLM_ALIGN_IF(32) vec4 mat4[4];
+ #else
+ typedef CGLM_ALIGN_IF(16) vec4 mat4[4];
+ #endif
+
+As you can see types don't store extra informations in favor of space.
+You can send these values e.g. matrix to OpenGL directly without casting or calling a function like *value_ptr*
+
+Alignment Is Required:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**vec4** and **mat4** requires 16 (32 for **mat4** if AVX is enabled) byte alignment because **vec4** and **mat4** operations are vectorized by SIMD instructions (SSE/AVX/NEON).
+
+**UPDATE:**
+ By starting v0.4.5 cglm provides an option to disable alignment requirement, it is enabled as default
+
+ | Check :doc:`opt` page for more details
+
+ Also alignment is disabled for older msvc verisons as default. Now alignment is only required in Visual Studio 2017 version 15.6+ if CGLM_ALL_UNALIGNED macro is not defined.
+
+Allocations:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*cglm* doesn't alloc any memory on heap. So it doesn't provide any allocator.
+You must allocate memory yourself. You should alloc memory for out parameters too if you pass pointer of memory location. When allocating memory, don't forget that **vec4** and **mat4** require alignment.
+
+**NOTE:** Unaligned **vec4** and unaligned **mat4** operations will be supported in the future. Check todo list.
+Because you may want to multiply a CGLM matrix with external matrix.
+There is no guarantee that non-CGLM matrix is aligned. Unaligned types will have *u* prefix e.g. **umat4**
+
+Array vs Struct:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+*cglm* uses arrays for vector and matrix types. So you can't access individual
+elements like vec.x, vec.y, vec.z... You must use subscript to access vector elements
+e.g. vec[0], vec[1], vec[2].
+
+Also I think it is more meaningful to access matrix elements with subscript
+e.g **matrix[2][3]** instead of **matrix._23**. Since matrix is array of vectors,
+vectors are also defined as array. This makes types homogeneous.
+
+**Return arrays?**
+
+Since C doesn't support return arrays, cglm also doesn't support this feature.
+
+Function design:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. image:: cglm-intro.png
+ :width: 492px 
+ :height: 297px
+ :align: center
+
+cglm provides a few way to call a function to do same operation.
+
+* Inline - *glm_, glm_u*
+* Pre-compiled - *glmc_, glmc_u*
+
+For instance **glm_mat4_mul** is inline (all *glm_* functions are inline), to make it non-inline (pre-compiled),
+call it as **glmc_mat4_mul** from library, to use unaligned version use **glm_umat4_mul** (todo).
+
+Most functions have **dest** parameter for output. For instance mat4_mul func looks like this:
+
+.. code-block:: c
+
+ CGLM_INLINE
+ void
+ glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest)
+
+The dest parameter is out parameter. Result will be stored in **dest**.
+Also in this case matrix multiplication order is dest = m1 * m2.
+
+* Changing parameter order will change the multiplication order.
+* You can pass all parameter same (this is similar to m1 `*=` m1), you can pass **dest** as m1 or m2 (this is similar to m1 `*=` m2)
+
+**v** postfix in function names
+-------------------------------
+
+You may see **v** postfix in some function names, v stands for vector.
+For instance consider a function that accepts three parameters x, y, z.
+This function may be overloaded by **v** postfix to accept vector (vec3) instead of separate parameters.
+In some places the v means that it will be apply to a vector.
+
+**_to** postfix in function names
+---------------------------------
+
+*_to* version of function will store the result in specified parameter instead of in-out parameter.
+Some functions don't have _to prefix but they still behave like this e.g. glm_mat4_mul.
diff --git a/libs/cglm/docs/source/index.rst b/libs/cglm/docs/source/index.rst
new file mode 100644
index 0000000..34a71c4
--- /dev/null
+++ b/libs/cglm/docs/source/index.rst
@@ -0,0 +1,53 @@
+.. cglm documentation master file, created by
+ sphinx-quickstart on Tue Jun 6 20:31:05 2017.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+cglm Documentation
+================================
+
+**cglm** is an optimized 3D math library written in C99 (compatible with C89).
+It is similar to the original **glm** library, except **cglm** is mainly for
+**C**.
+
+**cglm** stores matrices as column-major order but in the future row-major is
+considered to be supported as optional.
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Getting Started:
+
+ features
+ build
+ getting_started
+
+.. toctree::
+ :maxdepth: 2
+ :caption: How To:
+
+ opengl
+
+.. toctree::
+ :maxdepth: 2
+ :caption: API:
+
+ api
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Options:
+
+ opt
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Troubleshooting:
+
+ troubleshooting
+
+Indices and Tables:
+===================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/libs/cglm/docs/source/io.rst b/libs/cglm/docs/source/io.rst
new file mode 100644
index 0000000..cead0be
--- /dev/null
+++ b/libs/cglm/docs/source/io.rst
@@ -0,0 +1,119 @@
+.. default-domain:: C
+
+io (input / output e.g. print)
+================================================================================
+
+Header: cglm/io.h
+
+There are some built-in print functions which may save your time,
+especially for debugging.
+
+All functions accept **FILE** parameter which makes very flexible.
+You can even print it to file on disk.
+
+In general you will want to print them to console to see results.
+You can use **stdout** and **stderr** to write results to console.
+Some programs may occupy **stdout** but you can still use **stderr**.
+Using **stderr** is suggested.
+
+Example to print mat4 matrix:
+
+.. code-block:: c
+
+ mat4 transform;
+ /* ... */
+ glm_mat4_print(transform, stderr);
+
+**NOTE:** print functions use **%0.4f** precision if you need more
+(you probably will in some cases), you can change it temporary.
+cglm may provide precision parameter in the future
+
+Changes since **v0.7.3**:
+* Now mis-alignment of columns are fixed: larger numbers are printed via %g and others are printed via %f. Column withs are calculated before print.
+* Now values are colorful ;)
+* Some print improvements
+* New options with default values:
+
+.. code-block:: c
+
+ #define CGLM_PRINT_PRECISION 5
+ #define CGLM_PRINT_MAX_TO_SHORT 1e5
+ #define CGLM_PRINT_COLOR "\033[36m"
+ #define CGLM_PRINT_COLOR_RESET "\033[0m"
+
+* Inline prints are only enabled in DEBUG mode and if **CGLM_DEFINE_PRINTS** is defined.
+
+Check options page.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_mat4_print`
+#. :c:func:`glm_mat3_print`
+#. :c:func:`glm_vec4_print`
+#. :c:func:`glm_vec3_print`
+#. :c:func:`glm_ivec3_print`
+#. :c:func:`glm_versor_print`
+#. :c:func:`glm_aabb_print`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_mat4_print(mat4 matrix, FILE * __restrict ostream)
+
+ | print mat4 to given stream
+
+ Parameters:
+ | *[in]* **matrix** matrix
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_mat3_print(mat3 matrix, FILE * __restrict ostream)
+
+ | print mat3 to given stream
+
+ Parameters:
+ | *[in]* **matrix** matrix
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_vec4_print(vec4 vec, FILE * __restrict ostream)
+
+ | print vec4 to given stream
+
+ Parameters:
+ | *[in]* **vec** vector
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_vec3_print(vec3 vec, FILE * __restrict ostream)
+
+ | print vec3 to given stream
+
+ Parameters:
+ | *[in]* **vec** vector
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_ivec3_print(ivec3 vec, FILE * __restrict ostream)
+
+ | print ivec3 to given stream
+
+ Parameters:
+ | *[in]* **vec** vector
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_versor_print(versor vec, FILE * __restrict ostream)
+
+ | print quaternion to given stream
+
+ Parameters:
+ | *[in]* **vec** quaternion
+ | *[in]* **ostream** FILE to write
+
+.. c:function:: void glm_aabb_print(versor vec, const char * __restrict tag, FILE * __restrict ostream)
+
+ | print aabb to given stream
+
+ Parameters:
+ | *[in]* **vec** aabb (axis-aligned bounding box)
+ | *[in]* **tag** tag to find it more easly in logs
+ | *[in]* **ostream** FILE to write
diff --git a/libs/cglm/docs/source/ivec2.rst b/libs/cglm/docs/source/ivec2.rst
new file mode 100644
index 0000000..c10bc4c
--- /dev/null
+++ b/libs/cglm/docs/source/ivec2.rst
@@ -0,0 +1,163 @@
+.. default-domain:: C
+
+ivec2
+=====
+
+Header: cglm/ivec2.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_ivec2`
+#. :c:func:`glm_ivec2_copy`
+#. :c:func:`glm_ivec2_zero`
+#. :c:func:`glm_ivec2_one`
+#. :c:func:`glm_ivec2_add`
+#. :c:func:`glm_ivec2_adds`
+#. :c:func:`glm_ivec2_sub`
+#. :c:func:`glm_ivec2_subs`
+#. :c:func:`glm_ivec2_mul`
+#. :c:func:`glm_ivec2_scale`
+#. :c:func:`glm_ivec2_distance2`
+#. :c:func:`glm_ivec2_distance`
+#. :c:func:`glm_ivec2_maxv`
+#. :c:func:`glm_ivec2_minv`
+#. :c:func:`glm_ivec2_clamp`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_ivec2(int * v, ivec2 dest)
+
+ init ivec2 using vec3 or vec4
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_copy(ivec2 a, ivec2 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_zero(ivec2 v)
+
+ set all members of [v] to zero
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec2_one(ivec2 v)
+
+ set all members of [v] to one
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec2_add(ivec2 a, ivec2 b, ivec2 dest)
+
+ add vector [a] to vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_adds(ivec2 v, int s, ivec2 dest)
+
+ add scalar s to vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_sub(ivec2 a, ivec2 b, ivec2 dest)
+
+ subtract vector [b] from vector [a] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_subs(ivec2 v, int s, ivec2 dest)
+
+ subtract scalar s from vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_mul(ivec2 a, ivec2 b, ivec2 dest)
+
+ multiply vector [a] with vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_scale(ivec2 v, int s, ivec2 dest)
+
+ multiply vector [a] with scalar s and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: int glm_ivec2_distance2(ivec2 a, ivec2 b)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ squared distance (distance * distance)
+
+.. c:function:: float glm_ivec2_distance(ivec2 a, ivec2 b)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ distance
+
+.. c:function:: void glm_ivec2_maxv(ivec2 a, ivec2 b, ivec2 dest)
+
+ set each member of dest to greater of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_minv(ivec2 a, ivec2 b, ivec2 dest)
+
+ set each member of dest to lesser of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec2_clamp(ivec2 v, int minVal, int maxVal)
+
+ clamp each member of [v] between minVal and maxVal (inclusive)
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
diff --git a/libs/cglm/docs/source/ivec3.rst b/libs/cglm/docs/source/ivec3.rst
new file mode 100644
index 0000000..312078a
--- /dev/null
+++ b/libs/cglm/docs/source/ivec3.rst
@@ -0,0 +1,163 @@
+.. default-domain:: C
+
+ivec3
+=====
+
+Header: cglm/ivec3.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_ivec3`
+#. :c:func:`glm_ivec3_copy`
+#. :c:func:`glm_ivec3_zero`
+#. :c:func:`glm_ivec3_one`
+#. :c:func:`glm_ivec3_add`
+#. :c:func:`glm_ivec3_adds`
+#. :c:func:`glm_ivec3_sub`
+#. :c:func:`glm_ivec3_subs`
+#. :c:func:`glm_ivec3_mul`
+#. :c:func:`glm_ivec3_scale`
+#. :c:func:`glm_ivec3_distance2`
+#. :c:func:`glm_ivec3_distance`
+#. :c:func:`glm_ivec3_maxv`
+#. :c:func:`glm_ivec3_minv`
+#. :c:func:`glm_ivec3_clamp`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_ivec3(ivec4 v4, ivec3 dest)
+
+ init ivec3 using ivec4
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_copy(ivec3 a, ivec3 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_zero(ivec3 v)
+
+ set all members of [v] to zero
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec3_one(ivec3 v)
+
+ set all members of [v] to one
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec3_add(ivec3 a, ivec3 b, ivec3 dest)
+
+ add vector [a] to vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_adds(ivec3 v, int s, ivec3 dest)
+
+ add scalar s to vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_sub(ivec3 a, ivec3 b, ivec3 dest)
+
+ subtract vector [b] from vector [a] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_subs(ivec3 v, int s, ivec3 dest)
+
+ subtract scalar s from vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_mul(ivec3 a, ivec3 b, ivec3 dest)
+
+ multiply vector [a] with vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_scale(ivec3 v, int s, ivec3 dest)
+
+ multiply vector [a] with scalar s and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: int glm_ivec3_distance2(ivec3 a, ivec3 b)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ squared distance (distance * distance)
+
+.. c:function:: float glm_ivec3_distance(ivec3 a, ivec3 b)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ distance
+
+.. c:function:: void glm_ivec3_maxv(ivec3 a, ivec3 b, ivec3 dest)
+
+ set each member of dest to greater of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_minv(ivec3 a, ivec3 b, ivec3 dest)
+
+ set each member of dest to lesser of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec3_clamp(ivec3 v, int minVal, int maxVal)
+
+ clamp each member of [v] between minVal and maxVal (inclusive)
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
diff --git a/libs/cglm/docs/source/ivec4.rst b/libs/cglm/docs/source/ivec4.rst
new file mode 100644
index 0000000..a175631
--- /dev/null
+++ b/libs/cglm/docs/source/ivec4.rst
@@ -0,0 +1,163 @@
+.. default-domain:: C
+
+ivec4
+=====
+
+Header: cglm/ivec4.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_ivec4`
+#. :c:func:`glm_ivec4_copy`
+#. :c:func:`glm_ivec4_zero`
+#. :c:func:`glm_ivec4_one`
+#. :c:func:`glm_ivec4_add`
+#. :c:func:`glm_ivec4_adds`
+#. :c:func:`glm_ivec4_sub`
+#. :c:func:`glm_ivec4_subs`
+#. :c:func:`glm_ivec4_mul`
+#. :c:func:`glm_ivec4_scale`
+#. :c:func:`glm_ivec4_distance2`
+#. :c:func:`glm_ivec4_distance`
+#. :c:func:`glm_ivec4_maxv`
+#. :c:func:`glm_ivec4_minv`
+#. :c:func:`glm_ivec4_clamp`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_ivec4(ivec3 v3, int last, ivec4 dest)
+
+ init ivec4 using ivec3
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_copy(ivec4 a, ivec4 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_zero(ivec4 v)
+
+ set all members of [v] to zero
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec4_one(ivec4 v)
+
+ set all members of [v] to one
+
+ Parameters:
+ | *[out]* **v** vector
+
+.. c:function:: void glm_ivec4_add(ivec4 a, ivec4 b, ivec4 dest)
+
+ add vector [a] to vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_adds(ivec4 v, int s, ivec4 dest)
+
+ add scalar s to vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_sub(ivec4 a, ivec4 b, ivec4 dest)
+
+ subtract vector [b] from vector [a] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_subs(ivec4 v, int s, ivec4 dest)
+
+ subtract scalar s from vector [v] and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_mul(ivec4 a, ivec4 b, ivec4 dest)
+
+ multiply vector [a] with vector [b] and store result in [dest]
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_scale(ivec4 v, int s, ivec4 dest)
+
+ multiply vector [a] with scalar s and store result in [dest]
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination
+
+.. c:function:: int glm_ivec4_distance2(ivec4 a, ivec4 b)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ squared distance (distance * distance)
+
+.. c:function:: float glm_ivec4_distance(ivec4 a, ivec4 b)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+
+ Returns:
+ distance
+
+.. c:function:: void glm_ivec4_maxv(ivec4 a, ivec4 b, ivec4 dest)
+
+ set each member of dest to greater of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_minv(ivec4 a, ivec4 b, ivec4 dest)
+
+ set each member of dest to lesser of vector a and b
+
+ Parameters:
+ | *[in]* **a** first vector
+ | *[in]* **b** second vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_ivec4_clamp(ivec4 v, int minVal, int maxVal)
+
+ clamp each member of [v] between minVal and maxVal (inclusive)
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
diff --git a/libs/cglm/docs/source/mat2.rst b/libs/cglm/docs/source/mat2.rst
new file mode 100644
index 0000000..6e55c83
--- /dev/null
+++ b/libs/cglm/docs/source/mat2.rst
@@ -0,0 +1,179 @@
+.. default-domain:: C
+
+mat2
+====
+
+Header: cglm/mat2.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. GLM_mat2_IDENTITY_INIT
+#. GLM_mat2_ZERO_INIT
+#. GLM_mat2_IDENTITY
+#. GLM_mat2_ZERO
+
+Functions:
+
+1. :c:func:`glm_mat2_copy`
+#. :c:func:`glm_mat2_identity`
+#. :c:func:`glm_mat2_identity_array`
+#. :c:func:`glm_mat2_zero`
+#. :c:func:`glm_mat2_mul`
+#. :c:func:`glm_mat2_transpose_to`
+#. :c:func:`glm_mat2_transpose`
+#. :c:func:`glm_mat2_mulv`
+#. :c:func:`glm_mat2_scale`
+#. :c:func:`glm_mat2_det`
+#. :c:func:`glm_mat2_inv`
+#. :c:func:`glm_mat2_trace`
+#. :c:func:`glm_mat2_swap_col`
+#. :c:func:`glm_mat2_swap_row`
+#. :c:func:`glm_mat2_rmc`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_mat2_copy(mat2 mat, mat2 dest)
+
+ copy mat2 to another one (dest).
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat2_identity(mat2 mat)
+
+ copy identity mat2 to mat, or makes mat to identiy
+
+ Parameters:
+ | *[out]* **mat** matrix
+
+.. c:function:: void glm_mat2_identity_array(mat2 * __restrict mat, size_t count)
+
+ make given matrix array's each element identity matrix
+
+ Parameters:
+ | *[in,out]* **mat** matrix array (must be aligned (16/32) if alignment is not disabled)
+ | *[in]* **count** count of matrices
+
+.. c:function:: void glm_mat2_zero(mat2 mat)
+
+ make given matrix zero
+
+ Parameters:
+ | *[in,out]* **mat** matrix to
+
+.. c:function:: void glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest)
+
+ multiply m1 and m2 to dest
+ m1, m2 and dest matrices can be same matrix, it is possible to write this:
+
+ .. code-block:: c
+
+ mat2 m = GLM_mat2_IDENTITY_INIT;
+ glm_mat2_mul(m, m, m);
+
+ Parameters:
+ | *[in]* **m1** left matrix
+ | *[in]* **m2** right matrix
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat2_transpose_to(mat2 m, mat2 dest)
+
+ transpose mat4 and store in dest
+ source matrix will not be transposed unless dest is m
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat2_transpose(mat2 m)
+
+ tranpose mat2 and store result in same matrix
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat2_mulv(mat2 m, vec2 v, vec2 dest)
+
+ multiply mat4 with vec4 (column vector) and store in dest vector
+
+ Parameters:
+ | *[in]* **mat** mat2 (left)
+ | *[in]* **v** vec2 (right, column vector)
+ | *[out]* **dest** destination (result, column vector)
+
+.. c:function:: void glm_mat2_scale(mat2 m, float s)
+
+ multiply matrix with scalar
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **dest** scalar
+
+.. c:function:: float glm_mat2_det(mat2 mat)
+
+ returns mat2 determinant
+
+ Parameters:
+ | *[in]* **mat** matrix
+
+ Returns:
+ mat2 determinant
+
+.. c:function:: void glm_mat2_inv(mat2 mat, mat2 dest)
+
+ inverse mat2 and store in dest
+
+ Parameters:
+ | *[in]* **mat** matrix
+ | *[out]* **dest** destination (inverse matrix)
+
+.. c:function:: void glm_mat2_trace(mat2 m)
+
+ | sum of the elements on the main diagonal from upper left to the lower right
+
+ Parameters:
+ | *[in]* **m** matrix
+
+ Returns:
+ trace of matrix
+
+.. c:function:: void glm_mat2_swap_col(mat2 mat, int col1, int col2)
+
+ swap two matrix columns
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **col1** col1
+ | *[in]* **col2** col2
+
+.. c:function:: void glm_mat2_swap_row(mat2 mat, int row1, int row2)
+
+ swap two matrix rows
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **row1** row1
+ | *[in]* **row2** row2
+
+.. c:function:: float glm_mat2_rmc(vec2 r, mat2 m, vec2 c)
+
+ | **rmc** stands for **Row** * **Matrix** * **Column**
+
+ | helper for R (row vector) * M (matrix) * C (column vector)
+
+ | the result is scalar because R * M = Matrix1x2 (row vector),
+ | then Matrix1x2 * Vec2 (column vector) = Matrix1x1 (Scalar)
+
+ Parameters:
+ | *[in]* **r** row vector or matrix1x2
+ | *[in]* **m** matrix2x2
+ | *[in]* **c** column vector or matrix2x1
+
+ Returns:
+ scalar value e.g. Matrix1x1
diff --git a/libs/cglm/docs/source/mat3.rst b/libs/cglm/docs/source/mat3.rst
new file mode 100644
index 0000000..e577ce4
--- /dev/null
+++ b/libs/cglm/docs/source/mat3.rst
@@ -0,0 +1,189 @@
+.. default-domain:: C
+
+mat3
+====
+
+Header: cglm/mat3.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. GLM_MAT3_IDENTITY_INIT
+#. GLM_MAT3_ZERO_INIT
+#. GLM_MAT3_IDENTITY
+#. GLM_MAT3_ZERO
+#. glm_mat3_dup(mat, dest)
+
+Functions:
+
+1. :c:func:`glm_mat3_copy`
+#. :c:func:`glm_mat3_identity`
+#. :c:func:`glm_mat3_identity_array`
+#. :c:func:`glm_mat3_zero`
+#. :c:func:`glm_mat3_mul`
+#. :c:func:`glm_mat3_transpose_to`
+#. :c:func:`glm_mat3_transpose`
+#. :c:func:`glm_mat3_mulv`
+#. :c:func:`glm_mat3_quat`
+#. :c:func:`glm_mat3_scale`
+#. :c:func:`glm_mat3_det`
+#. :c:func:`glm_mat3_inv`
+#. :c:func:`glm_mat3_trace`
+#. :c:func:`glm_mat3_swap_col`
+#. :c:func:`glm_mat3_swap_row`
+#. :c:func:`glm_mat3_rmc`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_mat3_copy(mat3 mat, mat3 dest)
+
+ copy mat3 to another one (dest).
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat3_identity(mat3 mat)
+
+ copy identity mat3 to mat, or makes mat to identiy
+
+ Parameters:
+ | *[out]* **mat** matrix
+
+.. c:function:: void glm_mat3_identity_array(mat3 * __restrict mat, size_t count)
+
+ make given matrix array's each element identity matrix
+
+ Parameters:
+ | *[in,out]* **mat** matrix array (must be aligned (16/32) if alignment is not disabled)
+ | *[in]* **count** count of matrices
+
+.. c:function:: void glm_mat3_zero(mat3 mat)
+
+ make given matrix zero
+
+ Parameters:
+ | *[in,out]* **mat** matrix to
+
+.. c:function:: void glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest)
+
+ multiply m1 and m2 to dest
+ m1, m2 and dest matrices can be same matrix, it is possible to write this:
+
+ .. code-block:: c
+
+ mat3 m = GLM_MAT3_IDENTITY_INIT;
+ glm_mat3_mul(m, m, m);
+
+ Parameters:
+ | *[in]* **m1** left matrix
+ | *[in]* **m2** right matrix
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat3_transpose_to(mat3 m, mat3 dest)
+
+ transpose mat4 and store in dest
+ source matrix will not be transposed unless dest is m
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat3_transpose(mat3 m)
+
+ tranpose mat3 and store result in same matrix
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat3_mulv(mat3 m, vec3 v, vec3 dest)
+
+ multiply mat4 with vec4 (column vector) and store in dest vector
+
+ Parameters:
+ | *[in]* **mat** mat3 (left)
+ | *[in]* **v** vec3 (right, column vector)
+ | *[out]* **dest** destination (result, column vector)
+
+.. c:function:: void glm_mat3_quat(mat3 m, versor dest)
+
+ convert mat3 to quaternion
+
+ Parameters:
+ | *[in]* **m** rotation matrix
+ | *[out]* **dest** destination quaternion
+
+.. c:function:: void glm_mat3_scale(mat3 m, float s)
+
+ multiply matrix with scalar
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **dest** scalar
+
+.. c:function:: float glm_mat3_det(mat3 mat)
+
+ returns mat3 determinant
+
+ Parameters:
+ | *[in]* **mat** matrix
+
+ Returns:
+ mat3 determinant
+
+.. c:function:: void glm_mat3_inv(mat3 mat, mat3 dest)
+
+ inverse mat3 and store in dest
+
+ Parameters:
+ | *[in]* **mat** matrix
+ | *[out]* **dest** destination (inverse matrix)
+
+.. c:function:: void glm_mat3_trace(mat3 m)
+
+ | sum of the elements on the main diagonal from upper left to the lower right
+
+ Parameters:
+ | *[in]* **m** matrix
+
+ Returns:
+ trace of matrix
+
+.. c:function:: void glm_mat3_swap_col(mat3 mat, int col1, int col2)
+
+ swap two matrix columns
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **col1** col1
+ | *[in]* **col2** col2
+
+.. c:function:: void glm_mat3_swap_row(mat3 mat, int row1, int row2)
+
+ swap two matrix rows
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **row1** row1
+ | *[in]* **row2** row2
+
+.. c:function:: float glm_mat3_rmc(vec3 r, mat3 m, vec3 c)
+
+ | **rmc** stands for **Row** * **Matrix** * **Column**
+
+ | helper for R (row vector) * M (matrix) * C (column vector)
+
+ | the result is scalar because R * M = Matrix1x3 (row vector),
+ | then Matrix1x3 * Vec3 (column vector) = Matrix1x1 (Scalar)
+
+ Parameters:
+ | *[in]* **r** row vector or matrix1x3
+ | *[in]* **m** matrix3x3
+ | *[in]* **c** column vector or matrix3x1
+
+ Returns:
+ scalar value e.g. Matrix1x1
diff --git a/libs/cglm/docs/source/mat4.rst b/libs/cglm/docs/source/mat4.rst
new file mode 100644
index 0000000..33251b9
--- /dev/null
+++ b/libs/cglm/docs/source/mat4.rst
@@ -0,0 +1,304 @@
+.. default-domain:: C
+
+mat4
+====
+
+Header: cglm/mat4.h
+
+Important: :c:func:`glm_mat4_scale` multiplies mat4 with scalar, if you need to
+apply scale transform use :c:func:`glm_scale` functions.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. GLM_MAT4_IDENTITY_INIT
+#. GLM_MAT4_ZERO_INIT
+#. GLM_MAT4_IDENTITY
+#. GLM_MAT4_ZERO
+#. glm_mat4_udup(mat, dest)
+#. glm_mat4_dup(mat, dest)
+
+Functions:
+
+1. :c:func:`glm_mat4_ucopy`
+#. :c:func:`glm_mat4_copy`
+#. :c:func:`glm_mat4_identity`
+#. :c:func:`glm_mat4_identity_array`
+#. :c:func:`glm_mat4_zero`
+#. :c:func:`glm_mat4_pick3`
+#. :c:func:`glm_mat4_pick3t`
+#. :c:func:`glm_mat4_ins3`
+#. :c:func:`glm_mat4_mul`
+#. :c:func:`glm_mat4_mulN`
+#. :c:func:`glm_mat4_mulv`
+#. :c:func:`glm_mat4_mulv3`
+#. :c:func:`glm_mat3_trace`
+#. :c:func:`glm_mat3_trace3`
+#. :c:func:`glm_mat4_quat`
+#. :c:func:`glm_mat4_transpose_to`
+#. :c:func:`glm_mat4_transpose`
+#. :c:func:`glm_mat4_scale_p`
+#. :c:func:`glm_mat4_scale`
+#. :c:func:`glm_mat4_det`
+#. :c:func:`glm_mat4_inv`
+#. :c:func:`glm_mat4_inv_fast`
+#. :c:func:`glm_mat4_swap_col`
+#. :c:func:`glm_mat4_swap_row`
+#. :c:func:`glm_mat4_rmc`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_mat4_ucopy(mat4 mat, mat4 dest)
+
+ copy mat4 to another one (dest). u means align is not required for dest
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_copy(mat4 mat, mat4 dest)
+
+ copy mat4 to another one (dest).
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_identity(mat4 mat)
+
+ copy identity mat4 to mat, or makes mat to identiy
+
+ Parameters:
+ | *[out]* **mat** matrix
+
+.. c:function:: void glm_mat4_identity_array(mat4 * __restrict mat, size_t count)
+
+ make given matrix array's each element identity matrix
+
+ Parameters:
+ | *[in,out]* **mat** matrix array (must be aligned (16/32) if alignment is not disabled)
+ | *[in]* **count** count of matrices
+
+.. c:function:: void glm_mat4_zero(mat4 mat)
+
+ make given matrix zero
+
+ Parameters:
+ | *[in,out]* **mat** matrix to
+
+.. c:function:: void glm_mat4_pick3(mat4 mat, mat3 dest)
+
+ copy upper-left of mat4 to mat3
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_pick3t(mat4 mat, mat4 dest)
+
+ copy upper-left of mat4 to mat3 (transposed)
+ the postfix t stands for transpose
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_ins3(mat3 mat, mat4 dest)
+
+ copy mat3 to mat4's upper-left. this function does not fill mat4's other
+ elements. To do that use glm_mat4.
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest)
+
+ multiply m1 and m2 to dest
+ m1, m2 and dest matrices can be same matrix, it is possible to write this:
+
+ .. code-block:: c
+
+ mat4 m = GLM_MAT4_IDENTITY_INIT;
+ glm_mat4_mul(m, m, m);
+
+ Parameters:
+ | *[in]* **m1** left matrix
+ | *[in]* **m2** right matrix
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat4_mulN(mat4 * __restrict matrices[], int len, mat4 dest)
+
+ mupliply N mat4 matrices and store result in dest
+ | this function lets you multiply multiple (more than two or more...)
+ | matrices
+
+ | multiplication will be done in loop, this may reduce instructions
+ | size but if **len** is too small then compiler may unroll whole loop
+
+ .. code-block:: c
+
+ mat m1, m2, m3, m4, res;
+ glm_mat4_mulN((mat4 *[]){&m1, &m2, &m3, &m4}, 4, res);
+
+ Parameters:
+ | *[in]* **matrices** array of mat4
+ | *[in]* **len** matrices count
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest)
+
+ multiply mat4 with vec4 (column vector) and store in dest vector
+
+ Parameters:
+ | *[in]* **m** mat4 (left)
+ | *[in]* **v** vec4 (right, column vector)
+ | *[in]* **last** 4th item to make it vec4
+ | *[out]* **dest** vec4 (result, column vector)
+
+.. c:function:: void glm_mat4_mulv3(mat4 m, vec3 v, float last, vec3 dest)
+
+ | multiply **vec3** with **mat4** and get **vec3** as result
+ |
+ | actually the result is **vec4**, after multiplication,
+ the last component is trimmed, if you need the result's last component
+ then don't use this function and consider to use **glm_mat4_mulv()**
+
+ Parameters:
+ | *[in]* **m** mat4(affine transform)
+ | *[in]* **v** vec3
+ | *[in]* **last** 4th item to make it vec4
+ | *[out]* **dest** result vector (vec3)
+
+.. c:function:: void glm_mat4_trace(mat4 m)
+
+ | sum of the elements on the main diagonal from upper left to the lower right
+
+ Parameters:
+ | *[in]* **m** matrix
+
+ Returns:
+ trace of matrix
+
+.. c:function:: void glm_mat4_trace3(mat4 m)
+
+ | trace of matrix (rotation part)
+ | sum of the elements on the main diagonal from upper left to the lower right
+
+ Parameters:
+ | *[in]* **m** matrix
+
+ Returns:
+ trace of matrix
+
+.. c:function:: void glm_mat4_quat(mat4 m, versor dest)
+
+ convert mat4's rotation part to quaternion
+
+ Parameters:
+ | *[in]* **m** affine matrix
+ | *[out]* **dest** destination quaternion
+
+.. c:function:: void glm_mat4_transpose_to(mat4 m, mat4 dest)
+
+ transpose mat4 and store in dest
+ source matrix will not be transposed unless dest is m
+
+ Parameters:
+ | *[in]* **m** matrix
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat4_transpose(mat4 m)
+
+ tranpose mat4 and store result in same matrix
+
+ Parameters:
+ | *[in]* **m** source
+ | *[out]* **dest** destination matrix
+
+.. c:function:: void glm_mat4_scale_p(mat4 m, float s)
+
+ scale (multiply with scalar) matrix without simd optimization
+
+ Parameters:
+ | *[in, out]* **m** matrix
+ | *[in]* **s** scalar
+
+.. c:function:: void glm_mat4_scale(mat4 m, float s)
+
+ scale (multiply with scalar) matrix
+ THIS IS NOT SCALE TRANSFORM, use glm_scale for that.
+
+ Parameters:
+ | *[in, out]* **m** matrix
+ | *[in]* **s** scalar
+
+.. c:function:: float glm_mat4_det(mat4 mat)
+
+ mat4 determinant
+
+ Parameters:
+ | *[in]* **mat** matrix
+
+ Return:
+ | determinant
+
+.. c:function:: void glm_mat4_inv(mat4 mat, mat4 dest)
+
+ inverse mat4 and store in dest
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination matrix (inverse matrix)
+
+.. c:function:: void glm_mat4_inv_fast(mat4 mat, mat4 dest)
+
+ inverse mat4 and store in dest
+
+ | this func uses reciprocal approximation without extra corrections
+ | e.g Newton-Raphson. this should work faster than normal,
+ | to get more precise use glm_mat4_inv version.
+
+ | NOTE: You will lose precision, glm_mat4_inv is more accurate
+
+ Parameters:
+ | *[in]* **mat** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_mat4_swap_col(mat4 mat, int col1, int col2)
+
+ swap two matrix columns
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **col1** col1
+ | *[in]* **col2** col2
+
+.. c:function:: void glm_mat4_swap_row(mat4 mat, int row1, int row2)
+
+ swap two matrix rows
+
+ Parameters:
+ | *[in, out]* **mat** matrix
+ | *[in]* **row1** row1
+ | *[in]* **row2** row2
+
+.. c:function:: float glm_mat4_rmc(vec4 r, mat4 m, vec4 c)
+
+ | **rmc** stands for **Row** * **Matrix** * **Column**
+
+ | helper for R (row vector) * M (matrix) * C (column vector)
+
+ | the result is scalar because R * M = Matrix1x4 (row vector),
+ | then Matrix1x4 * Vec4 (column vector) = Matrix1x1 (Scalar)
+
+ Parameters:
+ | *[in]* **r** row vector or matrix1x4
+ | *[in]* **m** matrix4x4
+ | *[in]* **c** column vector or matrix4x1
+
+ Returns:
+ scalar value e.g. Matrix1x1
diff --git a/libs/cglm/docs/source/opengl.rst b/libs/cglm/docs/source/opengl.rst
new file mode 100644
index 0000000..2cebae0
--- /dev/null
+++ b/libs/cglm/docs/source/opengl.rst
@@ -0,0 +1,61 @@
+How to send vector or matrix to OpenGL like API
+==================================================
+
+*cglm*'s vector and matrix types are arrays. So you can send them directly to a
+function which accepts pointer. But you may got warnings for matrix because it is
+two dimensional array.
+
+Passing / Uniforming Matrix to OpenGL:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**glUniformMatrix4fv** accepts float pointer, you can pass matrix to that parameter
+and it should work but with warnings. "You can pass" doesn't mean that you must pass like that.
+
+**Correct options:**
+
+Correct doesn't mean correct way to use OpenGL it is just shows correct way to pass cglm type to it.
+
+1. Pass first column
+---------------------
+
+The goal is that pass address of matrix, first element of matrix is also address of matrix,
+because it is array of vectors and vector is array of floats.
+
+.. code-block:: c
+
+ mat4 matrix;
+ /* ... */
+ glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0]);
+
+array of matrices:
+
+.. code-block:: c
+
+ mat4 matrix;
+ /* ... */
+ glUniformMatrix4fv(location, count, GL_FALSE, matrix[0][0]);
+
+1. Cast matrix to pointer
+--------------------------
+
+.. code-block:: c
+
+ mat4 matrix;
+ /* ... */
+ glUniformMatrix4fv(location, count, GL_FALSE, (float *)matrix);
+
+in this way, passing aray of matrices is same
+
+Passing / Uniforming Vectors to OpenGL:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You don't need to do extra thing when passing cglm vectors to OpengL or other APIs.
+Because a function like **glUniform4fv** accepts vector as pointer. cglm's vectors
+are array of floats. So you can pass it directly ot those functions:
+
+.. code-block:: c
+
+ vec4 vec;
+ /* ... */
+ glUniform4fv(location, 1, vec);
+
+this show how to pass **vec4** others are same.
diff --git a/libs/cglm/docs/source/opt.rst b/libs/cglm/docs/source/opt.rst
new file mode 100644
index 0000000..9b28054
--- /dev/null
+++ b/libs/cglm/docs/source/opt.rst
@@ -0,0 +1,124 @@
+.. default-domain:: C
+
+Options
+===============================================================================
+
+A few options are provided via macros.
+
+Alignment Option
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As default, cglm requires types to be aligned. Alignment requirements:
+
+vec3: 8 byte
+vec4: 16 byte
+mat4: 16 byte
+versor: 16 byte
+
+By starting **v0.4.5** cglm provides an option to disable alignment requirement.
+To enable this option define **CGLM_ALL_UNALIGNED** macro before all headers.
+You can define it in Xcode, Visual Studio (or other IDEs) or you can also prefer
+to define it in build system. If you use pre-compiled versions then you
+have to compile cglm with **CGLM_ALL_UNALIGNED** macro.
+
+**VERY VERY IMPORTANT:** If you use cglm in multiple projects and
+ those projects are depends on each other, then
+
+ | *ALWAYS* or *NEVER USE* **CGLM_ALL_UNALIGNED** macro in linked projects
+
+ if you do not know what you are doing. Because a cglm header included
+ via 'project A' may force types to be aligned and another cglm header
+ included via 'project B' may not require alignment. In this case
+ cglm functions will read from and write to **INVALID MEMORY LOCATIONs**.
+
+ ALWAYS USE SAME CONFIGURATION / OPTION for **cglm** if you have multiple projects.
+
+ For instance if you set CGLM_ALL_UNALIGNED in a project then set it in other projects too
+
+Clipspace Option[s]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By starting **v0.8.3** cglm provides options to switch between clipspace configurations.
+
+Clipspace related files are located at `include/cglm/[struct]/clipspace.h` but
+these are included in related files like `cam.h`. If you don't want to change your existing
+clipspace configuration and want to use different clipspace function like `glm_lookat_zo` or `glm_lookat_lh_zo`...
+then you can include individual headers or just define `CGLM_CLIPSPACE_INCLUDE_ALL` which will iclude all headers for you.
+
+1. **CGLM_CLIPSPACE_INCLUDE_ALL**
+2. **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
+3. **CGLM_FORCE_LEFT_HANDED**
+
+
+1. **CGLM_CLIPSPACE_INCLUDE_ALL**:
+
+By defining this macro, **cglm** will include all clipspace functions for you by just using
+`#include cglm/cglm.h` or `#include cglm/struct.h` or `#include cglm/call.h`
+
+Otherwise you need to include header you want manually e.g. `#include cglm/clipspace/view_rh_zo.h`
+
+2. **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
+
+This is similar to **GLM**'s **GLM_FORCE_DEPTH_ZERO_TO_ONE** option.
+This will set clip space between 0 to 1 which makes **cglm** Vulkan, Metal friendly.
+
+You can use functions like `glm_lookat_lh_zo()` individually. By setting **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
+functions in cam.h for instance will use `_zo` versions.
+
+3. **CGLM_FORCE_LEFT_HANDED**
+
+Force **cglm** to use the left handed coordinate system by default, currently **cglm** uses right handed coordinate system as default,
+you can change this behavior with this option.
+
+**VERY VERY IMPORTANT:**
+
+Be careful if you include **cglm** in multiple projects.
+
+SSE and SSE2 Shuffle Option
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**_mm_shuffle_ps** generates **shufps** instruction even if registers are same.
+You can force it to generate **pshufd** instruction by defining
+**CGLM_USE_INT_DOMAIN** macro. As default it is not defined.
+
+SSE3 and SSE4 Dot Product Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You have to extra options for dot product: **CGLM_SSE4_DOT** and **CGLM_SSE3_DOT**.
+
+- If **SSE4** is enabled then you can define **CGLM_SSE4_DOT** to force cglm to use **_mm_dp_ps** instruction.
+- If **SSE3** is enabled then you can define **CGLM_SSE3_DOT** to force cglm to use **_mm_hadd_ps** instructions.
+
+otherwise cglm will use custom cglm's hadd functions which are optimized too.
+
+Print Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. **CGLM_DEFINE_PRINTS**
+2. **CGLM_NO_PRINTS_NOOP** (use CGLM_DEFINE_PRINTS)
+
+Inline prints are only enabled in **DEBUG** mode or if **CGLM_DEFINE_PRINTS** is defined.
+**glmc_** versions will always print too.
+
+Because **cglm** tried to enable print functions in debug mode and disable them in
+release/production mode to eliminate printing costs when we do not need them.
+
+**cglm** checks **DEBUG** or **_DEBUG** macros to test debug mode, if these are not working for you then you can use
+**CGLM_DEFINE_PRINTS** to force enable, or create a PR to introduce new macro to test against debugging mode.
+
+If DEBUG mode is not enabled then print functions will be emptied to eliminate print function calls.
+You can disable this feature too by defining **CGLM_DEFINE_PRINTS** macro top of cglm header
+or in project/build settings...
+
+3. **CGLM_PRINT_PRECISION** 5
+
+precision.
+
+4. **CGLM_PRINT_MAX_TO_SHORT** 1e5
+
+if a number is greater than this value then %g will be used, since this is shorten print you won't be able to see high precision.
+
+5. **CGLM_PRINT_COLOR** "\033[36m"
+6. **CGLM_PRINT_COLOR_RESET** "\033[0m"
+
+You can disable colorful print output by defining **CGLM_PRINT_COLOR** and **CGLM_PRINT_COLOR_RESET** as empty macro.
+Because some terminals may not support colors.
diff --git a/libs/cglm/docs/source/plane.rst b/libs/cglm/docs/source/plane.rst
new file mode 100644
index 0000000..b9afbed
--- /dev/null
+++ b/libs/cglm/docs/source/plane.rst
@@ -0,0 +1,33 @@
+.. default-domain:: C
+
+plane
+================================================================================
+
+Header: cglm/plane.h
+
+Plane extract functions are in frustum header and documented
+in :doc:`frustum` page.
+
+**Definition of plane:**
+
+Plane equation: **Ax + By + Cz + D = 0**
+
+Plan is stored in **vec4** as **[A, B, C, D]**. (A, B, C) is normal and D is distance
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_plane_normalize`
+
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_plane_normalize(vec4 plane)
+
+ | normalizes a plane
+
+ Parameters:
+ | *[in, out]* **plane** pnale to normalize
diff --git a/libs/cglm/docs/source/project.rst b/libs/cglm/docs/source/project.rst
new file mode 100644
index 0000000..b31a86a
--- /dev/null
+++ b/libs/cglm/docs/source/project.rst
@@ -0,0 +1,102 @@
+.. default-domain:: C
+
+Project / UnProject
+================================================================================
+
+Header: cglm/project.h
+
+Viewport is required as *vec4* **[X, Y, Width, Height]** but this doesn't mean
+that you should store it as **vec4**. You can convert your data representation
+to vec4 before passing it to related functions.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_unprojecti`
+#. :c:func:`glm_unproject`
+#. :c:func:`glm_project`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest)
+
+ | maps the specified viewport coordinates into specified space [1]
+ the matrix should contain projection matrix.
+
+ if you don't have ( and don't want to have ) an inverse matrix then use
+ glm_unproject version. You may use existing inverse of matrix in somewhere
+ else, this is why glm_unprojecti exists to save save inversion cost
+
+ [1] space:
+ - if m = invProj: View Space
+ - if m = invViewProj: World Space
+ - if m = invMVP: Object Space
+
+ You probably want to map the coordinates into object space
+ so use invMVP as m
+
+ Computing viewProj:
+
+ .. code-block:: c
+
+ glm_mat4_mul(proj, view, viewProj);
+ glm_mat4_mul(viewProj, model, MVP);
+ glm_mat4_inv(viewProj, invMVP);
+
+ Parameters:
+ | *[in]* **pos** point/position in viewport coordinates
+ | *[in]* **invMat** matrix (see brief)
+ | *[in]* **vp** viewport as [x, y, width, height]
+ | *[out]* **dest** unprojected coordinates
+
+.. c:function:: void glm_unproject(vec3 pos, mat4 m, vec4 vp, vec3 dest)
+
+ | maps the specified viewport coordinates into specified space [1]
+ the matrix should contain projection matrix.
+
+ this is same as glm_unprojecti except this function get inverse matrix for
+ you.
+
+ [1] space:
+ - if m = proj: View Space
+ - if m = viewProj: World Space
+ - if m = MVP: Object Space
+
+ You probably want to map the coordinates into object space so use MVP as m
+
+ Computing viewProj and MVP:
+
+ .. code-block:: c
+
+ glm_mat4_mul(proj, view, viewProj);
+ glm_mat4_mul(viewProj, model, MVP);
+
+ Parameters:
+ | *[in]* **pos** point/position in viewport coordinates
+ | *[in]* **m** matrix (see brief)
+ | *[in]* **vp** viewport as [x, y, width, height]
+ | *[out]* **dest** unprojected coordinates
+
+.. c:function:: void glm_project(vec3 pos, mat4 m, vec4 vp, vec3 dest)
+
+ | map object coordinates to window coordinates
+
+ Computing MVP:
+
+ .. code-block:: c
+
+ glm_mat4_mul(proj, view, viewProj);
+ glm_mat4_mul(viewProj, model, MVP);
+
+ this could be useful for gettng a bbox which fits with view frustum and
+ object bounding boxes. In this case you crop view frustum box with objects
+ box
+
+ Parameters:
+ | *[in]* **pos** object coordinates
+ | *[in]* **m** MVP matrix
+ | *[in]* **vp** viewport as [x, y, width, height]
+ | *[out]* **dest** projected coordinates
diff --git a/libs/cglm/docs/source/quat.rst b/libs/cglm/docs/source/quat.rst
new file mode 100644
index 0000000..a44c918
--- /dev/null
+++ b/libs/cglm/docs/source/quat.rst
@@ -0,0 +1,422 @@
+.. default-domain:: C
+
+quaternions
+===========
+
+Header: cglm/quat.h
+
+ **Important:** *cglm* stores quaternion as **[x, y, z, w]** in memory
+ since **v0.4.0** it was **[w, x, y, z]**
+ before v0.4.0 ( **v0.3.5 and earlier** ). w is real part.
+
+What you can do with quaternions with existing functions is (Some of them):
+
+- You can rotate transform matrix using quaterion
+- You can rotate vector using quaterion
+- You can create view matrix using quaterion
+- You can create a lookrotation (from source point to dest)
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. GLM_QUAT_IDENTITY_INIT
+#. GLM_QUAT_IDENTITY
+
+Functions:
+
+1. :c:func:`glm_quat_identity`
+#. :c:func:`glm_quat_identity_array`
+#. :c:func:`glm_quat_init`
+#. :c:func:`glm_quat`
+#. :c:func:`glm_quatv`
+#. :c:func:`glm_quat_copy`
+#. :c:func:`glm_quat_from_vecs`
+#. :c:func:`glm_quat_norm`
+#. :c:func:`glm_quat_normalize`
+#. :c:func:`glm_quat_normalize_to`
+#. :c:func:`glm_quat_dot`
+#. :c:func:`glm_quat_conjugate`
+#. :c:func:`glm_quat_inv`
+#. :c:func:`glm_quat_add`
+#. :c:func:`glm_quat_sub`
+#. :c:func:`glm_quat_real`
+#. :c:func:`glm_quat_imag`
+#. :c:func:`glm_quat_imagn`
+#. :c:func:`glm_quat_imaglen`
+#. :c:func:`glm_quat_angle`
+#. :c:func:`glm_quat_axis`
+#. :c:func:`glm_quat_mul`
+#. :c:func:`glm_quat_mat4`
+#. :c:func:`glm_quat_mat4t`
+#. :c:func:`glm_quat_mat3`
+#. :c:func:`glm_quat_mat3t`
+#. :c:func:`glm_quat_lerp`
+#. :c:func:`glm_quat_nlerp`
+#. :c:func:`glm_quat_slerp`
+#. :c:func:`glm_quat_look`
+#. :c:func:`glm_quat_for`
+#. :c:func:`glm_quat_forp`
+#. :c:func:`glm_quat_rotatev`
+#. :c:func:`glm_quat_rotate`
+#. :c:func:`glm_quat_rotate_at`
+#. :c:func:`glm_quat_rotate_atm`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_quat_identity(versor q)
+
+ | makes given quat to identity
+
+ Parameters:
+ | *[in, out]* **q** quaternion
+
+.. c:function:: void glm_quat_identity_array(versor * __restrict q, size_t count)
+
+ | make given quaternion array's each element identity quaternion
+
+ Parameters:
+ | *[in, out]* **q** quat array (must be aligned (16) if alignment is not disabled)
+ | *[in]* **count** count of quaternions
+
+.. c:function:: void glm_quat_init(versor q, float x, float y, float z, float w)
+
+ | inits quaternion with given values
+
+ Parameters:
+ | *[out]* **q** quaternion
+ | *[in]* **x** imag.x
+ | *[in]* **y** imag.y
+ | *[in]* **z** imag.z
+ | *[in]* **w** w (real part)
+
+.. c:function:: void glm_quat(versor q, float angle, float x, float y, float z)
+
+ | creates NEW quaternion with individual axis components
+
+ | given axis will be normalized
+
+ Parameters:
+ | *[out]* **q** quaternion
+ | *[in]* **angle** angle (radians)
+ | *[in]* **x** axis.x
+ | *[in]* **y** axis.y
+ | *[in]* **z** axis.z
+
+.. c:function:: void glm_quatv(versor q, float angle, vec3 axis)
+
+ | creates NEW quaternion with axis vector
+
+ | given axis will be normalized
+
+ Parameters:
+ | *[out]* **q** quaternion
+ | *[in]* **angle** angle (radians)
+ | *[in]* **axis** axis (will be normalized)
+
+.. c:function:: void glm_quat_copy(versor q, versor dest)
+
+ | copy quaternion to another one
+
+ Parameters:
+ | *[in]* **q** source quaternion
+ | *[out]* **dest** destination quaternion
+
+.. c:function:: void glm_quat_from_vecs(vec3 a, vec3 b, versor dest)
+
+ | compute unit quaternion needed to rotate a into b
+
+ References:
+ * `Finding quaternion representing the rotation from one vector to another <https://stackoverflow.com/a/11741520/183120>`_
+ * `Quaternion from two vectors <http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final>`_
+ * `Angle between vectors <http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/minorlogic.htm>`_
+
+ Parameters:
+ | *[in]* **a** unit vector
+ | *[in]* **b** unit vector
+ | *[in]* **dest** unit quaternion
+
+.. c:function:: float glm_quat_norm(versor q)
+
+ | returns norm (magnitude) of quaternion
+
+ Parameters:
+ | *[in]* **a** quaternion
+
+ Returns:
+ norm (magnitude)
+
+.. c:function:: void glm_quat_normalize_to(versor q, versor dest)
+
+ | normalize quaternion and store result in dest, original one will not be normalized
+
+ Parameters:
+ | *[in]* **q** quaternion to normalize into
+ | *[out]* **dest** destination quaternion
+
+.. c:function:: void glm_quat_normalize(versor q)
+
+ | normalize quaternion
+
+ Parameters:
+ | *[in, out]* **q** quaternion
+
+.. c:function:: float glm_quat_dot(versor p, versor q)
+
+ dot product of two quaternion
+
+ Parameters:
+ | *[in]* **p** quaternion 1
+ | *[in]* **q** quaternion 2
+
+ Returns:
+ dot product
+
+.. c:function:: void glm_quat_conjugate(versor q, versor dest)
+
+ conjugate of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[in]* **dest** conjugate
+
+.. c:function:: void glm_quat_inv(versor q, versor dest)
+
+ inverse of non-zero quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[in]* **dest** inverse quaternion
+
+.. c:function:: void glm_quat_add(versor p, versor q, versor dest)
+
+ add (componentwise) two quaternions and store result in dest
+
+ Parameters:
+ | *[in]* **p** quaternion 1
+ | *[in]* **q** quaternion 2
+ | *[in]* **dest** result quaternion
+
+.. c:function:: void glm_quat_sub(versor p, versor q, versor dest)
+
+ subtract (componentwise) two quaternions and store result in dest
+
+ Parameters:
+ | *[in]* **p** quaternion 1
+ | *[in]* **q** quaternion 2
+ | *[in]* **dest** result quaternion
+
+.. c:function:: float glm_quat_real(versor q)
+
+ returns real part of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+
+ Returns:
+ real part (quat.w)
+
+.. c:function:: void glm_quat_imag(versor q, vec3 dest)
+
+ returns imaginary part of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** imag
+
+.. c:function:: void glm_quat_imagn(versor q, vec3 dest)
+
+ returns normalized imaginary part of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** imag
+
+.. c:function:: float glm_quat_imaglen(versor q)
+
+ returns length of imaginary part of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+
+ Returns:
+ norm of imaginary part
+
+.. c:function:: float glm_quat_angle(versor q)
+
+ returns angle of quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+
+ Returns:
+ angles of quat (radians)
+
+.. c:function:: void glm_quat_axis(versor q, versor dest)
+
+ axis of quaternion
+
+ Parameters:
+ | *[in]* **p** quaternion
+ | *[out]* **dest** axis of quaternion
+
+.. c:function:: void glm_quat_mul(versor p, versor q, versor dest)
+
+ | multiplies two quaternion and stores result in dest
+
+ | this is also called Hamilton Product
+
+ | According to WikiPedia:
+ | The product of two rotation quaternions [clarification needed] will be
+ equivalent to the rotation q followed by the rotation p
+
+ Parameters:
+ | *[in]* **p** quaternion 1 (first rotation)
+ | *[in]* **q** quaternion 2 (second rotation)
+ | *[out]* **dest** result quaternion
+
+.. c:function:: void glm_quat_mat4(versor q, mat4 dest)
+
+ | convert quaternion to mat4
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_mat4t(versor q, mat4 dest)
+
+ | convert quaternion to mat4 (transposed). This is transposed version of glm_quat_mat4
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_mat3(versor q, mat3 dest)
+
+ | convert quaternion to mat3
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_mat3t(versor q, mat3 dest)
+
+ | convert quaternion to mat3 (transposed). This is transposed version of glm_quat_mat3
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_lerp(versor from, versor to, float t, versor dest)
+
+ | interpolates between two quaternions
+ | using spherical linear interpolation (LERP)
+
+ Parameters:
+ | *[in]* **from** from
+ | *[in]* **to** to
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** result quaternion
+
+.. c:function:: void glm_quat_nlerp(versor q, versor r, float t, versor dest)
+
+ | interpolates between two quaternions
+ | taking the shortest rotation path using
+ | normalized linear interpolation (NLERP)
+
+ | This is a cheaper alternative to slerp; most games use nlerp
+ | for animations as it visually makes little difference.
+
+ References:
+ * `Understanding Slerp, Then Not Using it <http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It>`_
+ * `Lerp, Slerp and Nlerp <https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/>`_
+
+ Parameters:
+ | *[in]* **from** from
+ | *[in]* **to** to
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** result quaternion
+
+.. c:function:: void glm_quat_slerp(versor q, versor r, float t, versor dest)
+
+ | interpolates between two quaternions
+ | using spherical linear interpolation (SLERP)
+
+ Parameters:
+ | *[in]* **from** from
+ | *[in]* **to** to
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** result quaternion
+
+.. c:function:: void glm_quat_look(vec3 eye, versor ori, mat4 dest)
+
+ | creates view matrix using quaternion as camera orientation
+
+ Parameters:
+ | *[in]* **eye** eye
+ | *[in]* **ori** orientation in world space as quaternion
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_for(vec3 dir, vec3 up, versor dest)
+
+ | creates look rotation quaternion
+
+ Parameters:
+ | *[in]* **dir** direction to look
+ | *[in]* **up** up vector
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_forp(vec3 from, vec3 to, vec3 up, versor dest)
+
+ | creates look rotation quaternion using source and destination positions p suffix stands for position
+
+ | this is similar to glm_quat_for except this computes direction for glm_quat_for for you.
+
+ Parameters:
+ | *[in]* **from** source point
+ | *[in]* **to** destination point
+ | *[in]* **up** up vector
+ | *[out]* **dest** result matrix
+
+.. c:function:: void glm_quat_rotatev(versor q, vec3 v, vec3 dest)
+
+ | crotate vector using using quaternion
+
+ Parameters:
+ | *[in]* **q** quaternion
+ | *[in]* **v** vector to rotate
+ | *[out]* **dest** rotated vector
+
+.. c:function:: void glm_quat_rotate(mat4 m, versor q, mat4 dest)
+
+ | rotate existing transform matrix using quaternion
+
+ instead of passing identity matrix, consider to use quat_mat4 functions
+
+ Parameters:
+ | *[in]* **m** existing transform matrix to rotate
+ | *[in]* **q** quaternion
+ | *[out]* **dest** rotated matrix/transform
+
+.. c:function:: void glm_quat_rotate_at(mat4 m, versor q, vec3 pivot)
+
+ | rotate existing transform matrix using quaternion at pivot point
+
+ Parameters:
+ | *[in, out]* **m** existing transform matrix to rotate
+ | *[in]* **q** quaternion
+ | *[in]* **pivot** pivot
+
+.. c:function:: void glm_quat_rotate_atm(mat4 m, versor q, vec3 pivot)
+
+ | rotate NEW transform matrix using quaternion at pivot point
+ | this creates rotation matrix, it assumes you don't have a matrix
+
+ | this should work faster than glm_quat_rotate_at because it reduces one glm_translate.
+
+ Parameters:
+ | *[in, out]* **m** existing transform matrix to rotate
+ | *[in]* **q** quaternion
+ | *[in]* **pivot** pivot
diff --git a/libs/cglm/docs/source/ray.rst b/libs/cglm/docs/source/ray.rst
new file mode 100644
index 0000000..c5faf33
--- /dev/null
+++ b/libs/cglm/docs/source/ray.rst
@@ -0,0 +1,31 @@
+.. default-domain:: C
+
+ray
+====
+
+Header: cglm/ray.h
+
+This is for collision-checks used by ray-tracers and the like.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_ray_triangle`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: bool glm_ray_triangle(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d)
+
+ Möller–Trumbore ray-triangle intersection algorithm
+
+ Parameters:
+ | *[in]* **origin** origin of ray
+ | *[in]* **direction** direction of ray
+ | *[in]* **v0** first vertex of triangle
+ | *[in]* **v1** second vertex of triangle
+ | *[in]* **v2** third vertex of triangle
+ | *[in, out]* **d** float pointer to save distance to intersection
+ | *[out]* **intersection** whether there is intersection
diff --git a/libs/cglm/docs/source/sphere.rst b/libs/cglm/docs/source/sphere.rst
new file mode 100644
index 0000000..db238f4
--- /dev/null
+++ b/libs/cglm/docs/source/sphere.rst
@@ -0,0 +1,74 @@
+.. default-domain:: C
+
+Sphere
+================================================================================
+
+Header: cglm/sphere.h
+
+**Definition of sphere:**
+
+Sphere Representation in cglm is *vec4*: **[center.x, center.y, center.z, radii]**
+
+You can call any vec3 function by pasing sphere. Because first three elements
+defines center of sphere.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_sphere_radii`
+#. :c:func:`glm_sphere_transform`
+#. :c:func:`glm_sphere_merge`
+#. :c:func:`glm_sphere_sphere`
+#. :c:func:`glm_sphere_point`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_sphere_radii(vec4 s)
+
+ | helper for getting sphere radius
+
+ Parameters:
+ | *[in]* **s** sphere
+
+ Returns:
+ returns radii
+
+.. c:function:: void glm_sphere_transform(vec4 s, mat4 m, vec4 dest)
+
+ | apply transform to sphere, it is just wrapper for glm_mat4_mulv3
+
+ Parameters:
+ | *[in]* **s** sphere
+ | *[in]* **m** transform matrix
+ | *[out]* **dest** transformed sphere
+
+.. c:function:: void glm_sphere_merge(vec4 s1, vec4 s2, vec4 dest)
+
+ | merges two spheres and creates a new one
+
+ two sphere must be in same space, for instance if one in world space then
+ the other must be in world space too, not in local space.
+
+ Parameters:
+ | *[in]* **s1** sphere 1
+ | *[in]* **s2** sphere 2
+ | *[out]* **dest** merged/extended sphere
+
+.. c:function:: bool glm_sphere_sphere(vec4 s1, vec4 s2)
+
+ | check if two sphere intersects
+
+ Parameters:
+ | *[in]* **s1** sphere
+ | *[in]* **s2** other sphere
+
+.. c:function:: bool glm_sphere_point(vec4 s, vec3 point)
+
+ | check if sphere intersects with point
+
+ Parameters:
+ | *[in]* **s** sphere
+ | *[in]* **point** point
diff --git a/libs/cglm/docs/source/troubleshooting.rst b/libs/cglm/docs/source/troubleshooting.rst
new file mode 100644
index 0000000..fb1433f
--- /dev/null
+++ b/libs/cglm/docs/source/troubleshooting.rst
@@ -0,0 +1,99 @@
+.. default-domain:: C
+
+Troubleshooting
+================================================================================
+
+It is possible that sometimes you may get crashes or wrong results.
+Follow these topics
+
+Memory Allocation:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Again, **cglm** doesn't alloc any memory on heap.
+cglm functions works like memcpy; it copies data from src,
+makes calculations then copy the result to dest.
+
+You are responsible for allocation of **src** and **dest** parameters.
+
+Alignment:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**vec4** and **mat4** types requires 16 byte alignment.
+These types are marked with align attribute to let compiler know about this
+requirement.
+
+But since MSVC (Windows) throws the error:
+
+**"formal parameter with requested alignment of 16 won't be aligned"**
+
+The alignment attribute has been commented for MSVC
+
+.. code-block:: c
+
+ #if defined(_MSC_VER)
+ # define CGLM_ALIGN(X) /* __declspec(align(X)) */
+ #else
+ # define CGLM_ALIGN(X) __attribute((aligned(X)))
+ #endif.
+
+So MSVC may not know about alignment requirements when creating variables.
+The interesting thing is that, if I remember correctly Visual Studio 2017
+doesn't throw the above error. So we may uncomment that line for Visual Studio 2017,
+you may do it yourself.
+
+**This MSVC issue is still in TODOs.**
+
+**UPDATE:** By starting v0.4.5 cglm provides an option to disable alignment requirement.
+Also alignment is disabled for older msvc verisons as default. Now alignment is only required in Visual Studio 2017 version 15.6+ if CGLM_ALL_UNALIGNED macro is not defined.
+
+Crashes, Invalid Memory Access:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Probably you are trying to write to invalid memory location.
+
+You may used wrong function for what you want to do.
+
+For instance you may called **glm_vec4_** functions for **vec3** data type.
+It will try to write 32 byte but since **vec3** is 24 byte it should throw
+memory access error or exit the app without saying anything.
+
+**UPDATE - IMPORTANT:**
+
+ | On MSVC or some other compilers, if alignment is enabled (default) then double check alignment requirements if you got a crash.
+
+ | If you send GLM_VEC4_ONE or similar macros directly to a function, it may be crashed.
+ | Because compiler may not apply alignment as defined on **typedef** to that macro while passing it (on stack) to a function.
+
+Wrong Results:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Again, you may used wrong function.
+
+For instance if you use **glm_normalize()** or **glm_vec3_normalize()** for **vec4**,
+it will assume that passed param is **vec3** and will normalize it for **vec3**.
+Since you need to **vec4** to be normalized in your case, you will get wrong results.
+
+Accessing vec4 type with vec3 functions is valid, you will not get any error, exception or crash.
+You only get wrong results if you don't know what you are doing!
+
+So be carefull, when your IDE (Xcode, Visual Studio ...) tried to autocomplete function names, READ IT :)
+
+**Also implementation may be wrong please let us know by creating an issue on Github.**
+
+BAD_ACCESS : Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) or Similar Errors/Crashes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is similar issue with alignment. For instance if you compiled **cglm** with
+AVX (**-mavx**, intentionally or not) and if you use **cglm** in an environment that doesn't
+support AVX (or if AVX is disabled intentionally) e.g. environment that max support SSE2/3/4,
+then you probably get **BAD ACCESS** or similar...
+
+Because if you compile **cglm** with AVX it aligns **mat4** with 32 byte boundary,
+and your project aligns that as 16 byte boundary...
+
+Check alignment, supported vector extension or simd in **cglm** and linked projects...
+
+Other Issues?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Please let us know by creating an issue on Github.**
diff --git a/libs/cglm/docs/source/util.rst b/libs/cglm/docs/source/util.rst
new file mode 100644
index 0000000..02495f4
--- /dev/null
+++ b/libs/cglm/docs/source/util.rst
@@ -0,0 +1,182 @@
+.. default-domain:: C
+
+utils / helpers
+================================================================================
+
+Header: cglm/util.h
+
+
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_sign`
+#. :c:func:`glm_signf`
+#. :c:func:`glm_rad`
+#. :c:func:`glm_deg`
+#. :c:func:`glm_make_rad`
+#. :c:func:`glm_make_deg`
+#. :c:func:`glm_pow2`
+#. :c:func:`glm_min`
+#. :c:func:`glm_max`
+#. :c:func:`glm_clamp`
+#. :c:func:`glm_lerp`
+#. :c:func:`glm_swapf`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: int glm_sign(int val)
+
+ | returns sign of 32 bit integer as +1, -1, 0
+
+ | **Important**: It returns 0 for zero input
+
+ Parameters:
+ | *[in]* **val** an integer
+
+ Returns:
+ sign of given number
+
+.. c:function:: float glm_signf(float val)
+
+ | returns sign of 32 bit integer as +1.0, -1.0, 0.0
+
+ | **Important**: It returns 0.0f for zero input
+
+ Parameters:
+ | *[in]* **val** a float
+
+ Returns:
+ sign of given number
+
+.. c:function:: float glm_rad(float deg)
+
+ | convert degree to radians
+
+ Parameters:
+ | *[in]* **deg** angle in degrees
+
+.. c:function:: float glm_deg(float rad)
+
+ | convert radians to degree
+
+ Parameters:
+ | *[in]* **rad** angle in radians
+
+.. c:function:: void glm_make_rad(float *degm)
+
+ | convert exsisting degree to radians. this will override degrees value
+
+ Parameters:
+ | *[in, out]* **deg** pointer to angle in degrees
+
+.. c:function:: void glm_make_deg(float *rad)
+
+ | convert exsisting radians to degree. this will override radians value
+
+ Parameters:
+ | *[in, out]* **rad** pointer to angle in radians
+
+.. c:function:: float glm_pow2(float x)
+
+ | multiplies given parameter with itself = x * x or powf(x, 2)
+
+ Parameters:
+ | *[in]* **x** value
+
+ Returns:
+ square of a given number
+
+.. c:function:: float glm_min(float a, float b)
+
+ | returns minimum of given two values
+
+ Parameters:
+ | *[in]* **a** number 1
+ | *[in]* **b** number 2
+
+ Returns:
+ minimum value
+
+.. c:function:: float glm_max(float a, float b)
+
+ | returns maximum of given two values
+
+ Parameters:
+ | *[in]* **a** number 1
+ | *[in]* **b** number 2
+
+ Returns:
+ maximum value
+
+.. c:function:: void glm_clamp(float val, float minVal, float maxVal)
+
+ constrain a value to lie between two further values
+
+ Parameters:
+ | *[in]* **val** input value
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
+
+ Returns:
+ clamped value
+
+.. c:function:: float glm_lerp(float from, float to, float t)
+
+ linear interpolation between two number
+
+ | formula: from + s * (to - from)
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+
+ Returns:
+ interpolated value
+
+.. c:function:: bool glm_eq(float a, float b)
+
+ check if two float equal with using EPSILON
+
+ Parameters:
+ | *[in]* **a** a
+ | *[in]* **b** b
+
+ Returns:
+ true if a and b are equal
+
+.. c:function:: float glm_percent(float from, float to, float current)
+
+ percentage of current value between start and end value
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **current** value between from and to values
+
+ Returns:
+ percentage of current value
+
+.. c:function:: float glm_percentc(float from, float to, float current)
+
+ clamped percentage of current value between start and end value
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **current** value between from and to values
+
+ Returns:
+ clamped normalized percent (0-100 in 0-1)
+
+.. c:function:: void glm_swapf(float *a, float *b)
+
+ swap two float values
+
+ Parameters:
+ | *[in]* **a** float 1
+ | *[in]* **b** float 2
diff --git a/libs/cglm/docs/source/vec2-ext.rst b/libs/cglm/docs/source/vec2-ext.rst
new file mode 100644
index 0000000..619d48f
--- /dev/null
+++ b/libs/cglm/docs/source/vec2-ext.rst
@@ -0,0 +1,134 @@
+.. default-domain:: C
+
+vec2 extra
+==========
+
+Header: cglm/vec2-ext.h
+
+There are some functions are in called in extra header. These are called extra
+because they are not used like other functions in vec2.h in the future some of
+these functions ma be moved to vec2 header.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_vec2_fill`
+#. :c:func:`glm_vec2_eq`
+#. :c:func:`glm_vec2_eq_eps`
+#. :c:func:`glm_vec2_eq_all`
+#. :c:func:`glm_vec2_eqv`
+#. :c:func:`glm_vec2_eqv_eps`
+#. :c:func:`glm_vec2_max`
+#. :c:func:`glm_vec2_min`
+#. :c:func:`glm_vec2_isnan`
+#. :c:func:`glm_vec2_isinf`
+#. :c:func:`glm_vec2_isvalid`
+#. :c:func:`glm_vec2_sign`
+#. :c:func:`glm_vec2_sqrt`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec2_fill(vec2 v, float val)
+
+ fill a vector with specified value
+
+ Parameters:
+ | *[in,out]* **dest** destination
+ | *[in]* **val** value
+
+
+.. c:function:: bool glm_vec2_eq(vec2 v, float val)
+
+ check if vector is equal to value (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec2_eq_eps(vec2 v, float val)
+
+ check if vector is equal to value (with epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec2_eq_all(vec2 v)
+
+ check if vectors members are equal (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec2_eqv(vec2 v1, vec2 v2)
+
+ check if vector is equal to another (without epsilon) vector
+
+ Parameters:
+ | *[in]* **vec** vector 1
+ | *[in]* **vec** vector 2
+
+.. c:function:: bool glm_vec2_eqv_eps(vec2 v1, vec2 v2)
+
+ check if vector is equal to another (with epsilon)
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+.. c:function:: float glm_vec2_max(vec2 v)
+
+ max value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: float glm_vec2_min(vec2 v)
+
+ min value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec2_isnan(vec2 v)
+
+ | check if one of items is NaN (not a number)
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec2_isinf(vec2 v)
+
+ | check if one of items is INFINITY
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec2_isvalid(vec2 v)
+
+ | check if all items are valid number
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: void glm_vec2_sign(vec2 v, vec2 dest)
+
+ get sign of 32 bit float as +1, -1, 0
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** sign vector (only keeps signs as -1, 0, -1)
+
+.. c:function:: void glm_vec2_sqrt(vec2 v, vec2 dest)
+
+ square root of each vector item
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination vector (sqrt(v))
diff --git a/libs/cglm/docs/source/vec2.rst b/libs/cglm/docs/source/vec2.rst
new file mode 100644
index 0000000..93d8663
--- /dev/null
+++ b/libs/cglm/docs/source/vec2.rst
@@ -0,0 +1,375 @@
+.. default-domain:: C
+
+vec2
+====
+
+Header: cglm/vec2.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. GLM_vec2_ONE_INIT
+#. GLM_vec2_ZERO_INIT
+#. GLM_vec2_ONE
+#. GLM_vec2_ZERO
+
+Functions:
+
+1. :c:func:`glm_vec2`
+#. :c:func:`glm_vec2_copy`
+#. :c:func:`glm_vec2_zero`
+#. :c:func:`glm_vec2_one`
+#. :c:func:`glm_vec2_dot`
+#. :c:func:`glm_vec2_cross`
+#. :c:func:`glm_vec2_norm2`
+#. :c:func:`glm_vec2_norm`
+#. :c:func:`glm_vec2_add`
+#. :c:func:`glm_vec2_adds`
+#. :c:func:`glm_vec2_sub`
+#. :c:func:`glm_vec2_subs`
+#. :c:func:`glm_vec2_mul`
+#. :c:func:`glm_vec2_scale`
+#. :c:func:`glm_vec2_scale_as`
+#. :c:func:`glm_vec2_div`
+#. :c:func:`glm_vec2_divs`
+#. :c:func:`glm_vec2_addadd`
+#. :c:func:`glm_vec2_subadd`
+#. :c:func:`glm_vec2_muladd`
+#. :c:func:`glm_vec2_muladds`
+#. :c:func:`glm_vec2_maxadd`
+#. :c:func:`glm_vec2_minadd`
+#. :c:func:`glm_vec2_negate`
+#. :c:func:`glm_vec2_negate_to`
+#. :c:func:`glm_vec2_normalize`
+#. :c:func:`glm_vec2_normalize_to`
+#. :c:func:`glm_vec2_rotate`
+#. :c:func:`glm_vec2_distance2`
+#. :c:func:`glm_vec2_distance`
+#. :c:func:`glm_vec2_maxv`
+#. :c:func:`glm_vec2_minv`
+#. :c:func:`glm_vec2_clamp`
+#. :c:func:`glm_vec2_lerp`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec2(float * v, vec2 dest)
+
+ init vec2 using vec3 or vec4
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec2_copy(vec2 a, vec2 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec2_zero(vec2 v)
+
+ makes all members 0.0f (zero)
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec2_one(vec2 v)
+
+ makes all members 1.0f (one)
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: float glm_vec2_dot(vec2 a, vec2 b)
+
+ dot product of vec2
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+
+ Returns:
+ dot product
+
+.. c:function:: void glm_vec2_cross(vec2 a, vec2 b, vec2 d)
+
+ cross product of two vector (RH)
+
+ | ref: http://allenchou.net/2013/07/cross-product-of-2d-vectors/
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** destination
+
+ Returns:
+ Z component of cross product
+
+.. c:function:: float glm_vec2_norm2(vec2 v)
+
+ norm * norm (magnitude) of vector
+
+ 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
+
+ Parameters:
+ | *[in]* **v** vector
+
+ Returns:
+ square of norm / magnitude
+
+.. c:function:: float glm_vec2_norm(vec2 vec)
+
+ | euclidean norm (magnitude), also called L2 norm
+ | this will give magnitude of vector in euclidean space
+
+ Parameters:
+ | *[in]* **vec** vector
+
+.. c:function:: void glm_vec2_add(vec2 a, vec2 b, vec2 dest)
+
+ add a vector to b vector store result in dest
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_adds(vec2 a, float s, vec2 dest)
+
+ add scalar to v vector store result in dest (d = v + vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_sub(vec2 v1, vec2 v2, vec2 dest)
+
+ subtract b vector from a vector store result in dest (d = v1 - v2)
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_subs(vec2 v, float s, vec2 dest)
+
+ subtract scalar from v vector store result in dest (d = v - vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_mul(vec2 a, vec2 b, vec2 d)
+
+ multiply two vector (component-wise multiplication)
+
+ Parameters:
+ | *[in]* **a** vector
+ | *[in]* **b** scalar
+ | *[out]* **d** result = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
+
+.. c:function:: void glm_vec2_scale(vec2 v, float s, vec2 dest)
+
+ multiply/scale vec2 vector with scalar: result = v * s
+
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_scale_as(vec2 v, float s, vec2 dest)
+
+ make vec2 vector scale as specified: result = unit(v) * s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec2_div(vec2 a, vec2 b, vec2 dest)
+
+ div vector with another component-wise division: d = a / b
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** result = (a[0] / b[0], a[1] / b[1], a[2] / b[2])
+
+.. c:function:: void glm_vec2_divs(vec2 v, float s, vec2 dest)
+
+ div vector with scalar: d = v / s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** result = (a[0] / s, a[1] / s, a[2] / s])
+
+.. c:function:: void glm_vec2_addadd(vec2 a, vec2 b, vec2 dest)
+
+ | add two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a + b)
+
+.. c:function:: void glm_vec2_subadd(vec2 a, vec2 b, vec2 dest)
+
+ | sub two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a - b)
+
+.. c:function:: void glm_vec2_muladd(vec2 a, vec2 b, vec2 dest)
+
+ | mul two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec2_muladds(vec2 a, float s, vec2 dest)
+
+ | mul vector with scalar and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest)
+
+ | add max of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec2_minadd(vec2 a, vec2 b, vec2 dest)
+
+ | add min of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec2_negate(vec2 v)
+
+ negate vector components
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec2_negate_to(vec2 v, vec2 dest)
+
+ negate vector components and store result in dest
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** negated vector
+
+.. c:function:: void glm_vec2_normalize(vec2 v)
+
+ normalize vec2 and store result in same vec
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec2_normalize_to(vec2 vec, vec2 dest)
+
+ normalize vec2 to dest
+
+ Parameters:
+ | *[in]* **vec** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec2_rotate(vec2 v, float angle, vec2 dest)
+
+ rotate vec2 around axis by angle using Rodrigues' rotation formula
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **axis** axis vector
+ | *[out]* **dest** destination
+
+.. c:function:: float glm_vec2_distance2(vec2 v1, vec2 v2)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **mat** vector1
+ | *[in]* **row1** vector2
+
+ Returns:
+ | squared distance (distance * distance)
+
+.. c:function:: float glm_vec2_distance(vec2 v1, vec2 v2)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **mat** vector1
+ | *[in]* **row1** vector2
+
+ Returns:
+ | distance
+
+.. c:function:: void glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest)
+
+ max values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest)
+
+ min values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec2_clamp(vec2 v, float minVal, float maxVal)
+
+ constrain a value to lie between two further values
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
+
+.. c:function:: void glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest)
+
+ linear interpolation between two vector
+
+ | formula: from + s * (to - from)
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** destination
diff --git a/libs/cglm/docs/source/vec3-ext.rst b/libs/cglm/docs/source/vec3-ext.rst
new file mode 100644
index 0000000..88f3699
--- /dev/null
+++ b/libs/cglm/docs/source/vec3-ext.rst
@@ -0,0 +1,143 @@
+.. default-domain:: C
+
+vec3 extra
+==========
+
+Header: cglm/vec3-ext.h
+
+There are some functions are in called in extra header. These are called extra
+because they are not used like other functions in vec3.h in the future some of
+these functions ma be moved to vec3 header.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_vec3_mulv`
+#. :c:func:`glm_vec3_broadcast`
+#. :c:func:`glm_vec3_eq`
+#. :c:func:`glm_vec3_eq_eps`
+#. :c:func:`glm_vec3_eq_all`
+#. :c:func:`glm_vec3_eqv`
+#. :c:func:`glm_vec3_eqv_eps`
+#. :c:func:`glm_vec3_max`
+#. :c:func:`glm_vec3_min`
+#. :c:func:`glm_vec3_isnan`
+#. :c:func:`glm_vec3_isinf`
+#. :c:func:`glm_vec3_isvalid`
+#. :c:func:`glm_vec3_sign`
+#. :c:func:`glm_vec3_sqrt`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec3_mulv(vec3 a, vec3 b, vec3 d)
+
+ multiplies individual items
+
+ Parameters:
+ | *[in]* **a** vec1
+ | *[in]* **b** vec2
+ | *[out]* **d** destination (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2])
+
+.. c:function:: void glm_vec3_broadcast(float val, vec3 d)
+
+ fill a vector with specified value
+
+ Parameters:
+ | *[in]* **val** value
+ | *[out]* **dest** destination
+
+.. c:function:: bool glm_vec3_eq(vec3 v, float val)
+
+ check if vector is equal to value (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec3_eq_eps(vec3 v, float val)
+
+ check if vector is equal to value (with epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec3_eq_all(vec3 v)
+
+ check if vectors members are equal (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec3_eqv(vec3 v1, vec3 v2)
+
+ check if vector is equal to another (without epsilon) vector
+
+ Parameters:
+ | *[in]* **vec** vector 1
+ | *[in]* **vec** vector 2
+
+.. c:function:: bool glm_vec3_eqv_eps(vec3 v1, vec3 v2)
+
+ check if vector is equal to another (with epsilon)
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+.. c:function:: float glm_vec3_max(vec3 v)
+
+ max value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: float glm_vec3_min(vec3 v)
+
+ min value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec3_isnan(vec3 v)
+
+ | check if one of items is NaN (not a number)
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec3_isinf(vec3 v)
+
+ | check if one of items is INFINITY
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec3_isvalid(vec3 v)
+
+ | check if all items are valid number
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: void glm_vec3_sign(vec3 v, vec3 dest)
+
+ get sign of 32 bit float as +1, -1, 0
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** sign vector (only keeps signs as -1, 0, -1)
+
+.. c:function:: void glm_vec3_sqrt(vec3 v, vec3 dest)
+
+ square root of each vector item
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination vector (sqrt(v))
diff --git a/libs/cglm/docs/source/vec3.rst b/libs/cglm/docs/source/vec3.rst
new file mode 100644
index 0000000..17e4824
--- /dev/null
+++ b/libs/cglm/docs/source/vec3.rst
@@ -0,0 +1,503 @@
+.. default-domain:: C
+
+vec3
+====
+
+Header: cglm/vec3.h
+
+ **Important:** *cglm* was used **glm_vec_** namespace for vec3 functions until
+ **v0.5.0**, since **v0.5.0** cglm uses **glm_vec3_** namespace for vec3.
+
+ Also `glm_vec3_flipsign` has been renamed to `glm_vec3_negate`
+
+We mostly use vectors in graphics math, to make writing code faster
+and easy to read, some *vec3* functions are aliased in global namespace.
+For instance :c:func:`glm_dot` is alias of :c:func:`glm_vec3_dot`,
+alias means inline wrapper here. There is no call verison of alias functions
+
+There are also functions for rotating *vec3* vector. **_m4**, **_m3** prefixes
+rotate *vec3* with matrix.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. glm_vec3_dup(v, dest)
+#. GLM_VEC3_ONE_INIT
+#. GLM_VEC3_ZERO_INIT
+#. GLM_VEC3_ONE
+#. GLM_VEC3_ZERO
+#. GLM_YUP
+#. GLM_ZUP
+#. GLM_XUP
+
+Functions:
+
+1. :c:func:`glm_vec3`
+#. :c:func:`glm_vec3_copy`
+#. :c:func:`glm_vec3_zero`
+#. :c:func:`glm_vec3_one`
+#. :c:func:`glm_vec3_dot`
+#. :c:func:`glm_vec3_norm2`
+#. :c:func:`glm_vec3_norm`
+#. :c:func:`glm_vec3_add`
+#. :c:func:`glm_vec3_adds`
+#. :c:func:`glm_vec3_sub`
+#. :c:func:`glm_vec3_subs`
+#. :c:func:`glm_vec3_mul`
+#. :c:func:`glm_vec3_scale`
+#. :c:func:`glm_vec3_scale_as`
+#. :c:func:`glm_vec3_div`
+#. :c:func:`glm_vec3_divs`
+#. :c:func:`glm_vec3_addadd`
+#. :c:func:`glm_vec3_subadd`
+#. :c:func:`glm_vec3_muladd`
+#. :c:func:`glm_vec3_muladds`
+#. :c:func:`glm_vec3_maxadd`
+#. :c:func:`glm_vec3_minadd`
+#. :c:func:`glm_vec3_flipsign`
+#. :c:func:`glm_vec3_flipsign_to`
+#. :c:func:`glm_vec3_inv`
+#. :c:func:`glm_vec3_inv_to`
+#. :c:func:`glm_vec3_negate`
+#. :c:func:`glm_vec3_negate_to`
+#. :c:func:`glm_vec3_normalize`
+#. :c:func:`glm_vec3_normalize_to`
+#. :c:func:`glm_vec3_cross`
+#. :c:func:`glm_vec3_crossn`
+#. :c:func:`glm_vec3_distance2`
+#. :c:func:`glm_vec3_distance`
+#. :c:func:`glm_vec3_angle`
+#. :c:func:`glm_vec3_rotate`
+#. :c:func:`glm_vec3_rotate_m4`
+#. :c:func:`glm_vec3_rotate_m3`
+#. :c:func:`glm_vec3_proj`
+#. :c:func:`glm_vec3_center`
+#. :c:func:`glm_vec3_maxv`
+#. :c:func:`glm_vec3_minv`
+#. :c:func:`glm_vec3_ortho`
+#. :c:func:`glm_vec3_clamp`
+#. :c:func:`glm_vec3_lerp`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec3(vec4 v4, vec3 dest)
+
+ init vec3 using vec4
+
+ Parameters:
+ | *[in]* **v4** vector4
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_copy(vec3 a, vec3 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_zero(vec3 v)
+
+ makes all members 0.0f (zero)
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec3_one(vec3 v)
+
+ makes all members 1.0f (one)
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: float glm_vec3_dot(vec3 a, vec3 b)
+
+ dot product of vec3
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+
+ Returns:
+ dot product
+
+.. c:function:: void glm_vec3_cross(vec3 a, vec3 b, vec3 d)
+
+ cross product of two vector (RH)
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_crossn(vec3 a, vec3 b, vec3 dest)
+
+ cross product of two vector (RH) and normalize the result
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** destination
+
+.. c:function:: float glm_vec3_norm2(vec3 v)
+
+ norm * norm (magnitude) of vector
+
+ 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
+
+ Parameters:
+ | *[in]* **v** vector
+
+ Returns:
+ square of norm / magnitude
+
+.. c:function:: float glm_vec3_norm(vec3 vec)
+
+ | euclidean norm (magnitude), also called L2 norm
+ | this will give magnitude of vector in euclidean space
+
+ Parameters:
+ | *[in]* **vec** vector
+
+.. c:function:: void glm_vec3_add(vec3 a, vec3 b, vec3 dest)
+
+ add a vector to b vector store result in dest
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_adds(vec3 a, float s, vec3 dest)
+
+ add scalar to v vector store result in dest (d = v + vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_sub(vec3 v1, vec3 v2, vec3 dest)
+
+ subtract b vector from a vector store result in dest (d = v1 - v2)
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_subs(vec3 v, float s, vec3 dest)
+
+ subtract scalar from v vector store result in dest (d = v - vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_mul(vec3 a, vec3 b, vec3 d)
+
+ multiply two vector (component-wise multiplication)
+
+ Parameters:
+ | *[in]* **a** vector
+ | *[in]* **b** scalar
+ | *[out]* **d** result = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
+
+.. c:function:: void glm_vec3_scale(vec3 v, float s, vec3 dest)
+
+ multiply/scale vec3 vector with scalar: result = v * s
+
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_scale_as(vec3 v, float s, vec3 dest)
+
+ make vec3 vector scale as specified: result = unit(v) * s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec3_div(vec3 a, vec3 b, vec3 dest)
+
+ div vector with another component-wise division: d = a / b
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** result = (a[0] / b[0], a[1] / b[1], a[2] / b[2])
+
+.. c:function:: void glm_vec3_divs(vec3 v, float s, vec3 dest)
+
+ div vector with scalar: d = v / s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** result = (a[0] / s, a[1] / s, a[2] / s])
+
+.. c:function:: void glm_vec3_addadd(vec3 a, vec3 b, vec3 dest)
+
+ | add two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a + b)
+
+.. c:function:: void glm_vec3_subadd(vec3 a, vec3 b, vec3 dest)
+
+ | sub two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a - b)
+
+.. c:function:: void glm_vec3_muladd(vec3 a, vec3 b, vec3 dest)
+
+ | mul two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec3_muladds(vec3 a, float s, vec3 dest)
+
+ | mul vector with scalar and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec3_maxadd(vec3 a, vec3 b, vec3 dest)
+
+ | add max of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec3_minadd(vec3 a, vec3 b, vec3 dest)
+
+ | add min of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec3_flipsign(vec3 v)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec3_negate`
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec3_flipsign_to(vec3 v, vec3 dest)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec3_negate_to`
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** negated vector
+
+.. c:function:: void glm_vec3_inv(vec3 v)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec3_negate`
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec3_inv_to(vec3 v, vec3 dest)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec3_negate_to`
+
+ Parameters:
+ | *[in]* **v** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_negate(vec3 v)
+
+ negate vector components
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec3_negate_to(vec3 v, vec3 dest)
+
+ negate vector components and store result in dest
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** negated vector
+
+.. c:function:: void glm_vec3_normalize(vec3 v)
+
+ normalize vec3 and store result in same vec
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec3_normalize_to(vec3 vec, vec3 dest)
+
+ normalize vec3 to dest
+
+ Parameters:
+ | *[in]* **vec** source
+ | *[out]* **dest** destination
+
+.. c:function:: float glm_vec3_angle(vec3 v1, vec3 v2)
+
+ angle betwen two vector
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+ Return:
+ | angle as radians
+
+.. c:function:: void glm_vec3_rotate(vec3 v, float angle, vec3 axis)
+
+ rotate vec3 around axis by angle using Rodrigues' rotation formula
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **axis** axis vector (will be normalized)
+ | *[in]* **angle** angle (radians)
+
+.. c:function:: void glm_vec3_rotate_m4(mat4 m, vec3 v, vec3 dest)
+
+ apply rotation matrix to vector
+
+ Parameters:
+ | *[in]* **m** affine matrix or rot matrix
+ | *[in]* **v** vector
+ | *[out]* **dest** rotated vector
+
+.. c:function:: void glm_vec3_rotate_m3(mat3 m, vec3 v, vec3 dest)
+
+ apply rotation matrix to vector
+
+ Parameters:
+ | *[in]* **m** affine matrix or rot matrix
+ | *[in]* **v** vector
+ | *[out]* **dest** rotated vector
+
+.. c:function:: void glm_vec3_proj(vec3 a, vec3 b, vec3 dest)
+
+ project a vector onto b vector
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** projected vector
+
+.. c:function:: void glm_vec3_center(vec3 v1, vec3 v2, vec3 dest)
+
+ find center point of two vector
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** center point
+
+.. c:function:: float glm_vec3_distance2(vec3 v1, vec3 v2)
+
+ squared distance between two vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+ Returns:
+ | squared distance (distance * distance)
+
+.. c:function:: float glm_vec3_distance(vec3 v1, vec3 v2)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+ Returns:
+ | distance
+
+.. c:function:: void glm_vec3_maxv(vec3 v1, vec3 v2, vec3 dest)
+
+ max values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_minv(vec3 v1, vec3 v2, vec3 dest)
+
+ min values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec3_ortho(vec3 v, vec3 dest)
+
+ possible orthogonal/perpendicular vector
+
+ References:
+ * `On picking an orthogonal vector (and combing coconuts) <http://lolengine.net/blog/2013/09/21/picking-orthogonal-vector-combing-coconuts>`_
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** orthogonal/perpendicular vector
+
+.. c:function:: void glm_vec3_clamp(vec3 v, float minVal, float maxVal)
+
+ constrain a value to lie between two further values
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
+
+.. c:function:: void glm_vec3_lerp(vec3 from, vec3 to, float t, vec3 dest)
+
+ linear interpolation between two vector
+
+ | formula: from + s * (to - from)
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** destination
diff --git a/libs/cglm/docs/source/vec4-ext.rst b/libs/cglm/docs/source/vec4-ext.rst
new file mode 100644
index 0000000..722424e
--- /dev/null
+++ b/libs/cglm/docs/source/vec4-ext.rst
@@ -0,0 +1,138 @@
+.. default-domain:: C
+
+vec4 extra
+==========
+
+Header: cglm/vec4-ext.h
+
+There are some functions are in called in extra header. These are called extra
+because they are not used like other functions in vec4.h in the future some of
+these functions ma be moved to vec4 header.
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_vec4_mulv`
+#. :c:func:`glm_vec4_broadcast`
+#. :c:func:`glm_vec4_eq`
+#. :c:func:`glm_vec4_eq_eps`
+#. :c:func:`glm_vec4_eq_all`
+#. :c:func:`glm_vec4_eqv`
+#. :c:func:`glm_vec4_eqv_eps`
+#. :c:func:`glm_vec4_max`
+#. :c:func:`glm_vec4_min`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec4_mulv(vec4 a, vec4 b, vec4 d)
+
+ multiplies individual items
+
+ Parameters:
+ | *[in]* **a** vec1
+ | *[in]* **b** vec2
+ | *[out]* **d** destination
+
+.. c:function:: void glm_vec4_broadcast(float val, vec4 d)
+
+ fill a vector with specified value
+
+ Parameters:
+ | *[in]* **val** value
+ | *[out]* **dest** destination
+
+.. c:function:: bool glm_vec4_eq(vec4 v, float val)
+
+ check if vector is equal to value (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec4_eq_eps(vec4 v, float val)
+
+ check if vector is equal to value (with epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **val** value
+
+.. c:function:: bool glm_vec4_eq_all(vec4 v)
+
+ check if vectors members are equal (without epsilon)
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec4_eqv(vec4 v1, vec4 v2)
+
+ check if vector is equal to another (without epsilon) vector
+
+ Parameters:
+ | *[in]* **vec** vector 1
+ | *[in]* **vec** vector 2
+
+.. c:function:: bool glm_vec4_eqv_eps(vec4 v1, vec4 v2)
+
+ check if vector is equal to another (with epsilon)
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+
+.. c:function:: float glm_vec4_max(vec4 v)
+
+ max value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: float glm_vec4_min(vec4 v)
+
+ min value of vector
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec4_isnan(vec4 v)
+
+ | check if one of items is NaN (not a number)
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec4_isinf(vec4 v)
+
+ | check if one of items is INFINITY
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: bool glm_vec4_isvalid(vec4 v)
+
+ | check if all items are valid number
+ | you should only use this in DEBUG mode or very critical asserts
+
+ Parameters:
+ | *[in]* **v** vector
+
+.. c:function:: void glm_vec4_sign(vec4 v, vec4 dest)
+
+ get sign of 32 bit float as +1, -1, 0
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** sign vector (only keeps signs as -1, 0, -1)
+
+.. c:function:: void glm_vec4_sqrt(vec4 v, vec4 dest)
+
+ square root of each vector item
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** destination vector (sqrt(v))
diff --git a/libs/cglm/docs/source/vec4.rst b/libs/cglm/docs/source/vec4.rst
new file mode 100644
index 0000000..58c861e
--- /dev/null
+++ b/libs/cglm/docs/source/vec4.rst
@@ -0,0 +1,408 @@
+.. default-domain:: C
+
+vec4
+====
+
+Header: cglm/vec4.h
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Macros:
+
+1. glm_vec4_dup3(v, dest)
+#. glm_vec4_dup(v, dest)
+#. GLM_VEC4_ONE_INIT
+#. GLM_VEC4_BLACK_INIT
+#. GLM_VEC4_ZERO_INIT
+#. GLM_VEC4_ONE
+#. GLM_VEC4_BLACK
+#. GLM_VEC4_ZERO
+
+Functions:
+
+1. :c:func:`glm_vec4`
+#. :c:func:`glm_vec4_copy3`
+#. :c:func:`glm_vec4_copy`
+#. :c:func:`glm_vec4_ucopy`
+#. :c:func:`glm_vec4_zero`
+#. :c:func:`glm_vec4_one`
+#. :c:func:`glm_vec4_dot`
+#. :c:func:`glm_vec4_norm2`
+#. :c:func:`glm_vec4_norm`
+#. :c:func:`glm_vec4_add`
+#. :c:func:`glm_vec4_adds`
+#. :c:func:`glm_vec4_sub`
+#. :c:func:`glm_vec4_subs`
+#. :c:func:`glm_vec4_mul`
+#. :c:func:`glm_vec4_scale`
+#. :c:func:`glm_vec4_scale_as`
+#. :c:func:`glm_vec4_div`
+#. :c:func:`glm_vec4_divs`
+#. :c:func:`glm_vec4_addadd`
+#. :c:func:`glm_vec4_subadd`
+#. :c:func:`glm_vec4_muladd`
+#. :c:func:`glm_vec4_muladds`
+#. :c:func:`glm_vec4_maxadd`
+#. :c:func:`glm_vec4_minadd`
+#. :c:func:`glm_vec4_flipsign`
+#. :c:func:`glm_vec4_flipsign_to`
+#. :c:func:`glm_vec4_inv`
+#. :c:func:`glm_vec4_inv_to`
+#. :c:func:`glm_vec4_negate`
+#. :c:func:`glm_vec4_negate_to`
+#. :c:func:`glm_vec4_normalize`
+#. :c:func:`glm_vec4_normalize_to`
+#. :c:func:`glm_vec4_distance`
+#. :c:func:`glm_vec4_maxv`
+#. :c:func:`glm_vec4_minv`
+#. :c:func:`glm_vec4_clamp`
+#. :c:func:`glm_vec4_lerp`
+#. :c:func:`glm_vec4_cubic`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: void glm_vec4(vec3 v3, float last, vec4 dest)
+
+ init vec4 using vec3, since you are initializing vec4 with vec3
+ you need to set last item. cglm could set it zero but making it parameter
+ gives more control
+
+ Parameters:
+ | *[in]* **v3** vector4
+ | *[in]* **last** last item of vec4
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_copy3(vec4 a, vec3 dest)
+
+ copy first 3 members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **a** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_copy(vec4 v, vec4 dest)
+
+ copy all members of [a] to [dest]
+
+ Parameters:
+ | *[in]* **v** source
+ | *[in]* **dest** destination
+
+.. c:function:: void glm_vec4_ucopy(vec4 v, vec4 dest)
+
+ copy all members of [a] to [dest]
+
+ | alignment is not required
+
+ Parameters:
+ | *[in]* **v** source
+ | *[in]* **dest** destination
+
+.. c:function:: void glm_vec4_zero(vec4 v)
+
+ makes all members zero
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: float glm_vec4_dot(vec4 a, vec4 b)
+
+ dot product of vec4
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+
+ Returns:
+ dot product
+
+.. c:function:: float glm_vec4_norm2(vec4 v)
+
+ norm * norm (magnitude) of vector
+
+ 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
+
+ Parameters:
+ | *[in]* **v** vector
+
+ Returns:
+ square of norm / magnitude
+
+.. c:function:: float glm_vec4_norm(vec4 vec)
+
+ | euclidean norm (magnitude), also called L2 norm
+ | this will give magnitude of vector in euclidean space
+
+ Parameters:
+ | *[in]* **vec** vector
+
+.. c:function:: void glm_vec4_add(vec4 a, vec4 b, vec4 dest)
+
+ add a vector to b vector store result in dest
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_adds(vec4 v, float s, vec4 dest)
+
+ add scalar to v vector store result in dest (d = v + vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_sub(vec4 a, vec4 b, vec4 dest)
+
+ subtract b vector from a vector store result in dest (d = v1 - v2)
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_subs(vec4 v, float s, vec4 dest)
+
+ subtract scalar from v vector store result in dest (d = v - vec(s))
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_mul(vec4 a, vec4 b, vec4 d)
+
+ multiply two vector (component-wise multiplication)
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** result = (a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3])
+
+.. c:function:: void glm_vec4_scale(vec4 v, float s, vec4 dest)
+
+ multiply/scale vec4 vector with scalar: result = v * s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_scale_as(vec4 v, float s, vec4 dest)
+
+ make vec4 vector scale as specified: result = unit(v) * s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** destination vector
+
+.. c:function:: void glm_vec4_div(vec4 a, vec4 b, vec4 dest)
+
+ div vector with another component-wise division: d = v1 / v2
+
+ Parameters:
+ | *[in]* **a** vector1
+ | *[in]* **b** vector2
+ | *[out]* **dest** result = (a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3])
+
+.. c:function:: void glm_vec4_divs(vec4 v, float s, vec4 dest)
+
+ div vector with scalar: d = v / s
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** result = (a[0] / s, a[1] / s, a[2] / s, a[3] / s)
+
+.. c:function:: void glm_vec4_addadd(vec4 a, vec4 b, vec4 dest)
+
+ | add two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a + b)
+
+.. c:function:: void glm_vec4_subadd(vec4 a, vec4 b, vec4 dest)
+
+ | sub two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a - b)
+
+.. c:function:: void glm_vec4_muladd(vec4 a, vec4 b, vec4 dest)
+
+ | mul two vectors and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec4_muladds(vec4 a, float s, vec4 dest)
+
+ | mul vector with scalar and add result to sum
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector
+ | *[in]* **s** scalar
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec4_maxadd(vec4 a, vec4 b, vec4 dest)
+
+ | add max of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec4_minadd(vec4 a, vec4 b, vec4 dest)
+
+ | add min of two vector to result/dest
+ | it applies += operator so dest must be initialized
+
+ Parameters:
+ | *[in]* **a** vector 1
+ | *[in]* **b** vector 2
+ | *[out]* **dest** dest += (a * b)
+
+.. c:function:: void glm_vec4_flipsign(vec4 v)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec4_negate`
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec4_flipsign_to(vec4 v, vec4 dest)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec4_negate_to`
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** negated vector
+
+.. c:function:: void glm_vec4_inv(vec4 v)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec4_negate`
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec4_inv_to(vec4 v, vec4 dest)
+
+ **DEPRACATED!**
+
+ use :c:func:`glm_vec4_negate_to`
+
+ Parameters:
+ | *[in]* **v** source
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_negate(vec4 v)
+
+ negate vector components
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec4_negate_to(vec4 v, vec4 dest)
+
+ negate vector components and store result in dest
+
+ Parameters:
+ | *[in]* **v** vector
+ | *[out]* **dest** negated vector
+
+.. c:function:: void glm_vec4_normalize(vec4 v)
+
+ normalize vec4 and store result in same vec
+
+ Parameters:
+ | *[in, out]* **v** vector
+
+.. c:function:: void glm_vec4_normalize_to(vec4 vec, vec4 dest)
+
+ normalize vec4 to dest
+
+ Parameters:
+ | *[in]* **vec** source
+ | *[out]* **dest** destination
+
+.. c:function:: float glm_vec4_distance(vec4 v1, vec4 v2)
+
+ distance between two vectors
+
+ Parameters:
+ | *[in]* **mat** vector1
+ | *[in]* **row1** vector2
+
+ Returns:
+ | distance
+
+.. c:function:: void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest)
+
+ max values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest)
+
+ min values of vectors
+
+ Parameters:
+ | *[in]* **v1** vector1
+ | *[in]* **v2** vector2
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_clamp(vec4 v, float minVal, float maxVal)
+
+ constrain a value to lie between two further values
+
+ Parameters:
+ | *[in, out]* **v** vector
+ | *[in]* **minVal** minimum value
+ | *[in]* **maxVal** maximum value
+
+.. c:function:: void glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest)
+
+ linear interpolation between two vector
+
+ | formula: from + s * (to - from)
+
+ Parameters:
+ | *[in]* **from** from value
+ | *[in]* **to** to value
+ | *[in]* **t** interpolant (amount) clamped between 0 and 1
+ | *[out]* **dest** destination
+
+.. c:function:: void glm_vec4_cubic(float s, vec4 dest)
+
+ helper to fill vec4 as [S^3, S^2, S, 1]
+
+ Parameters:
+ | *[in]* **s** parameter
+ | *[out]* **dest** destination
diff --git a/libs/cglm/docs/source/version.rst b/libs/cglm/docs/source/version.rst
new file mode 100644
index 0000000..7e662f9
--- /dev/null
+++ b/libs/cglm/docs/source/version.rst
@@ -0,0 +1,15 @@
+.. default-domain:: C
+
+version
+================================================================================
+
+Header: cglm/version.h
+
+**cglm** uses semantic versioning (http://semver.org) which is MAJOR.MINOR.PATCH
+
+| **CGLM_VERSION_MAJOR** is major number of the version.
+| **CGLM_VERSION_MINOR** is minor number of the version.
+| **CGLM_VERSION_PATCH** is patch number of the version.
+
+every release increases these numbers. You can check existing version by
+including `cglm/version.h`