Compare commits

...

38 Commits

Author SHA1 Message Date
Recep Aslantas
a6a37995e9 build: update automake sources 2018-04-18 23:02:15 +03:00
Recep Aslantas
6202179c23 update version 2018-04-18 22:30:20 +03:00
Recep Aslantas
22b699174c build: improve calling libtoolize 2018-04-18 21:47:53 +03:00
Recep Aslantas
016c0a71a6 Merge pull request #46 from recp/affine
affine transform update
2018-04-18 15:25:40 +03:00
Recep Aslantas
e28cf1d3f6 remove unused variable 2018-04-18 15:23:07 +03:00
Recep Aslantas
63966ee5c0 quat: use the new "glm_mul_rot" for quaternion
* this should be faster than mat4_mul
2018-04-18 15:16:24 +03:00
Recep Aslantas
a723ecdb7e add troubleshooting to docs 2018-04-18 15:11:06 +03:00
Recep Aslantas
065f93ab3c update docs, drop scale1 2018-04-18 14:30:44 +03:00
Recep Aslantas
4dbcd28fdb use mul_rot for rotations to make thrm faster 2018-04-18 14:12:56 +03:00
Recep Aslantas
be0e3fc9f2 new matrix multiplication helper for rotation matrices 2018-04-18 14:05:09 +03:00
Recep Aslantas
d648f5772d affine: drop rotate_ndc functions 2018-04-18 10:57:35 +03:00
Recep Aslantas
f163fcd043 simd: load vec3 helpers for sse/sse2 2018-04-18 00:00:47 +03:00
Recep Aslantas
27ab6a7dd0 update docs, add clarifications for affine transforms 2018-04-17 15:42:24 +03:00
Recep Aslantas
33e951fe2e implement rotate_at for quat and provide make version 2018-04-17 12:17:04 +03:00
Recep Aslantas
c63c6c90ac implement rotate_at 2018-04-17 11:12:18 +03:00
Recep Aslantas
a2792178db add missing call funcs for affine transforms 2018-04-17 11:07:57 +03:00
Recep Aslantas
cefd5fb53d test: add some tests for affine transforms 2018-04-17 10:33:52 +03:00
Recep Aslantas
821c79572f test: add some tests for mat3 2018-04-15 20:47:38 +03:00
Recep Aslantas
f0a27d0ce2 now working on v0.4.2 2018-04-15 20:46:46 +03:00
Recep Aslantas
007ae62e06 update docs version 2018-04-15 13:10:07 +03:00
Recep Aslantas
826ddf0f5b improve normalize vectors 2018-04-15 12:46:29 +03:00
Recep Aslantas
b09b5f260b vec: fix rotate vector using mat4 and mat3 rotation matrices 2018-04-15 12:44:50 +03:00
Recep Aslantas
59aacee968 optimize clamp for vec4 2018-04-14 12:49:37 +03:00
Recep Aslantas
429aff087f optimize min and max for vec4 2018-04-14 11:35:28 +03:00
Recep Aslantas
ca9f61dd74 Merge pull request #44 from recp/vector
new vector functions and optimizations
2018-04-14 09:19:51 +03:00
Recep Aslantas
d6395d4fb8 vec: optimize rotate vector using matrix
* add mat3 version
2018-04-13 22:33:32 +03:00
Recep Aslantas
7f7007574b vec: implement muladd's scalar version 2018-04-13 22:30:44 +03:00
Recep Aslantas
13345f06c1 fix vec4 scalar ops 2018-04-13 15:50:05 +03:00
Recep Aslantas
725fac75d0 now working on v0.4.1 2018-04-13 15:47:45 +03:00
Recep Aslantas
c05f58a169 vec: add addadd, subadd and muladd helpers 2018-04-13 15:46:43 +03:00
Recep Aslantas
d841f8809d vec: add some new functions for vector
* _mul: multiply two vector (replacement for _mulv)
* _div: div two vector
* _divs: div vector with scalar
* adds: add scalar to each components of vec
* subs: sub scalar from each components of vec
2018-04-13 15:12:56 +03:00
Recep Aslantas
af5a2627b4 fix scale_as for zero length vector
* return zero if vector length is zero
2018-04-13 11:57:34 +03:00
Recep Aslantas
25fc3d0284 vec: add one and zero helpers for vectors 2018-04-13 11:57:14 +03:00
Recep Aslantas
c489955b00 add simd norm helper 2018-04-13 11:39:14 +03:00
Recep Aslantas
79f8b1ebf8 vec4: optimize vec4 norm and norm2 2018-04-13 11:18:42 +03:00
Recep Aslantas
0eb37da8bb vec4: optimize vec4 normalize with SIMD 2018-04-13 11:01:07 +03:00
Recep Aslantas
44728c536b ci: update travis ci 2018-04-12 15:52:06 +03:00
Recep Aslantas
c8ed8acbed Update README.md 2018-04-12 14:47:14 +03:00
40 changed files with 2105 additions and 310 deletions

View File

@@ -49,7 +49,7 @@ script:
after_success: after_success:
- if [[ "$CC" == "gcc" && "$CODE_COVERAGE" == "ON" ]]; then - if [[ "$CC" == "gcc" && "$CODE_COVERAGE" == "ON" ]]; then
pip install --user cpp-coveralls pip install --user cpp-coveralls &&
coveralls coveralls
--build-root . --build-root .
--exclude lib --exclude lib

View File

@@ -19,7 +19,9 @@ Complete documentation: http://cglm.readthedocs.io
- _dup (duplicate) is changed to _copy. For instance `glm_vec_dup -> glm_vec_copy` - _dup (duplicate) is changed to _copy. For instance `glm_vec_dup -> glm_vec_copy`
- OpenGL related functions are dropped to make this lib platform/third-party independent - OpenGL related functions are dropped to make this lib platform/third-party independent
- make sure you have latest version and feel free to report bugs, troubles - make sure you have latest version and feel free to report bugs, troubles
- **[bugfix]** euler angles was implemented in reverse order (extrinsic) it was fixed, now they are intrinsic. Make sure that you have the latest version - **[bugfix]** euler angles was implemented in reverse order (extrinsic) it was fixed, now they are intrinsic. Make sure that
you have the latest version
- **[major change]** by starting v0.4.0, quaternions are stored as [x, y, z, w], it was [w, x, y, z] in v0.3.5 and earlier versions
#### Note for C++ developers: #### Note for C++ developers:
If you don't aware about original GLM library yet, you may also want to look at: If you don't aware about original GLM library yet, you may also want to look at:

View File

@@ -8,17 +8,14 @@
cd $(dirname "$0") cd $(dirname "$0")
if [ "$(uname)" = "Darwin" ]; then
libtoolBin=$(which glibtoolize)
libtoolBinDir=$(dirname "${libtoolBin}")
if [ ! -f "${libtoolBinDir}/libtoolize" ]; then
ln -s $libtoolBin "${libtoolBinDir}/libtoolize"
fi
fi
autoheader autoheader
libtoolize
if [ "$(uname)" = "Darwin" ]; then
glibtoolize
else
libtoolize
fi
aclocal -I m4 aclocal -I m4
autoconf autoconf
automake --add-missing --copy automake --add-missing --copy

View File

@@ -7,7 +7,7 @@
#***************************************************************************** #*****************************************************************************
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([cglm], [0.4.0], [info@recp.me]) AC_INIT([cglm], [0.4.3], [info@recp.me])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@@ -33,6 +33,7 @@ Table of contents (click func go):
Functions: Functions:
1. :c:func:`glm_mul` 1. :c:func:`glm_mul`
#. :c:func:`glm_mul_rot`
#. :c:func:`glm_inv_tr` #. :c:func:`glm_inv_tr`
Functions documentation Functions documentation
@@ -59,6 +60,27 @@ Functions documentation
| *[in]* **m2** affine matrix 2 | *[in]* **m2** affine matrix 2
| *[out]* **dest** result matrix | *[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) .. c:function:: void glm_inv_tr(mat4 mat)
| inverse orthonormal rotation + translation matrix (ridig-body) | inverse orthonormal rotation + translation matrix (ridig-body)

View File

@@ -5,6 +5,8 @@ affine transforms
Header: cglm/affine.h Header: cglm/affine.h
Initialize Transform Matrices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions with **_make** prefix expect you don't have a matrix and they create 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. a matrix for you. You don't need to pass identity matrix.
@@ -15,6 +17,107 @@ before sending to transfrom functions.
There are also functions to decompose transform matrix. These functions can't There are also functions to decompose transform matrix. These functions can't
decompose matrix after projected. 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 */
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): Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -29,15 +132,14 @@ Functions:
#. :c:func:`glm_scale_to` #. :c:func:`glm_scale_to`
#. :c:func:`glm_scale_make` #. :c:func:`glm_scale_make`
#. :c:func:`glm_scale` #. :c:func:`glm_scale`
#. :c:func:`glm_scale1`
#. :c:func:`glm_scale_uni` #. :c:func:`glm_scale_uni`
#. :c:func:`glm_rotate_x` #. :c:func:`glm_rotate_x`
#. :c:func:`glm_rotate_y` #. :c:func:`glm_rotate_y`
#. :c:func:`glm_rotate_z` #. :c:func:`glm_rotate_z`
#. :c:func:`glm_rotate_ndc_make`
#. :c:func:`glm_rotate_make` #. :c:func:`glm_rotate_make`
#. :c:func:`glm_rotate_ndc`
#. :c:func:`glm_rotate` #. :c:func:`glm_rotate`
#. :c:func:`glm_rotate_at`
#. :c:func:`glm_rotate_atm`
#. :c:func:`glm_decompose_scalev` #. :c:func:`glm_decompose_scalev`
#. :c:func:`glm_uniscaled` #. :c:func:`glm_uniscaled`
#. :c:func:`glm_decompose_rs` #. :c:func:`glm_decompose_rs`
@@ -122,10 +224,6 @@ Functions documentation
| *[in, out]* **m** affine transfrom | *[in, out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z] | *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale1(mat4 m, float s)
DEPRECATED! Use glm_scale_uni
.. c:function:: void glm_scale_uni(mat4 m, float s) .. c:function:: void glm_scale_uni(mat4 m, float s)
applies uniform scale to existing transform matrix v = [s, s, s] applies uniform scale to existing transform matrix v = [s, s, s]
@@ -165,16 +263,6 @@ Functions documentation
| *[in]* **angle** angle (radians) | *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix | *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc)
creates NEW rotation matrix by angle and axis
this name may change in the future. axis must be is normalized
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis_ndc** normalized axis
.. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis) .. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
creates NEW rotation matrix by angle and axis, creates NEW rotation matrix by angle and axis,
@@ -185,16 +273,6 @@ Functions documentation
| *[in]* **axis** angle (radians) | *[in]* **axis** angle (radians)
| *[in]* **axis** axis | *[in]* **axis** axis
.. c:function:: void glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc)
rotate existing transform matrix around Z axis by angle and axis
this name may change in the future, axis must be normalized.
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis_ndc** normalized axis
.. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis) .. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis)
rotate existing transform matrix around Z axis by angle and axis rotate existing transform matrix around Z axis by angle and axis
@@ -204,6 +282,29 @@ Functions documentation
| *[in]* **angle** angle (radians) | *[in]* **angle** angle (radians)
| *[in]* **axis** axis | *[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) .. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
decompose scale vector decompose scale vector

View File

@@ -62,9 +62,9 @@ author = u'Recep Aslantas'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = u'0.3.4' version = u'0.4.3'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = u'0.3.4' release = u'0.4.3'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@@ -40,6 +40,7 @@ Also currently only **float** type is supported for most operations.
getting_started getting_started
opengl opengl
api api
troubleshooting
Indices and tables Indices and tables
================== ==================

View File

@@ -56,6 +56,9 @@ Functions:
#. :c:func:`glm_quat_for` #. :c:func:`glm_quat_for`
#. :c:func:`glm_quat_forp` #. :c:func:`glm_quat_forp`
#. :c:func:`glm_quat_rotatev` #. :c:func:`glm_quat_rotatev`
#. :c:func:`glm_quat_rotate`
#. :c:func:`glm_quat_rotate_at`
#. :c:func:`glm_quat_rotate_atm`
Functions documentation Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
@@ -354,3 +357,24 @@ Functions documentation
| *[in]* **m** existing transform matrix to rotate | *[in]* **m** existing transform matrix to rotate
| *[in]* **q** quaternion | *[in]* **q** quaternion
| *[out]* **dest** rotated matrix/transform | *[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(mat4 m, versor q, mat4 dest)
| 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

View File

@@ -0,0 +1,76 @@
.. 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.
Aligment:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**vec4** and **mat4** types requires 16 byte aligment aligment.
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 aligment 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 aligment 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.**
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.
Wrong Results:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Again, you may used wrong function.
For instance if you use **glm_normalize()** or **glm_vec_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.**
Other Issues?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Please let us know by creating an issue on Github.**

View File

@@ -31,14 +31,25 @@ Functions:
1. :c:func:`glm_vec3` 1. :c:func:`glm_vec3`
#. :c:func:`glm_vec_copy` #. :c:func:`glm_vec_copy`
#. :c:func:`glm_vec_zero`
#. :c:func:`glm_vec_one`
#. :c:func:`glm_vec_dot` #. :c:func:`glm_vec_dot`
#. :c:func:`glm_vec_cross` #. :c:func:`glm_vec_cross`
#. :c:func:`glm_vec_norm2` #. :c:func:`glm_vec_norm2`
#. :c:func:`glm_vec_norm` #. :c:func:`glm_vec_norm`
#. :c:func:`glm_vec_add` #. :c:func:`glm_vec_add`
#. :c:func:`glm_vec_adds`
#. :c:func:`glm_vec_sub` #. :c:func:`glm_vec_sub`
#. :c:func:`glm_vec_subs`
#. :c:func:`glm_vec_mul`
#. :c:func:`glm_vec_scale` #. :c:func:`glm_vec_scale`
#. :c:func:`glm_vec_scale_as` #. :c:func:`glm_vec_scale_as`
#. :c:func:`glm_vec_div`
#. :c:func:`glm_vec_divs`
#. :c:func:`glm_vec_addadd`
#. :c:func:`glm_vec_subadd`
#. :c:func:`glm_vec_muladd`
#. :c:func:`glm_vec_muladds`
#. :c:func:`glm_vec_flipsign` #. :c:func:`glm_vec_flipsign`
#. :c:func:`glm_vec_flipsign_to` #. :c:func:`glm_vec_flipsign_to`
#. :c:func:`glm_vec_inv` #. :c:func:`glm_vec_inv`
@@ -49,6 +60,7 @@ Functions:
#. :c:func:`glm_vec_angle` #. :c:func:`glm_vec_angle`
#. :c:func:`glm_vec_rotate` #. :c:func:`glm_vec_rotate`
#. :c:func:`glm_vec_rotate_m4` #. :c:func:`glm_vec_rotate_m4`
#. :c:func:`glm_vec_rotate_m3`
#. :c:func:`glm_vec_proj` #. :c:func:`glm_vec_proj`
#. :c:func:`glm_vec_center` #. :c:func:`glm_vec_center`
#. :c:func:`glm_vec_maxv` #. :c:func:`glm_vec_maxv`
@@ -76,6 +88,20 @@ Functions documentation
| *[in]* **a** source | *[in]* **a** source
| *[out]* **dest** destination | *[out]* **dest** destination
.. c:function:: void glm_vec_zero(vec3 v)
makes all members 0.0f (zero)
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec_one(vec3 v)
makes all members 1.0f (one)
Parameters:
| *[in, out]* **v** vector
.. c:function:: float glm_vec_dot(vec3 a, vec3 b) .. c:function:: float glm_vec_dot(vec3 a, vec3 b)
dot product of vec3 dot product of vec3
@@ -117,24 +143,51 @@ Functions documentation
Parameters: Parameters:
| *[in]* **vec** vector | *[in]* **vec** vector
.. c:function:: void glm_vec_add(vec3 v1, vec3 v2, vec3 dest) .. c:function:: void glm_vec_add(vec3 a, vec3 b, vec3 dest)
add v2 vector to v1 vector store result in dest add a vector to b vector store result in dest
Parameters: Parameters:
| *[in]* **v1** vector1 | *[in]* **a** vector1
| *[in]* **v2** vector2 | *[in]* **b** vector2
| *[out]* **dest** destination vector
.. c:function:: void glm_vec_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 | *[out]* **dest** destination vector
.. c:function:: void glm_vec_sub(vec3 v1, vec3 v2, vec3 dest) .. c:function:: void glm_vec_sub(vec3 v1, vec3 v2, vec3 dest)
subtract v2 vector from v1 vector store result in dest subtract b vector from a vector store result in dest (d = v1 - v2)
Parameters: Parameters:
| *[in]* **v1** vector1 | *[in]* **a** vector1
| *[in]* **v2** vector2 | *[in]* **b** vector2
| *[out]* **dest** destination vector | *[out]* **dest** destination vector
.. c:function:: void glm_vec_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_vec_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_vec_scale(vec3 v, float s, vec3 dest) .. c:function:: void glm_vec_scale(vec3 v, float s, vec3 dest)
multiply/scale vec3 vector with scalar: result = v * s multiply/scale vec3 vector with scalar: result = v * s
@@ -154,6 +207,64 @@ Functions documentation
| *[in]* **s** scalar | *[in]* **s** scalar
| *[out]* **dest** destination vector | *[out]* **dest** destination vector
.. c:function:: void glm_vec_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_vec_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_vec_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_vec_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_vec_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_vec_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_vec_flipsign(vec3 v) .. c:function:: void glm_vec_flipsign(vec3 v)
flip sign of all vec3 members flip sign of all vec3 members
@@ -228,6 +339,15 @@ Functions documentation
| *[in]* **v** vector | *[in]* **v** vector
| *[out]* **dest** rotated vector | *[out]* **dest** rotated vector
.. c:function:: void glm_vec_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_vec_proj(vec3 a, vec3 b, vec3 dest) .. c:function:: void glm_vec_proj(vec3 a, vec3 b, vec3 dest)
project a vector onto b vector project a vector onto b vector

View File

@@ -24,13 +24,24 @@ Functions:
1. :c:func:`glm_vec4` 1. :c:func:`glm_vec4`
#. :c:func:`glm_vec4_copy3` #. :c:func:`glm_vec4_copy3`
#. :c:func:`glm_vec4_copy` #. :c:func:`glm_vec4_copy`
#. :c:func:`glm_vec4_zero`
#. :c:func:`glm_vec4_one`
#. :c:func:`glm_vec4_dot` #. :c:func:`glm_vec4_dot`
#. :c:func:`glm_vec4_norm2` #. :c:func:`glm_vec4_norm2`
#. :c:func:`glm_vec4_norm` #. :c:func:`glm_vec4_norm`
#. :c:func:`glm_vec4_add` #. :c:func:`glm_vec4_add`
#. :c:func:`glm_vec4_adds`
#. :c:func:`glm_vec4_sub` #. :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`
#. :c:func:`glm_vec4_scale_as` #. :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_flipsign` #. :c:func:`glm_vec4_flipsign`
#. :c:func:`glm_vec_flipsign_to` #. :c:func:`glm_vec_flipsign_to`
#. :c:func:`glm_vec4_inv` #. :c:func:`glm_vec4_inv`
@@ -78,6 +89,13 @@ Functions documentation
| *[in]* **v** source | *[in]* **v** source
| *[in]* **dest** destination | *[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) .. c:function:: float glm_vec4_dot(vec4 a, vec4 b)
dot product of vec4 dot product of vec4
@@ -110,24 +128,51 @@ Functions documentation
Parameters: Parameters:
| *[in]* **vec** vector | *[in]* **vec** vector
.. c:function:: void glm_vec4_add(vec4 v1, vec4 v2, vec4 dest) .. c:function:: void glm_vec4_add(vec4 a, vec4 b, vec4 dest)
add v2 vector to v1 vector store result in dest add a vector to b vector store result in dest
Parameters: Parameters:
| *[in]* **v1** vector1 | *[in]* **a** vector1
| *[in]* **v2** vector2 | *[in]* **b** vector2
| *[out]* **dest** destination vector | *[out]* **dest** destination vector
.. c:function:: void glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest) .. c:function:: void glm_vec4_adds(vec4 v, float s, vec4 dest)
subtract v2 vector from v1 vector store result in dest add scalar to v vector store result in dest (d = v + vec(s))
Parameters: Parameters:
| *[in]* **v1** vector1 | *[in]* **v** vector
| *[in]* **v2** vector2 | *[in]* **s** scalar
| *[out]* **dest** destination vector | *[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) .. c:function:: void glm_vec4_scale(vec4 v, float s, vec4 dest)
multiply/scale vec4 vector with scalar: result = v * s multiply/scale vec4 vector with scalar: result = v * s
@@ -146,6 +191,64 @@ Functions documentation
| *[in]* **s** scalar | *[in]* **s** scalar
| *[out]* **dest** destination vector | *[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_flipsign(vec4 v) .. c:function:: void glm_vec4_flipsign(vec4 v)
flip sign of all vec4 members flip sign of all vec4 members

View File

@@ -81,6 +81,59 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) {
#endif #endif
} }
/*!
* @brief this is similar to glm_mat4_mul but specialized to affine transform
*
* Right Matrix format should be:
* 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
*
* @param[in] m1 affine matrix 1
* @param[in] m2 affine matrix 2
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_mul_rot_sse2(m1, m2, dest);
#else
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
a20 = m1[2][0], a21 = m1[2][1], a22 = m1[2][2], a23 = m1[2][3],
a30 = m1[3][0], a31 = m1[3][1], a32 = m1[3][2], a33 = m1[3][3],
b00 = m2[0][0], b01 = m2[0][1], b02 = m2[0][2],
b10 = m2[1][0], b11 = m2[1][1], b12 = m2[1][2],
b20 = m2[2][0], b21 = m2[2][1], b22 = m2[2][2];
dest[0][0] = a00 * b00 + a10 * b01 + a20 * b02;
dest[0][1] = a01 * b00 + a11 * b01 + a21 * b02;
dest[0][2] = a02 * b00 + a12 * b01 + a22 * b02;
dest[0][3] = a03 * b00 + a13 * b01 + a23 * b02;
dest[1][0] = a00 * b10 + a10 * b11 + a20 * b12;
dest[1][1] = a01 * b10 + a11 * b11 + a21 * b12;
dest[1][2] = a02 * b10 + a12 * b11 + a22 * b12;
dest[1][3] = a03 * b10 + a13 * b11 + a23 * b12;
dest[2][0] = a00 * b20 + a10 * b21 + a20 * b22;
dest[2][1] = a01 * b20 + a11 * b21 + a21 * b22;
dest[2][2] = a02 * b20 + a12 * b21 + a22 * b22;
dest[2][3] = a03 * b20 + a13 * b21 + a23 * b22;
dest[3][0] = a30;
dest[3][1] = a31;
dest[3][2] = a32;
dest[3][3] = a33;
#endif
}
/*! /*!
* @brief inverse orthonormal rotation + translation matrix (ridig-body) * @brief inverse orthonormal rotation + translation matrix (ridig-body)
* *

View File

@@ -16,15 +16,14 @@
CGLM_INLINE void glm_scale_to(mat4 m, vec3 v, mat4 dest); CGLM_INLINE void glm_scale_to(mat4 m, vec3 v, mat4 dest);
CGLM_INLINE void glm_scale_make(mat4 m, vec3 v); CGLM_INLINE void glm_scale_make(mat4 m, vec3 v);
CGLM_INLINE void glm_scale(mat4 m, vec3 v); CGLM_INLINE void glm_scale(mat4 m, vec3 v);
CGLM_INLINE void glm_scale1(mat4 m, float s);
CGLM_INLINE void glm_scale_uni(mat4 m, float s); CGLM_INLINE void glm_scale_uni(mat4 m, float s);
CGLM_INLINE void glm_rotate_x(mat4 m, float angle, mat4 dest); CGLM_INLINE void glm_rotate_x(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_y(mat4 m, float angle, mat4 dest); CGLM_INLINE void glm_rotate_y(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_z(mat4 m, float angle, mat4 dest); CGLM_INLINE void glm_rotate_z(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc);
CGLM_INLINE void glm_rotate_make(mat4 m, float angle, vec3 axis); CGLM_INLINE void glm_rotate_make(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_ndc(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotate(mat4 m, float angle, vec3 axis); CGLM_INLINE void glm_rotate(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_decompose_scalev(mat4 m, vec3 s); CGLM_INLINE void glm_decompose_scalev(mat4 m, vec3 s);
CGLM_INLINE bool glm_uniscaled(mat4 m); CGLM_INLINE bool glm_uniscaled(mat4 m);
CGLM_INLINE void glm_decompose_rs(mat4 m, mat4 r, vec3 s); CGLM_INLINE void glm_decompose_rs(mat4 m, mat4 r, vec3 s);
@@ -38,6 +37,11 @@
#include "vec4.h" #include "vec4.h"
#include "affine-mat.h" #include "affine-mat.h"
#include "util.h" #include "util.h"
#include "mat4.h"
CGLM_INLINE
void
glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest);
/*! /*!
* @brief translate existing transform matrix by v vector * @brief translate existing transform matrix by v vector
@@ -237,16 +241,6 @@ glm_scale(mat4 m, vec3 v) {
glm_scale_to(m, v, m); glm_scale_to(m, v, m);
} }
/*!
* @brief DEPRECATED! Use glm_scale_uni
*/
CGLM_INLINE
void
glm_scale1(mat4 m, float s) {
vec3 v = { s, s, s };
glm_scale_to(m, v, m);
}
/*! /*!
* @brief applies uniform scale to existing transform matrix v = [s, s, s] * @brief applies uniform scale to existing transform matrix v = [s, s, s]
* and stores result in same matrix * and stores result in same matrix
@@ -272,19 +266,18 @@ glm_scale_uni(mat4 m, float s) {
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_x(mat4 m, float angle, mat4 dest) { glm_rotate_x(mat4 m, float angle, mat4 dest) {
float cosVal;
float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
cosVal = cosf(angle); c = cosf(angle);
sinVal = sinf(angle); s = sinf(angle);
t[1][1] = cosVal; t[1][1] = c;
t[1][2] = sinVal; t[1][2] = s;
t[2][1] = -sinVal; t[2][1] = -s;
t[2][2] = cosVal; t[2][2] = c;
glm_mat4_mul(m, t, dest); glm_mul_rot(m, t, dest);
} }
/*! /*!
@@ -298,19 +291,18 @@ glm_rotate_x(mat4 m, float angle, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_y(mat4 m, float angle, mat4 dest) { glm_rotate_y(mat4 m, float angle, mat4 dest) {
float cosVal;
float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
cosVal = cosf(angle); c = cosf(angle);
sinVal = sinf(angle); s = sinf(angle);
t[0][0] = cosVal; t[0][0] = c;
t[0][2] = -sinVal; t[0][2] = -s;
t[2][0] = sinVal; t[2][0] = s;
t[2][2] = cosVal; t[2][2] = c;
glm_mat4_mul(m, t, dest); glm_mul_rot(m, t, dest);
} }
/*! /*!
@@ -324,61 +316,18 @@ glm_rotate_y(mat4 m, float angle, mat4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_z(mat4 m, float angle, mat4 dest) { glm_rotate_z(mat4 m, float angle, mat4 dest) {
float cosVal;
float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
cosVal = cosf(angle);
sinVal = sinf(angle);
t[0][0] = cosVal;
t[0][1] = sinVal;
t[1][0] = -sinVal;
t[1][1] = cosVal;
glm_mat4_mul(m, t, dest);
}
/*!
* @brief creates NEW rotation matrix by angle and axis
*
* this name may change in the future. axis must be is normalized
*
* @param[out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis_ndc normalized axis
*/
CGLM_INLINE
void
glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
/* https://www.opengl.org/sdk/docs/man2/xhtml/glRotate.xml */
vec3 v, vs;
float c;
c = cosf(angle); c = cosf(angle);
s = sinf(angle);
glm_vec_scale(axis_ndc, 1.0f - c, v); t[0][0] = c;
glm_vec_scale(axis_ndc, sinf(angle), vs); t[0][1] = s;
t[1][0] = -s;
t[1][1] = c;
glm_vec_scale(axis_ndc, v[0], m[0]); glm_mul_rot(m, t, dest);
glm_vec_scale(axis_ndc, v[1], m[1]);
glm_vec_scale(axis_ndc, v[2], m[2]);
m[0][0] += c;
m[0][1] += vs[2];
m[0][2] -= vs[1];
m[1][0] -= vs[2];
m[1][1] += c;
m[1][2] += vs[0];
m[2][0] += vs[1];
m[2][1] -= vs[0];
m[2][2] += c;
m[0][3] = m[1][3] = m[2][3] = m[3][0] = m[3][1] = m[3][2] = 0.0f;
m[3][3] = 1.0f;
} }
/*! /*!
@@ -393,53 +342,29 @@ glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_make(mat4 m, float angle, vec3 axis) { glm_rotate_make(mat4 m, float angle, vec3 axis) {
vec3 axis_ndc; vec3 axisn, v, vs;
float c;
glm_vec_normalize_to(axis, axis_ndc); c = cosf(angle);
glm_rotate_ndc_make(m, angle, axis_ndc);
glm_vec_normalize_to(axis, axisn);
glm_vec_scale(axisn, 1.0f - c, v);
glm_vec_scale(axisn, sinf(angle), vs);
glm_vec_scale(axisn, v[0], m[0]);
glm_vec_scale(axisn, v[1], m[1]);
glm_vec_scale(axisn, v[2], m[2]);
m[0][0] += c; m[1][0] -= vs[2]; m[2][0] += vs[1];
m[0][1] += vs[2]; m[1][1] += c; m[2][1] -= vs[0];
m[0][2] -= vs[1]; m[1][2] += vs[0]; m[2][2] += c;
m[0][3] = m[1][3] = m[2][3] = m[3][0] = m[3][1] = m[3][2] = 0.0f;
m[3][3] = 1.0f;
} }
/*! /*!
* @brief rotate existing transform matrix around Z axis by angle and axis * @brief rotate existing transform matrix around given axis by angle
*
* this name may change in the future, axis must be normalized.
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis_ndc normalized axis
*/
CGLM_INLINE
void
glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
mat4 rot, tmp;
glm_rotate_ndc_make(rot, angle, axis_ndc);
glm_vec4_scale(m[0], rot[0][0], tmp[1]);
glm_vec4_scale(m[1], rot[0][1], tmp[0]);
glm_vec4_add(tmp[1], tmp[0], tmp[1]);
glm_vec4_scale(m[2], rot[0][2], tmp[0]);
glm_vec4_add(tmp[1], tmp[0], tmp[1]);
glm_vec4_scale(m[0], rot[1][0], tmp[2]);
glm_vec4_scale(m[1], rot[1][1], tmp[0]);
glm_vec4_add(tmp[2], tmp[0], tmp[2]);
glm_vec4_scale(m[2], rot[1][2], tmp[0]);
glm_vec4_add(tmp[2], tmp[0], tmp[2]);
glm_vec4_scale(m[0], rot[2][0], tmp[3]);
glm_vec4_scale(m[1], rot[2][1], tmp[0]);
glm_vec4_add(tmp[3], tmp[0], tmp[3]);
glm_vec4_scale(m[2], rot[2][2], tmp[0]);
glm_vec4_add(tmp[3], tmp[0], tmp[3]);
glm_vec4_copy(tmp[1], m[0]);
glm_vec4_copy(tmp[2], m[1]);
glm_vec4_copy(tmp[3], m[2]);
}
/*!
* @brief rotate existing transform matrix around Z axis by angle and axis
* *
* @param[in, out] m affine transfrom * @param[in, out] m affine transfrom
* @param[in] angle angle (radians) * @param[in] angle angle (radians)
@@ -448,10 +373,56 @@ glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
CGLM_INLINE CGLM_INLINE
void void
glm_rotate(mat4 m, float angle, vec3 axis) { glm_rotate(mat4 m, float angle, vec3 axis) {
vec3 axis_ndc; mat4 rot;
glm_rotate_make(rot, angle, axis);
glm_mul_rot(m, rot, m);
}
glm_vec_normalize_to(axis, axis_ndc); /*!
glm_rotate_ndc(m, angle, axis_ndc); * @brief rotate existing transform
* around given axis by angle at given pivot point (rotation center)
*
* @param[in, out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) {
vec3 pivotInv;
glm_vec_inv_to(pivot, pivotInv);
glm_translate(m, pivot);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
}
/*!
* @brief 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.
*
* @param[out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) {
vec3 pivotInv;
glm_vec_inv_to(pivot, pivotInv);
glm_mat4_identity(m);
glm_vec_copy(pivot, m[3]);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
} }
/*! /*!
@@ -469,7 +440,7 @@ glm_decompose_scalev(mat4 m, vec3 s) {
} }
/*! /*!
* @brief returns true if matrix is uniform scaled. This is helpful for * @brief returns true if matrix is uniform scaled. This is helpful for
* creating normal matrix. * creating normal matrix.
* *
* @param[in] m m * @param[in] m m

View File

@@ -13,6 +13,10 @@ extern "C" {
#include "../cglm.h" #include "../cglm.h"
CGLM_EXPORT
void
glmc_translate_make(mat4 m, vec3 v);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_translate_to(mat4 m, vec3 v, mat4 dest); glmc_translate_to(mat4 m, vec3 v, mat4 dest);
@@ -33,6 +37,10 @@ CGLM_EXPORT
void void
glmc_translate_z(mat4 m, float to); glmc_translate_z(mat4 m, float to);
CGLM_EXPORT
void
glmc_scale_make(mat4 m, vec3 v);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_scale_to(mat4 m, vec3 v, mat4 dest); glmc_scale_to(mat4 m, vec3 v, mat4 dest);
@@ -43,7 +51,7 @@ glmc_scale(mat4 m, vec3 v);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_scale1(mat4 m, float s); glmc_scale_uni(mat4 m, float s);
CGLM_EXPORT CGLM_EXPORT
void void
@@ -57,26 +65,30 @@ CGLM_EXPORT
void void
glmc_rotate_z(mat4 m, float rad, mat4 dest); glmc_rotate_z(mat4 m, float rad, mat4 dest);
CGLM_EXPORT
void
glmc_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_rotate_make(mat4 m, float angle, vec3 axis); glmc_rotate_make(mat4 m, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_rotate_ndc(mat4 m, float angle, vec3 axis_ndc);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_rotate(mat4 m, float angle, vec3 axis); glmc_rotate(mat4 m, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_decompose_scalev(mat4 m, vec3 s); glmc_decompose_scalev(mat4 m, vec3 s);
CGLM_EXPORT
bool
glmc_uniscaled(mat4 m);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_decompose_rs(mat4 m, mat4 r, vec3 s); glmc_decompose_rs(mat4 m, mat4 r, vec3 s);

View File

@@ -137,6 +137,14 @@ CGLM_EXPORT
void void
glmc_quat_rotate(mat4 m, versor q, mat4 dest); glmc_quat_rotate(mat4 m, versor q, mat4 dest);
CGLM_EXPORT
void
glmc_quat_rotate_at(mat4 model, versor q, vec3 pivot);
CGLM_EXPORT
void
glmc_quat_rotate_atm(mat4 m, versor q, vec3 pivot);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -24,6 +24,14 @@ CGLM_EXPORT
void void
glmc_vec_copy(vec3 a, vec3 dest); glmc_vec_copy(vec3 a, vec3 dest);
CGLM_EXPORT
void
glmc_vec_zero(vec3 v);
CGLM_EXPORT
void
glmc_vec_one(vec3 v);
CGLM_EXPORT CGLM_EXPORT
float float
glmc_vec_dot(vec3 a, vec3 b); glmc_vec_dot(vec3 a, vec3 b);
@@ -54,7 +62,19 @@ glmc_vec_add(vec3 v1, vec3 v2, vec3 dest);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec_sub(vec3 v1, vec3 v2, vec3 dest); glmc_vec_adds(vec3 v, float s, vec3 dest);
CGLM_EXPORT
void
glmc_vec_sub(vec3 a, vec3 b, vec3 dest);
CGLM_EXPORT
void
glmc_vec_subs(vec3 v, float s, vec3 dest);
CGLM_EXPORT
void
glmc_vec_mul(vec3 a, vec3 b, vec3 d);
CGLM_EXPORT CGLM_EXPORT
void void
@@ -64,6 +84,30 @@ CGLM_EXPORT
void void
glmc_vec_scale_as(vec3 v, float s, vec3 dest); glmc_vec_scale_as(vec3 v, float s, vec3 dest);
CGLM_EXPORT
void
glmc_vec_div(vec3 a, vec3 b, vec3 dest);
CGLM_EXPORT
void
glmc_vec_divs(vec3 a, float s, vec3 dest);
CGLM_EXPORT
void
glmc_vec_addadd(vec3 a, vec3 b, vec3 dest);
CGLM_EXPORT
void
glmc_vec_subadd(vec3 a, vec3 b, vec3 dest);
CGLM_EXPORT
void
glmc_vec_muladd(vec3 a, vec3 b, vec3 dest);
CGLM_EXPORT
void
glmc_vec_muladds(vec3 a, float s, vec3 dest);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec_flipsign(vec3 v); glmc_vec_flipsign(vec3 v);

View File

@@ -21,6 +21,14 @@ CGLM_EXPORT
void void
glmc_vec4(vec3 v3, float last, vec4 dest); glmc_vec4(vec3 v3, float last, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_zero(vec4 v);
CGLM_EXPORT
void
glmc_vec4_one(vec4 v);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_copy3(vec4 a, vec3 dest); glmc_vec4_copy3(vec4 a, vec3 dest);
@@ -51,11 +59,23 @@ glmc_vec4_normalize(vec4 v);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_add(vec4 v1, vec4 v2, vec4 dest); glmc_vec4_add(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_sub(vec4 v1, vec4 v2, vec4 dest); glmc_vec4_adds(vec4 v, float s, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_sub(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_subs(vec4 v, float s, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_mul(vec4 a, vec4 b, vec4 d);
CGLM_EXPORT CGLM_EXPORT
void void
@@ -65,6 +85,30 @@ CGLM_EXPORT
void void
glmc_vec4_scale_as(vec3 v, float s, vec3 dest); glmc_vec4_scale_as(vec3 v, float s, vec3 dest);
CGLM_EXPORT
void
glmc_vec4_div(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_divs(vec4 v, float s, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_addadd(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_subadd(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_muladd(vec4 a, vec4 b, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_muladds(vec4 a, float s, vec4 dest);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_flipsign(vec4 v); glmc_vec4_flipsign(vec4 v);

View File

@@ -55,18 +55,27 @@
#include "vec4.h" #include "vec4.h"
#include "mat4.h" #include "mat4.h"
#include "mat3.h" #include "mat3.h"
#include "affine-mat.h"
#ifdef CGLM_SSE_FP #ifdef CGLM_SSE_FP
# include "simd/sse2/quat.h" # include "simd/sse2/quat.h"
#endif #endif
CGLM_INLINE
void
glm_mat4_identity(mat4 mat);
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest); glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
CGLM_INLINE CGLM_INLINE
void void
glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest); glm_mul_rot(mat4 m1, mat4 m2, mat4 dest);
CGLM_INLINE
void
glm_translate(mat4 m, vec3 v);
/* /*
* IMPORTANT: * IMPORTANT:
@@ -737,7 +746,51 @@ void
glm_quat_rotate(mat4 m, versor q, mat4 dest) { glm_quat_rotate(mat4 m, versor q, mat4 dest) {
mat4 rot; mat4 rot;
glm_quat_mat4(q, rot); glm_quat_mat4(q, rot);
glm_mat4_mul(m, rot, dest); glm_mul_rot(m, rot, dest);
}
/*!
* @brief rotate existing transform matrix using quaternion at pivot point
*
* @param[in, out] m existing transform matrix
* @param[in] q quaternion
* @param[out] pivot pivot
*/
CGLM_INLINE
void
glm_quat_rotate_at(mat4 m, versor q, vec3 pivot) {
vec3 pivotInv;
glm_vec_inv_to(pivot, pivotInv);
glm_translate(m, pivot);
glm_quat_rotate(m, q, m);
glm_translate(m, pivotInv);
}
/*!
* @brief 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.
*
* @param[out] m existing transform matrix
* @param[in] q quaternion
* @param[in] pivot pivot
*/
CGLM_INLINE
void
glm_quat_rotate_atm(mat4 m, versor q, vec3 pivot) {
vec3 pivotInv;
glm_vec_inv_to(pivot, pivotInv);
glm_mat4_identity(m);
glm_vec_copy(pivot, m[3]);
glm_quat_rotate(m, q, m);
glm_translate(m, pivotInv);
} }
#endif /* cglm_quat_h */ #endif /* cglm_quat_h */

View File

@@ -40,6 +40,31 @@ glm_simd_dot(__m128 a, __m128 b) {
return _mm_add_ps(x0, _mm_shuffle1_ps(x0, 0, 1, 0, 1)); return _mm_add_ps(x0, _mm_shuffle1_ps(x0, 0, 1, 0, 1));
} }
CGLM_INLINE
__m128
glm_simd_norm(__m128 a) {
return _mm_sqrt_ps(glm_simd_dot(a, a));
}
static inline
__m128
glm_simd_load_v3(vec3 v) {
__m128i xy;
__m128 z;
xy = _mm_loadl_epi64((const __m128i *)v);
z = _mm_load_ss(&v[2]);
return _mm_movelh_ps(_mm_castsi128_ps(xy), z);
}
static inline
void
glm_simd_store_v3(__m128 vx, vec3 v) {
_mm_storel_pi((__m64 *)&v[0], vx);
_mm_store_ss(&v[2], _mm_shuffle1_ps(vx, 2, 2, 2, 2));
}
#endif #endif
/* x86, x64 */ /* x86, x64 */

View File

@@ -49,6 +49,38 @@ glm_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
_mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3)))); _mm_mul_ps(_mm_shuffle1_ps1(r, 3), l3))));
} }
CGLM_INLINE
void
glm_mul_rot_sse2(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
__m128 l0, l1, l2, l3, r;
l0 = _mm_load_ps(m1[0]);
l1 = _mm_load_ps(m1[1]);
l2 = _mm_load_ps(m1[2]);
l3 = _mm_load_ps(m1[3]);
r = _mm_load_ps(m2[0]);
_mm_store_ps(dest[0],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
r = _mm_load_ps(m2[1]);
_mm_store_ps(dest[1],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
r = _mm_load_ps(m2[2]);
_mm_store_ps(dest[2],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(_mm_shuffle1_ps1(r, 0), l0),
_mm_mul_ps(_mm_shuffle1_ps1(r, 1), l1)),
_mm_mul_ps(_mm_shuffle1_ps1(r, 2), l2)));
_mm_store_ps(dest[3], l3);
}
CGLM_INLINE CGLM_INLINE
void void
glm_inv_tr_sse2(mat4 mat) { glm_inv_tr_sse2(mat4 mat) {

View File

@@ -15,12 +15,12 @@
#endif #endif
typedef float vec2[2]; typedef float vec2[2];
typedef float vec3[3]; typedef CGLM_ALIGN(8) float vec3[3];
typedef int ivec3[3]; typedef int ivec3[3];
typedef CGLM_ALIGN(16) float vec4[4]; typedef CGLM_ALIGN(16) float vec4[4];
typedef vec3 mat3[3]; typedef vec3 mat3[3];
typedef vec4 mat4[4]; typedef CGLM_ALIGN(16) vec4 mat4[4];
typedef vec4 versor; typedef vec4 versor;

View File

@@ -32,7 +32,7 @@
#include <float.h> #include <float.h>
/*! /*!
* @brief multiplies individual items, just for convenient like SIMD * @brief DEPRECATED! use glm_vec_mul
* *
* @param[in] a vec1 * @param[in] a vec1
* @param[in] b vec2 * @param[in] b vec2

View File

@@ -28,10 +28,18 @@
CGLM_INLINE void glm_vec_cross(vec3 a, vec3 b, vec3 d); CGLM_INLINE void glm_vec_cross(vec3 a, vec3 b, vec3 d);
CGLM_INLINE float glm_vec_norm2(vec3 v); CGLM_INLINE float glm_vec_norm2(vec3 v);
CGLM_INLINE float glm_vec_norm(vec3 vec); CGLM_INLINE float glm_vec_norm(vec3 vec);
CGLM_INLINE void glm_vec_add(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_add(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_sub(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_adds(vec3 a, float s, vec3 dest);
CGLM_INLINE void glm_vec_sub(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_subs(vec3 a, float s, vec3 dest);
CGLM_INLINE void glm_vec_mul(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_scale(vec3 v, float s, vec3 dest); CGLM_INLINE void glm_vec_scale(vec3 v, float s, vec3 dest);
CGLM_INLINE void glm_vec_scale_as(vec3 v, float s, vec3 dest); CGLM_INLINE void glm_vec_scale_as(vec3 v, float s, vec3 dest);
CGLM_INLINE void glm_vec_div(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_divs(vec3 a, float s, vec3 dest);
CGLM_INLINE void glm_vec_addadd(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_subadd(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_muladd(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_flipsign(vec3 v); CGLM_INLINE void glm_vec_flipsign(vec3 v);
CGLM_INLINE void glm_vec_inv(vec3 v); CGLM_INLINE void glm_vec_inv(vec3 v);
CGLM_INLINE void glm_vec_inv_to(vec3 v, vec3 dest); CGLM_INLINE void glm_vec_inv_to(vec3 v, vec3 dest);
@@ -59,6 +67,7 @@
#define cglm_vec3_h #define cglm_vec3_h
#include "common.h" #include "common.h"
#include "vec4.h"
#include "vec3-ext.h" #include "vec3-ext.h"
#include "util.h" #include "util.h"
@@ -103,6 +112,32 @@ glm_vec_copy(vec3 a, vec3 dest) {
dest[2] = a[2]; dest[2] = a[2];
} }
/*!
* @brief make vector zero
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec_zero(vec3 v) {
v[0] = 0.0f;
v[1] = 0.0f;
v[2] = 0.0f;
}
/*!
* @brief make vector one
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec_one(vec3 v) {
v[0] = 1.0f;
v[1] = 1.0f;
v[2] = 1.0f;
}
/*! /*!
* @brief vec3 dot product * @brief vec3 dot product
* *
@@ -164,33 +199,78 @@ glm_vec_norm(vec3 vec) {
} }
/*! /*!
* @brief add v2 vector to v1 vector store result in dest * @brief add a vector to b vector store result in dest
* *
* @param[in] v1 vector1 * @param[in] a vector1
* @param[in] v2 vector2 * @param[in] b vector2
* @param[out] dest destination vector * @param[out] dest destination vector
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_vec_add(vec3 v1, vec3 v2, vec3 dest) { glm_vec_add(vec3 a, vec3 b, vec3 dest) {
dest[0] = v1[0] + v2[0]; dest[0] = a[0] + b[0];
dest[1] = v1[1] + v2[1]; dest[1] = a[1] + b[1];
dest[2] = v1[2] + v2[2]; dest[2] = a[2] + b[2];
}
/*!
* @brief add scalar to v vector store result in dest (d = v + s)
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination vector
*/
CGLM_INLINE
void
glm_vec_adds(vec3 v, float s, vec3 dest) {
dest[0] = v[0] + s;
dest[1] = v[1] + s;
dest[2] = v[2] + s;
} }
/*! /*!
* @brief subtract v2 vector from v1 vector store result in dest * @brief subtract v2 vector from v1 vector store result in dest
* *
* @param[in] v1 vector1 * @param[in] a vector1
* @param[in] v2 vector2 * @param[in] b vector2
* @param[out] dest destination vector * @param[out] dest destination vector
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_vec_sub(vec3 v1, vec3 v2, vec3 dest) { glm_vec_sub(vec3 a, vec3 b, vec3 dest) {
dest[0] = v1[0] - v2[0]; dest[0] = a[0] - b[0];
dest[1] = v1[1] - v2[1]; dest[1] = a[1] - b[1];
dest[2] = v1[2] - v2[2]; dest[2] = a[2] - b[2];
}
/*!
* @brief subtract scalar from v vector store result in dest (d = v - s)
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination vector
*/
CGLM_INLINE
void
glm_vec_subs(vec3 v, float s, vec3 dest) {
dest[0] = v[0] - s;
dest[1] = v[1] - s;
dest[2] = v[2] - s;
}
/*!
* @brief multiply two vector (component-wise multiplication)
*
* @param a v1
* @param b v2
* @param d v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2])
*/
CGLM_INLINE
void
glm_vec_mul(vec3 a, vec3 b, vec3 d) {
d[0] = a[0] * b[0];
d[1] = a[1] * b[1];
d[2] = a[2] * b[2];
} }
/*! /*!
@@ -221,14 +301,112 @@ glm_vec_scale_as(vec3 v, float s, vec3 dest) {
float norm; float norm;
norm = glm_vec_norm(v); norm = glm_vec_norm(v);
if (norm == 0) { if (norm == 0.0f) {
glm_vec_copy(v, dest); glm_vec_zero(dest);
return; return;
} }
glm_vec_scale(v, s / norm, dest); glm_vec_scale(v, s / norm, dest);
} }
/*!
* @brief div vector with another component-wise division: d = a / b
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest result = (a[0]/b[0], a[1]/b[1], a[2]/b[2])
*/
CGLM_INLINE
void
glm_vec_div(vec3 a, vec3 b, vec3 dest) {
dest[0] = a[0] / b[0];
dest[1] = a[1] / b[1];
dest[2] = a[2] / b[2];
}
/*!
* @brief div vector with scalar: d = v / s
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest result = (a[0]/s, a[1]/s, a[2]/s)
*/
CGLM_INLINE
void
glm_vec_divs(vec3 v, float s, vec3 dest) {
dest[0] = v[0] / s;
dest[1] = v[1] / s;
dest[2] = v[2] / s;
}
/*!
* @brief add two vectors and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a + b)
*/
CGLM_INLINE
void
glm_vec_addadd(vec3 a, vec3 b, vec3 dest) {
dest[0] += a[0] + b[0];
dest[1] += a[1] + b[1];
dest[2] += a[2] + b[2];
}
/*!
* @brief sub two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a + b)
*/
CGLM_INLINE
void
glm_vec_subadd(vec3 a, vec3 b, vec3 dest) {
dest[0] += a[0] - b[0];
dest[1] += a[1] - b[1];
dest[2] += a[2] - b[2];
}
/*!
* @brief mul two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a * b)
*/
CGLM_INLINE
void
glm_vec_muladd(vec3 a, vec3 b, vec3 dest) {
dest[0] += a[0] * b[0];
dest[1] += a[1] * b[1];
dest[2] += a[2] * b[2];
}
/*!
* @brief mul vector with scalar and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] s scalar
* @param[out] dest dest += (a * b)
*/
CGLM_INLINE
void
glm_vec_muladds(vec3 a, float s, vec3 dest) {
dest[0] += a[0] * s;
dest[1] += a[1] * s;
dest[2] += a[2] * s;
}
/*! /*!
* @brief flip sign of all vec3 members * @brief flip sign of all vec3 members
* *
@@ -314,7 +492,7 @@ glm_vec_normalize_to(vec3 vec, vec3 dest) {
norm = glm_vec_norm(vec); norm = glm_vec_norm(vec);
if (norm == 0.0f) { if (norm == 0.0f) {
dest[0] = dest[1] = dest[2] = 0.0f; glm_vec_zero(dest);
return; return;
} }
@@ -374,6 +552,12 @@ glm_vec_rotate(vec3 v, float angle, vec3 axis) {
/*! /*!
* @brief apply rotation matrix to vector * @brief apply rotation matrix to vector
* *
* matrix format should be (no perspective):
* a b c x
* e f g y
* i j k z
* 0 0 0 w
*
* @param[in] m affine matrix or rot matrix * @param[in] m affine matrix or rot matrix
* @param[in] v vector * @param[in] v vector
* @param[out] dest rotated vector * @param[out] dest rotated vector
@@ -381,17 +565,44 @@ glm_vec_rotate(vec3 v, float angle, vec3 axis) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest) { glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest) {
vec3 res, x, y, z; vec4 x, y, z, res;
glm_vec_normalize_to(m[0], x); glm_vec4_normalize_to(m[0], x);
glm_vec_normalize_to(m[1], y); glm_vec4_normalize_to(m[1], y);
glm_vec_normalize_to(m[2], z); glm_vec4_normalize_to(m[2], z);
res[0] = x[0] * v[0] + y[0] * v[1] + z[0] * v[2]; glm_vec4_scale(x, v[0], res);
res[1] = x[1] * v[0] + y[1] * v[1] + z[1] * v[2]; glm_vec4_muladds(y, v[1], res);
res[2] = x[2] * v[0] + y[2] * v[1] + z[2] * v[2]; glm_vec4_muladds(z, v[2], res);
glm_vec_copy(res, dest); glm_vec3(res, dest);
}
/*!
* @brief apply rotation matrix to vector
*
* @param[in] m affine matrix or rot matrix
* @param[in] v vector
* @param[out] dest rotated vector
*/
CGLM_INLINE
void
glm_vec_rotate_m3(mat3 m, vec3 v, vec3 dest) {
vec4 res, x, y, z;
glm_vec4(m[0], 0.0f, x);
glm_vec4(m[1], 0.0f, y);
glm_vec4(m[2], 0.0f, z);
glm_vec4_normalize(x);
glm_vec4_normalize(y);
glm_vec4_normalize(z);
glm_vec4_scale(x, v[0], res);
glm_vec4_muladds(y, v[1], res);
glm_vec4_muladds(z, v[2], res);
glm_vec3(res, dest);
} }
/*! /*!

View File

@@ -32,7 +32,7 @@
#include <float.h> #include <float.h>
/*! /*!
* @brief multiplies individual items, just for convenient like SIMD * @brief DEPRECATED! use glm_vec4_mul
* *
* @param a v1 * @param a v1
* @param b v2 * @param b v2

View File

@@ -28,10 +28,18 @@
CGLM_INLINE float glm_vec4_dot(vec4 a, vec4 b); CGLM_INLINE float glm_vec4_dot(vec4 a, vec4 b);
CGLM_INLINE float glm_vec4_norm2(vec4 v); CGLM_INLINE float glm_vec4_norm2(vec4 v);
CGLM_INLINE float glm_vec4_norm(vec4 vec); CGLM_INLINE float glm_vec4_norm(vec4 vec);
CGLM_INLINE void glm_vec4_add(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_add(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_adds(vec4 v, float s, vec4 dest);
CGLM_INLINE void glm_vec4_sub(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_subs(vec4 v, float s, vec4 dest);
CGLM_INLINE void glm_vec4_mul(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_scale(vec4 v, float s, vec4 dest); CGLM_INLINE void glm_vec4_scale(vec4 v, float s, vec4 dest);
CGLM_INLINE void glm_vec4_scale_as(vec4 v, float s, vec4 dest); CGLM_INLINE void glm_vec4_scale_as(vec4 v, float s, vec4 dest);
CGLM_INLINE void glm_vec4_div(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_divs(vec4 v, float s, vec4 dest);
CGLM_INLINE void glm_vec4_addadd(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_subadd(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_muladd(vec4 a, vec4 b, vec4 dest);
CGLM_INLINE void glm_vec4_flipsign(vec4 v); CGLM_INLINE void glm_vec4_flipsign(vec4 v);
CGLM_INLINE void glm_vec4_inv(vec4 v); CGLM_INLINE void glm_vec4_inv(vec4 v);
CGLM_INLINE void glm_vec4_inv_to(vec4 v, vec4 dest); CGLM_INLINE void glm_vec4_inv_to(vec4 v, vec4 dest);
@@ -41,6 +49,7 @@
CGLM_INLINE void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest);
CGLM_INLINE void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest);
CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal); CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal);
CGLM_INLINE void glm_vec4_lerp(vec4 from, vec4 to, float t, vec4 dest)
*/ */
#ifndef cglm_vec4_h #ifndef cglm_vec4_h
@@ -111,6 +120,42 @@ glm_vec4_copy(vec4 v, vec4 dest) {
#endif #endif
} }
/*!
* @brief make vector zero
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec4_zero(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(v, _mm_setzero_ps());
#else
v[0] = 0.0f;
v[1] = 0.0f;
v[2] = 0.0f;
v[3] = 0.0f;
#endif
}
/*!
* @brief make vector one
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec4_one(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(v, _mm_set1_ps(1.0f));
#else
v[0] = 1.0f;
v[1] = 1.0f;
v[2] = 1.0f;
v[3] = 1.0f;
#endif
}
/*! /*!
* @brief vec4 dot product * @brief vec4 dot product
* *
@@ -146,7 +191,15 @@ glm_vec4_dot(vec4 a, vec4 b) {
CGLM_INLINE CGLM_INLINE
float float
glm_vec4_norm2(vec4 v) { glm_vec4_norm2(vec4 v) {
return glm_vec4_dot(v, v); #if defined( __SSE__ ) || defined( __SSE2__ )
__m128 x0;
x0 = _mm_load_ps(v);
x0 = _mm_mul_ps(x0, x0);
x0 = _mm_add_ps(x0, _mm_shuffle1_ps(x0, 1, 0, 3, 2));
return _mm_cvtss_f32(_mm_add_ss(x0, _mm_shuffle1_ps(x0, 0, 1, 0, 1)));
#else
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
#endif
} }
/*! /*!
@@ -159,50 +212,112 @@ glm_vec4_norm2(vec4 v) {
CGLM_INLINE CGLM_INLINE
float float
glm_vec4_norm(vec4 vec) { glm_vec4_norm(vec4 vec) {
#if defined( __SSE__ ) || defined( __SSE2__ )
__m128 x0;
x0 = _mm_load_ps(vec);
return _mm_cvtss_f32(_mm_sqrt_ss(glm_simd_dot(x0, x0)));
#else
return sqrtf(glm_vec4_norm2(vec)); return sqrtf(glm_vec4_norm2(vec));
#endif
} }
/*! /*!
* @brief add v2 vector to v1 vector store result in dest * @brief add v2 vector to v1 vector store result in dest
* *
* @param[in] v1 vector1 * @param[in] a vector1
* @param[in] v2 vector2 * @param[in] b vector2
* @param[out] dest destination vector * @param[out] dest destination vector
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_add(vec4 v1, vec4 v2, vec4 dest) { glm_vec4_add(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_store_ps(dest, _mm_add_ps(_mm_load_ps(a), _mm_load_ps(b)));
_mm_add_ps(_mm_load_ps(v1),
_mm_load_ps(v2)));
#else #else
dest[0] = v1[0] + v2[0]; dest[0] = a[0] + b[0];
dest[1] = v1[1] + v2[1]; dest[1] = a[1] + b[1];
dest[2] = v1[2] + v2[2]; dest[2] = a[2] + b[2];
dest[3] = v1[3] + v2[3]; dest[3] = a[3] + b[3];
#endif #endif
} }
/*! /*!
* @brief subtract v2 vector from v1 vector store result in dest * @brief add scalar to v vector store result in dest (d = v + vec(s))
* *
* @param[in] v1 vector1 * @param[in] v vector
* @param[in] v2 vector2 * @param[in] s scalar
* @param[out] dest destination vector * @param[out] dest destination vector
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest) { glm_vec4_adds(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_store_ps(dest, _mm_add_ps(_mm_load_ps(v), _mm_set1_ps(s)));
_mm_sub_ps(_mm_load_ps(v1),
_mm_load_ps(v2)));
#else #else
dest[0] = v1[0] - v2[0]; dest[0] = v[0] + s;
dest[1] = v1[1] - v2[1]; dest[1] = v[1] + s;
dest[2] = v1[2] - v2[2]; dest[2] = v[2] + s;
dest[3] = v1[3] - v2[3]; dest[3] = v[3] + s;
#endif
}
/*!
* @brief subtract b vector from a vector store result in dest (d = v1 - v2)
*
* @param[in] a vector1
* @param[in] b vector2
* @param[out] dest destination vector
*/
CGLM_INLINE
void
glm_vec4_sub(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_sub_ps(_mm_load_ps(a), _mm_load_ps(b)));
#else
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
dest[3] = a[3] - b[3];
#endif
}
/*!
* @brief subtract scalar from v vector store result in dest (d = v - vec(s))
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination vector
*/
CGLM_INLINE
void
glm_vec4_subs(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_sub_ps(_mm_load_ps(v), _mm_set1_ps(s)));
#else
dest[0] = v[0] - s;
dest[1] = v[1] - s;
dest[2] = v[2] - s;
dest[3] = v[3] - s;
#endif
}
/*!
* @brief multiply two vector (component-wise multiplication)
*
* @param a v1
* @param b v2
* @param d v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3])
*/
CGLM_INLINE
void
glm_vec4_mul(vec4 a, vec4 b, vec4 d) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(d, _mm_mul_ps(_mm_load_ps(a), _mm_load_ps(b)));
#else
d[0] = a[0] * b[0];
d[1] = a[1] * b[1];
d[2] = a[2] * b[2];
d[3] = a[3] * b[3];
#endif #endif
} }
@@ -217,9 +332,7 @@ CGLM_INLINE
void void
glm_vec4_scale(vec4 v, float s, vec4 dest) { glm_vec4_scale(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_store_ps(dest, _mm_mul_ps(_mm_load_ps(v), _mm_set1_ps(s)));
_mm_mul_ps(_mm_load_ps(v),
_mm_set1_ps(s)));
#else #else
dest[0] = v[0] * s; dest[0] = v[0] * s;
dest[1] = v[1] * s; dest[1] = v[1] * s;
@@ -241,14 +354,148 @@ glm_vec4_scale_as(vec4 v, float s, vec4 dest) {
float norm; float norm;
norm = glm_vec4_norm(v); norm = glm_vec4_norm(v);
if (norm == 0) { if (norm == 0.0f) {
glm_vec4_copy(v, dest); glm_vec4_zero(dest);
return; return;
} }
glm_vec4_scale(v, s / norm, dest); glm_vec4_scale(v, s / norm, dest);
} }
/*!
* @brief div vector with another component-wise division: d = v1 / v2
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest result = (a[0]/b[0], a[1]/b[1], a[2]/b[2], a[3]/b[3])
*/
CGLM_INLINE
void
glm_vec4_div(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_div_ps(_mm_load_ps(a), _mm_load_ps(b)));
#else
dest[0] = a[0] / b[0];
dest[1] = a[1] / b[1];
dest[2] = a[2] / b[2];
dest[3] = a[3] / b[3];
#endif
}
/*!
* @brief div vec4 vector with scalar: d = v / s
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination vector
*/
CGLM_INLINE
void
glm_vec4_divs(vec4 v, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_div_ps(_mm_load_ps(v), _mm_set1_ps(s)));
#else
glm_vec4_scale(v, 1.0f / s, dest);
#endif
}
/*!
* @brief add two vectors and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a + b)
*/
CGLM_INLINE
void
glm_vec4_addadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest),
_mm_add_ps(_mm_load_ps(a),
_mm_load_ps(b))));
#else
dest[0] += a[0] + b[0];
dest[1] += a[1] + b[1];
dest[2] += a[2] + b[2];
dest[3] += a[3] + b[3];
#endif
}
/*!
* @brief sub two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a - b)
*/
CGLM_INLINE
void
glm_vec4_subadd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest),
_mm_sub_ps(_mm_load_ps(a),
_mm_load_ps(b))));
#else
dest[0] += a[0] - b[0];
dest[1] += a[1] - b[1];
dest[2] += a[2] - b[2];
dest[3] += a[3] - b[3];
#endif
}
/*!
* @brief mul two vectors and add result to dest
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector 1
* @param[in] b vector 2
* @param[out] dest dest += (a * b)
*/
CGLM_INLINE
void
glm_vec4_muladd(vec4 a, vec4 b, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest),
_mm_mul_ps(_mm_load_ps(a),
_mm_load_ps(b))));
#else
dest[0] += a[0] * b[0];
dest[1] += a[1] * b[1];
dest[2] += a[2] * b[2];
dest[3] += a[3] * b[3];
#endif
}
/*!
* @brief mul vector with scalar and add result to sum
*
* it applies += operator so dest must be initialized
*
* @param[in] a vector
* @param[in] s scalar
* @param[out] dest dest += (a * b)
*/
CGLM_INLINE
void
glm_vec4_muladds(vec4 a, float s, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_add_ps(_mm_load_ps(dest),
_mm_mul_ps(_mm_load_ps(a),
_mm_set1_ps(s))));
#else
dest[0] += a[0] * s;
dest[1] += a[1] * s;
dest[2] += a[2] * s;
dest[3] += a[3] * s;
#endif
}
/*! /*!
* @brief flip sign of all vec4 members * @brief flip sign of all vec4 members
* *
@@ -258,8 +505,7 @@ CGLM_INLINE
void void
glm_vec4_flipsign(vec4 v) { glm_vec4_flipsign(vec4 v) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(v, _mm_xor_ps(_mm_load_ps(v), _mm_store_ps(v, _mm_xor_ps(_mm_load_ps(v), _mm_set1_ps(-0.0f)));
_mm_set1_ps(-0.0f)));
#else #else
v[0] = -v[0]; v[0] = -v[0];
v[1] = -v[1]; v[1] = -v[1];
@@ -312,26 +558,6 @@ glm_vec4_inv_to(vec4 v, vec4 dest) {
glm_vec4_flipsign(dest); glm_vec4_flipsign(dest);
} }
/*!
* @brief normalize vec4 and store result in same vec
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec4_normalize(vec4 v) {
float norm;
norm = glm_vec4_norm(v);
if (norm == 0.0f) {
v[0] = v[1] = v[2] = v[3] = 0.0f;
return;
}
glm_vec4_scale(v, 1.0f / norm, v);
}
/*! /*!
* @brief normalize vec4 to dest * @brief normalize vec4 to dest
* *
@@ -341,16 +567,43 @@ glm_vec4_normalize(vec4 v) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_normalize_to(vec4 vec, vec4 dest) { glm_vec4_normalize_to(vec4 vec, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
__m128 xdot, x0;
float dot;
x0 = _mm_load_ps(vec);
xdot = glm_simd_dot(x0, x0);
dot = _mm_cvtss_f32(xdot);
if (dot == 0.0f) {
_mm_store_ps(dest, _mm_setzero_ps());
return;
}
_mm_store_ps(dest, _mm_div_ps(x0, _mm_sqrt_ps(xdot)));
#else
float norm; float norm;
norm = glm_vec4_norm(vec); norm = glm_vec4_norm(vec);
if (norm == 0.0f) { if (norm == 0.0f) {
dest[0] = dest[1] = dest[2] = dest[3] = 0.0f; glm_vec4_zero(dest);
return; return;
} }
glm_vec4_scale(vec, 1.0f / norm, dest); glm_vec4_scale(vec, 1.0f / norm, dest);
#endif
}
/*!
* @brief normalize vec4 and store result in same vec
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_vec4_normalize(vec4 v) {
glm_vec4_normalize_to(v, v);
} }
/** /**
@@ -379,10 +632,14 @@ glm_vec4_distance(vec4 v1, vec4 v2) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest) { glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_max_ps(_mm_load_ps(v1), _mm_load_ps(v2)));
#else
dest[0] = glm_max(v1[0], v2[0]); dest[0] = glm_max(v1[0], v2[0]);
dest[1] = glm_max(v1[1], v2[1]); dest[1] = glm_max(v1[1], v2[1]);
dest[2] = glm_max(v1[2], v2[2]); dest[2] = glm_max(v1[2], v2[2]);
dest[3] = glm_max(v1[3], v2[3]); dest[3] = glm_max(v1[3], v2[3]);
#endif
} }
/*! /*!
@@ -395,10 +652,14 @@ glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest) { glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(dest, _mm_min_ps(_mm_load_ps(v1), _mm_load_ps(v2)));
#else
dest[0] = glm_min(v1[0], v2[0]); dest[0] = glm_min(v1[0], v2[0]);
dest[1] = glm_min(v1[1], v2[1]); dest[1] = glm_min(v1[1], v2[1]);
dest[2] = glm_min(v1[2], v2[2]); dest[2] = glm_min(v1[2], v2[2]);
dest[3] = glm_min(v1[3], v2[3]); dest[3] = glm_min(v1[3], v2[3]);
#endif
} }
/*! /*!
@@ -411,10 +672,15 @@ glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest) {
CGLM_INLINE CGLM_INLINE
void void
glm_vec4_clamp(vec4 v, float minVal, float maxVal) { glm_vec4_clamp(vec4 v, float minVal, float maxVal) {
#if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(v, _mm_min_ps(_mm_max_ps(_mm_load_ps(v), _mm_set1_ps(minVal)),
_mm_set1_ps(maxVal)));
#else
v[0] = glm_clamp(v[0], minVal, maxVal); v[0] = glm_clamp(v[0], minVal, maxVal);
v[1] = glm_clamp(v[1], minVal, maxVal); v[1] = glm_clamp(v[1], minVal, maxVal);
v[2] = glm_clamp(v[2], minVal, maxVal); v[2] = glm_clamp(v[2], minVal, maxVal);
v[3] = glm_clamp(v[3], minVal, maxVal); v[3] = glm_clamp(v[3], minVal, maxVal);
#endif
} }
/*! /*!

View File

@@ -10,6 +10,6 @@
#define CGLM_VERSION_MAJOR 0 #define CGLM_VERSION_MAJOR 0
#define CGLM_VERSION_MINOR 4 #define CGLM_VERSION_MINOR 4
#define CGLM_VERSION_PATCH 0 #define CGLM_VERSION_PATCH 3
#endif /* cglm_version_h */ #endif /* cglm_version_h */

View File

@@ -54,7 +54,8 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/plane.h \ include/cglm/plane.h \
include/cglm/frustum.h \ include/cglm/frustum.h \
include/cglm/box.h \ include/cglm/box.h \
include/cglm/color.h include/cglm/color.h \
include/cglm/project.h
cglm_calldir=$(includedir)/cglm/call cglm_calldir=$(includedir)/cglm/call
cglm_call_HEADERS = include/cglm/call/mat4.h \ cglm_call_HEADERS = include/cglm/call/mat4.h \
@@ -68,7 +69,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/euler.h \ include/cglm/call/euler.h \
include/cglm/call/plane.h \ include/cglm/call/plane.h \
include/cglm/call/frustum.h \ include/cglm/call/frustum.h \
include/cglm/call/box.h include/cglm/call/box.h \
include/cglm/call/project.h
cglm_simddir=$(includedir)/cglm/simd cglm_simddir=$(includedir)/cglm/simd
cglm_simd_HEADERS = include/cglm/simd/intrin.h cglm_simd_HEADERS = include/cglm/simd/intrin.h
@@ -110,7 +112,10 @@ test_tests_SOURCES=\
test/src/test_clamp.c \ test/src/test_clamp.c \
test/src/test_euler.c \ test/src/test_euler.c \
test/src/test_quat.c \ test/src/test_quat.c \
test/src/test_vec4.c test/src/test_vec4.c \
test/src/test_vec3.c \
test/src/test_mat3.c \
test/src/test_affine.c
all-local: all-local:
sh ./post-build.sh sh ./post-build.sh

View File

@@ -8,6 +8,12 @@
#include "../include/cglm/cglm.h" #include "../include/cglm/cglm.h"
#include "../include/cglm/call.h" #include "../include/cglm/call.h"
CGLM_EXPORT
void
glmc_translate_make(mat4 m, vec3 v) {
glm_translate_make(m, v);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_translate_to(mat4 m, vec3 v, mat4 dest) { glmc_translate_to(mat4 m, vec3 v, mat4 dest) {
@@ -38,6 +44,12 @@ glmc_translate_z(mat4 m, float to) {
glm_translate_z(m, to); glm_translate_z(m, to);
} }
CGLM_EXPORT
void
glmc_scale_make(mat4 m, vec3 v) {
glm_scale_make(m, v);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_scale_to(mat4 m, vec3 v, mat4 dest) { glmc_scale_to(mat4 m, vec3 v, mat4 dest) {
@@ -52,8 +64,8 @@ glmc_scale(mat4 m, vec3 v) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_scale1(mat4 m, float s) { glmc_scale_uni(mat4 m, float s) {
glm_scale1(m, s); glm_scale_uni(m, s);
} }
CGLM_EXPORT CGLM_EXPORT
@@ -74,36 +86,42 @@ glmc_rotate_z(mat4 m, float rad, mat4 dest) {
glm_rotate_z(m, rad, dest); glm_rotate_z(m, rad, dest);
} }
CGLM_EXPORT
void
glmc_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
glm_rotate_ndc_make(m, angle, axis_ndc);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_rotate_make(mat4 m, float angle, vec3 axis) { glmc_rotate_make(mat4 m, float angle, vec3 axis) {
glm_rotate_make(m, angle, axis); glm_rotate_make(m, angle, axis);
} }
CGLM_EXPORT
void
glmc_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
glm_rotate_ndc(m, angle, axis_ndc);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_rotate(mat4 m, float angle, vec3 axis) { glmc_rotate(mat4 m, float angle, vec3 axis) {
glm_rotate(m, angle, axis); glm_rotate(m, angle, axis);
} }
CGLM_EXPORT
void
glmc_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) {
glm_rotate_at(m, pivot, angle, axis);
}
CGLM_EXPORT
void
glmc_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) {
glm_rotate_atm(m, pivot, angle, axis);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_decompose_scalev(mat4 m, vec3 s) { glmc_decompose_scalev(mat4 m, vec3 s) {
glm_decompose_scalev(m, s); glm_decompose_scalev(m, s);
} }
CGLM_EXPORT
bool
glmc_uniscaled(mat4 m) {
return glm_uniscaled(m);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_decompose_rs(mat4 m, mat4 r, vec3 s) { glmc_decompose_rs(mat4 m, mat4 r, vec3 s) {

View File

@@ -194,3 +194,15 @@ void
glmc_quat_rotate(mat4 m, versor q, mat4 dest) { glmc_quat_rotate(mat4 m, versor q, mat4 dest) {
glm_quat_rotate(m, q, dest); glm_quat_rotate(m, q, dest);
} }
CGLM_EXPORT
void
glmc_quat_rotate_at(mat4 model, versor q, vec3 pivot) {
glm_quat_rotate_at(model, q, pivot);
}
CGLM_EXPORT
void
glmc_quat_rotate_atm(mat4 m, versor q, vec3 pivot) {
glm_quat_rotate_atm(m, q, pivot);
}

View File

@@ -20,6 +20,18 @@ glmc_vec_copy(vec3 a, vec3 dest) {
glm_vec_copy(a, dest); glm_vec_copy(a, dest);
} }
CGLM_EXPORT
void
glmc_vec_zero(vec3 v) {
glm_vec_zero(v);
}
CGLM_EXPORT
void
glmc_vec_one(vec3 v) {
glm_vec_one(v);
}
CGLM_EXPORT CGLM_EXPORT
float float
glmc_vec_dot(vec3 a, vec3 b) { glmc_vec_dot(vec3 a, vec3 b) {
@@ -64,8 +76,26 @@ glmc_vec_add(vec3 v1, vec3 v2, vec3 dest) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec_sub(vec3 v1, vec3 v2, vec3 dest) { glmc_vec_adds(vec3 v, float s, vec3 dest) {
glm_vec_sub(v1, v2, dest); glm_vec_adds(v, s, dest);
}
CGLM_EXPORT
void
glmc_vec_sub(vec3 a, vec3 b, vec3 dest) {
glm_vec_sub(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec_subs(vec3 v, float s, vec3 dest) {
glm_vec_subs(v, s, dest);
}
CGLM_EXPORT
void
glmc_vec_mul(vec3 a, vec3 b, vec3 d) {
glm_vec_mul(a, b, d);
} }
CGLM_EXPORT CGLM_EXPORT
@@ -80,6 +110,42 @@ glmc_vec_scale_as(vec3 v, float s, vec3 dest) {
glm_vec_scale_as(v, s, dest); glm_vec_scale_as(v, s, dest);
} }
CGLM_EXPORT
void
glmc_vec_div(vec3 a, vec3 b, vec3 dest) {
glm_vec_div(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec_divs(vec3 a, float s, vec3 dest) {
glm_vec_divs(a, s, dest);
}
CGLM_EXPORT
void
glmc_vec_addadd(vec3 a, vec3 b, vec3 dest) {
glm_vec_addadd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec_subadd(vec3 a, vec3 b, vec3 dest) {
glm_vec_subadd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec_muladd(vec3 a, vec3 b, vec3 dest) {
glm_vec_muladd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec_muladds(vec3 a, float s, vec3 dest) {
glm_vec_muladds(a, s, dest);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec_flipsign(vec3 v) { glmc_vec_flipsign(vec3 v) {

View File

@@ -14,6 +14,18 @@ glmc_vec4(vec3 v3, float last, vec4 dest) {
glm_vec4(v3, last, dest); glm_vec4(v3, last, dest);
} }
CGLM_EXPORT
void
glmc_vec4_zero(vec4 v) {
glm_vec4_zero(v);
}
CGLM_EXPORT
void
glmc_vec4_one(vec4 v) {
glm_vec4_one(v);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_copy3(vec4 a, vec3 dest) { glmc_vec4_copy3(vec4 a, vec3 dest) {
@@ -58,14 +70,32 @@ glmc_vec4_norm2(vec4 vec) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_add(vec4 v1, vec4 v2, vec4 dest) { glmc_vec4_add(vec4 a, vec4 b, vec4 dest) {
glm_vec4_add(v1, v2, dest); glm_vec4_add(a, b, dest);
} }
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_sub(vec4 v1, vec4 v2, vec4 dest) { glmc_vec4_adds(vec4 v, float s, vec4 dest) {
glm_vec4_sub(v1, v2, dest); glm_vec4_adds(v, s, dest);
}
CGLM_EXPORT
void
glmc_vec4_sub(vec4 a, vec4 b, vec4 dest) {
glm_vec4_sub(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec4_subs(vec4 v, float s, vec4 dest) {
glm_vec4_subs(v, s, dest);
}
CGLM_EXPORT
void
glmc_vec4_mul(vec4 a, vec4 b, vec4 d) {
glm_vec4_mul(a, b, d);
} }
CGLM_EXPORT CGLM_EXPORT
@@ -76,10 +106,46 @@ glmc_vec4_scale(vec4 v, float s, vec4 dest) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_scale_as(vec3 v, float s, vec3 dest) { glmc_vec4_scale_as(vec4 v, float s, vec4 dest) {
glm_vec4_scale_as(v, s, dest); glm_vec4_scale_as(v, s, dest);
} }
CGLM_EXPORT
void
glmc_vec4_div(vec4 a, vec4 b, vec4 dest) {
glm_vec4_div(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec4_divs(vec4 v, float s, vec4 dest) {
glm_vec4_divs(v, s, dest);
}
CGLM_EXPORT
void
glmc_vec4_addadd(vec4 a, vec4 b, vec4 dest) {
glm_vec4_addadd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec4_subadd(vec4 a, vec4 b, vec4 dest) {
glm_vec4_subadd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec4_muladd(vec4 a, vec4 b, vec4 dest) {
glm_vec4_muladd(a, b, dest);
}
CGLM_EXPORT
void
glmc_vec4_muladds(vec4 a, float s, vec4 dest) {
glm_vec4_muladds(a, s, dest);
}
CGLM_EXPORT CGLM_EXPORT
void void
glmc_vec4_flipsign(vec4 v) { glmc_vec4_flipsign(vec4 v) {

113
test/src/test_affine.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "test_common.h"
void
test_affine(void **state) {
mat4 t1, t2, t3, t4, t5;
/* test translate is postmultiplied */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t1, t2, t3); /* R * T */
glm_translate(t1, (vec3){34, 57, 36});
test_assert_mat4_eq(t1, t3);
/* test rotate is postmultiplied */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glm_rotate(t2, M_PI_4, GLM_YUP);
test_assert_mat4_eq(t2, t3);
/* test scale is postmultiplied */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){34, 57, 36});
glm_scale_make(t4, (vec3){3, 5, 6});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glmc_mat4_mul(t3, t4, t5); /* T * R * S */
glm_scale(t3, (vec3){3, 5, 6});
test_assert_mat4_eq(t3, t5);
/* test translate_x */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){34, 0, 0});
glmc_mat4_mul(t1, t2, t3); /* R * T */
glm_translate_x(t1, 34);
test_assert_mat4_eq(t1, t3);
/* test translate_y */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){0, 57, 0});
glmc_mat4_mul(t1, t2, t3); /* R * T */
glm_translate_y(t1, 57);
test_assert_mat4_eq(t1, t3);
/* test translate_z */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){0, 0, 36});
glmc_mat4_mul(t1, t2, t3); /* R * T */
glm_translate_z(t1, 36);
test_assert_mat4_eq(t1, t3);
/* test rotate_x */
glmc_rotate_make(t1, M_PI_4, (vec3){1, 0, 0});
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glm_rotate_x(t2, M_PI_4, t2);
test_assert_mat4_eq(t2, t3);
/* test rotate_y */
glmc_rotate_make(t1, M_PI_4, (vec3){0, 1, 0});
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glm_rotate_y(t2, M_PI_4, t2);
test_assert_mat4_eq(t2, t3);
/* test rotate_z */
glmc_rotate_make(t1, M_PI_4, (vec3){0, 0, 1});
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glm_rotate_z(t2, M_PI_4, t2);
test_assert_mat4_eq(t2, t3);
/* test rotate */
glmc_rotate_make(t1, M_PI_4, (vec3){0, 0, 1});
glm_translate_make(t2, (vec3){34, 57, 36});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glmc_rotate(t2, M_PI_4, (vec3){0, 0, 1});
test_assert_mat4_eq(t3, t2);
/* test scale_uni */
glmc_rotate_make(t1, M_PI_4, GLM_YUP);
glm_translate_make(t2, (vec3){34, 57, 36});
glm_scale_make(t4, (vec3){3, 3, 3});
glmc_mat4_mul(t2, t1, t3); /* T * R */
glmc_mat4_mul(t3, t4, t5); /* T * R * S */
glm_scale_uni(t3, 3);
test_assert_mat4_eq(t3, t5);
}

View File

@@ -27,6 +27,17 @@ test_rand_mat4(mat4 dest) {
/* glm_scale(dest, (vec3){drand48(), drand48(), drand48()}); */ /* glm_scale(dest, (vec3){drand48(), drand48(), drand48()}); */
} }
void
test_rand_mat3(mat3 dest) {
mat4 m4;
srand((unsigned int)time(NULL));
/* random rotatation around random axis with random angle */
glm_rotate_make(m4, drand48(), (vec3){drand48(), drand48(), drand48()});
glm_mat4_pick3(m4, dest);
}
void void
test_rand_vec3(vec3 dest) { test_rand_vec3(vec3 dest) {
srand((unsigned int)time(NULL)); srand((unsigned int)time(NULL));
@@ -84,6 +95,23 @@ test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps) {
} }
} }
void
test_assert_mat3_eq(mat3 m1, mat3 m2) {
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++)
assert_true(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009);
}
}
}
void
test_assert_eqf(float a, float b) {
assert_true(fabsf(a - b) <= 0.000009); /* rounding errors */
}
void void
test_assert_vec3_eq(vec3 v1, vec3 v2) { test_assert_vec3_eq(vec3 v1, vec3 v2) {
assert_true(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */ assert_true(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */
@@ -91,6 +119,14 @@ test_assert_vec3_eq(vec3 v1, vec3 v2) {
assert_true(fabsf(v1[2] - v2[2]) <= 0.000009); assert_true(fabsf(v1[2] - v2[2]) <= 0.000009);
} }
void
test_assert_vec4_eq(vec4 v1, vec4 v2) {
assert_true(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */
assert_true(fabsf(v1[1] - v2[1]) <= 0.000009);
assert_true(fabsf(v1[2] - v2[2]) <= 0.000009);
assert_true(fabsf(v1[3] - v2[3]) <= 0.000009);
}
void void
test_assert_quat_eq_abs(versor v1, versor v2) { test_assert_quat_eq_abs(versor v1, versor v2) {
assert_true(fabsf(fabsf(v1[0]) - fabsf(v2[0])) <= 0.0009); /* rounding errors */ assert_true(fabsf(fabsf(v1[0]) - fabsf(v2[0])) <= 0.0009); /* rounding errors */

View File

@@ -25,15 +25,27 @@
void void
test_rand_mat4(mat4 dest); test_rand_mat4(mat4 dest);
void
test_rand_mat3(mat3 dest);
void
test_assert_eqf(float a, float b);
void void
test_assert_mat4_eq(mat4 m1, mat4 m2); test_assert_mat4_eq(mat4 m1, mat4 m2);
void void
test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps); test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps);
void
test_assert_mat3_eq(mat3 m1, mat3 m2);
void void
test_assert_vec3_eq(vec3 v1, vec3 v2); test_assert_vec3_eq(vec3 v1, vec3 v2);
void
test_assert_vec4_eq(vec4 v1, vec4 v2);
void void
test_assert_quat_eq(versor v1, versor v2); test_assert_quat_eq(versor v1, versor v2);

View File

@@ -12,6 +12,9 @@ main(int argc, const char * argv[]) {
/* mat4 */ /* mat4 */
cmocka_unit_test(test_mat4), cmocka_unit_test(test_mat4),
/* mat3 */
cmocka_unit_test(test_mat3),
/* camera */ /* camera */
cmocka_unit_test(test_camera_lookat), cmocka_unit_test(test_camera_lookat),
cmocka_unit_test(test_camera_decomp), cmocka_unit_test(test_camera_decomp),
@@ -29,7 +32,13 @@ main(int argc, const char * argv[]) {
cmocka_unit_test(test_quat), cmocka_unit_test(test_quat),
/* vec4 */ /* vec4 */
cmocka_unit_test(test_vec4) cmocka_unit_test(test_vec4),
/* vec3 */
cmocka_unit_test(test_vec3),
/* affine */
cmocka_unit_test(test_affine)
}; };
return cmocka_run_group_tests(tests, NULL, NULL); return cmocka_run_group_tests(tests, NULL, NULL);

58
test/src/test_mat3.c Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "test_common.h"
#define m 3
#define n 3
void
test_mat3(void **state) {
mat3 m1 = GLM_MAT3_IDENTITY_INIT;
mat3 m2 = GLM_MAT3_IDENTITY_INIT;
mat3 m3;
mat3 m4 = GLM_MAT3_ZERO_INIT;
mat3 m5;
int i, j, k;
/* test identity matrix multiplication */
glmc_mat3_mul(m1, m2, m3);
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
if (i == j)
assert_true(m3[i][j] == 1.0f);
else
assert_true(m3[i][j] == 0.0f);
}
}
/* test random matrices */
/* random matrices */
test_rand_mat3(m1);
test_rand_mat3(m2);
glmc_mat3_mul(m1, m2, m3);
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < m; k++)
/* column-major */
m4[i][j] += m1[k][j] * m2[i][k];
}
}
test_assert_mat3_eq(m3, m4);
for (i = 0; i < 100000; i++) {
test_rand_mat3(m3);
test_rand_mat3(m4);
/* test inverse precise */
glmc_mat3_inv(m3, m4);
glmc_mat3_inv(m4, m5);
test_assert_mat3_eq(m3, m5);
}
}

View File

@@ -9,6 +9,9 @@
/* mat4 */ /* mat4 */
void test_mat4(void **state); void test_mat4(void **state);
/* mat3 */
void test_mat3(void **state);
/* camera */ /* camera */
void void
test_camera_lookat(void **state); test_camera_lookat(void **state);
@@ -31,4 +34,10 @@ test_quat(void **state);
void void
test_vec4(void **state); test_vec4(void **state);
void
test_vec3(void **state);
void
test_affine(void **state);
#endif /* test_tests_h */ #endif /* test_tests_h */

78
test/src/test_vec3.c Normal file
View File

@@ -0,0 +1,78 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "test_common.h"
void
test_vec3(void **state) {
mat3 rot1m3;
mat4 rot1;
vec3 v, v1, v2;
/* test zero */
glm_vec_zero(v);
test_assert_vec3_eq(GLM_VEC3_ZERO, v);
/* test one */
glm_vec_one(v);
test_assert_vec3_eq(GLM_VEC3_ONE, v);
/* adds, subs, div, divs, mul */
glm_vec_add(v, GLM_VEC3_ONE, v);
assert_true(glmc_vec_eq_eps(v, 2));
glm_vec_adds(v, 10, v);
assert_true(glmc_vec_eq_eps(v, 12));
glm_vec_sub(v, GLM_VEC3_ONE, v);
assert_true(glmc_vec_eq_eps(v, 11));
glm_vec_subs(v, 1, v);
assert_true(glmc_vec_eq_eps(v, 10));
glm_vec_broadcast(2, v1);
glm_vec_div(v, v1, v);
assert_true(glmc_vec_eq_eps(v, 5));
glm_vec_divs(v, 0.5, v);
assert_true(glmc_vec_eq_eps(v, 10));
glm_vec_mul(v, v1, v);
assert_true(glmc_vec_eq_eps(v, 20));
glm_vec_scale(v, 0.5, v);
assert_true(glmc_vec_eq_eps(v, 10));
glm_vec_normalize_to(v, v1);
glm_vec_scale(v1, 0.8, v1);
glm_vec_scale_as(v, 0.8, v);
test_assert_vec3_eq(v1, v);
/* addadd, subadd, muladd */
glm_vec_one(v);
glm_vec_addadd(GLM_VEC3_ONE, GLM_VEC3_ONE, v);
assert_true(glmc_vec_eq_eps(v, 3));
glm_vec_subadd(GLM_VEC3_ONE, GLM_VEC3_ZERO, v);
assert_true(glmc_vec_eq_eps(v, 4));
glm_vec_broadcast(2, v1);
glm_vec_broadcast(3, v2);
glm_vec_muladd(v1, v2, v);
assert_true(glmc_vec_eq_eps(v, 10));
/* rotate */
glm_vec_copy(GLM_YUP, v);
glm_rotate_make(rot1, glm_rad(90), GLM_XUP);
glm_vec_rotate_m4(rot1, v, v1);
glm_mat4_pick3(rot1, rot1m3);
glm_vec_rotate_m3(rot1m3, v, v2);
test_assert_vec3_eq(v1, v2);
test_assert_vec3_eq(v1, GLM_ZUP);
}

View File

@@ -13,18 +13,166 @@ test_vec4_dot(vec4 a, vec4 b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
} }
CGLM_INLINE
void
test_vec4_normalize_to(vec4 vec, vec4 dest) {
float norm;
norm = glm_vec4_norm(vec);
if (norm == 0.0f) {
dest[0] = dest[1] = dest[2] = dest[3] = 0.0f;
return;
}
glm_vec4_scale(vec, 1.0f / norm, dest);
}
float
test_vec4_norm2(vec4 vec) {
return test_vec4_dot(vec, vec);
}
float
test_vec4_norm(vec4 vec) {
return sqrtf(test_vec4_dot(vec, vec));
}
void
test_vec4_maxv(vec4 v1, vec4 v2, vec4 dest) {
dest[0] = glm_max(v1[0], v2[0]);
dest[1] = glm_max(v1[1], v2[1]);
dest[2] = glm_max(v1[2], v2[2]);
dest[3] = glm_max(v1[3], v2[3]);
}
void
test_vec4_minv(vec4 v1, vec4 v2, vec4 dest) {
dest[0] = glm_min(v1[0], v2[0]);
dest[1] = glm_min(v1[1], v2[1]);
dest[2] = glm_min(v1[2], v2[2]);
dest[3] = glm_min(v1[3], v2[3]);
}
void
test_vec4_clamp(vec4 v, float minVal, float maxVal) {
v[0] = glm_clamp(v[0], minVal, maxVal);
v[1] = glm_clamp(v[1], minVal, maxVal);
v[2] = glm_clamp(v[2], minVal, maxVal);
v[3] = glm_clamp(v[3], minVal, maxVal);
}
void void
test_vec4(void **state) { test_vec4(void **state) {
vec4 v; vec4 v, v1, v2, v3, v4;
int i; int i;
float d1, d2; float d1, d2;
/* test SSE/SIMD dot product */
for (i = 0; i < 100; i++) { for (i = 0; i < 1000; i++) {
/* 1. test SSE/SIMD dot product */
test_rand_vec4(v); test_rand_vec4(v);
d1 = glm_vec4_dot(v, v); d1 = glm_vec4_dot(v, v);
d2 = test_vec4_dot(v, v); d2 = test_vec4_dot(v, v);
assert_true(fabsf(d1 - d2) <= 0.000009); assert_true(fabsf(d1 - d2) <= 0.000009);
/* 2. test SIMD normalize */
test_vec4_normalize_to(v, v1);
glm_vec4_normalize_to(v, v2);
glm_vec4_normalize(v);
/* all must be same */
test_assert_vec4_eq(v1, v2);
test_assert_vec4_eq(v, v2);
/* 3. test SIMD norm */
test_rand_vec4(v);
test_assert_eqf(test_vec4_norm(v), glm_vec4_norm(v));
/* 3. test SIMD norm2 */
test_rand_vec4(v);
test_assert_eqf(test_vec4_norm2(v), glm_vec4_norm2(v));
} }
/* test zero */
glm_vec4_zero(v);
test_assert_vec4_eq(GLM_VEC4_ZERO, v);
/* test one */
glm_vec4_one(v);
test_assert_vec4_eq(GLM_VEC4_ONE, v);
/* adds, subs, div, divs, mul */
glm_vec4_add(v, GLM_VEC4_ONE, v);
assert_true(glmc_vec4_eq_eps(v, 2));
glm_vec4_adds(v, 10, v);
assert_true(glmc_vec4_eq_eps(v, 12));
glm_vec4_sub(v, GLM_VEC4_ONE, v);
assert_true(glmc_vec4_eq_eps(v, 11));
glm_vec4_subs(v, 1, v);
assert_true(glmc_vec4_eq_eps(v, 10));
glm_vec4_broadcast(2, v1);
glm_vec4_div(v, v1, v);
assert_true(glmc_vec4_eq_eps(v, 5));
glm_vec4_divs(v, 0.5, v);
assert_true(glmc_vec4_eq_eps(v, 10));
glm_vec4_mul(v, v1, v);
assert_true(glmc_vec4_eq_eps(v, 20));
glm_vec4_scale(v, 0.5, v);
assert_true(glmc_vec4_eq_eps(v, 10));
glm_vec4_normalize_to(v, v1);
glm_vec4_scale(v1, 0.8, v1);
glm_vec4_scale_as(v, 0.8, v);
test_assert_vec4_eq(v1, v);
/* addadd, subadd, muladd */
glm_vec4_one(v);
glm_vec4_addadd(GLM_VEC4_ONE, GLM_VEC4_ONE, v);
assert_true(glmc_vec4_eq_eps(v, 3));
glm_vec4_subadd(GLM_VEC4_ONE, GLM_VEC4_ZERO, v);
assert_true(glmc_vec4_eq_eps(v, 4));
glm_vec4_broadcast(2, v1);
glm_vec4_broadcast(3, v2);
glm_vec4_muladd(v1, v2, v);
assert_true(glmc_vec4_eq_eps(v, 10));
/* min, max */
test_rand_vec4(v1);
test_rand_vec4(v2);
glm_vec4_maxv(v1, v2, v3);
test_vec4_maxv(v1, v2, v4);
test_assert_vec4_eq(v3, v4);
glm_vec4_minv(v1, v2, v3);
test_vec4_minv(v1, v2, v4);
test_assert_vec4_eq(v3, v4);
glm_vec4_print(v3, stderr);
glm_vec4_print(v4, stderr);
/* clamp */
glm_vec4_clamp(v3, 0.1, 0.8);
test_vec4_clamp(v4, 0.1, 0.8);
test_assert_vec4_eq(v3, v4);
glm_vec4_print(v3, stderr);
glm_vec4_print(v4, stderr);
assert_true(v3[0] >= 0.0999 && v3[0] <= 0.80001); /* rounding erros */
assert_true(v3[1] >= 0.0999 && v3[1] <= 0.80001);
assert_true(v3[2] >= 0.0999 && v3[2] <= 0.80001);
assert_true(v3[3] >= 0.0999 && v3[3] <= 0.80001);
} }