Compare commits

..

74 Commits
v0.3.1 ... ndc

Author SHA1 Message Date
Recep Aslantas
fadde1e26a fix libtool version number 2018-03-08 13:04:29 +03:00
Recep Aslantas
cfab79e546 now working on v0.3.5 2018-03-08 12:18:07 +03:00
Recep Aslantas
da2f3aaafd docs: fix aabb docs 2018-03-03 18:17:58 +03:00
Recep Aslantas
0e964a1a62 complete documentation 2018-03-03 17:59:50 +03:00
Recep Aslantas
1fd0a74478 docs: euler angles documentation 2018-03-01 18:27:56 +03:00
Recep Aslantas
b3a39aa13c docs: add docs for quaternions 2018-02-27 11:14:03 +03:00
Recep Aslantas
b737bb2dde docs: add docs for affine matrix 2018-02-27 10:53:45 +03:00
Recep Aslantas
a610626693 fix vec4 parameter type 2018-02-26 23:24:43 +03:00
Recep Aslantas
425bf87c1f docs: add docs for camera 2018-02-26 23:23:31 +03:00
Recep Aslantas
23698b7e48 docs: add docs for vec4 2018-02-26 22:08:04 +03:00
Recep Aslantas
be3f117374 docs: add docs for vec3-ext 2018-02-26 17:10:33 +03:00
Recep Aslantas
77e62163ea docs: add docs for vec3 2018-02-26 16:21:04 +03:00
Recep Aslantas
96f773417a docs: add docs for mat3 2018-02-26 12:16:09 +03:00
Recep Aslantas
02ab66a8b3 docs: add docs for transforms 2018-02-24 20:12:05 +03:00
Recep Aslantas
fc424631a4 docs: add docs for api, mat4 2018-02-24 13:18:28 +03:00
Recep Aslantas
6d5734fe7e docs: update sphinx conf 2018-02-24 13:18:13 +03:00
Recep Aslantas
d95bf60b02 docs: update docs 2018-02-24 00:54:59 +03:00
Recep Aslantas
891148cbe3 Merge pull request #29 from recp/color
color: add luminance function
2018-02-23 18:00:50 +03:00
Recep Aslantas
4ce2e86d9f color: add luminance function 2018-02-23 11:12:55 +03:00
Recep Aslantas
8a16f358a3 build: fix C flags for older compiler[s] 2018-02-22 19:55:16 +03:00
Recep Aslantas
43d0837303 Update README.md 2018-02-21 11:53:31 +03:00
Recep Aslantas
c1c659489a surround macro values with parentheses 2018-02-18 11:16:03 +03:00
Recep Aslantas
681a74b39c move credits to its own file to keep LICENSE more clear 2018-02-18 10:46:17 +03:00
Recep Aslantas
5ccf80cd0e Update README.md 2018-02-05 18:13:40 +03:00
Recep Aslantas
3882b72f7f vec: helper macro for zero vectors 2018-02-05 17:46:28 +03:00
Recep Aslantas
55d1e240a2 Merge pull request #23 from recp/box
bounding box
2018-01-18 23:40:27 +03:00
Recep Aslantas
e4727e6c88 Update README.md 2018-01-18 23:39:19 +03:00
Recep Aslantas
9649a0285f fix documentation param names 2018-01-18 20:52:24 +03:00
Recep Aslantas
0f9f4748d7 box: cull frustum with aabb helper 2018-01-18 20:08:45 +03:00
Recep Aslantas
a832d58d9f box: cull frustum with aabb helper 2018-01-18 20:04:21 +03:00
Recep Aslantas
8b2c74b0cc bounding box 2018-01-18 16:36:58 +03:00
Recep Aslantas
da8bbc6536 improve minv and maxv 2018-01-18 16:24:30 +03:00
Recep Aslantas
4a7cd2eb26 cam: convenient util for crating orthographic proj with AABB 2018-01-18 16:23:34 +03:00
Recep Aslantas
565ee2d6eb frustum: fix bounding box
default value 0.0 causes to get min or max as 0 if max < 0 or min > 0
2018-01-18 16:12:44 +03:00
Recep Aslantas
c58db651a6 vec: convenient wrappers/utils for vectors (#21)
* vec: convenient wrappers/utils for vectors
* add additional convenient funcs
2018-01-16 23:10:35 +03:00
Recep Aslantas
ee78459340 add documentation to quaternion header 2018-01-15 16:33:57 +03:00
Recep Aslantas
37f6bb8725 add documentation to util header 2018-01-15 16:02:48 +03:00
Recep Aslantas
703c74b6ca add documentaiton to affine-mat header 2018-01-15 15:57:08 +03:00
Recep Aslantas
42d8f58960 update affine header
* add come documentation to affine header
* rename scale1 to scale_uni
2018-01-15 15:52:13 +03:00
Stephen Strowes
74201aaef9 add new headers to makefile.am (#20)
* add new headers to makefile.am
* add missing call headers to makefile.am
2018-01-14 23:08:46 +03:00
Recep Aslantas
c6b0d96e71 Merge pull request #19 from recp/dev
move frustum related stuff to separate frustum header
2018-01-14 15:01:33 +03:00
Recep Aslantas
8bcd6bd077 frustum: make clipspace coords configurable
* now users can override clip space coords
* add more desc to header
* add call version for _corners_at
2018-01-14 11:03:03 +03:00
Recep Aslantas
6dcd919130 Update README.md 2018-01-14 00:24:43 +03:00
Recep Aslantas
944d285e14 frustum: new util for getting a plane's corners between near and far planes
* optimize frustum box func
2018-01-13 21:40:34 +03:00
Recep Aslantas
a56da8cc4a frustum: new macros for frustum 2018-01-13 21:37:15 +03:00
Recep Aslantas
40458be41b frustum: fix array index 2018-01-13 17:27:06 +03:00
Recep Aslantas
b6dc5029dd build, win: update windows solution and proejct files 2018-01-12 16:41:34 +03:00
Recep Aslantas
2349bbff31 move frustum related stuff to frustum header
* create helpers macro which defines corner index
* func for get bounding box frustum
* add missing source to make file
* add more desc to glm_frustum_corners
2018-01-12 15:21:36 +03:00
Recep Aslantas
b76f78948b Merge pull request #18 from recp/dev
new wrappers for lookat
2018-01-12 15:05:48 +03:00
Recep Aslantas
2b7994778d fix lib call version of look_anyup 2018-01-12 12:54:33 +03:00
Recep Aslantas
4e6ab470c2 update glm_look_any to glm_look_anyup 2018-01-12 12:52:25 +03:00
Recep Aslantas
50c23ce1c0 add missing definitions, fix initizlizing vector 2018-01-10 22:42:34 +03:00
Recep Aslantas
61ac032751 new wrappers for lookat 2018-01-10 22:02:14 +03:00
Recep Aslantas
9ee79a8b13 possible orthogonal/perpendicular vector 2018-01-10 00:26:13 +03:00
Recep Aslantas
efe6729891 Merge pull request #16 from recp/dev
convenient functions for perspective projection matrix
2018-01-10 00:06:23 +03:00
Recep Aslantas
42743e3b82 use float literal suffix for numbers 2018-01-10 00:01:06 +03:00
Recep Aslantas
b3c3e3a034 fix variable names 2018-01-08 16:03:53 +03:00
Recep Aslantas
642cc8d603 perspective sizes 2018-01-04 13:54:35 +03:00
Recep Aslantas
d53f95314d apply optimizations 2018-01-04 13:52:35 +03:00
Recep Aslantas
797c4581ee extract fovy and aspect for perpective matrix 2018-01-04 11:16:09 +03:00
Recep Aslantas
6534f4a6c7 Merge pull request #14 from recp/dev
feature: extract view frustum planes and corners
2018-01-02 20:15:09 +03:00
Recep Aslantas
3e4f52b3af optimize operations, fix max sign 2018-01-02 10:16:46 +03:00
Recep Aslantas
eaf45e489d view frustum center 2017-12-31 17:17:39 +03:00
Recep Aslantas
2d0a3ad828 use frustum namespace for frustum specific funcs 2017-12-30 18:05:11 +03:00
Recep Aslantas
400fc6cbee extracting view frustum corners 2017-12-30 17:51:40 +03:00
Recep Aslantas
634e1170a3 min and max util 2017-12-30 17:50:53 +03:00
Recep Aslantas
99669a21a4 move extracting planes to camera header
* since it related to view frustum / camera it should be in thie header or separate header called frustum.h
* update LICENSE to add authors of algorithm
2017-12-30 13:55:17 +03:00
Recep Aslantas
d14627ac52 vec: fix parameter types 2017-12-30 13:14:09 +03:00
Recep Aslantas
c98340d9d2 exracting planes 2017-12-30 12:18:32 +03:00
Recep Aslantas
3f616ce6a3 update version 2017-12-27 16:32:49 +03:00
Recep Aslantas
35d078a1ed avoid using far and near names because windows uses it as macro!!! 2017-12-27 16:31:26 +03:00
Recep Aslantas
034371c689 Merge pull request #11 from winduptoy/master
Fixed GLM_QUAT_IDENTITY_INIT (wxyz) instead of (xyzw). Addresses #10.
2017-12-26 17:44:03 +03:00
Matt Reyer
b797863ba3 Fixed GLM_QUAT_IDENTITY_INIT (wxyz) instead of (xyzw). Addresses #10. 2017-12-26 08:51:21 -05:00
Recep Aslantas
63eaee5049 vec: implement min and max 2017-12-17 16:55:04 +03:00
66 changed files with 4480 additions and 231 deletions

45
CREDITS Normal file
View File

@@ -0,0 +1,45 @@
This library [initially] used some [piece of] implementations
(may include codes) from these open source projects/resources:
1. Affine Transforms
The original glm repo (g-truc), url: https://github.com/g-truc/glm
LICENSE[S]:
The Happy Bunny License (Modified MIT License)
The MIT License
Copyright (c) 2005 - 2016 G-Truc Creation
FULL LICENSE: https://github.com/g-truc/glm/blob/master/copying.txt
2. Quaternions
Anton's OpenGL 4 Tutorials book source code:
LICENSE:
OpenGL 4 Example Code.
Accompanies written series "Anton's OpenGL 4 Tutorials"
Email: anton at antongerdelan dot net
First version 27 Jan 2014
Copyright Dr Anton Gerdelan, Trinity College Dublin, Ireland.
3. Euler Angles
David Eberly
Geometric Tools, LLC http://www.geometrictools.com/
Copyright (c) 1998-2016. All Rights Reserved.
Computing Euler angles from a rotation matrix (euler.pdf)
Gregory G. Slabaugh
4. Extracting Planes
Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
Authors:
Gil Gribb (ggribb@ravensoft.com)
Klaus Hartmann (k_hartmann@osnabrueck.netsurf.de)
5. Transform AABB
Transform Axis Aligned Bounding Boxes:
http://dev.theomader.com/transform-bounding-boxes/
https://github.com/erich666/GraphicsGems/blob/master/gems/TransBox.c
6. Cull frustum
http://www.txutxi.com/?p=584
http://old.cescg.org/CESCG-2002/DSykoraJJelinek/

33
LICENSE
View File

@@ -19,36 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
-
This library [initially] used some [piece of] implementations
(may include codes) from these open source projects/resources:
1. Affine Transforms
The original glm repo (g-truc), url: https://github.com/g-truc/glm
LICENSE[S]:
The Happy Bunny License (Modified MIT License)
The MIT License
Copyright (c) 2005 - 2016 G-Truc Creation
FULL LICENSE: https://github.com/g-truc/glm/blob/master/copying.txt
2. Quaternions
Anton's OpenGL 4 Tutorials book source code:
LICENSE:
OpenGL 4 Example Code.
Accompanies written series "Anton's OpenGL 4 Tutorials"
Email: anton at antongerdelan dot net
First version 27 Jan 2014
Copyright Dr Anton Gerdelan, Trinity College Dublin, Ireland.
3. Euler Angles
David Eberly
Geometric Tools, LLC http://www.geometrictools.com/
Copyright (c) 1998-2016. All Rights Reserved.
Computing Euler angles from a rotation matrix (euler.pdf)
Gregory G. Slabaugh

View File

@@ -1,15 +1,16 @@
# 🎥 OpenGL Mathematics (glm) for `C` # 🎥 OpenGL Mathematics (glm) for `C`
[![Build Status](https://travis-ci.org/recp/cglm.svg?branch=master)](https://travis-ci.org/recp/cglm) [![Build Status](https://travis-ci.org/recp/cglm.svg?branch=master)](https://travis-ci.org/recp/cglm)
[![Build status](https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true)](https://ci.appveyor.com/project/recp/cglm/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true)](https://ci.appveyor.com/project/recp/cglm/branch/master)
[![Documentation Status](https://readthedocs.org/projects/cglm/badge/?version=latest)](http://cglm.readthedocs.io/en/latest/?badge=latest)
[![Coverage Status](https://coveralls.io/repos/github/recp/cglm/badge.svg?branch=master)](https://coveralls.io/github/recp/cglm?branch=master) [![Coverage Status](https://coveralls.io/repos/github/recp/cglm/badge.svg?branch=master)](https://coveralls.io/github/recp/cglm?branch=master)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/6a62b37d5f214f178ebef269dc4a6bf1)](https://www.codacy.com/app/recp/cglm?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=recp/cglm&amp;utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6a62b37d5f214f178ebef269dc4a6bf1)](https://www.codacy.com/app/recp/cglm?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=recp/cglm&amp;utm_campaign=Badge_Grade)
The original glm library is for C++ only (templates, namespaces, classes...), this library targeted to C99 but currently you can use it for C89 safely by language extensions e.g `__register` The original glm library is for C++ only (templates, namespaces, classes...), this library targeted to C99 but currently you can use it for C89 safely by language extensions e.g `__restrict`
#### Documentation #### Documentation
Almost all functions (inline versions) and parameters are documented inside related headers. <br /> Almost all functions (inline versions) and parameters are documented inside related headers. <br />
Complete documentation is in progress: http://cglm.readthedocs.io Complete documentation: http://cglm.readthedocs.io
#### Note for previous versions: #### Note for previous versions:
@@ -21,6 +22,26 @@ Complete documentation is in progress: http://cglm.readthedocs.io
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:
https://github.com/g-truc/glm https://github.com/g-truc/glm
#### Note for new comers (Important):
- `vec4` and `mat4` variables must be aligned. (There will be unaligned versions later)
- **in** and **[in, out]** parameters must be initialized (please). But **[out]** parameters not, initializing out param is also redundant
- All functions are inline if you don't want to use pre-compiled versions with glmc_ prefix, you can ignore build process. Just incliude headers.
- if your debugger takes you to cglm headers then make sure you are not trying to copy vec4 to vec3 or alig issues...
- Welcome!
#### Note for experienced developers:
- Since I'm testing this library in my projects, sometimes bugs occurs; finding that bug[s] and making improvements would be more easy with multiple developer/contributor and their projects or knowledge. Consider to make some tests if you suspect something is wrong and any feedbacks, contributions and bug reports are always welcome.
#### Allocations?
`cglm` doesn't alloc any memory on heap. So it doesn't provide any allocator. You should alloc memory for **out** parameters too if you pass pointer of memory location. Don't forget that **vec4** (also quat/**versor**) and **mat4** must be aligned (16-bytes), because *cglm* uses SIMD instructions to optimize most operations if available.
#### Returning vector or matrix... ?
Since almost all types are arrays and **C** doesn't allow returning arrays, so **cglm** doesn't support this feature. In the future *cglm* may use **struct** for some types for this purpose.
#### Other APIs like Vulkan, Metal, Dx?
Currently *cglm* uses default clip space configuration (-1, 1) for camera functions (perspective, extract corners...), in the future other clip space configurations will be supported
<hr/>
<table> <table>
<tbody> <tbody>
@@ -50,6 +71,8 @@ https://github.com/g-truc/glm
- euler angles / yaw-pitch-roll to matrix - euler angles / yaw-pitch-roll to matrix
- extract euler angles - extract euler angles
- inline or pre-compiled function call - inline or pre-compiled function call
- frustum (extract view frustum planes, corners...)
- bounding box (AABB in Frustum (culling), crop, merge...)
<hr /> <hr />
@@ -98,13 +121,15 @@ MIT. check the LICENSE file
### Unix (Autotools) ### Unix (Autotools)
```text ```bash
$ sh ./build-deps.sh # run only once (dependencies) $ sh ./build-deps.sh # run only once (dependencies) [Optional].
$ # You can pass this step if you don't want to run `make check` for tests.
$ # cglm uses cmocka for tests and it may reqiure cmake for building it
$ $
$ sh autogen.sh $ sh autogen.sh
$ ./configure $ ./configure
$ make $ make
$ make install $ make check # [Optional] (if you run `sh ./build-deps.sh`)
$ [sudo] make install $ [sudo] make install
``` ```
@@ -122,6 +147,15 @@ if `msbuild` won't work (because of multi version VS) then try to build with `de
$ devenv cglm.sln /Build Release $ devenv cglm.sln /Build Release
``` ```
### Building Docs
First you need install Sphinx: http://www.sphinx-doc.org/en/master/usage/installation.html
then:
```bash
$ cd docs
$ sphinx-build source build
```
it will compile docs into build folder, you can run index.html inside that function.
## How to use ## How to use
If you want to use inline versions of funcstions then; include main header If you want to use inline versions of funcstions then; include main header
```C ```C
@@ -151,7 +185,34 @@ this header will include all heaers with c postfix. You need to call functions w
glmc_vec_normalize(vec); glmc_vec_normalize(vec);
``` ```
Function usage and parameters are documented inside related headers. Function usage and parameters are documented inside related headers. You may see same parameter passed twice in some examples like this:
```C
glm_mat4_mul(m1, m2, m1);
/* or */
glm_mat4_mul(m1, m1, m1);
```
the first two parameter are **[in]** and the last one is **[out]** parameter. After multiplied *m1* and *m2* the result is stored in *m1*. This is why we send *m1* twice. You may store result in different matrix, this just an example.
## How to send matrix to OpenGL
mat4 is array of vec4 and vec4 is array of floats. `glUniformMatrix4fv` functions accecpts `float*` as `value` (last param), so you can cast mat4 to float* or you can pass first column of matrix as beginning of memory of matrix:
Option 1: Send first column
```C
glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0]);
/* array of matrices */
glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0][0]);
```
Option 2: Cast matrix to pointer type (also valid for multiple dimensional arrays)
```C
glUniformMatrix4fv(location, 1, GL_FALSE, (float *)matrix);
```
You can pass same way to another APIs e.g. Vulkan, DX...
## Notes ## Notes
- This library uses float types only, does not support Integers, Double... yet - This library uses float types only, does not support Integers, Double... yet
@@ -162,5 +223,5 @@ Function usage and parameters are documented inside related headers.
- [ ] Unit tests for comparing cglm with glm results - [ ] Unit tests for comparing cglm with glm results
- [x] Add version info - [x] Add version info
- [ ] Unaligned operations (e.g. `glm_umat4_mul`) - [ ] Unaligned operations (e.g. `glm_umat4_mul`)
- [ ] Extra documentation - [x] Extra documentation
- [ ] ARM Neon Arch (In Progress) - [ ] ARM Neon Arch (In Progress)

View File

@@ -7,7 +7,7 @@
#***************************************************************************** #*****************************************************************************
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([cglm], [0.2.1], [info@recp.me]) AC_INIT([cglm], [0.3.5], [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

@@ -0,0 +1,77 @@
.. default-domain:: C
affine transform matrix (specialized functions)
================================================================================
Header: cglm/affine-mat.h
We mostly use glm_mat4_* for 4x4 general and transform matrices. **cglm**
provides optimized version of some functions. Because affine transform matrix is
a known format, for instance all last item of first three columns is zero.
You should be careful when using these functions. For instance :c:func:`glm_mul`
assumes matrix will be this format:
.. code-block:: text
R R R X
R R R Y
R R R Z
0 0 0 W
if you override zero values here then use :c:func:`glm_mat4_mul` version.
You cannot use :c:func:`glm_mul` anymore.
Same is also true for :c:func:`glm_inv_tr` if you only have rotation and
translation then it will work as expected, otherwise you cannot use that.
In the future it may accept scale factors too but currectly it does not.
Table of contents (click func go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_mul`
#. :c:func:`glm_inv_tr`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_mul(mat4 m1, mat4 m2, mat4 dest)
| this is similar to glm_mat4_mul but specialized to affine transform
Matrix format should be:
.. code-block:: text
R R R X
R R R Y
R R R Z
0 0 0 W
this reduces some multiplications. It should be faster than mat4_mul.
if you are not sure about matrix format then DON'T use this! use mat4_mul
Parameters:
| *[in]* **m1** affine matrix 1
| *[in]* **m2** affine matrix 2
| *[out]* **dest** result matrix
.. c:function:: void glm_inv_tr(mat4 mat)
| inverse orthonormal rotation + translation matrix (ridig-body)
.. code-block:: text
X = | R T | X' = | R' -R'T |
| 0 1 | | 0 1 |
use this if you only have rotation + translation, this should work faster
than :c:func:`glm_mat4_inv`
Don't use this if your matrix includes other things e.g. scale, shear...
Parameters:
| *[in,out]* **mat** affine matrix

242
docs/source/affine.rst Normal file
View File

@@ -0,0 +1,242 @@
.. default-domain:: C
affine transforms
================================================================================
Header: cglm/affine.h
Functions with **_make** prefix expect you don't have a matrix and they create
a matrix for you. You don't need to pass identity matrix.
But other functions expect you have a matrix and you want to transform them. If
you didn't have any existing matrix you have to initialize matrix to identity
before sending to transfrom functions.
There are also functions to decompose transform matrix. These functions can't
decompose matrix after projected.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_translate_to`
#. :c:func:`glm_translate`
#. :c:func:`glm_translate_x`
#. :c:func:`glm_translate_y`
#. :c:func:`glm_translate_z`
#. :c:func:`glm_translate_make`
#. :c:func:`glm_scale_to`
#. :c:func:`glm_scale_make`
#. :c:func:`glm_scale`
#. :c:func:`glm_scale1`
#. :c:func:`glm_scale_uni`
#. :c:func:`glm_rotate_x`
#. :c:func:`glm_rotate_y`
#. :c:func:`glm_rotate_z`
#. :c:func:`glm_rotate_ndc_make`
#. :c:func:`glm_rotate_make`
#. :c:func:`glm_rotate_ndc`
#. :c:func:`glm_rotate`
#. :c:func:`glm_decompose_scalev`
#. :c:func:`glm_uniscaled`
#. :c:func:`glm_decompose_rs`
#. :c:func:`glm_decompose`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_translate_to(mat4 m, vec3 v, mat4 dest)
translate existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
| *[out]* **dest** translated matrix
.. c:function:: void glm_translate(mat4 m, vec3 v)
translate existing transform matrix by *v* vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_translate_x(mat4 m, float x)
translate existing transform matrix by x factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** x factor
.. c:function:: void glm_translate_y(mat4 m, float y)
translate existing transform matrix by *y* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** y factor
.. c:function:: void glm_translate_z(mat4 m, float z)
translate existing transform matrix by *z* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** z factor
.. c:function:: void glm_translate_make(mat4 m, vec3 v)
creates NEW translate transform matrix by *v* vector.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
scale existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
| *[out]* **dest** scaled matrix
.. c:function:: void glm_scale_make(mat4 m, vec3 v)
creates NEW scale matrix by v vector
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale(mat4 m, vec3 v)
scales existing transform matrix by v vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale1(mat4 m, float s)
DEPRECATED! Use glm_scale_uni
.. c:function:: void glm_scale_uni(mat4 m, float s)
applies uniform scale to existing transform matrix v = [s, s, s]
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale factor
.. c:function:: void glm_rotate_x(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around X axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_y(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Y axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_z(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Z axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_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)
creates NEW rotation matrix by angle and axis,
axis will be normalized so you don't need to normalize it
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **axis** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate_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)
rotate existing transform matrix around Z axis by angle and axis
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
decompose scale vector
Parameters:
| *[in]* **m** affine transform
| *[out]* **s** scale vector (Sx, Sy, Sz)
.. c:function:: bool glm_uniscaled(mat4 m)
returns true if matrix is uniform scaled.
This is helpful for creating normal matrix.
Parameters:
| *[in]* **m** matrix
.. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transform
| *[out]* **r** rotation matrix
| *[out]* **s** scale matrix
.. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
decompose affine transform, TODO: extract shear factors.
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transfrom
| *[out]* **t** translation vector
| *[out]* **r** rotation matrix (mat4)
| *[out]* **s** scaling vector [X, Y, Z]

46
docs/source/api.rst Normal file
View File

@@ -0,0 +1,46 @@
API documentation
================================
Some functions may exist twice,
once for their namespace and once for global namespace
to make easier to write very common functions
For instance, in general we use :code:`glm_vec_dot` to get dot product
of two **vec3**. Now we can also do this with :code:`glm_dot`,
same for *_cross* and so on...
The original function stays where it is, the function in global namespace
of same name is just an alias, so there is no call version of those functions.
e.g there is no func like :code:`glmc_dot` because *glm_dot* is just alias for
:code:`glm_vec_dot`
By including **cglm/cglm.h** header you will include all inline version
of functions. Since functions in this header[s] are inline you don't need to
build or link *cglm* against your project.
But by including **cglm/call.h** header you will include all *non-inline*
version of functions. You need to build *cglm* and link it.
Follow the :doc:`build` documentation for this
.. toctree::
:maxdepth: 1
:caption: API categories:
affine
affine-mat
cam
frustum
box
quat
euler
mat4
mat3
vec3
vec3-ext
vec4
vec4-ext
color
plane
util
io
call

93
docs/source/box.rst Normal file
View File

@@ -0,0 +1,93 @@
.. default-domain:: C
axis aligned bounding box (AABB)
================================================================================
Header: cglm/box.h
Some convenient functions provided for AABB.
**Definition of box:**
cglm defines box as two dimensional array of vec3.
The first element is **min** point and the second one is **max** point.
If you have another type e.g. struct or even another representation then you must
convert it before and after call cglm box function.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_aabb_transform`
#. :c:func:`glm_aabb_merge`
#. :c:func:`glm_aabb_crop`
#. :c:func:`glm_aabb_crop_until`
#. :c:func:`glm_aabb_frustum`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2])
| apply transform to Axis-Aligned Bounding Box
Parameters:
| *[in]* **box** bounding box
| *[in]* **m** transform matrix
| *[out]* **dest** transformed bounding box
.. c:function:: void glm_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2])
| merges two AABB bounding box and creates new one
two box must be in same space, if one of box is in different space then
you should consider to convert it's space by glm_box_space
Parameters:
| *[in]* **box1** bounding box 1
| *[in]* **box2** bounding box 2
| *[out]* **dest** merged bounding box
.. c:function:: void glm_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2])
| crops a bounding box with another one.
this could be useful for gettng a bbox which fits with view frustum and
object bounding boxes. In this case you crop view frustum box with objects
box
Parameters:
| *[in]* **box** bounding box 1
| *[in]* **cropBox** crop box
| *[out]* **dest** cropped bounding box
.. c:function:: void glm_aabb_crop_until(vec3 box[2], vec3 cropBox[2], vec3 clampBox[2], vec3 dest[2])
| crops a bounding box with another one.
this could be useful for gettng a bbox which fits with view frustum and
object bounding boxes. In this case you crop view frustum box with objects
box
Parameters:
| *[in]* **box** bounding box
| *[in]* **cropBox** crop box
| *[in]* **clampBox** miniumum box
| *[out]* **dest** cropped bounding box
.. c:function:: bool glm_aabb_frustum(vec3 box[2], vec4 planes[6])
| check if AABB intersects with frustum planes
this could be useful for frustum culling using AABB.
OPTIMIZATION HINT:
if planes order is similar to LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
then this method should run even faster because it would only use two
planes if object is not inside the two planes
fortunately cglm extracts planes as this order! just pass what you got!
Parameters:
| *[in]* **box** bounding box
| *[out]* **planes** frustum planes

19
docs/source/call.rst Normal file
View File

@@ -0,0 +1,19 @@
.. default-domain:: C
precompiled functions (call)
================================================================================
All funcitons in **glm_** namespace are forced to **inline**.
Most functions also have pre-compiled version.
Precompiled versions are in **glmc_** namespace. *c* in the namespace stands for
"call".
Since precompiled functions are just wrapper for inline verisons,
these functions are not documented individually.
It would be duplicate documentation also it
would be hard to sync documentation between inline and call verison for me.
By including **clgm/cglm.h** you include all inline verisons. To get precompiled
versions you need to include **cglm/call.h** header it also includes all
call versions plus *clgm/cglm.h* (inline verisons)

298
docs/source/cam.rst Normal file
View File

@@ -0,0 +1,298 @@
.. default-domain:: C
camera
======
Header: cglm/cam.h
There are many convenient functions for camera. For instance :c:func:`glm_look`
is just wrapper for :c:func:`glm_lookat`. Sometimes you only have direction
instead of target, so that makes easy to build view matrix using direction.
There is also :c:func:`glm_look_anyup` function which can help build view matrix
without providing UP axis. It uses :c:func:`glm_vec_ortho` to get a UP axis and
builds view matrix.
You can also *_default* versions of ortho and perspective to build projection
fast if you don't care specific projection values.
*_decomp* means decompose; these function can help to decompose projection
matrices.
**NOTE**: Be careful when working with high range (very small near, very large
far) projection matrices. You may not get exact value you gave.
**float** type cannot store very high precision so you will lose precision.
Also your projection matrix will be inaccurate due to losing precision
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_frustum`
#. :c:func:`glm_ortho`
#. :c:func:`glm_ortho_aabb`
#. :c:func:`glm_ortho_aabb_p`
#. :c:func:`glm_ortho_aabb_pz`
#. :c:func:`glm_ortho_default`
#. :c:func:`glm_ortho_default_s`
#. :c:func:`glm_perspective`
#. :c:func:`glm_perspective_default`
#. :c:func:`glm_perspective_resize`
#. :c:func:`glm_lookat`
#. :c:func:`glm_look`
#. :c:func:`glm_look_anyup`
#. :c:func:`glm_persp_decomp`
#. :c:func:`glm_persp_decompv`
#. :c:func:`glm_persp_decomp_x`
#. :c:func:`glm_persp_decomp_y`
#. :c:func:`glm_persp_decomp_z`
#. :c:func:`glm_persp_decomp_far`
#. :c:func:`glm_persp_decomp_near`
#. :c:func:`glm_persp_fovy`
#. :c:func:`glm_persp_aspect`
#. :c:func:`glm_persp_sizes`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_frustum(float left, float right, float bottom, float top, float nearVal, float farVal, mat4 dest)
| set up perspective peprojection matrix
Parameters:
| *[in]* **left** viewport.left
| *[in]* **right** viewport.right
| *[in]* **bottom** viewport.bottom
| *[in]* **top** viewport.top
| *[in]* **nearVal** near clipping plane
| *[in]* **farVal** far clipping plane
| *[out]* **dest** result matrix
.. c:function:: void glm_ortho(float left, float right, float bottom, float top, float nearVal, float farVal, mat4 dest)
| set up orthographic projection matrix
Parameters:
| *[in]* **left** viewport.left
| *[in]* **right** viewport.right
| *[in]* **bottom** viewport.bottom
| *[in]* **top** viewport.top
| *[in]* **nearVal** near clipping plane
| *[in]* **farVal** far clipping plane
| *[out]* **dest** result matrix
.. c:function:: void glm_ortho_aabb(vec3 box[2], mat4 dest)
| set up orthographic projection matrix using bounding box
| bounding box (AABB) must be in view space
Parameters:
| *[in]* **box** AABB
| *[in]* **dest** result matrix
.. c:function:: void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
| set up orthographic projection matrix using bounding box
| bounding box (AABB) must be in view space
this version adds padding to box
Parameters:
| *[in]* **box** AABB
| *[in]* **padding** padding
| *[out]* **d** result matrix
.. c:function:: void glm_ortho_aabb_pz(vec3 box[2], float padding, mat4 dest)
| set up orthographic projection matrix using bounding box
| bounding box (AABB) must be in view space
this version adds Z padding to box
Parameters:
| *[in]* **box** AABB
| *[in]* **padding** padding for near and far
| *[out]* **d** result matrix
Returns:
square of norm / magnitude
.. c:function:: void glm_ortho_default(float aspect, mat4 dest)
| set up unit orthographic projection matrix
Parameters:
| *[in]* **aspect** aspect ration ( width / height )
| *[out]* **dest** result matrix
.. c:function:: void glm_ortho_default_s(float aspect, float size, mat4 dest)
| set up orthographic projection matrix with given CUBE size
Parameters:
| *[in]* **aspect** aspect ration ( width / height )
| *[in]* **size** cube size
| *[out]* **dest** result matrix
.. c:function:: void glm_perspective(float fovy, float aspect, float nearVal, float farVal, mat4 dest)
| set up perspective projection matrix
Parameters:
| *[in]* **fovy** field of view angle
| *[in]* **aspect** aspect ratio ( width / height )
| *[in]* **nearVal** near clipping plane
| *[in]* **farVal** far clipping planes
| *[out]* **dest** result matrix
.. c:function:: void glm_perspective_default(float aspect, mat4 dest)
| set up perspective projection matrix with default near/far
and angle values
Parameters:
| *[in]* **aspect** aspect aspect ratio ( width / height )
| *[out]* **dest** result matrix
.. c:function:: void glm_perspective_resize(float aspect, mat4 proj)
| resize perspective matrix by aspect ratio ( width / height )
this makes very easy to resize proj matrix when window / viewport reized
Parameters:
| *[in]* **aspect** aspect ratio ( width / height )
| *[in, out]* **proj** perspective projection matrix
.. c:function:: void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest)
| set up view matrix
Parameters:
| *[in]* **eye** eye vector
| *[in]* **center** center vector
| *[in]* **up** up vector
| *[out]* **dest** result matrix
.. c:function:: void glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest)
| set up view matrix
convenient wrapper for :c:func:`glm_lookat`: if you only have direction not
target self then this might be useful. Because you need to get target
from direction.
Parameters:
| *[in]* **eye** eye vector
| *[in]* **center** direction vector
| *[in]* **up** up vector
| *[out]* **dest** result matrix
.. c:function:: void glm_look_anyup(vec3 eye, vec3 dir, mat4 dest)
| set up view matrix
convenient wrapper for :c:func:`glm_look` if you only have direction
and if you don't care what UP vector is then this might be useful
to create view matrix
Parameters:
| *[in]* **eye** eye vector
| *[in]* **center** direction vector
| *[out]* **dest** result matrix
.. c:function:: void glm_persp_decomp(mat4 proj, float *nearVal, float *farVal, float *top, float *bottom, float *left, float *right)
| decomposes frustum values of perspective projection.
Parameters:
| *[in]* **eye** perspective projection matrix
| *[out]* **nearVal** near
| *[out]* **farVal** far
| *[out]* **top** top
| *[out]* **bottom** bottom
| *[out]* **left** left
| *[out]* **right** right
.. c:function:: void glm_persp_decompv(mat4 proj, float dest[6])
| decomposes frustum values of perspective projection.
| this makes easy to get all values at once
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **dest** array
.. c:function:: void glm_persp_decomp_x(mat4 proj, float *left, float *right)
| decomposes left and right values of perspective projection.
| x stands for x axis (left / right axis)
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **left** left
| *[out]* **right** right
.. c:function:: void glm_persp_decomp_y(mat4 proj, float *top, float *bottom)
| decomposes top and bottom values of perspective projection.
| y stands for y axis (top / botom axis)
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **top** top
| *[out]* **bottom** bottom
.. c:function:: void glm_persp_decomp_z(mat4 proj, float *nearVal, float *farVal)
| decomposes near and far values of perspective projection.
| z stands for z axis (near / far axis)
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **nearVal** near
| *[out]* **farVal** far
.. c:function:: void glm_persp_decomp_far(mat4 proj, float * __restrict farVal)
| decomposes far value of perspective projection.
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **farVal** far
.. c:function:: void glm_persp_decomp_near(mat4 proj, float * __restrict nearVal)
| decomposes near value of perspective projection.
Parameters:
| *[in]* **proj** perspective projection matrix
| *[out]* **nearVal** near
.. c:function:: float glm_persp_fovy(mat4 proj)
| returns field of view angle along the Y-axis (in radians)
if you need to degrees, use glm_deg to convert it or use this:
fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
Parameters:
| *[in]* **proj** perspective projection matrix
Returns:
| fovy in radians
.. c:function:: float glm_persp_aspect(mat4 proj)
| returns aspect ratio of perspective projection
Parameters:
| *[in]* **proj** perspective projection matrix
.. c:function:: void glm_persp_sizes(mat4 proj, float fovy, vec4 dest)
| returns sizes of near and far planes of perspective projection
Parameters:
| *[in]* **proj** perspective projection matrix
| *[in]* **fovy** fovy (see brief)
| *[out]* **dest** sizes order: [Wnear, Hnear, Wfar, Hfar]

BIN
docs/source/cglm-intro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

34
docs/source/color.rst Normal file
View File

@@ -0,0 +1,34 @@
.. default-domain:: C
color
================================================================================
Header: cglm/color.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_luminance`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: float glm_luminance(vec3 rgb)
| averages the color channels into one value
This function uses formula in COLLADA 1.5 spec which is
.. code-block:: text
luminance = (color.r * 0.212671) +
(color.g * 0.715160) +
(color.b * 0.072169)
It is based on the ISO/CIE color standards (see ITU-R Recommendation BT.709-4),
that averages the color channels into one value
Parameters:
| *[in]* **rgb** RGB color

View File

@@ -30,7 +30,15 @@
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [] extensions = [
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.mathjax',
'sphinx.ext.ifconfig',
'sphinx.ext.viewcode',
'sphinx.ext.githubpages'
]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates'] templates_path = ['_templates']
@@ -54,9 +62,9 @@ author = u'Recep Aslantas'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = u'0.2.1' version = u'0.3.4'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = u'0.2.1' release = u'0.3.4'
# 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.
@@ -161,3 +169,31 @@ texinfo_documents = [
author, 'cglm', 'One line description of project.', author, 'cglm', 'One line description of project.',
'Miscellaneous'), 'Miscellaneous'),
] ]
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''
# A unique identification for the text.
#
# epub_uid = ''
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
# -- Extension configuration -------------------------------------------------
# -- Options for todo extension ----------------------------------------------
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

171
docs/source/euler.rst Normal file
View File

@@ -0,0 +1,171 @@
.. default-domain:: C
euler angles
============
Header: cglm/euler.h
You may wonder what **glm_euler_sq** type ( **_sq** stands for sequence ) and
:c:func:`glm_euler_by_order` do.
I used them to convert euler angles in one coordinate system to another. For
instance if you have **Z_UP** euler angles and if you want to convert it
to **Y_UP** axis then :c:func:`glm_euler_by_order` is your friend. For more
information check :c:func:`glm_euler_order` documentation
You must pass arrays as array, if you use C compiler then you can use something
like this:
.. code-block:: c
float pitch, yaw, roll;
mat4 rot;
/* pitch = ...; yaw = ...; roll = ... */
glm_euler((vec3){pitch, yaw, roll}, rot);
Rotation Conveniention
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Current *cglm*'s euler functions uses these convention:
* TaitBryan angles (x-y-z convention)
* Intrinsic rotations (pitch, yaw and roll).
This is reserve order of extrinsic (elevation, heading and bank) rotation
* Right hand rule (actually all rotations in *cglm* use **RH**)
* All angles used in *cglm* are **RADIANS** not degrees
**NOTE**: The default :c:func:`glm_euler` function is the short name of
:c:func:`glm_euler_xyz` this is why you can't see :c:func:`glm_euler_xyz`.
When you see an euler function which doesn't have any X, Y, Z suffix then
assume that uses **_xyz** (or instead it accept order as parameter).
If rotation doesn't work properly, your options:
1. If you use (or paste) degrees convert it to radians before calling an euler function
.. code-block:: c
float pitch, yaw, roll;
mat4 rot;
/* pitch = degrees; yaw = degrees; roll = degrees */
glm_euler((vec3){glm_rad(pitch), glm_rad(yaw), glm_rad(roll)}, rot);
2. Convention mismatch. You may have extrinsic angles,
if you do (if you must) then consider to use reverse order e.g if you have
**xyz** extrinsic then use **zyx**
3. *cglm* may implemented it wrong, consider to create an issue to report it
or pull request to fix it
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Types:
1. glm_euler_sq
Functions:
1. :c:func:`glm_euler_order`
#. :c:func:`glm_euler_angles`
#. :c:func:`glm_euler`
#. :c:func:`glm_euler_zyx`
#. :c:func:`glm_euler_zxy`
#. :c:func:`glm_euler_xzy`
#. :c:func:`glm_euler_yzx`
#. :c:func:`glm_euler_yxz`
#. :c:func:`glm_euler_by_order`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: glm_euler_sq glm_euler_order(int ord[3])
| packs euler angles order to glm_euler_sq enum.
To use :c:func:`glm_euler_by_order` function you need *glm_euler_sq*. You
can get it with this function.
You can build param like this:
| X = 0, Y = 1, Z = 2
if you have ZYX order then you pass this: [2, 1, 0] = ZYX.
if you have YXZ order then you pass this: [1, 0, 2] = YXZ
As you can see first item specifies which axis will be first then the
second one specifies which one will be next an so on.
Parameters:
| *[in]* **ord** euler angles order [Angle1, Angle2, Angle2]
Returns:
packed euler order
.. c:function:: void glm_euler_angles(mat4 m, vec3 dest)
| extract euler angles (in radians) using xyz order
Parameters:
| *[in]* **m** affine transform
| *[out]* **dest** angles vector [x, y, z]
.. c:function:: void glm_euler(vec3 angles, mat4 dest)
| build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ex, Ey, Ez]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_zyx(vec3 angles, mat4 dest)
| build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ez, Ey, Ex]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_zxy(vec3 angles, mat4 dest)
| build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ez, Ex, Ey]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_xzy(vec3 angles, mat4 dest)
| build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ex, Ez, Ey]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_yzx(vec3 angles, mat4 dest)
build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ey, Ez, Ex]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_yxz(vec3 angles, mat4 dest)
| build rotation matrix from euler angles
Parameters:
| *[in]* **angles** angles as vector [Ey, Ex, Ez]
| *[in]* **dest** rotation matrix
.. c:function:: void glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest)
| build rotation matrix from euler angles with given euler order.
Use :c:func:`glm_euler_order` function to build *ord* parameter
Parameters:
| *[in]* **angles** angles as vector (ord parameter spceifies angles order)
| *[in]* **ord** euler order
| *[in]* **dest** rotation matrix

168
docs/source/frustum.rst Normal file
View File

@@ -0,0 +1,168 @@
.. default-domain:: C
frustum
=============
Header: cglm/frustum.h
cglm provides convenient functions to extract frustum planes, corners...
All extracted corners are **vec4** so you must create array of **vec4**
not **vec3**. If you want to store them to save space you msut convert them
yourself.
**vec4** is used to speed up functions need to corners. This is why frustum
fucntions use *vec4* instead of *vec3*
Currenty related-functions use [-1, 1] clip space configuration to extract
corners but you can override it by prodiving **GLM_CUSTOM_CLIPSPACE** macro.
If you provide it then you have to all bottom macros as *vec4*
Current configuration:
.. code-block:: c
/* near */
GLM_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
GLM_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
GLM_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
GLM_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
/* far */
GLM_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
GLM_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
GLM_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
GLM_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
Explain of short names:
* **LBN**: left bottom near
* **LTN**: left top near
* **RTN**: right top near
* **RBN**: right bottom near
* **LBF**: left bottom far
* **LTF**: left top far
* **RTF**: right top far
* **RBF**: right bottom far
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
.. code-block:: c
GLM_LBN 0 /* left bottom near */
GLM_LTN 1 /* left top near */
GLM_RTN 2 /* right top near */
GLM_RBN 3 /* right bottom near */
GLM_LBF 4 /* left bottom far */
GLM_LTF 5 /* left top far */
GLM_RTF 6 /* right top far */
GLM_RBF 7 /* right bottom far */
GLM_LEFT 0
GLM_RIGHT 1
GLM_BOTTOM 2
GLM_TOP 3
GLM_NEAR 4
GLM_FAR 5
Functions:
1. :c:func:`glm_frustum_planes`
#. :c:func:`glm_frustum_corners`
#. :c:func:`glm_frustum_center`
#. :c:func:`glm_frustum_box`
#. :c:func:`glm_frustum_corners_at`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_frustum_planes(mat4 m, vec4 dest[6])
| extracts view frustum planes
planes' space:
- if m = proj: View Space
- if m = viewProj: World Space
- if m = MVP: Object Space
You probably want to extract planes in world space so use viewProj as m
Computing viewProj:
.. code-block:: c
glm_mat4_mul(proj, view, viewProj);
Exracted planes order: [left, right, bottom, top, near, far]
Parameters:
| *[in]* **m** matrix
| *[out]* **dest** exracted view frustum planes
.. c:function:: void glm_frustum_corners(mat4 invMat, vec4 dest[8])
| extracts view frustum corners using clip-space coordinates
corners' space:
- if m = invViewProj: World Space
- if m = invMVP: Object Space
You probably want to extract corners in world space so use **invViewProj**
Computing invViewProj:
.. code-block:: c
glm_mat4_mul(proj, view, viewProj);
...
glm_mat4_inv(viewProj, invViewProj);
if you have a near coord at **i** index,
you can get it's far coord by i + 4;
follow example below to understand that
For instance to find center coordinates between a near and its far coord:
.. code-block:: c
for (j = 0; j < 4; j++) {
glm_vec_center(corners[i], corners[i + 4], centerCorners[i]);
}
corners[i + 4] is far of corners[i] point.
Parameters:
| *[in]* **invMat** matrix
| *[out]* **dest** exracted view frustum corners
.. c:function:: void glm_frustum_center(vec4 corners[8], vec4 dest)
| finds center of view frustum
Parameters:
| *[in]* **corners** view frustum corners
| *[out]* **dest** view frustum center
.. c:function:: void glm_frustum_box(vec4 corners[8], mat4 m, vec3 box[2])
| finds bounding box of frustum relative to given matrix e.g. view mat
Parameters:
| *[in]* **corners** view frustum corners
| *[in]* **m** matrix to convert existing conners
| *[out]* **box** bounding box as array [min, max]
.. c:function:: void glm_frustum_corners_at(vec4 corners[8], float splitDist, float farDist, vec4 planeCorners[4])
| finds planes corners which is between near and far planes (parallel)
this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
find planes' corners but you will need to one more plane.
Actually you have it, it is near, far or created previously with this func ;)
Parameters:
| *[in]* **corners** frustum corners
| *[in]* **splitDist** split distance
| *[in]* **farDist** far distance (zFar)
| *[out]* **planeCorners** plane corners [LB, LT, RT, RB]

View File

@@ -1,6 +1,9 @@
Getting Started Getting Started
================================ ================================
Types:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**cglm** uses **glm** prefix for all functions e.g. glm_lookat. You can see supported types in common header file: **cglm** uses **glm** prefix for all functions e.g. glm_lookat. You can see supported types in common header file:
.. code-block:: c .. code-block:: c
@@ -18,23 +21,50 @@ Getting Started
As you can see types don't store extra informations in favor of space. As you can see types don't store extra informations in favor of space.
You can send these values e.g. matrix to OpenGL directly without casting or calling a function like *value_ptr* You can send these values e.g. matrix to OpenGL directly without casting or calling a function like *value_ptr*
*vec4* and *mat4* requires 16 byte aligment because vec4 and mat4 operations are Aligment is Required:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**vec4** and **mat4** requires 16 byte aligment because vec4 and mat4 operations are
vectorized by SIMD instructions (SSE/AVX). vectorized by SIMD instructions (SSE/AVX).
Allocations:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*cglm* doesn't alloc any memory on heap. So it doesn't provide any allocator.
You must allocate memory yourself. You should alloc memory for out parameters too if you pass pointer of memory location.
When allocating memory don't forget that **vec4** and **mat4** requires aligment.
**NOTE:** Unaligned vec4 and unaligned mat4 operations will be supported in the future. Check todo list. **NOTE:** Unaligned vec4 and unaligned mat4 operations will be supported in the future. Check todo list.
Because you may want to multiply a CGLM matrix with external matrix. Because you may want to multiply a CGLM matrix with external matrix.
There is no guarantee that non-CGLM matrix is aligned. Unaligned types will have *u* prefix e.g. **umat4** There is no guarantee that non-CGLM matrix is aligned. Unaligned types will have *u* prefix e.g. **umat4**
Array vs Struct:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*cglm* uses arrays for vector and matrix types. So you can't access individual
elements like vec.x, vec.y, vec.z... You must use subscript to access vector elements
e.g. vec[0], vec[1], vec[2].
Also I think it is more meaningful to access matrix elements with subscript
e.g **matrix[2][3]** instead of **matrix._23**. Since matrix is array of vectors,
vectors are also defined as array. This makes types homogeneous.
**Return arrays?**
Since C doesn't support return arrays, cglm also doesn't support this feature.
Function design:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: cglm-intro.png
:width: 492px
:height: 297px
:align: center
cglm provides a few way to call a function to do same operation. cglm provides a few way to call a function to do same operation.
* Inline - *glm_, glm_u* * Inline - *glm_, glm_u*
* aligned
* unaligned (todo)
* Pre-compiled - *glmc_, glmc_u* * Pre-compiled - *glmc_, glmc_u*
* aligned
* unaligned (todo)
For instance **glm_mat4_mul** is inline (all *glm_* functions are inline), to make it non-inline (pre-compiled) For instance **glm_mat4_mul** is inline (all *glm_* functions are inline), to make it non-inline (pre-compiled),
call it as **glmc_mat4_mul** from library, to use unaligned version use **glm_umat4_mul** (todo). call it as **glmc_mat4_mul** from library, to use unaligned version use **glm_umat4_mul** (todo).
Most functions have **dest** parameter for output. For instance mat4_mul func looks like this: Most functions have **dest** parameter for output. For instance mat4_mul func looks like this:

View File

@@ -9,7 +9,7 @@ Welcome to cglm's documentation!
**cglm** is optimized 3D math library written in C99 (compatible with C89). **cglm** is optimized 3D math library written in C99 (compatible with C89).
It is similar to original **glm** library except this is mainly for **C** It is similar to original **glm** library except this is mainly for **C**
This library stores matrices as row-major order but in the future column-major This library stores matrices as column-major order but in the future row-major
is considered to be supported as optional. is considered to be supported as optional.
Also currently only **float** type is supported for most operations. Also currently only **float** type is supported for most operations.
@@ -28,14 +28,18 @@ Also currently only **float** type is supported for most operations.
* euler angles / yaw-pitch-roll to matrix * euler angles / yaw-pitch-roll to matrix
* extract euler angles * extract euler angles
* inline or pre-compiled function call * inline or pre-compiled function call
* more features (todo) * frustum (extract view frustum planes, corners...)
* bounding box (AABB in Frustum (culling), crop, merge...)
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 1
:caption: Table Of Contents: :caption: Table Of Contents:
build build
getting_started getting_started
opengl
api
Indices and tables Indices and tables
================== ==================

92
docs/source/io.rst Normal file
View File

@@ -0,0 +1,92 @@
.. default-domain:: C
io (input / output e.g. print)
================================================================================
Header: cglm/io.h
There are some built-in print functions which may save your time,
especially for debugging.
All functions accept **FILE** parameter which makes very flexible.
You can even print it to file on disk.
In general you will want to print them to console to see results.
You can use **stdout** and **stderr** to write results to console.
Some programs may occupy **stdout** but you can still use **stderr**.
Using **stderr** is suggested.
Example to print mat4 matrix:
.. code-block:: c
mat4 transform;
/* ... */
glm_mat4_print(transform, stderr);
**NOTE:** print functions use **%0.4f** precision if you need more
(you probably will in some cases), you can change it temporary.
cglm may provide precision parameter in the future
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_mat4_print`
#. :c:func:`glm_mat3_print`
#. :c:func:`glm_vec4_print`
#. :c:func:`glm_vec3_print`
#. :c:func:`glm_ivec3_print`
#. :c:func:`glm_versor_print`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_mat4_print(mat4 matrix, FILE * __restrict ostream)
| print mat4 to given stream
Parameters:
| *[in]* **matrix** matrix
| *[in]* **ostream** FILE to write
.. c:function:: void glm_mat3_print(mat3 matrix, FILE * __restrict ostream)
| print mat3 to given stream
Parameters:
| *[in]* **matrix** matrix
| *[in]* **ostream** FILE to write
.. c:function:: void glm_vec4_print(vec4 vec, FILE * __restrict ostream)
| print vec4 to given stream
Parameters:
| *[in]* **vec** vector
| *[in]* **ostream** FILE to write
.. c:function:: void glm_vec3_print(vec3 vec, FILE * __restrict ostream)
| print vec3 to given stream
Parameters:
| *[in]* **vec** vector
| *[in]* **ostream** FILE to write
.. c:function:: void glm_ivec3_print(ivec3 vec, FILE * __restrict ostream)
| print ivec3 to given stream
Parameters:
| *[in]* **vec** vector
| *[in]* **ostream** FILE to write
.. c:function:: void glm_versor_print(versor vec, FILE * __restrict ostream)
| print quaternion to given stream
Parameters:
| *[in]* **vec** quaternion
| *[in]* **ostream** FILE to write

134
docs/source/mat3.rst Normal file
View File

@@ -0,0 +1,134 @@
.. default-domain:: C
mat3
====
Header: cglm/mat3.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
1. GLM_MAT3_IDENTITY_INIT
#. GLM_MAT3_ZERO_INIT
#. GLM_MAT3_IDENTITY
#. GLM_MAT3_ZERO
#. glm_mat3_dup(mat, dest)
Functions:
1. :c:func:`glm_mat3_copy`
#. :c:func:`glm_mat3_identity`
#. :c:func:`glm_mat3_mul`
#. :c:func:`glm_mat3_transpose_to`
#. :c:func:`glm_mat3_transpose`
#. :c:func:`glm_mat3_mulv`
#. :c:func:`glm_mat3_scale`
#. :c:func:`glm_mat3_det`
#. :c:func:`glm_mat3_inv`
#. :c:func:`glm_mat3_swap_col`
#. :c:func:`glm_mat3_swap_row`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_mat3_copy(mat3 mat, mat3 dest)
copy mat3 to another one (dest).
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat3_identity(mat3 mat)
copy identity mat3 to mat, or makes mat to identiy
Parameters:
| *[out]* **mat** matrix
.. c:function:: void glm_mat3_mul(mat3 m1, mat3 m2, mat3 dest)
multiply m1 and m2 to dest
m1, m2 and dest matrices can be same matrix, it is possible to write this:
.. code-block:: c
mat3 m = GLM_MAT3_IDENTITY_INIT;
glm_mat3_mul(m, m, m);
Parameters:
| *[in]* **m1** left matrix
| *[in]* **m2** right matrix
| *[out]* **dest** destination matrix
.. c:function:: void glm_mat3_transpose_to(mat3 m, mat3 dest)
transpose mat4 and store in dest
source matrix will not be transposed unless dest is m
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat3_transpose(mat3 m)
tranpose mat3 and store result in same matrix
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat3_mulv(mat3 m, vec3 v, vec3 dest)
multiply mat4 with vec4 (column vector) and store in dest vector
Parameters:
| *[in]* **mat** mat3 (left)
| *[in]* **v** vec3 (right, column vector)
| *[out]* **dest** destination (result, column vector)
.. c:function:: void glm_mat3_scale(mat3 m, float s)
multiply matrix with scalar
Parameters:
| *[in, out]* **mat** matrix
| *[in]* **dest** scalar
.. c:function:: float glm_mat3_det(mat3 mat)
returns mat3 determinant
Parameters:
| *[in]* **mat** matrix
Returns:
mat3 determinant
.. c:function:: void glm_mat3_inv(mat3 mat, mat3 dest)
inverse mat3 and store in dest
Parameters:
| *[in]* **mat** matrix
| *[out]* **dest** destination (inverse matrix)
.. c:function:: void glm_mat3_swap_col(mat3 mat, int col1, int col2)
swap two matrix columns
Parameters:
| *[in, out]* **mat** matrix
| *[in]* **col1** col1
| *[in]* **col2** col2
.. c:function:: void glm_mat3_swap_row(mat3 mat, int row1, int row2)
swap two matrix rows
Parameters:
| *[in, out]* **mat** matrix
| *[in]* **row1** row1
| *[in]* **row2** row2

231
docs/source/mat4.rst Normal file
View File

@@ -0,0 +1,231 @@
.. default-domain:: C
mat4
====
Header: cglm/mat4.h
Important: :c:func:`glm_mat4_scale` multiplies mat4 with scalar, if you need to
apply scale transform use :c:func:`glm_scale` functions.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
1. GLM_MAT4_IDENTITY_INIT
#. GLM_MAT4_ZERO_INIT
#. GLM_MAT4_IDENTITY
#. GLM_MAT4_ZERO
#. glm_mat4_udup(mat, dest)
#. glm_mat4_dup(mat, dest)
Functions:
1. :c:func:`glm_mat4_ucopy`
#. :c:func:`glm_mat4_copy`
#. :c:func:`glm_mat4_identity`
#. :c:func:`glm_mat4_pick3`
#. :c:func:`glm_mat4_pick3t`
#. :c:func:`glm_mat4_ins3`
#. :c:func:`glm_mat4_mul`
#. :c:func:`glm_mat4_mulN`
#. :c:func:`glm_mat4_mulv`
#. :c:func:`glm_mat4_mulv3`
#. :c:func:`glm_mat4_transpose_to`
#. :c:func:`glm_mat4_transpose`
#. :c:func:`glm_mat4_scale_p`
#. :c:func:`glm_mat4_scale`
#. :c:func:`glm_mat4_det`
#. :c:func:`glm_mat4_inv`
#. :c:func:`glm_mat4_inv_fast`
#. :c:func:`glm_mat4_swap_col`
#. :c:func:`glm_mat4_swap_row`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_mat4_ucopy(mat4 mat, mat4 dest)
copy mat4 to another one (dest). u means align is not required for dest
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_copy(mat4 mat, mat4 dest)
copy mat4 to another one (dest).
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_identity(mat4 mat)
copy identity mat4 to mat, or makes mat to identiy
Parameters:
| *[out]* **mat** matrix
.. c:function:: void glm_mat4_pick3(mat4 mat, mat3 dest)
copy upper-left of mat4 to mat3
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_pick3t(mat4 mat, mat4 dest)
copy upper-left of mat4 to mat3 (transposed)
the postfix t stands for transpose
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_ins3(mat3 mat, mat4 dest)
copy mat3 to mat4's upper-left. this function does not fill mat4's other
elements. To do that use glm_mat4.
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest)
multiply m1 and m2 to dest
m1, m2 and dest matrices can be same matrix, it is possible to write this:
.. code-block:: c
mat4 m = GLM_MAT4_IDENTITY_INIT;
glm_mat4_mul(m, m, m);
Parameters:
| *[in]* **m1** left matrix
| *[in]* **m2** right matrix
| *[out]* **dest** destination matrix
.. c:function:: void glm_mat4_mulN(mat4 * __restrict matrices[], int len, mat4 dest)
mupliply N mat4 matrices and store result in dest
| this function lets you multiply multiple (more than two or more...)
| matrices
| multiplication will be done in loop, this may reduce instructions
| size but if **len** is too small then compiler may unroll whole loop
.. code-block:: c
mat m1, m2, m3, m4, res;
glm_mat4_mulN((mat4 *[]){&m1, &m2, &m3, &m4}, 4, res);
Parameters:
| *[in]* **matrices** array of mat4
| *[in]* **len** matrices count
| *[out]* **dest** destination matrix
.. c:function:: void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest)
multiply mat4 with vec4 (column vector) and store in dest vector
Parameters:
| *[in]* **m** mat4 (left)
| *[in]* **v** vec4 (right, column vector)
| *[out]* **dest** vec4 (result, column vector)
.. c:function:: void glm_mat4_mulv3(mat4 m, vec3 v, vec3 dest)
multiply vector with mat4's mat3 part(rotation)
Parameters:
| *[in]* **m** mat4 (left)
| *[in]* **v** vec3 (right, column vector)
| *[out]* **dest** vec3 (result, column vector)
.. c:function:: void glm_mat4_transpose_to(mat4 m, mat4 dest)
transpose mat4 and store in dest
source matrix will not be transposed unless dest is m
Parameters:
| *[in]* **m** matrix
| *[out]* **dest** destination matrix
.. c:function:: void glm_mat4_transpose(mat4 m)
tranpose mat4 and store result in same matrix
Parameters:
| *[in]* **m** source
| *[out]* **dest** destination matrix
.. c:function:: void glm_mat4_scale_p(mat4 m, float s)
scale (multiply with scalar) matrix without simd optimization
Parameters:
| *[in, out]* **m** matrix
| *[in]* **s** scalar
.. c:function:: void glm_mat4_scale(mat4 m, float s)
scale (multiply with scalar) matrix
THIS IS NOT SCALE TRANSFORM, use glm_scale for that.
Parameters:
| *[in, out]* **m** matrix
| *[in]* **s** scalar
.. c:function:: float glm_mat4_det(mat4 mat)
mat4 determinant
Parameters:
| *[in]* **mat** matrix
Return:
| determinant
.. c:function:: void glm_mat4_inv(mat4 mat, mat4 dest)
inverse mat4 and store in dest
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination matrix (inverse matrix)
.. c:function:: void glm_mat4_inv_fast(mat4 mat, mat4 dest)
inverse mat4 and store in dest
| this func uses reciprocal approximation without extra corrections
| e.g Newton-Raphson. this should work faster than normal,
| to get more precise use glm_mat4_inv version.
| NOTE: You will lose precision, glm_mat4_inv is more accurate
Parameters:
| *[in]* **mat** source
| *[out]* **dest** destination
.. c:function:: void glm_mat4_swap_col(mat4 mat, int col1, int col2)
swap two matrix columns
Parameters:
| *[in, out]* **mat** matrix
| *[in]* **col1** col1
| *[in]* **col2** col2
.. c:function:: void glm_mat4_swap_row(mat4 mat, int row1, int row2)
swap two matrix rows
Parameters:
| *[in, out]* **mat** matrix
| *[in]* **row1** row1
| *[in]* **row2** row2

61
docs/source/opengl.rst Normal file
View File

@@ -0,0 +1,61 @@
How to send vector or matrix to OpenGL like API
==================================================
*cglm*'s vector and matrix types are arrays. So you can send them directly to a
function which accecpts pointer. But you may got warnings for matrix because it is
two dimensional array.
Passing / Uniforming Matrix to OpenGL:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**glUniformMatrix4fv** accepts float pointer, you can pass matrix to that parameter
and it should work but with warnings. "You can pass" doesn't mean that you must pass like that.
**Correct options:**
Correct doesn't mean correct way to use OpenGL it is just shows correct way to pass cglm type to it.
1. Pass first column
---------------------
The goal is that pass address of matrix, first element of matrix is also address of matrix,
because it is array of vectors and vector is array of floats.
.. code-block:: c
mat4 matrix;
/* ... */
glUniformMatrix4fv(location, 1, GL_FALSE, matrix[0]);
array of matrices:
.. code-block:: c
mat4 matrix;
/* ... */
glUniformMatrix4fv(location, count, GL_FALSE, matrix[0][0]);
1. Cast matrix to pointer
--------------------------
.. code-block:: c
mat4 matrix;
/* ... */
glUniformMatrix4fv(location, count, GL_FALSE, (float *)matrix);
in this way, passing aray of matrices is same
Passing / Uniforming Vectors to OpenGL:¶
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You don't need to do extra thing when passing cglm vectors to OpengL or other APIs.
Because a function like **glUniform4fv** accepts vector as pointer. cglm's vectors
are array of floats. So you can pass it directly ot those functions:
.. code-block:: c
vec4 vec;
/* ... */
glUniform4fv(location, 1, vec);
this show how to pass **vec4** others are same.

33
docs/source/plane.rst Normal file
View File

@@ -0,0 +1,33 @@
.. default-domain:: C
plane
================================================================================
Header: cglm/plane.h
Plane extract functions are in frustum header and documented
in :doc:`frustum` page.
**Definition of plane:**
Plane equation: **Ax + By + Cz + D = 0**
Plan is stored in **vec4** as **[A, B, C, D]**. (A, B, C) is normal and D is distance
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_plane_normalize`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_plane_normalize(vec4 plane)
| normalizes a plane
Parameters:
| *[in, out]* **plane** pnale to normalize

124
docs/source/quat.rst Normal file
View File

@@ -0,0 +1,124 @@
.. default-domain:: C
quaternions
===========
Header: cglm/quat.h
**Important:** *cglm* stores quaternion as [w, x, y, z] in memory, don't
forget that when changing quaternion items manually. For instance *quat[3]*
is *quat.z* and *quat[0*] is *quat.w*. This may change in the future if *cglm*
will got enough request to do that. Probably it will not be changed in near
future
There are some TODOs for quaternions check TODO list to see them.
Also **versor** is identity quaternion so the type may change to **vec4** or
something else. This will not affect existing functions for your engine because
*versor* is alias of *vec4*
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
1. GLM_QUAT_IDENTITY_INIT
#. GLM_QUAT_IDENTITY
Functions:
1. :c:func:`glm_quat_identity`
#. :c:func:`glm_quat`
#. :c:func:`glm_quatv`
#. :c:func:`glm_quat_norm`
#. :c:func:`glm_quat_normalize`
#. :c:func:`glm_quat_dot`
#. :c:func:`glm_quat_mulv`
#. :c:func:`glm_quat_mat4`
#. :c:func:`glm_quat_slerp`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_quat_identity(versor q)
| makes given quat to identity
Parameters:
| *[in, out]* **q** quaternion
.. c:function:: void glm_quat(versor q, float angle, float x, float y, float z)
| creates NEW quaternion with individual axis components
Parameters:
| *[out]* **q** quaternion
| *[in]* **angle** angle (radians)
| *[in]* **x** axis.x
| *[in]* **y** axis.y
| *[in]* **z** axis.z
.. c:function:: void glm_quatv(versor q, float angle, vec3 v)
| creates NEW quaternion with axis vector
Parameters:
| *[out]* **q** quaternion
| *[in]* **angle** angle (radians)
| *[in]* **v** axis
.. c:function:: float glm_quat_norm(versor q)
| returns norm (magnitude) of quaternion
Parameters:
| *[in]* **a** quaternion
Returns:
norm (magnitude)
.. c:function:: void glm_quat_normalize(versor q)
| normalize quaternion
Parameters:
| *[in, out]* **q** quaternion
.. c:function:: float glm_quat_dot(versor q, versor r)
dot product of two quaternion
Parameters:
| *[in]* **q1** quaternion 1
| *[in]* **q2** quaternion 2
Returns:
dot product
.. c:function:: void glm_quat_mulv(versor q1, versor q2, versor dest)
| multiplies two quaternion and stores result in dest
Parameters:
| *[in]* **q1** quaternion 1
| *[in]* **q2** quaternion 2
| *[out]* **dest** result quaternion
.. c:function:: void glm_quat_mat4(versor q, mat4 dest)
| convert quaternion to mat4
Parameters:
| *[in]* **q** quaternion
| *[out]* **dest** result matrix
.. c:function:: void glm_quat_slerp(versor q, versor r, float t, versor dest)
| interpolates between two quaternions
| using spherical linear interpolation (SLERP)
Parameters:
| *[in]* **q** from
| *[in]* **r** to
| *[in]* **t** amout
| *[out]* **dest** result quaternion

93
docs/source/util.rst Normal file
View File

@@ -0,0 +1,93 @@
.. default-domain:: C
utils / helpers
================================================================================
Header: cglm/util.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_sign`
#. :c:func:`glm_rad`
#. :c:func:`glm_deg`
#. :c:func:`glm_make_rad`
#. :c:func:`glm_make_deg`
#. :c:func:`glm_pow2`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: int glm_sign(int val)
| returns sign of 32 bit integer as +1 or -1
Parameters:
| *[in]* **val** an integer
Returns:
sign of given number
.. c:function:: float glm_rad(float deg)
| convert degree to radians
Parameters:
| *[in]* **deg** angle in degrees
.. c:function:: float glm_deg(float rad)
| convert radians to degree
Parameters:
| *[in]* **rad** angle in radians
.. c:function:: void glm_make_rad(float *degm)
| convert exsisting degree to radians. this will override degrees value
Parameters:
| *[in, out]* **deg** pointer to angle in degrees
.. c:function:: void glm_make_deg(float *rad)
| convert exsisting radians to degree. this will override radians value
Parameters:
| *[in, out]* **rad** pointer to angle in radians
.. c:function:: float glm_pow2(float x)
| multiplies given parameter with itself = x * x or powf(x, 2)
Parameters:
| *[in]* **x** value
Returns:
square of a given number
.. c:function:: float glm_min(float a, float b)
| returns minimum of given two values
Parameters:
| *[in]* **a** number 1
| *[in]* **b** number 2
Returns:
minimum value
.. c:function:: float glm_max(float a, float b)
| returns maximum of given two values
Parameters:
| *[in]* **a** number 1
| *[in]* **b** number 2
Returns:
maximum value

98
docs/source/vec3-ext.rst Normal file
View File

@@ -0,0 +1,98 @@
.. default-domain:: C
vec3 extra
==========
Header: cglm/vec3-ext.h
There are some functions are in called in extra header. These are called extra
because they are not used like other functions in vec3.h in the future some of
these functions ma be moved to vec3 header.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_vec_mulv`
#. :c:func:`glm_vec_broadcast`
#. :c:func:`glm_vec_eq`
#. :c:func:`glm_vec_eq_eps`
#. :c:func:`glm_vec_eq_all`
#. :c:func:`glm_vec_eqv`
#. :c:func:`glm_vec_eqv_eps`
#. :c:func:`glm_vec_max`
#. :c:func:`glm_vec_min`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_vec_mulv(vec3 a, vec3 b, vec3 d)
multiplies individual items
Parameters:
| *[in]* **a** vec1
| *[in]* **b** vec2
| *[out]* **d** destination (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2])
.. c:function:: void glm_vec_broadcast(float val, vec3 d)
fill a vector with specified value
Parameters:
| *[in]* **val** value
| *[out]* **dest** destination
.. c:function:: bool glm_vec_eq(vec3 v, float val)
check if vector is equal to value (without epsilon)
Parameters:
| *[in]* **v** vector
| *[in]* **val** value
.. c:function:: bool glm_vec_eq_eps(vec3 v, float val)
check if vector is equal to value (with epsilon)
Parameters:
| *[in]* **v** vector
| *[in]* **val** value
.. c:function:: bool glm_vec_eq_all(vec3 v)
check if vectors members are equal (without epsilon)
Parameters:
| *[in]* **v** vector
.. c:function:: bool glm_vec_eqv(vec3 v1, vec3 v2)
check if vector is equal to another (without epsilon) vector
Parameters:
| *[in]* **vec** vector 1
| *[in]* **vec** vector 2
.. c:function:: bool glm_vec_eqv_eps(vec3 v1, vec3 v2)
check if vector is equal to another (with epsilon)
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
.. c:function:: float glm_vec_max(vec3 v)
max value of vector
Parameters:
| *[in]* **v** vector
.. c:function:: float glm_vec_min(vec3 v)
min value of vector
Parameters:
| *[in]* **v** vector

273
docs/source/vec3.rst Normal file
View File

@@ -0,0 +1,273 @@
.. default-domain:: C
vec3
====
Header: cglm/vec3.h
We mostly use vectors in graphics math, to make writing code faster
and easy to read, some *vec3* functions are aliased in global namespace.
For instance :c:func:`glm_dot` is alias of :c:func:`glm_vec_dot`,
alias means inline wrapper here. There is no call verison of alias functions
There are also functions for rotating *vec3* vector. **_m4**, **_m3** prefixes
rotate *vec3* with matrix.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
1. glm_vec_dup(v, dest)
#. GLM_VEC3_ONE_INIT
#. GLM_VEC3_ZERO_INIT
#. GLM_VEC3_ONE
#. GLM_VEC3_ZERO
#. GLM_YUP
#. GLM_ZUP
#. GLM_XUP
Functions:
1. :c:func:`glm_vec3`
#. :c:func:`glm_vec_copy`
#. :c:func:`glm_vec_dot`
#. :c:func:`glm_vec_cross`
#. :c:func:`glm_vec_norm2`
#. :c:func:`glm_vec_norm`
#. :c:func:`glm_vec_add`
#. :c:func:`glm_vec_sub`
#. :c:func:`glm_vec_scale`
#. :c:func:`glm_vec_scale_as`
#. :c:func:`glm_vec_flipsign`
#. :c:func:`glm_vec_inv`
#. :c:func:`glm_vec_inv_to`
#. :c:func:`glm_vec_normalize`
#. :c:func:`glm_vec_normalize_to`
#. :c:func:`glm_vec_distance`
#. :c:func:`glm_vec_angle`
#. :c:func:`glm_vec_rotate`
#. :c:func:`glm_vec_rotate_m4`
#. :c:func:`glm_vec_proj`
#. :c:func:`glm_vec_center`
#. :c:func:`glm_vec_maxv`
#. :c:func:`glm_vec_minv`
#. :c:func:`glm_vec_ortho`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_vec3(vec4 v4, vec3 dest)
init vec3 using vec4
Parameters:
| *[in]* **v4** vector4
| *[out]* **dest** destination
.. c:function:: void glm_vec_copy(vec3 a, vec3 dest)
copy all members of [a] to [dest]
Parameters:
| *[in]* **a** source
| *[out]* **dest** destination
.. c:function:: float glm_vec_dot(vec3 a, vec3 b)
dot product of vec3
Parameters:
| *[in]* **a** vector1
| *[in]* **b** vector2
Returns:
dot product
.. c:function:: void glm_vec_cross(vec3 a, vec3 b, vec3 d)
cross product
Parameters:
| *[in]* **a** source 1
| *[in]* **b** source 2
| *[out]* **d** destination
.. c:function:: float glm_vec_norm2(vec3 v)
norm * norm (magnitude) of vector
we can use this func instead of calling norm * norm, because it would call
sqrtf fuction twice but with this func we can avoid func call, maybe this is
not good name for this func
Parameters:
| *[in]* **v** vector
Returns:
square of norm / magnitude
.. c:function:: float glm_vec_norm(vec3 vec)
norm (magnitude) of vec3
Parameters:
| *[in]* **vec** vector
.. c:function:: void glm_vec_add(vec3 v1, vec3 v2, vec3 dest)
add v2 vector to v1 vector store result in dest
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination vector
.. c:function:: void glm_vec_sub(vec3 v1, vec3 v2, vec3 dest)
subtract v2 vector from v1 vector store result in dest
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination vector
.. c:function:: void glm_vec_scale(vec3 v, float s, vec3 dest)
multiply/scale vec3 vector with scalar: result = v * s
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination vector
.. c:function:: void glm_vec_scale_as(vec3 v, float s, vec3 dest)
make vec3 vector scale as specified: result = unit(v) * s
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination vector
.. c:function:: void glm_vec_flipsign(vec3 v)
flip sign of all vec3 members
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec_inv(vec3 v)
make vector as inverse/opposite of itself
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec_inv_to(vec3 v, vec3 dest)
inverse/opposite vector
Parameters:
| *[in]* **v** source
| *[out]* **dest** destination
.. c:function:: void glm_vec_normalize(vec3 v)
normalize vec3 and store result in same vec
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec_normalize_to(vec3 vec, vec3 dest)
normalize vec3 to dest
Parameters:
| *[in]* **vec** source
| *[out]* **dest** destination
.. c:function:: float glm_vec_angle(vec3 v1, vec3 v2)
angle betwen two vector
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
Return:
| angle as radians
.. c:function:: void glm_vec_rotate(vec3 v, float angle, vec3 axis)
rotate vec3 around axis by angle using Rodrigues' rotation formula
Parameters:
| *[in, out]* **v** vector
| *[in]* **axis** axis vector (must be unit vector)
| *[out]* **angle** angle (radians)
.. c:function:: void glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest)
apply rotation matrix to vector
Parameters:
| *[in]* **m** affine matrix or rot matrix
| *[in]* **v** vector
| *[out]* **dest** rotated vector
.. c:function:: void glm_vec_proj(vec3 a, vec3 b, vec3 dest)
project a vector onto b vector
Parameters:
| *[in]* **a** vector1
| *[in]* **b** vector2
| *[out]* **dest** projected vector
.. c:function:: void glm_vec_center(vec3 v1, vec3 v2, vec3 dest)
find center point of two vector
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** center point
.. c:function:: float glm_vec_distance(vec3 v1, vec3 v2)
distance between two vectors
Parameters:
| *[in]* **mat** vector1
| *[in]* **row1** vector2
Returns:
| distance
.. c:function:: void glm_vec_maxv(vec3 v1, vec3 v2, vec3 dest)
max values of vectors
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination
.. c:function:: void glm_vec_minv(vec3 v1, vec3 v2, vec3 dest)
min values of vectors
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination
.. c:function:: void glm_vec_ortho(vec3 v, vec3 dest)
possible orthogonal/perpendicular vector
Parameters:
| *[in]* **mat** vector
| *[out]* **dest** orthogonal/perpendicular vector

98
docs/source/vec4-ext.rst Normal file
View File

@@ -0,0 +1,98 @@
.. default-domain:: C
vec4 extra
==========
Header: cglm/vec4-ext.h
There are some functions are in called in extra header. These are called extra
because they are not used like other functions in vec4.h in the future some of
these functions ma be moved to vec4 header.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_vec4_mulv`
#. :c:func:`glm_vec4_broadcast`
#. :c:func:`glm_vec4_eq`
#. :c:func:`glm_vec4_eq_eps`
#. :c:func:`glm_vec4_eq_all`
#. :c:func:`glm_vec4_eqv`
#. :c:func:`glm_vec4_eqv_eps`
#. :c:func:`glm_vec4_max`
#. :c:func:`glm_vec4_min`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_vec4_mulv(vec4 a, vec4 b, vec4 d)
multiplies individual items
Parameters:
| *[in]* **a** vec1
| *[in]* **b** vec2
| *[out]* **d** destination
.. c:function:: void glm_vec4_broadcast(float val, vec4 d)
fill a vector with specified value
Parameters:
| *[in]* **val** value
| *[out]* **dest** destination
.. c:function:: bool glm_vec4_eq(vec4 v, float val)
check if vector is equal to value (without epsilon)
Parameters:
| *[in]* **v** vector
| *[in]* **val** value
.. c:function:: bool glm_vec4_eq_eps(vec4 v, float val)
check if vector is equal to value (with epsilon)
Parameters:
| *[in]* **v** vector
| *[in]* **val** value
.. c:function:: bool glm_vec4_eq_all(vec4 v)
check if vectors members are equal (without epsilon)
Parameters:
| *[in]* **v** vector
.. c:function:: bool glm_vec4_eqv(vec4 v1, vec4 v2)
check if vector is equal to another (without epsilon) vector
Parameters:
| *[in]* **vec** vector 1
| *[in]* **vec** vector 2
.. c:function:: bool glm_vec4_eqv_eps(vec4 v1, vec4 v2)
check if vector is equal to another (with epsilon)
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
.. c:function:: float glm_vec4_max(vec4 v)
max value of vector
Parameters:
| *[in]* **v** vector
.. c:function:: float glm_vec4_min(vec4 v)
min value of vector
Parameters:
| *[in]* **v** vector

205
docs/source/vec4.rst Normal file
View File

@@ -0,0 +1,205 @@
.. default-domain:: C
vec4
====
Header: cglm/vec4.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Macros:
1. glm_vec4_dup3(v, dest)
#. glm_vec4_dup(v, dest)
#. GLM_VEC4_ONE_INIT
#. GLM_VEC4_BLACK_INIT
#. GLM_VEC4_ZERO_INIT
#. GLM_VEC4_ONE
#. GLM_VEC4_BLACK
#. GLM_VEC4_ZERO
Functions:
1. :c:func:`glm_vec4`
#. :c:func:`glm_vec4_copy3`
#. :c:func:`glm_vec4_copy`
#. :c:func:`glm_vec4_dot`
#. :c:func:`glm_vec4_norm2`
#. :c:func:`glm_vec4_norm`
#. :c:func:`glm_vec4_add`
#. :c:func:`glm_vec4_sub`
#. :c:func:`glm_vec4_scale`
#. :c:func:`glm_vec4_scale_as`
#. :c:func:`glm_vec4_flipsign`
#. :c:func:`glm_vec4_inv`
#. :c:func:`glm_vec4_inv_to`
#. :c:func:`glm_vec4_normalize`
#. :c:func:`glm_vec4_normalize_to`
#. :c:func:`glm_vec4_distance`
#. :c:func:`glm_vec4_maxv`
#. :c:func:`glm_vec4_minv`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_vec4(vec3 v3, float last, vec4 dest)
init vec4 using vec3, since you are initializing vec4 with vec3
you need to set last item. cglm could set it zero but making it parameter
gives more control
Parameters:
| *[in]* **v3** vector4
| *[in]* **last** last item of vec4
| *[out]* **dest** destination
.. c:function:: void glm_vec4_copy3(vec4 a, vec3 dest)
copy first 3 members of [a] to [dest]
Parameters:
| *[in]* **a** source
| *[out]* **dest** destination
.. c:function:: void glm_vec4_copy(vec4 v, vec4 dest)
copy all members of [a] to [dest]
Parameters:
| *[in]* **v** source
| *[in]* **dest** destination
.. c:function:: float glm_vec4_dot(vec4 a, vec4 b)
dot product of vec4
Parameters:
| *[in]* **a** vector1
| *[in]* **b** vector2
Returns:
dot product
.. c:function:: float glm_vec4_norm2(vec4 v)
norm * norm (magnitude) of vector
we can use this func instead of calling norm * norm, because it would call
sqrtf fuction twice but with this func we can avoid func call, maybe this is
not good name for this func
Parameters:
| *[in]* **v** vector
Returns:
square of norm / magnitude
.. c:function:: float glm_vec4_norm(vec4 vec)
norm (magnitude) of vec4
Parameters:
| *[in]* **vec** vector
.. c:function:: void glm_vec4_add(vec4 v1, vec4 v2, vec4 dest)
add v2 vector to v1 vector store result in dest
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination vector
.. c:function:: void glm_vec4_sub(vec4 v1, vec4 v2, vec4 dest)
subtract v2 vector from v1 vector store result in dest
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination vector
.. c:function:: void glm_vec4_scale(vec4 v, float s, vec4 dest)
multiply/scale vec4 vector with scalar: result = v * s
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination vector
.. c:function:: void glm_vec4_scale_as(vec4 v, float s, vec4 dest)
make vec4 vector scale as specified: result = unit(v) * s
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination vector
.. c:function:: void glm_vec4_flipsign(vec4 v)
flip sign of all vec4 members
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec4_inv(vec4 v)
make vector as inverse/opposite of itself
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec4_inv_to(vec4 v, vec4 dest)
inverse/opposite vector
Parameters:
| *[in]* **v** source
| *[out]* **dest** destination
.. c:function:: void glm_vec4_normalize(vec4 v)
normalize vec4 and store result in same vec
Parameters:
| *[in, out]* **v** vector
.. c:function:: void glm_vec4_normalize_to(vec4 vec, vec4 dest)
normalize vec4 to dest
Parameters:
| *[in]* **vec** source
| *[out]* **dest** destination
.. c:function:: float glm_vec4_distance(vec4 v1, vec4 v2)
distance between two vectors
Parameters:
| *[in]* **mat** vector1
| *[in]* **row1** vector2
Returns:
| distance
.. c:function:: void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest)
max values of vectors
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination
.. c:function:: void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest)
min values of vectors
Parameters:
| *[in]* **v1** vector1
| *[in]* **v2** vector2
| *[out]* **dest** destination

View File

@@ -25,8 +25,22 @@
# include "simd/avx/affine.h" # include "simd/avx/affine.h"
#endif #endif
#include <assert.h> /*!
* @brief this is similar to glm_mat4_mul but specialized to affine transform
*
* Matrix format should be:
* R R R X
* R R R Y
* R R R Z
* 0 0 0 W
*
* this reduces some multiplications. It should be faster than mat4_mul.
* if you are not sure about matrix format then DON'T use this! use mat4_mul
*
* @param[in] m1 affine matrix 1
* @param[in] m2 affine matrix 2
* @param[out] dest result matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_mul(mat4 m1, mat4 m2, mat4 dest) { glm_mul(mat4 m1, mat4 m2, mat4 dest) {

View File

@@ -17,12 +17,13 @@
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_scale1(mat4 m, float s);
CGLM_INLINE void glm_rotate_x(mat4 m, float rad, mat4 dest); CGLM_INLINE void glm_scale_uni(mat4 m, float s);
CGLM_INLINE void glm_rotate_y(mat4 m, float rad, mat4 dest); CGLM_INLINE void glm_rotate_x(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_z(mat4 m, float rad, 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_ndc_make(mat4 m, float angle, vec3 axis_ndc); 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_ndc); 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_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);
@@ -38,6 +39,14 @@
#include "affine-mat.h" #include "affine-mat.h"
#include "util.h" #include "util.h"
/*!
* @brief translate existing transform matrix by v vector
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] v translate vector [x, y, z]
* @param[out] dest translated matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate_to(mat4 m, vec3 v, mat4 dest) { glm_translate_to(mat4 m, vec3 v, mat4 dest) {
@@ -72,6 +81,13 @@ glm_translate_to(mat4 m, vec3 v, mat4 dest) {
#endif #endif
} }
/*!
* @brief translate existing transform matrix by v vector
* and stores result in same matrix
*
* @param[in, out] m affine transfrom
* @param[in] v translate vector [x, y, z]
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate(mat4 m, vec3 v) { glm_translate(mat4 m, vec3 v) {
@@ -98,54 +114,78 @@ glm_translate(mat4 m, vec3 v) {
#endif #endif
} }
/*!
* @brief translate existing transform matrix by x factor
*
* @param[in, out] m affine transfrom
* @param[in] x x factor
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate_x(mat4 m, float to) { glm_translate_x(mat4 m, float x) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(m[3], _mm_store_ps(m[3],
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[0]), _mm_add_ps(_mm_mul_ps(_mm_load_ps(m[0]),
_mm_set1_ps(to)), _mm_set1_ps(x)),
_mm_load_ps(m[3]))) _mm_load_ps(m[3])))
; ;
#else #else
vec4 v1; vec4 v1;
glm_vec4_scale(m[0], to, v1); glm_vec4_scale(m[0], x, v1);
glm_vec4_add(v1, m[3], m[3]); glm_vec4_add(v1, m[3], m[3]);
#endif #endif
} }
/*!
* @brief translate existing transform matrix by y factor
*
* @param[in, out] m affine transfrom
* @param[in] y y factor
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate_y(mat4 m, float to) { glm_translate_y(mat4 m, float y) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(m[3], _mm_store_ps(m[3],
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[1]), _mm_add_ps(_mm_mul_ps(_mm_load_ps(m[1]),
_mm_set1_ps(to)), _mm_set1_ps(y)),
_mm_load_ps(m[3]))) _mm_load_ps(m[3])))
; ;
#else #else
vec4 v1; vec4 v1;
glm_vec4_scale(m[1], to, v1); glm_vec4_scale(m[1], y, v1);
glm_vec4_add(v1, m[3], m[3]); glm_vec4_add(v1, m[3], m[3]);
#endif #endif
} }
/*!
* @brief translate existing transform matrix by z factor
*
* @param[in, out] m affine transfrom
* @param[in] z z factor
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate_z(mat4 m, float to) { glm_translate_z(mat4 m, float z) {
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
_mm_store_ps(m[3], _mm_store_ps(m[3],
_mm_add_ps(_mm_mul_ps(_mm_load_ps(m[2]), _mm_add_ps(_mm_mul_ps(_mm_load_ps(m[2]),
_mm_set1_ps(to)), _mm_set1_ps(z)),
_mm_load_ps(m[3]))) _mm_load_ps(m[3])))
; ;
#else #else
vec4 v1; vec4 v1;
glm_vec4_scale(m[2], to, v1); glm_vec4_scale(m[2], z, v1);
glm_vec4_add(v1, m[3], m[3]); glm_vec4_add(v1, m[3], m[3]);
#endif #endif
} }
/*!
* @brief creates NEW translate transform matrix by v vector
*
* @param[out] m affine transfrom
* @param[in] v translate vector [x, y, z]
*/
CGLM_INLINE CGLM_INLINE
void void
glm_translate_make(mat4 m, vec3 v) { glm_translate_make(mat4 m, vec3 v) {
@@ -153,8 +193,14 @@ glm_translate_make(mat4 m, vec3 v) {
glm_translate_to(t, v, m); glm_translate_to(t, v, m);
} }
/* scale */ /*!
* @brief scale existing transform matrix by v vector
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] v scale vector [x, y, z]
* @param[out] dest scaled matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_scale_to(mat4 m, vec3 v, mat4 dest) { glm_scale_to(mat4 m, vec3 v, mat4 dest) {
@@ -165,6 +211,12 @@ glm_scale_to(mat4 m, vec3 v, mat4 dest) {
glm_vec4_copy(m[3], dest[3]); glm_vec4_copy(m[3], dest[3]);
} }
/*!
* @brief creates NEW scale matrix by v vector
*
* @param[out] m affine transfrom
* @param[in] v scale vector [x, y, z]
*/
CGLM_INLINE CGLM_INLINE
void void
glm_scale_make(mat4 m, vec3 v) { glm_scale_make(mat4 m, vec3 v) {
@@ -172,12 +224,22 @@ glm_scale_make(mat4 m, vec3 v) {
glm_scale_to(t, v, m); glm_scale_to(t, v, m);
} }
/*!
* @brief scales existing transform matrix by v vector
* and stores result in same matrix
*
* @param[in, out] m affine transfrom
* @param[in] v scale vector [x, y, z]
*/
CGLM_INLINE CGLM_INLINE
void void
glm_scale(mat4 m, vec3 v) { 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 CGLM_INLINE
void void
glm_scale1(mat4 m, float s) { glm_scale1(mat4 m, float s) {
@@ -185,15 +247,37 @@ glm_scale1(mat4 m, float s) {
glm_scale_to(m, v, m); glm_scale_to(m, v, m);
} }
/*!
* @brief applies uniform scale to existing transform matrix v = [s, s, s]
* and stores result in same matrix
*
* @param[in, out] m affine transfrom
* @param[in] s scale factor
*/
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_x(mat4 m, float rad, mat4 dest) { glm_scale_uni(mat4 m, float s) {
vec3 v = { s, s, s };
glm_scale_to(m, v, m);
}
/*!
* @brief rotate existing transform matrix around X axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE
void
glm_rotate_x(mat4 m, float angle, mat4 dest) {
float cosVal; float cosVal;
float sinVal; float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
cosVal = cosf(rad); cosVal = cosf(angle);
sinVal = sinf(rad); sinVal = sinf(angle);
t[1][1] = cosVal; t[1][1] = cosVal;
t[1][2] = sinVal; t[1][2] = sinVal;
@@ -203,15 +287,23 @@ glm_rotate_x(mat4 m, float rad, mat4 dest) {
glm_mat4_mul(m, t, dest); glm_mat4_mul(m, t, dest);
} }
/*!
* @brief rotate existing transform matrix around Y axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_y(mat4 m, float rad, mat4 dest) { glm_rotate_y(mat4 m, float angle, mat4 dest) {
float cosVal; float cosVal;
float sinVal; float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
cosVal = cosf(rad); cosVal = cosf(angle);
sinVal = sinf(rad); sinVal = sinf(angle);
t[0][0] = cosVal; t[0][0] = cosVal;
t[0][2] = -sinVal; t[0][2] = -sinVal;
@@ -221,15 +313,23 @@ glm_rotate_y(mat4 m, float rad, mat4 dest) {
glm_mat4_mul(m, t, dest); glm_mat4_mul(m, t, dest);
} }
/*!
* @brief rotate existing transform matrix around Z axis by angle
* and store result in dest
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_z(mat4 m, float rad, mat4 dest) { glm_rotate_z(mat4 m, float angle, mat4 dest) {
float cosVal; float cosVal;
float sinVal; float sinVal;
mat4 t = GLM_MAT4_IDENTITY_INIT; mat4 t = GLM_MAT4_IDENTITY_INIT;
cosVal = cosf(rad); cosVal = cosf(angle);
sinVal = sinf(rad); sinVal = sinf(angle);
t[0][0] = cosVal; t[0][0] = cosVal;
t[0][1] = sinVal; t[0][1] = sinVal;
@@ -239,6 +339,15 @@ glm_rotate_z(mat4 m, float rad, mat4 dest) {
glm_mat4_mul(m, t, dest); 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 CGLM_INLINE
void void
glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) { glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
@@ -272,6 +381,15 @@ glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc) {
m[3][3] = 1.0f; m[3][3] = 1.0f;
} }
/*!
* @brief creates NEW rotation matrix by angle and axis
*
* axis will be normalized so you don't need to normalize it
*
* @param[out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE CGLM_INLINE
void void
glm_rotate_make(mat4 m, float angle, vec3 axis) { glm_rotate_make(mat4 m, float angle, vec3 axis) {
@@ -281,6 +399,15 @@ glm_rotate_make(mat4 m, float angle, vec3 axis) {
glm_rotate_ndc_make(m, angle, axis_ndc); glm_rotate_ndc_make(m, angle, axis_ndc);
} }
/*!
* @brief rotate existing transform matrix around Z axis by angle and axis
*
* 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 CGLM_INLINE
void void
glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) { glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
@@ -311,6 +438,13 @@ glm_rotate_ndc(mat4 m, float angle, vec3 axis_ndc) {
glm_vec4_copy(tmp[3], m[2]); 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] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE CGLM_INLINE
void void
glm_rotate(mat4 m, float angle, vec3 axis) { glm_rotate(mat4 m, float angle, vec3 axis) {
@@ -323,8 +457,8 @@ glm_rotate(mat4 m, float angle, vec3 axis) {
/*! /*!
* @brief decompose scale vector * @brief decompose scale vector
* *
* @param[in] m affine transform * @param[in] m affine transform
* @param[out] s scale vector (Sx, Sy, Sz) * @param[out] s scale vector (Sx, Sy, Sz)
*/ */
CGLM_INLINE CGLM_INLINE
void void

156
include/cglm/box.h Normal file
View File

@@ -0,0 +1,156 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_box_h
#define cglm_box_h
#include "common.h"
#include "vec3.h"
#include "vec4.h"
/*!
* @brief apply transform to Axis-Aligned Bounding Box
*
* @param[in] box bounding box
* @param[in] m transform matrix
* @param[out] dest transformed bounding box
*/
CGLM_INLINE
void
glm_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]) {
vec3 v[2], xa, xb, ya, yb, za, zb, tmp;
glm_vec_scale(m[0], box[0][0], xa);
glm_vec_scale(m[0], box[1][0], xb);
glm_vec_scale(m[1], box[0][1], ya);
glm_vec_scale(m[1], box[1][1], yb);
glm_vec_scale(m[2], box[0][2], za);
glm_vec_scale(m[2], box[1][2], zb);
/* min(xa, xb) + min(ya, yb) + min(za, zb) + translation */
glm_vec_minv(xa, xb, v[0]);
glm_vec_minv(ya, yb, tmp);
glm_vec_add(v[0], tmp, v[0]);
glm_vec_minv(za, zb, tmp);
glm_vec_add(v[0], tmp, v[0]);
glm_vec_add(v[0], m[3], v[0]);
/* max(xa, xb) + max(ya, yb) + max(za, zb) + translation */
glm_vec_maxv(xa, xb, v[1]);
glm_vec_maxv(ya, yb, tmp);
glm_vec_add(v[1], tmp, v[1]);
glm_vec_maxv(za, zb, tmp);
glm_vec_add(v[1], tmp, v[1]);
glm_vec_add(v[1], m[3], v[1]);
glm_vec_copy(v[0], dest[0]);
glm_vec_copy(v[1], dest[1]);
}
/*!
* @brief merges two AABB bounding box and creates new one
*
* two box must be in same space, if one of box is in different space then
* you should consider to convert it's space by glm_box_space
*
* @param[in] box1 bounding box 1
* @param[in] box2 bounding box 2
* @param[out] dest merged bounding box
*/
CGLM_INLINE
void
glm_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]) {
dest[0][0] = glm_min(box1[0][0], box2[0][0]);
dest[0][1] = glm_min(box1[0][1], box2[0][1]);
dest[0][2] = glm_min(box1[0][2], box2[0][2]);
dest[1][0] = glm_max(box1[1][0], box2[1][0]);
dest[1][1] = glm_max(box1[1][1], box2[1][1]);
dest[1][2] = glm_max(box1[1][2], box2[1][2]);
}
/*!
* @brief crops a bounding box with another one.
*
* this could be useful for gettng a bbox which fits with view frustum and
* object bounding boxes. In this case you crop view frustum box with objects
* box
*
* @param[in] box bounding box 1
* @param[in] cropBox crop box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glm_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]) {
dest[0][0] = glm_max(box[0][0], cropBox[0][0]);
dest[0][1] = glm_max(box[0][1], cropBox[0][1]);
dest[0][2] = glm_max(box[0][2], cropBox[0][2]);
dest[1][0] = glm_min(box[1][0], cropBox[1][0]);
dest[1][1] = glm_min(box[1][1], cropBox[1][1]);
dest[1][2] = glm_min(box[1][2], cropBox[1][2]);
}
/*!
* @brief crops a bounding box with another one.
*
* this could be useful for gettng a bbox which fits with view frustum and
* object bounding boxes. In this case you crop view frustum box with objects
* box
*
* @param[in] box bounding box
* @param[in] cropBox crop box
* @param[in] clampBox miniumum box
* @param[out] dest cropped bounding box
*/
CGLM_INLINE
void
glm_aabb_crop_until(vec3 box[2],
vec3 cropBox[2],
vec3 clampBox[2],
vec3 dest[2]) {
glm_aabb_crop(box, cropBox, dest);
glm_aabb_merge(clampBox, dest, dest);
}
/*!
* @brief check if AABB intersects with frustum planes
*
* this could be useful for frustum culling using AABB.
*
* OPTIMIZATION HINT:
* if planes order is similar to LEFT, RIGHT, BOTTOM, TOP, NEAR, FAR
* then this method should run even faster because it would only use two
* planes if object is not inside the two planes
* fortunately cglm extracts planes as this order! just pass what you got!
*
* @param[in] box bounding box
* @param[in] planes frustum planes
*/
CGLM_INLINE
bool
glm_aabb_frustum(vec3 box[2], vec4 planes[6]) {
float *p, dp;
int i;
for (i = 0; i < 6; i++) {
p = planes[i];
dp = p[0] * box[p[0] > 0.0f][0]
+ p[1] * box[p[1] > 0.0f][1]
+ p[2] * box[p[2] > 0.0f][2];
if (dp < -p[3])
return false;
}
return true;
}
#endif /* cglm_box_h */

View File

@@ -20,6 +20,9 @@ extern "C" {
#include "call/cam.h" #include "call/cam.h"
#include "call/quat.h" #include "call/quat.h"
#include "call/euler.h" #include "call/euler.h"
#include "call/plane.h"
#include "call/frustum.h"
#include "call/box.h"
#include "call/io.h" #include "call/io.h"
#ifdef __cplusplus #ifdef __cplusplus

39
include/cglm/call/box.h Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_box_h
#define cglmc_box_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]);
CGLM_EXPORT
void
glmc_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]);
CGLM_EXPORT
void
glmc_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]);
CGLM_EXPORT
void
glmc_aabb_crop_until(vec3 box[2],
vec3 cropBox[2],
vec3 clampBox[2],
vec3 dest[2]);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_box_h */

View File

@@ -43,10 +43,15 @@ glmc_perspective(float fovy,
CGLM_EXPORT CGLM_EXPORT
void void
glmc_lookat(vec3 eye, glmc_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest);
vec3 center,
vec3 up, CGLM_EXPORT
mat4 dest); void
glmc_look(vec3 eye, vec3 dir, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_frustum_h
#define cglmc_frustum_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_frustum_planes(mat4 m, vec4 dest[6]);
CGLM_EXPORT
void
glmc_frustum_corners(mat4 invMat, vec4 dest[8]);
CGLM_EXPORT
void
glmc_frustum_center(vec4 corners[8], vec4 dest);
CGLM_EXPORT
void
glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]);
CGLM_EXPORT
void
glmc_frustum_corners_at(vec4 corners[8],
float splitDist,
float farDist,
vec4 planeCorners[4]);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_frustum_h */

23
include/cglm/call/plane.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_plane_h
#define cglmc_plane_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_plane_normalize(vec4 plane);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_plane_h */

View File

@@ -96,6 +96,14 @@ CGLM_EXPORT
float float
glmc_vec_distance(vec3 v1, vec3 v2); glmc_vec_distance(vec3 v1, vec3 v2);
CGLM_EXPORT
void
glmc_vec_maxv(vec3 v1, vec3 v2, vec3 dest);
CGLM_EXPORT
void
glmc_vec_minv(vec3 v1, vec3 v2, vec3 dest);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -77,6 +77,14 @@ CGLM_EXPORT
float float
glmc_vec4_distance(vec4 v1, vec4 v2); glmc_vec4_distance(vec4 v1, vec4 v2);
CGLM_EXPORT
void
glmc_vec4_maxv(vec4 v1, vec4 v2, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_minv(vec4 v1, vec4 v2, vec4 dest);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -7,55 +7,60 @@
/* /*
Functions: Functions:
CGLM_INLINE void glm_frustum(float left, CGLM_INLINE void glm_frustum(float left,
float right, float right,
float bottom, float bottom,
float top, float top,
float near, float nearVal,
float far, float farVal,
mat4 dest); mat4 dest)
CGLM_INLINE void glm_ortho(float left, CGLM_INLINE void glm_ortho(float left,
float right, float right,
float bottom, float bottom,
float top, float top,
float near, float nearVal,
float far, float farVal,
mat4 dest); mat4 dest)
CGLM_INLINE void glm_ortho_default(float aspect, mat4 dest); CGLM_INLINE void glm_ortho_aabb(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_default_s(float aspect, float size, mat4 dest); CGLM_INLINE void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
CGLM_INLINE void glm_perspective(float fovy, CGLM_INLINE void glm_ortho_aabb_pz(vec3 box[2], float padding, mat4 dest)
float aspect, CGLM_INLINE void glm_ortho_default(float aspect, mat4 dest)
float near, CGLM_INLINE void glm_ortho_default_s(float aspect, float size, mat4 dest)
float far, CGLM_INLINE void glm_perspective(float fovy,
mat4 dest); float aspect,
CGLM_INLINE void glm_perspective_default(float aspect, mat4 dest); float nearVal,
CGLM_INLINE void glm_perspective_resize(float aspect, mat4 proj); float farVal,
CGLM_INLINE void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest); mat4 dest)
CGLM_INLINE void glm_persp_decomp(mat4 proj, CGLM_INLINE void glm_perspective_default(float aspect, mat4 dest)
float * __restrict near, CGLM_INLINE void glm_perspective_resize(float aspect, mat4 proj)
float * __restrict far, CGLM_INLINE void glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest)
float * __restrict top, CGLM_INLINE void glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest)
float * __restrict bottom, CGLM_INLINE void glm_look_anyup(vec3 eye, vec3 dir, mat4 dest)
float * __restrict left, CGLM_INLINE void glm_persp_decomp(mat4 proj,
float * __restrict right); float *nearVal,
CGLM_INLINE void glm_persp_decompv(mat4 proj, float dest[6]); float *farVal,
CGLM_INLINE void glm_persp_decomp_x(mat4 proj, float *top,
float * __restrict left, float *bottom,
float * __restrict right); float *left,
CGLM_INLINE void glm_persp_decomp_y(mat4 proj, float *right)
float * __restrict top, CGLM_INLINE void glm_persp_decompv(mat4 proj, float dest[6])
float * __restrict bottom); CGLM_INLINE void glm_persp_decomp_x(mat4 proj, float *left, float *right)
CGLM_INLINE void glm_persp_decomp_z(mat4 proj, CGLM_INLINE void glm_persp_decomp_y(mat4 proj, float *top, float *bottom)
float * __restrict near, CGLM_INLINE void glm_persp_decomp_z(mat4 proj,
float * __restrict far); float *nearVal,
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float * __restrict far); float *farVal)
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float * __restrict near); CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float *farVal)
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float *nearVal)
CGLM_INLINE float glm_persp_fovy(mat4 proj)
CGLM_INLINE float glm_persp_aspect(mat4 proj)
CGLM_INLINE void glm_persp_sizes(mat4 proj, float fovy, vec4 dest)
*/ */
#ifndef cglm_vcam_h #ifndef cglm_vcam_h
#define cglm_vcam_h #define cglm_vcam_h
#include "common.h" #include "common.h"
#include "plane.h"
/*! /*!
* @brief set up perspective peprojection matrix * @brief set up perspective peprojection matrix
@@ -132,6 +137,59 @@ glm_ortho(float left,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb(vec3 box[2], mat4 dest) {
glm_ortho(box[0][0], box[1][0],
box[0][1], box[1][1],
-box[1][2], -box[0][2],
dest);
}
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[in] padding padding
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest) {
glm_ortho(box[0][0] - padding, box[1][0] + padding,
box[0][1] - padding, box[1][1] + padding,
-(box[1][2] + padding), -(box[0][2] - padding),
dest);
}
/*!
* @brief set up orthographic projection matrix using bounding box
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[in] padding padding for near and far
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_pz(vec3 box[2], float padding, mat4 dest) {
glm_ortho(box[0][0], box[1][0],
box[0][1], box[1][1],
-(box[1][2] + padding), -(box[0][2] - padding),
dest);
}
/*! /*!
* @brief set up unit orthographic projection matrix * @brief set up unit orthographic projection matrix
* *
@@ -244,7 +302,7 @@ glm_perspective_default(float aspect,
/*! /*!
* @brief resize perspective matrix by aspect ratio ( width / height ) * @brief resize perspective matrix by aspect ratio ( width / height )
* this very make easy to resize proj matrix when window, viewport * this makes very easy to resize proj matrix when window /viewport
* reized * reized
* *
* @param[in] aspect aspect ratio ( width / height ) * @param[in] aspect aspect ratio ( width / height )
@@ -300,32 +358,85 @@ glm_lookat(vec3 eye,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief set up view matrix
*
* convenient wrapper for lookat: if you only have direction not target self
* then this might be useful. Because you need to get target from direction.
*
* @param[in] eye eye vector
* @param[in] dir direction vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
vec3 target;
glm_vec_add(eye, dir, target);
glm_lookat(eye, target, up, dest);
}
/*!
* @brief set up view matrix
*
* convenient wrapper for look: if you only have direction and if you don't
* care what UP vector is then this might be useful to create view matrix
*
* @param[in] eye eye vector
* @param[in] dir direction vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_look_anyup(vec3 eye, vec3 dir, mat4 dest) {
vec3 up;
glm_vec_ortho(dir, up);
glm_look(eye, dir, up, dest);
}
/*! /*!
* @brief decomposes frustum values of perspective projection. * @brief decomposes frustum values of perspective projection.
* *
* @param[in] proj perspective projection matrix * @param[in] proj perspective projection matrix
* @param[out] near near * @param[out] nearVal near
* @param[out] far far * @param[out] farVal far
* @param[out] top top * @param[out] top top
* @param[out] bottom bottom * @param[out] bottom bottom
* @param[out] left left * @param[out] left left
* @param[out] right right * @param[out] right right
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_persp_decomp(mat4 proj, glm_persp_decomp(mat4 proj,
float * __restrict near, float * __restrict nearVal,
float * __restrict far, float * __restrict farVal,
float * __restrict top, float * __restrict top,
float * __restrict bottom, float * __restrict bottom,
float * __restrict left, float * __restrict left,
float * __restrict right) { float * __restrict right) {
*near = proj[3][2] / (proj[2][2] - 1); float m00, m11, m20, m21, m22, m32, n, f;
*far = proj[3][2] / (proj[2][2] + 1); float n_m11, n_m00;
*bottom = *near * (proj[2][1] - 1) / proj[1][1];
*top = *near * (proj[2][1] + 1) / proj[1][1]; m00 = proj[0][0];
*left = *near * (proj[2][0] - 1) / proj[0][0]; m11 = proj[1][1];
*right = *near * (proj[2][0] + 1) / proj[0][0]; m20 = proj[2][0];
m21 = proj[2][1];
m22 = proj[2][2];
m32 = proj[3][2];
n = m32 / (m22 - 1.0f);
f = m32 / (m22 + 1.0f);
n_m11 = n / m11;
n_m00 = n / m00;
*nearVal = n;
*farVal = f;
*bottom = n_m11 * (m21 - 1.0f);
*top = n_m11 * (m21 + 1.0f);
*left = n_m00 * (m20 - 1.0f);
*right = n_m00 * (m20 + 1.0f);
} }
/*! /*!
@@ -337,7 +448,7 @@ glm_persp_decomp(mat4 proj,
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_persp_decompv(mat4 proj, float dest[6]) { glm_persp_decompv(mat4 proj, float dest[6]) {
glm_persp_decomp(proj, &dest[0], &dest[1], &dest[2], glm_persp_decomp(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]); &dest[3], &dest[4], &dest[5]);
} }
@@ -346,7 +457,7 @@ glm_persp_decompv(mat4 proj, float dest[6]) {
* @brief decomposes left and right values of perspective projection. * @brief decomposes left and right values of perspective projection.
* x stands for x axis (left / right axis) * x stands for x axis (left / right axis)
* *
* @param[in] proj perspective projection matrix * @param[in] proj perspective projection matrix
* @param[out] left left * @param[out] left left
* @param[out] right right * @param[out] right right
*/ */
@@ -355,11 +466,14 @@ void
glm_persp_decomp_x(mat4 proj, glm_persp_decomp_x(mat4 proj,
float * __restrict left, float * __restrict left,
float * __restrict right) { float * __restrict right) {
float near; float nearVal, m20, m00;
near = proj[3][2] / (proj[3][3] - 1); m00 = proj[0][0];
*left = near * (proj[2][0] - 1) / proj[0][0]; m20 = proj[2][0];
*right = near * (proj[2][0] + 1) / proj[0][0];
nearVal = proj[3][2] / (proj[3][3] - 1.0f);
*left = nearVal * (m20 - 1.0f) / m00;
*right = nearVal * (m20 + 1.0f) / m00;
} }
/*! /*!
@@ -375,51 +489,108 @@ void
glm_persp_decomp_y(mat4 proj, glm_persp_decomp_y(mat4 proj,
float * __restrict top, float * __restrict top,
float * __restrict bottom) { float * __restrict bottom) {
float near; float nearVal, m21, m11;
near = proj[3][2] / (proj[3][3] - 1); m21 = proj[2][1];
*bottom = near * (proj[2][1] - 1) / proj[1][1]; m11 = proj[1][1];
*top = near * (proj[2][1] + 1) / proj[1][1];
nearVal = proj[3][2] / (proj[3][3] - 1.0f);
*bottom = nearVal * (m21 - 1) / m11;
*top = nearVal * (m21 + 1) / m11;
} }
/*! /*!
* @brief decomposes near and far values of perspective projection. * @brief decomposes near and far values of perspective projection.
* z stands for z axis (near / far axis) * z stands for z axis (near / far axis)
* *
* @param[in] proj perspective projection matrix * @param[in] proj perspective projection matrix
* @param[out] near near * @param[out] nearVal near
* @param[out] far far * @param[out] farVal far
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_persp_decomp_z(mat4 proj, glm_persp_decomp_z(mat4 proj,
float * __restrict near, float * __restrict nearVal,
float * __restrict far) { float * __restrict farVal) {
*near = proj[3][2] / (proj[2][2] - 1); float m32, m22;
*far = proj[3][2] / (proj[2][2] + 1);
m32 = proj[3][2];
m22 = proj[2][2];
*nearVal = m32 / (m22 - 1.0f);
*farVal = m32 / (m22 + 1.0f);
} }
/*! /*!
* @brief decomposes far value of perspective projection. * @brief decomposes far value of perspective projection.
* *
* @param[in] proj perspective projection matrix * @param[in] proj perspective projection matrix
* @param[out] far far * @param[out] farVal far
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_persp_decomp_far(mat4 proj, float * __restrict far) { glm_persp_decomp_far(mat4 proj, float * __restrict farVal) {
*far = proj[3][2] / (proj[2][2] + 1); *farVal = proj[3][2] / (proj[2][2] + 1.0f);
} }
/*! /*!
* @brief decomposes near value of perspective projection. * @brief decomposes near value of perspective projection.
* *
* @param[in] proj perspective projection matrix * @param[in] proj perspective projection matrix
* @param[out] near near * @param[out] nearVal near
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_persp_decomp_near(mat4 proj, float * __restrict near) { glm_persp_decomp_near(mat4 proj, float * __restrict nearVal) {
*near = proj[3][2] / (proj[2][2] - 1); *nearVal = proj[3][2] / (proj[2][2] - 1.0f);
} }
/*!
* @brief returns field of view angle along the Y-axis (in radians)
*
* if you need to degrees, use glm_deg to convert it or use this:
* fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_fovy(mat4 proj) {
return 2.0f * atanf(1.0f / proj[1][1]);
}
/*!
* @brief returns aspect ratio of perspective projection
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_aspect(mat4 proj) {
return proj[1][1] / proj[0][0];
}
/*!
* @brief returns sizes of near and far planes of perspective projection
*
* @param[in] proj perspective projection matrix
* @param[in] fovy fovy (see brief)
* @param[out] dest sizes order: [Wnear, Hnear, Wfar, Hfar]
*/
CGLM_INLINE
void
glm_persp_sizes(mat4 proj, float fovy, vec4 dest) {
float t, a, nearVal, farVal;
t = 2.0f * tanf(fovy * 0.5f);
a = glm_persp_aspect(proj);
glm_persp_decomp_z(proj, &nearVal, &farVal);
dest[1] = t * nearVal;
dest[3] = t * farVal;
dest[0] = a * dest[1];
dest[2] = a * dest[3];
}
#endif /* cglm_vcam_h */ #endif /* cglm_vcam_h */

View File

@@ -15,8 +15,12 @@
#include "mat3.h" #include "mat3.h"
#include "affine.h" #include "affine.h"
#include "cam.h" #include "cam.h"
#include "frustum.h"
#include "quat.h" #include "quat.h"
#include "euler.h" #include "euler.h"
#include "plane.h"
#include "box.h"
#include "color.h"
#include "util.h" #include "util.h"
#include "io.h" #include "io.h"

26
include/cglm/color.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_color_h
#define cglm_color_h
#include "common.h"
#include "vec3.h"
/*!
* @brief averages the color channels into one value
*
* @param[in] rgb RGB color
*/
CGLM_INLINE
float
glm_luminance(vec3 rgb) {
vec3 l = {0.212671f, 0.715160f, 0.072169f};
return glm_dot(rgb, l);
}
#endif /* cglm_color_h */

View File

@@ -12,6 +12,7 @@
#include <stdint.h> #include <stdint.h>
#include <math.h> #include <math.h>
#include <float.h>
#if defined(_WIN32) #if defined(_WIN32)
# ifdef CGLM_DLL # ifdef CGLM_DLL

View File

@@ -19,7 +19,7 @@
CGLM_INLINE void glm_euler_yzx(vec3 angles, mat4 dest); CGLM_INLINE void glm_euler_yzx(vec3 angles, mat4 dest);
CGLM_INLINE void glm_euler_yxz(vec3 angles, mat4 dest); CGLM_INLINE void glm_euler_yxz(vec3 angles, mat4 dest);
CGLM_INLINE void glm_euler_by_order(vec3 angles, CGLM_INLINE void glm_euler_by_order(vec3 angles,
glm_euler_sq axis, glm_euler_sq ord,
mat4 dest); mat4 dest);
*/ */
@@ -48,12 +48,12 @@ typedef enum glm_euler_sq {
CGLM_INLINE CGLM_INLINE
glm_euler_sq glm_euler_sq
glm_euler_order(int newOrder[3]) { glm_euler_order(int ord[3]) {
return (glm_euler_sq)(newOrder[0] | newOrder[1] << 2 | newOrder[2] << 4); return (glm_euler_sq)(ord[0] << 0 | ord[1] << 2 | ord[2] << 4);
} }
/*! /*!
* @brief euler angles (in radian) using xyz sequence * @brief extract euler angles (in radians) using xyz order
* *
* @param[in] m affine transform * @param[in] m affine transform
* @param[out] dest angles vector [x, y, z] * @param[out] dest angles vector [x, y, z]
@@ -96,7 +96,7 @@ glm_euler_angles(mat4 m, vec3 dest) {
} }
/*! /*!
* @brief build rotation matrix from euler angles(ExEyEz/RzRyRx) * @brief build rotation matrix from euler angles
* *
* @param[in] angles angles as vector [Ex, Ey, Ez] * @param[in] angles angles as vector [Ex, Ey, Ez]
* @param[out] dest rotation matrix * @param[out] dest rotation matrix
@@ -130,7 +130,10 @@ glm_euler(vec3 angles, mat4 dest) {
} }
/*! /*!
* @brief build rotation matrix from euler angles (EzEyEx/RxRyRz) * @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Ez, Ey, Ex]
* @param[out] dest rotation matrix
*/ */
CGLM_INLINE CGLM_INLINE
void void
@@ -161,6 +164,12 @@ glm_euler_zyx(vec3 angles,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Ez, Ex, Ey]
* @param[out] dest rotation matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_euler_zxy(vec3 angles, glm_euler_zxy(vec3 angles,
@@ -190,6 +199,12 @@ glm_euler_zxy(vec3 angles,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Ex, Ez, Ey]
* @param[out] dest rotation matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_euler_xzy(vec3 angles, glm_euler_xzy(vec3 angles,
@@ -219,6 +234,12 @@ glm_euler_xzy(vec3 angles,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Ey, Ez, Ex]
* @param[out] dest rotation matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_euler_yzx(vec3 angles, glm_euler_yzx(vec3 angles,
@@ -248,6 +269,12 @@ glm_euler_yzx(vec3 angles,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector [Ey, Ex, Ez]
* @param[out] dest rotation matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_euler_yxz(vec3 angles, glm_euler_yxz(vec3 angles,
@@ -277,9 +304,16 @@ glm_euler_yxz(vec3 angles,
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief build rotation matrix from euler angles
*
* @param[in] angles angles as vector (ord parameter spceifies angles order)
* @param[in] ord euler order
* @param[out] dest rotation matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_euler_by_order(vec3 angles, glm_euler_sq axis, mat4 dest) { glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest) {
float cx, cy, cz, float cx, cy, cz,
sx, sy, sz; sx, sy, sz;
@@ -297,7 +331,7 @@ glm_euler_by_order(vec3 angles, glm_euler_sq axis, mat4 dest) {
czsx = cz * sx; cxsz = cx * sz; czsx = cz * sx; cxsz = cx * sz;
sysz = sy * sz; sysz = sy * sz;
switch (axis) { switch (ord) {
case GLM_EULER_XYZ: case GLM_EULER_XYZ:
dest[0][0] = cycz; dest[0][0] = cycz;
dest[0][1] = cysz; dest[0][1] = cysz;

252
include/cglm/frustum.h Normal file
View File

@@ -0,0 +1,252 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_frustum_h
#define cglm_frustum_h
#include "common.h"
#include "plane.h"
#define GLM_LBN 0 /* left bottom near */
#define GLM_LTN 1 /* left top near */
#define GLM_RTN 2 /* right top near */
#define GLM_RBN 3 /* right bottom near */
#define GLM_LBF 4 /* left bottom far */
#define GLM_LTF 5 /* left top far */
#define GLM_RTF 6 /* right top far */
#define GLM_RBF 7 /* right bottom far */
#define GLM_LEFT 0
#define GLM_RIGHT 1
#define GLM_BOTTOM 2
#define GLM_TOP 3
#define GLM_NEAR 4
#define GLM_FAR 5
/* you can override clip space coords
but you have to provide all with same name
e.g.: define GLM_CSCOORD_LBN {0.0f, 0.0f, 1.0f, 1.0f} */
#ifndef GLM_CUSTOM_CLIPSPACE
/* near */
#define GLM_CSCOORD_LBN {-1.0f, -1.0f, -1.0f, 1.0f}
#define GLM_CSCOORD_LTN {-1.0f, 1.0f, -1.0f, 1.0f}
#define GLM_CSCOORD_RTN { 1.0f, 1.0f, -1.0f, 1.0f}
#define GLM_CSCOORD_RBN { 1.0f, -1.0f, -1.0f, 1.0f}
/* far */
#define GLM_CSCOORD_LBF {-1.0f, -1.0f, 1.0f, 1.0f}
#define GLM_CSCOORD_LTF {-1.0f, 1.0f, 1.0f, 1.0f}
#define GLM_CSCOORD_RTF { 1.0f, 1.0f, 1.0f, 1.0f}
#define GLM_CSCOORD_RBF { 1.0f, -1.0f, 1.0f, 1.0f}
#endif
/*!
* @brief extracts view frustum planes
*
* planes' space:
* 1- if m = proj: View Space
* 2- if m = viewProj: World Space
* 3- if m = MVP: Object Space
*
* You probably want to extract planes in world space so use viewProj as m
* Computing viewProj:
* glm_mat4_mul(proj, view, viewProj);
*
* Exracted planes order: [left, right, bottom, top, near, far]
*
* @param[in] m matrix (see brief)
* @param[out] dest exracted view frustum planes (see brief)
*/
CGLM_INLINE
void
glm_frustum_planes(mat4 m, vec4 dest[6]) {
mat4 t;
glm_mat4_transpose_to(m, t);
glm_vec4_add(t[3], t[0], dest[0]); /* left */
glm_vec4_sub(t[3], t[0], dest[1]); /* right */
glm_vec4_add(t[3], t[1], dest[2]); /* bottom */
glm_vec4_sub(t[3], t[1], dest[3]); /* top */
glm_vec4_add(t[3], t[2], dest[4]); /* near */
glm_vec4_sub(t[3], t[2], dest[5]); /* far */
glm_plane_normalize(dest[0]);
glm_plane_normalize(dest[1]);
glm_plane_normalize(dest[2]);
glm_plane_normalize(dest[3]);
glm_plane_normalize(dest[4]);
glm_plane_normalize(dest[5]);
}
/*!
* @brief extracts view frustum corners using clip-space coordinates
*
* corners' space:
* 1- if m = invViewProj: World Space
* 2- if m = invMVP: Object Space
*
* You probably want to extract corners in world space so use invViewProj
* Computing invViewProj:
* glm_mat4_mul(proj, view, viewProj);
* ...
* glm_mat4_inv(viewProj, invViewProj);
*
* if you have a near coord at i index, you can get it's far coord by i + 4
*
* Find center coordinates:
* for (j = 0; j < 4; j++) {
* glm_vec_center(corners[i], corners[i + 4], centerCorners[i]);
* }
*
* @param[in] invMat matrix (see brief)
* @param[out] dest exracted view frustum corners (see brief)
*/
CGLM_INLINE
void
glm_frustum_corners(mat4 invMat, vec4 dest[8]) {
vec4 c[8];
/* indexOf(nearCoord) = indexOf(farCoord) + 4 */
vec4 csCoords[8] = {
GLM_CSCOORD_LBN,
GLM_CSCOORD_LTN,
GLM_CSCOORD_RTN,
GLM_CSCOORD_RBN,
GLM_CSCOORD_LBF,
GLM_CSCOORD_LTF,
GLM_CSCOORD_RTF,
GLM_CSCOORD_RBF
};
glm_mat4_mulv(invMat, csCoords[0], c[0]);
glm_mat4_mulv(invMat, csCoords[1], c[1]);
glm_mat4_mulv(invMat, csCoords[2], c[2]);
glm_mat4_mulv(invMat, csCoords[3], c[3]);
glm_mat4_mulv(invMat, csCoords[4], c[4]);
glm_mat4_mulv(invMat, csCoords[5], c[5]);
glm_mat4_mulv(invMat, csCoords[6], c[6]);
glm_mat4_mulv(invMat, csCoords[7], c[7]);
glm_vec4_scale(c[0], 1.0f / c[0][3], dest[0]);
glm_vec4_scale(c[1], 1.0f / c[1][3], dest[1]);
glm_vec4_scale(c[2], 1.0f / c[2][3], dest[2]);
glm_vec4_scale(c[3], 1.0f / c[3][3], dest[3]);
glm_vec4_scale(c[4], 1.0f / c[4][3], dest[4]);
glm_vec4_scale(c[5], 1.0f / c[5][3], dest[5]);
glm_vec4_scale(c[6], 1.0f / c[6][3], dest[6]);
glm_vec4_scale(c[7], 1.0f / c[7][3], dest[7]);
}
/*!
* @brief finds center of view frustum
*
* @param[in] corners view frustum corners
* @param[out] dest view frustum center
*/
CGLM_INLINE
void
glm_frustum_center(vec4 corners[8], vec4 dest) {
vec4 center;
glm_vec4_copy(corners[0], center);
glm_vec4_add(corners[1], center, center);
glm_vec4_add(corners[2], center, center);
glm_vec4_add(corners[3], center, center);
glm_vec4_add(corners[4], center, center);
glm_vec4_add(corners[5], center, center);
glm_vec4_add(corners[6], center, center);
glm_vec4_add(corners[7], center, center);
glm_vec4_scale(center, 0.125f, dest);
}
/*!
* @brief finds bounding box of frustum relative to given matrix e.g. view mat
*
* @param[in] corners view frustum corners
* @param[in] m matrix to convert existing conners
* @param[out] box bounding box as array [min, max]
*/
CGLM_INLINE
void
glm_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) {
vec4 v;
vec3 min, max;
int i;
glm_vec_broadcast(FLT_MAX, min);
glm_vec_broadcast(-FLT_MAX, max);
for (i = 0; i < 8; i++) {
glm_mat4_mulv(m, corners[i], v);
min[0] = glm_min(min[0], v[0]);
min[1] = glm_min(min[1], v[1]);
min[2] = glm_min(min[2], v[2]);
max[0] = glm_max(max[0], v[0]);
max[1] = glm_max(max[1], v[1]);
max[2] = glm_max(max[2], v[2]);
}
glm_vec_copy(min, box[0]);
glm_vec_copy(max, box[1]);
}
/*!
* @brief finds planes corners which is between near and far planes (parallel)
*
* this will be helpful if you want to split a frustum e.g. CSM/PSSM. This will
* find planes' corners but you will need to one more plane.
* Actually you have it, it is near, far or created previously with this func ;)
*
* @param[in] corners view frustum corners
* @param[in] splitDist split distance
* @param[in] farDist far distance (zFar)
* @param[out] planeCorners plane corners [LB, LT, RT, RB]
*/
CGLM_INLINE
void
glm_frustum_corners_at(vec4 corners[8],
float splitDist,
float farDist,
vec4 planeCorners[4]) {
vec4 corner;
float dist, sc;
/* because distance and scale is same for all */
dist = glm_vec_distance(corners[GLM_RTF], corners[GLM_RTN]);
sc = dist * (splitDist / farDist);
/* left bottom */
glm_vec4_sub(corners[GLM_LBF], corners[GLM_LBN], corner);
glm_vec4_scale_as(corner, sc, corner);
glm_vec4_add(corners[GLM_LBN], corner, planeCorners[0]);
/* left top */
glm_vec4_sub(corners[GLM_LTF], corners[GLM_LTN], corner);
glm_vec4_scale_as(corner, sc, corner);
glm_vec4_add(corners[GLM_LTN], corner, planeCorners[1]);
/* right top */
glm_vec4_sub(corners[GLM_RTF], corners[GLM_RTN], corner);
glm_vec4_scale_as(corner, sc, corner);
glm_vec4_add(corners[GLM_RTN], corner, planeCorners[2]);
/* right bottom */
glm_vec4_sub(corners[GLM_RBF], corners[GLM_RBN], corner);
glm_vec4_scale_as(corner, sc, corner);
glm_vec4_add(corners[GLM_RBN], corner, planeCorners[3]);
}
#endif /* cglm_frustum_h */

View File

@@ -45,8 +45,8 @@
/* for C only */ /* for C only */
#define GLM_MAT3_IDENTITY (mat3)GLM_MAT3_IDENTITY_INIT #define GLM_MAT3_IDENTITY ((mat3)GLM_MAT3_IDENTITY_INIT)
#define GLM_MAT3_ZERO (mat3)GLM_MAT3_ZERO_INIT #define GLM_MAT3_ZERO ((mat3)GLM_MAT3_ZERO_INIT)
/* DEPRECATED! use _copy, _ucopy versions */ /* DEPRECATED! use _copy, _ucopy versions */
#define glm_mat3_dup(mat, dest) glm_mat3_copy(mat, dest) #define glm_mat3_dup(mat, dest) glm_mat3_copy(mat, dest)

View File

@@ -71,8 +71,8 @@
{0.0f, 0.0f, 0.0f, 0.0f}} {0.0f, 0.0f, 0.0f, 0.0f}}
/* for C only */ /* for C only */
#define GLM_MAT4_IDENTITY (mat4)GLM_MAT4_IDENTITY_INIT #define GLM_MAT4_IDENTITY ((mat4)GLM_MAT4_IDENTITY_INIT)
#define GLM_MAT4_ZERO (mat4)GLM_MAT4_ZERO_INIT #define GLM_MAT4_ZERO ((mat4)GLM_MAT4_ZERO_INIT)
/* DEPRECATED! use _copy, _ucopy versions */ /* DEPRECATED! use _copy, _ucopy versions */
#define glm_mat4_udup(mat, dest) glm_mat4_ucopy(mat, dest) #define glm_mat4_udup(mat, dest) glm_mat4_ucopy(mat, dest)

38
include/cglm/plane.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_plane_h
#define cglm_plane_h
#include "common.h"
#include "mat4.h"
#include "vec4.h"
#include "vec3.h"
/*
Plane equation: Ax + By + Cz + D = 0;
It stored in vec4 as [A, B, C, D]. (A, B, C) is normal and D is distance
*/
/*
Functions:
CGLM_INLINE void glm_plane_normalize(vec4 plane);
*/
/*!
* @brief normalizes a plane
*
* @param[in, out] plane pnale to normalize
*/
CGLM_INLINE
void
glm_plane_normalize(vec4 plane) {
glm_vec4_scale(plane, 1.0f / glm_vec_norm(plane), plane);
}
#endif /* cglm_plane_h */

View File

@@ -32,9 +32,27 @@
# include "simd/sse2/quat.h" # include "simd/sse2/quat.h"
#endif #endif
#define GLM_QUAT_IDENTITY_INIT {0.0f, 0.0f, 0.0f, 1.0f} /*
#define GLM_QUAT_IDENTITY (versor){0.0f, 0.0f, 0.0f, 1.0f} * IMPORTANT! cglm stores quat as [w, x, y, z]
*
* Possible changes (these may be changed in the future):
* - versor is identity quat, we can define new type for quat.
* it can't be quat or quaternion becuase someone can use that name for
* variable name. maybe just vec4.
* - it stores [w, x, y, z] but it may change to [x, y, z, w] if we get enough
* feedback to change it.
* - in general we use last param as dest, but this header used first param
* as dest this may be changed but decided yet
*/
#define GLM_QUAT_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 0.0f}
#define GLM_QUAT_IDENTITY ((versor)GLM_QUAT_IDENTITY_INIT)
/*!
* @brief makes given quat to identity
*
* @param[in, out] q quaternion
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat_identity(versor q) { glm_quat_identity(versor q) {
@@ -42,6 +60,15 @@ glm_quat_identity(versor q) {
glm_vec4_copy(v, q); glm_vec4_copy(v, q);
} }
/*!
* @brief creates NEW quaternion with individual axis components
*
* @param[out] q quaternion
* @param[in] angle angle (radians)
* @param[in] x axis.x
* @param[in] y axis.y
* @param[in] z axis.z
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat(versor q, glm_quat(versor q,
@@ -61,6 +88,13 @@ glm_quat(versor q,
q[3] = s * z; q[3] = s * z;
} }
/*!
* @brief creates NEW quaternion with axis vector
*
* @param[out] q quaternion
* @param[in] angle angle (radians)
* @param[in] v axis
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quatv(versor q, glm_quatv(versor q,
@@ -78,12 +112,22 @@ glm_quatv(versor q,
q[3] = s * v[2]; q[3] = s * v[2];
} }
/*!
* @brief returns norm (magnitude) of quaternion
*
* @param[out] q quaternion
*/
CGLM_INLINE CGLM_INLINE
float float
glm_quat_norm(versor q) { glm_quat_norm(versor q) {
return glm_vec4_norm(q); return glm_vec4_norm(q);
} }
/*!
* @brief normalize quaternion
*
* @param[in, out] q quaternion
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat_normalize(versor q) { glm_quat_normalize(versor q) {
@@ -98,12 +142,25 @@ glm_quat_normalize(versor q) {
glm_vec4_scale(q, 1.0f / sqrtf(sum), q); glm_vec4_scale(q, 1.0f / sqrtf(sum), q);
} }
/*!
* @brief dot product of two quaternion
*
* @param[in] q quaternion 1
* @param[in] r quaternion 2
*/
CGLM_INLINE CGLM_INLINE
float float
glm_quat_dot(versor q, versor r) { glm_quat_dot(versor q, versor r) {
return glm_vec4_dot(q, r); return glm_vec4_dot(q, r);
} }
/*!
* @brief multiplies two quaternion and stores result in dest
*
* @param[in] q1 quaternion 1
* @param[in] q2 quaternion 2
* @param[out] dest result quaternion
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat_mulv(versor q1, versor q2, versor dest) { glm_quat_mulv(versor q1, versor q2, versor dest) {
@@ -115,6 +172,12 @@ glm_quat_mulv(versor q1, versor q2, versor dest) {
glm_quat_normalize(dest); glm_quat_normalize(dest);
} }
/*!
* @brief convert quaternion to mat4
*
* @param[in] q quaternion
* @param[out] dest result matrix
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat_mat4(versor q, mat4 dest) { glm_quat_mat4(versor q, mat4 dest) {
@@ -153,6 +216,15 @@ glm_quat_mat4(versor q, mat4 dest) {
dest[3][3] = 1.0f; dest[3][3] = 1.0f;
} }
/*!
* @brief interpolates between two quaternions
* using spherical linear interpolation (SLERP)
*
* @param[in] q from
* @param[in] r to
* @param[in] t amout
* @param[out] dest result quaternion
*/
CGLM_INLINE CGLM_INLINE
void void
glm_quat_slerp(versor q, glm_quat_slerp(versor q,

View File

@@ -31,34 +31,88 @@ glm_sign(int val) {
return ((val >> 31) - (-val >> 31)); return ((val >> 31) - (-val >> 31));
} }
/*!
* @brief convert degree to radians
*
* @param[in] deg angle in degrees
*/
CGLM_INLINE CGLM_INLINE
float float
glm_rad(float deg) { glm_rad(float deg) {
return deg * CGLM_PI / 180.0f; return deg * CGLM_PI / 180.0f;
} }
/*!
* @brief convert radians to degree
*
* @param[in] rad angle in radians
*/
CGLM_INLINE CGLM_INLINE
float float
glm_deg(float rad) { glm_deg(float rad) {
return rad * 180.0f / CGLM_PI; return rad * 180.0f / CGLM_PI;
} }
/*!
* @brief convert exsisting degree to radians. this will override degrees value
*
* @param[in, out] deg pointer to angle in degrees
*/
CGLM_INLINE CGLM_INLINE
void void
glm_make_rad(float *deg) { glm_make_rad(float *deg) {
*deg = *deg * CGLM_PI / 180.0f; *deg = *deg * CGLM_PI / 180.0f;
} }
/*!
* @brief convert exsisting radians to degree. this will override radians value
*
* @param[in, out] rad pointer to angle in radians
*/
CGLM_INLINE CGLM_INLINE
void void
glm_make_deg(float *rad) { glm_make_deg(float *rad) {
*rad = *rad * 180.0f / CGLM_PI; *rad = *rad * 180.0f / CGLM_PI;
} }
/*!
* @brief multiplies given parameter with itself = x * x or powf(x, 2)
*
* @param[in] x x
*/
CGLM_INLINE CGLM_INLINE
float float
glm_pow2(float x) { glm_pow2(float x) {
return x * x; return x * x;
} }
/*!
* @brief find minimum of given two values
*
* @param[in] a number 1
* @param[in] b number 2
*/
CGLM_INLINE
float
glm_min(float a, float b) {
if (a < b)
return a;
return b;
}
/*!
* @brief find maximum of given two values
*
* @param[in] a number 1
* @param[in] b number 2
*/
CGLM_INLINE
float
glm_max(float a, float b) {
if (a > b)
return a;
return b;
}
#endif /* cglm_util_h */ #endif /* cglm_util_h */

View File

@@ -14,7 +14,7 @@
CGLM_INLINE void glm_vec_mulv(vec3 a, vec3 b, vec3 d); CGLM_INLINE void glm_vec_mulv(vec3 a, vec3 b, vec3 d);
CGLM_INLINE void glm_vec_broadcast(float val, vec3 d); CGLM_INLINE void glm_vec_broadcast(float val, vec3 d);
CGLM_INLINE bool glm_vec_eq(vec3 v, float val); CGLM_INLINE bool glm_vec_eq(vec3 v, float val);
CGLM_INLINE bool glm_vec_eq_eps(vec4 v, float val); CGLM_INLINE bool glm_vec_eq_eps(vec3 v, float val);
CGLM_INLINE bool glm_vec_eq_all(vec3 v); CGLM_INLINE bool glm_vec_eq_all(vec3 v);
CGLM_INLINE bool glm_vec_eqv(vec3 v1, vec3 v2); CGLM_INLINE bool glm_vec_eqv(vec3 v1, vec3 v2);
CGLM_INLINE bool glm_vec_eqv_eps(vec3 v1, vec3 v2); CGLM_INLINE bool glm_vec_eqv_eps(vec3 v1, vec3 v2);
@@ -33,9 +33,9 @@
/*! /*!
* @brief multiplies individual items, just for convenient like SIMD * @brief multiplies individual items, just for convenient like SIMD
* *
* @param a vec1 * @param[in] a vec1
* @param b vec2 * @param[in] b vec2
* @param d vec3 = (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]) * @param[out] d vec3 = (v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2])
*/ */
CGLM_INLINE CGLM_INLINE
void void
@@ -48,8 +48,8 @@ glm_vec_mulv(vec3 a, vec3 b, vec3 d) {
/*! /*!
* @brief fill a vector with specified value * @brief fill a vector with specified value
* *
* @param val value * @param[in] val value
* @param d dest * @param[out] d dest
*/ */
CGLM_INLINE CGLM_INLINE
void void
@@ -60,8 +60,8 @@ glm_vec_broadcast(float val, vec3 d) {
/*! /*!
* @brief check if vector is equal to value (without epsilon) * @brief check if vector is equal to value (without epsilon)
* *
* @param v vector * @param[in] v vector
* @param val value * @param[in] val value
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
@@ -72,12 +72,12 @@ glm_vec_eq(vec3 v, float val) {
/*! /*!
* @brief check if vector is equal to value (with epsilon) * @brief check if vector is equal to value (with epsilon)
* *
* @param v vector * @param[in] v vector
* @param val value * @param[in] val value
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
glm_vec_eq_eps(vec4 v, float val) { glm_vec_eq_eps(vec3 v, float val) {
return fabsf(v[0] - val) <= FLT_EPSILON return fabsf(v[0] - val) <= FLT_EPSILON
&& fabsf(v[1] - val) <= FLT_EPSILON && fabsf(v[1] - val) <= FLT_EPSILON
&& fabsf(v[2] - val) <= FLT_EPSILON; && fabsf(v[2] - val) <= FLT_EPSILON;
@@ -86,7 +86,7 @@ glm_vec_eq_eps(vec4 v, float val) {
/*! /*!
* @brief check if vectors members are equal (without epsilon) * @brief check if vectors members are equal (without epsilon)
* *
* @param v vector * @param[in] v vector
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
@@ -97,8 +97,8 @@ glm_vec_eq_all(vec3 v) {
/*! /*!
* @brief check if vector is equal to another (without epsilon) * @brief check if vector is equal to another (without epsilon)
* *
* @param v1 vector * @param[in] v1 vector
* @param v2 vector * @param[in] v2 vector
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
@@ -111,8 +111,8 @@ glm_vec_eqv(vec3 v1, vec3 v2) {
/*! /*!
* @brief check if vector is equal to another (with epsilon) * @brief check if vector is equal to another (with epsilon)
* *
* @param v1 vector * @param[in] v1 vector
* @param v2 vector * @param[in] v2 vector
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
@@ -125,7 +125,7 @@ glm_vec_eqv_eps(vec3 v1, vec3 v2) {
/*! /*!
* @brief max value of vector * @brief max value of vector
* *
* @param v vector * @param[in] v vector
*/ */
CGLM_INLINE CGLM_INLINE
float float
@@ -144,7 +144,7 @@ glm_vec_max(vec3 v) {
/*! /*!
* @brief min value of vector * @brief min value of vector
* *
* @param v vector * @param[in] v vector
*/ */
CGLM_INLINE CGLM_INLINE
float float

View File

@@ -14,12 +14,15 @@
Macros: Macros:
glm_vec_dup(v, dest) glm_vec_dup(v, dest)
GLM_VEC3_ONE_INIT GLM_VEC3_ONE_INIT
GLM_VEC3_ZERO_INIT
GLM_VEC3_ONE GLM_VEC3_ONE
GLM_VEC3_ZERO
GLM_YUP GLM_YUP
GLM_ZUP GLM_ZUP
GLM_XUP GLM_XUP
Functions: Functions:
CGLM_INLINE void glm_vec3(vec4 v4, vec3 dest);
CGLM_INLINE void glm_vec_copy(vec3 a, vec3 dest); CGLM_INLINE void glm_vec_copy(vec3 a, vec3 dest);
CGLM_INLINE float glm_vec_dot(vec3 a, vec3 b); CGLM_INLINE float glm_vec_dot(vec3 a, vec3 b);
CGLM_INLINE void glm_vec_cross(vec3 a, vec3 b, vec3 d); CGLM_INLINE void glm_vec_cross(vec3 a, vec3 b, vec3 d);
@@ -40,6 +43,15 @@
CGLM_INLINE void glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest); CGLM_INLINE void glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest);
CGLM_INLINE void glm_vec_proj(vec3 a, vec3 b, vec3 dest); CGLM_INLINE void glm_vec_proj(vec3 a, vec3 b, vec3 dest);
CGLM_INLINE void glm_vec_center(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_center(vec3 v1, vec3 v2, vec3 dest);
CGLM_INLINE void glm_vec_maxv(vec3 v1, vec3 v2, vec3 dest);
CGLM_INLINE void glm_vec_minv(vec3 v1, vec3 v2, vec3 dest);
CGLM_INLINE void glm_vec_ortho(vec3 v, vec3 dest);
Convenient:
CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d);
CGLM_INLINE float glm_dot(vec3 a, vec3 b);
CGLM_INLINE void glm_normalize(vec3 v);
CGLM_INLINE void glm_normalize_to(vec3 v, vec3 dest);
*/ */
#ifndef cglm_vec3_h #ifndef cglm_vec3_h
@@ -52,12 +64,29 @@
/* DEPRECATED! use _copy, _ucopy versions */ /* DEPRECATED! use _copy, _ucopy versions */
#define glm_vec_dup(v, dest) glm_vec_copy(v, dest) #define glm_vec_dup(v, dest) glm_vec_copy(v, dest)
#define GLM_VEC3_ONE_INIT {1.0f, 1.0f, 1.0f} #define GLM_VEC3_ONE_INIT {1.0f, 1.0f, 1.0f}
#define GLM_VEC3_ONE (vec3)GLM_VEC3_ONE_INIT #define GLM_VEC3_ZERO_INIT {0.0f, 0.0f, 0.0f}
#define GLM_YUP (vec3){0.0f, 1.0f, 0.0f} #define GLM_VEC3_ONE ((vec3)GLM_VEC3_ONE_INIT)
#define GLM_ZUP (vec3){0.0f, 0.0f, 1.0f} #define GLM_VEC3_ZERO ((vec3)GLM_VEC3_ZERO_INIT)
#define GLM_XUP (vec3){1.0f, 0.0f, 0.0f}
#define GLM_YUP ((vec3){0.0f, 1.0f, 0.0f})
#define GLM_ZUP ((vec3){0.0f, 0.0f, 1.0f})
#define GLM_XUP ((vec3){1.0f, 0.0f, 0.0f})
/*!
* @brief init vec3 using vec4
*
* @param[in] v4 vector4
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec3(vec4 v4, vec3 dest) {
dest[0] = v4[0];
dest[1] = v4[1];
dest[2] = v4[2];
}
/*! /*!
* @brief copy all members of [a] to [dest] * @brief copy all members of [a] to [dest]
@@ -280,6 +309,9 @@ glm_vec_normalize_to(vec3 vec, vec3 dest) {
/*! /*!
* @brief angle betwen two vector * @brief angle betwen two vector
* *
* @param[in] v1 vector1
* @param[in] v2 vector2
*
* @return angle as radians * @return angle as radians
*/ */
CGLM_INLINE CGLM_INLINE
@@ -398,8 +430,110 @@ CGLM_INLINE
float float
glm_vec_distance(vec3 v1, vec3 v2) { glm_vec_distance(vec3 v1, vec3 v2) {
return sqrtf(glm_pow2(v2[0] - v1[0]) return sqrtf(glm_pow2(v2[0] - v1[0])
+ glm_pow2(v2[1] - v1[1]) + glm_pow2(v2[1] - v1[1])
+ glm_pow2(v2[2] - v1[2])); + glm_pow2(v2[2] - v1[2]));
}
/*!
* @brief max values of vectors
*
* @param[in] v1 vector1
* @param[in] v2 vector2
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec_maxv(vec3 v1, vec3 v2, vec3 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]);
}
/*!
* @brief min values of vectors
*
* @param[in] v1 vector1
* @param[in] v2 vector2
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec_minv(vec3 v1, vec3 v2, vec3 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]);
}
/*!
* @brief possible orthogonal/perpendicular vector
*
* @param[in] v vector
* @param[out] dest orthogonal/perpendicular vector
*/
CGLM_INLINE
void
glm_vec_ortho(vec3 v, vec3 dest) {
dest[0] = v[1] - v[2];
dest[1] = v[2] - v[0];
dest[2] = v[0] - v[1];
}
/*!
* @brief vec3 cross product
*
* this is just convenient wrapper
*
* @param[in] a source 1
* @param[in] b source 2
* @param[out] d destination
*/
CGLM_INLINE
void
glm_cross(vec3 a, vec3 b, vec3 d) {
glm_vec_cross(a, b, d);
}
/*!
* @brief vec3 dot product
*
* this is just convenient wrapper
*
* @param[in] a vector1
* @param[in] b vector2
*
* @return dot product
*/
CGLM_INLINE
float
glm_dot(vec3 a, vec3 b) {
return glm_vec_dot(a, b);
}
/*!
* @brief normalize vec3 and store result in same vec
*
* this is just convenient wrapper
*
* @param[in, out] v vector
*/
CGLM_INLINE
void
glm_normalize(vec3 v) {
glm_vec_normalize(v);
}
/*!
* @brief normalize vec3 to dest
*
* this is just convenient wrapper
*
* @param[in] v source
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_normalize_to(vec3 v, vec3 dest) {
glm_vec_normalize_to(v, dest);
} }
#endif /* cglm_vec3_h */ #endif /* cglm_vec3_h */

View File

@@ -17,7 +17,7 @@
CGLM_INLINE bool glm_vec4_eq_eps(vec4 v, float val); CGLM_INLINE bool glm_vec4_eq_eps(vec4 v, float val);
CGLM_INLINE bool glm_vec4_eq_all(vec4 v); CGLM_INLINE bool glm_vec4_eq_all(vec4 v);
CGLM_INLINE bool glm_vec4_eqv(vec4 v1, vec4 v2); CGLM_INLINE bool glm_vec4_eqv(vec4 v1, vec4 v2);
CGLM_INLINE bool glm_vec4_eqv_eps(vec3 v1, vec3 v2); CGLM_INLINE bool glm_vec4_eqv_eps(vec4 v1, vec4 v2);
CGLM_INLINE float glm_vec4_max(vec4 v); CGLM_INLINE float glm_vec4_max(vec4 v);
CGLM_INLINE float glm_vec4_min(vec4 v); CGLM_INLINE float glm_vec4_min(vec4 v);
*/ */
@@ -26,6 +26,7 @@
#define cglm_vec4_ext_h #define cglm_vec4_ext_h
#include "common.h" #include "common.h"
#include "vec3-ext.h"
#include <stdbool.h> #include <stdbool.h>
#include <math.h> #include <math.h>
#include <float.h> #include <float.h>
@@ -132,7 +133,7 @@ glm_vec4_eqv(vec4 v1, vec4 v2) {
*/ */
CGLM_INLINE CGLM_INLINE
bool bool
glm_vec4_eqv_eps(vec3 v1, vec3 v2) { glm_vec4_eqv_eps(vec4 v1, vec4 v2) {
return fabsf(v1[0] - v2[0]) <= FLT_EPSILON return fabsf(v1[0] - v2[0]) <= FLT_EPSILON
&& fabsf(v1[1] - v2[1]) <= FLT_EPSILON && fabsf(v1[1] - v2[1]) <= FLT_EPSILON
&& fabsf(v1[2] - v2[2]) <= FLT_EPSILON && fabsf(v1[2] - v2[2]) <= FLT_EPSILON

View File

@@ -16,10 +16,13 @@
glm_vec4_dup(v, dest) glm_vec4_dup(v, dest)
GLM_VEC4_ONE_INIT GLM_VEC4_ONE_INIT
GLM_VEC4_BLACK_INIT GLM_VEC4_BLACK_INIT
GLM_VEC4_ZERO_INIT
GLM_VEC4_ONE GLM_VEC4_ONE
GLM_VEC4_BLACK GLM_VEC4_BLACK
GLM_VEC4_ZERO
Functions: Functions:
CGLM_INLINE void glm_vec4(vec3 v3, float last, vec4 dest);
CGLM_INLINE void glm_vec4_copy3(vec4 a, vec3 dest); CGLM_INLINE void glm_vec4_copy3(vec4 a, vec3 dest);
CGLM_INLINE void glm_vec4_copy(vec4 v, vec4 dest); CGLM_INLINE void glm_vec4_copy(vec4 v, vec4 dest);
CGLM_INLINE float glm_vec4_dot(vec4 a, vec4 b); CGLM_INLINE float glm_vec4_dot(vec4 a, vec4 b);
@@ -35,6 +38,8 @@
CGLM_INLINE void glm_vec4_normalize(vec4 v); CGLM_INLINE void glm_vec4_normalize(vec4 v);
CGLM_INLINE void glm_vec4_normalize_to(vec4 vec, vec4 dest); CGLM_INLINE void glm_vec4_normalize_to(vec4 vec, vec4 dest);
CGLM_INLINE float glm_vec4_distance(vec4 v1, vec4 v2); CGLM_INLINE float glm_vec4_distance(vec4 v1, vec4 v2);
CGLM_INLINE void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest);
CGLM_INLINE void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest);
*/ */
#ifndef cglm_vec4_h #ifndef cglm_vec4_h
@@ -50,9 +55,27 @@
#define GLM_VEC4_ONE_INIT {1.0f, 1.0f, 1.0f, 1.0f} #define GLM_VEC4_ONE_INIT {1.0f, 1.0f, 1.0f, 1.0f}
#define GLM_VEC4_BLACK_INIT {0.0f, 0.0f, 0.0f, 1.0f} #define GLM_VEC4_BLACK_INIT {0.0f, 0.0f, 0.0f, 1.0f}
#define GLM_VEC4_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f}
#define GLM_VEC4_ONE (vec4)GLM_VEC4_ONE_INIT #define GLM_VEC4_ONE ((vec4)GLM_VEC4_ONE_INIT)
#define GLM_VEC4_BLACK (vec4)GLM_VEC4_BLACK_INIT #define GLM_VEC4_BLACK ((vec4)GLM_VEC4_BLACK_INIT)
#define GLM_VEC4_ZERO ((vec4)GLM_VEC4_ZERO_INIT)
/*!
* @brief init vec4 using vec3
*
* @param[in] v3 vector3
* @param[in] last last item
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_vec4(vec3 v3, float last, vec4 dest) {
dest[0] = v3[0];
dest[1] = v3[1];
dest[2] = v3[2];
dest[3] = last;
}
/*! /*!
* @brief copy first 3 members of [a] to [dest] * @brief copy first 3 members of [a] to [dest]
@@ -313,9 +336,41 @@ CGLM_INLINE
float float
glm_vec4_distance(vec4 v1, vec4 v2) { glm_vec4_distance(vec4 v1, vec4 v2) {
return sqrtf(glm_pow2(v2[0] - v1[0]) return sqrtf(glm_pow2(v2[0] - v1[0])
+ glm_pow2(v2[1] - v1[1]) + glm_pow2(v2[1] - v1[1])
+ glm_pow2(v2[2] - v1[2]) + glm_pow2(v2[2] - v1[2])
+ glm_pow2(v2[3] - v1[3])); + glm_pow2(v2[3] - v1[3]));
}
/*!
* @brief max values of vectors
*
* @param[in] v1 vector1
* @param[in] v2 vector2
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_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]);
}
/*!
* @brief min values of vectors
*
* @param[in] v1 vector1
* @param[in] v2 vector2
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_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]);
} }
#endif /* cglm_vec4_h */ #endif /* cglm_vec4_h */

View File

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

View File

@@ -13,7 +13,7 @@ AM_CFLAGS = -Wall \
-O3 \ -O3 \
-Wstrict-aliasing=2 \ -Wstrict-aliasing=2 \
-fstrict-aliasing \ -fstrict-aliasing \
-Wpedantic -pedantic
lib_LTLIBRARIES = libcglm.la lib_LTLIBRARIES = libcglm.la
libcglm_la_LDFLAGS = -no-undefined -version-info 0:1:0 libcglm_la_LDFLAGS = -no-undefined -version-info 0:1:0
@@ -50,7 +50,11 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/euler.h \ include/cglm/euler.h \
include/cglm/util.h \ include/cglm/util.h \
include/cglm/quat.h \ include/cglm/quat.h \
include/cglm/affine-mat.h include/cglm/affine-mat.h \
include/cglm/plane.h \
include/cglm/frustum.h \
include/cglm/box.h \
include/cglm/color.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 \
@@ -61,7 +65,10 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/io.h \ include/cglm/call/io.h \
include/cglm/call/cam.h \ include/cglm/call/cam.h \
include/cglm/call/quat.h \ include/cglm/call/quat.h \
include/cglm/call/euler.h include/cglm/call/euler.h \
include/cglm/call/plane.h \
include/cglm/call/frustum.h \
include/cglm/call/box.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
@@ -88,12 +95,16 @@ libcglm_la_SOURCES=\
src/vec3.c \ src/vec3.c \
src/vec4.c \ src/vec4.c \
src/mat3.c \ src/mat3.c \
src/mat4.c src/mat4.c \
src/plane.c \
src/frustum.c \
src/box.c
test_tests_SOURCES=\ test_tests_SOURCES=\
test/src/test_common.c \ test/src/test_common.c \
test/src/test_main.c \ test/src/test_main.c \
test/src/test_mat4.c test/src/test_mat4.c \
test/src/test_cam.c
all-local: all-local:
sh ./post-build.sh sh ./post-build.sh

36
src/box.c Normal file
View File

@@ -0,0 +1,36 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "../include/cglm/cglm.h"
#include "../include/cglm/call.h"
CGLM_EXPORT
void
glmc_aabb_transform(vec3 box[2], mat4 m, vec3 dest[2]) {
glm_aabb_transform(box, m, dest);
}
CGLM_EXPORT
void
glmc_aabb_merge(vec3 box1[2], vec3 box2[2], vec3 dest[2]) {
glm_aabb_merge(box1, box2, dest);
}
CGLM_EXPORT
void
glmc_aabb_crop(vec3 box[2], vec3 cropBox[2], vec3 dest[2]) {
glm_aabb_crop(box, cropBox, dest);
}
CGLM_EXPORT
void
glmc_aabb_crop_until(vec3 box[2],
vec3 cropBox[2],
vec3 clampBox[2],
vec3 dest[2]) {
glm_aabb_crop_until(box, cropBox, clampBox, dest);
}

View File

@@ -66,3 +66,15 @@ glmc_lookat(vec3 eye,
mat4 dest) { mat4 dest) {
glm_lookat(eye, center, up, dest); glm_lookat(eye, center, up, dest);
} }
CGLM_EXPORT
void
glmc_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
glm_look(eye, dir, up, dest);
}
CGLM_EXPORT
void
glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest) {
glm_look_anyup(eye, dir, dest);
}

42
src/frustum.c Normal file
View File

@@ -0,0 +1,42 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "../include/cglm/cglm.h"
#include "../include/cglm/call.h"
CGLM_EXPORT
void
glmc_frustum_planes(mat4 m, vec4 dest[6]) {
glm_frustum_planes(m, dest);
}
CGLM_EXPORT
void
glmc_frustum_corners(mat4 invMat, vec4 dest[8]) {
glm_frustum_corners(invMat, dest);
}
CGLM_EXPORT
void
glmc_frustum_center(vec4 corners[8], vec4 dest) {
glm_frustum_center(corners, dest);
}
CGLM_EXPORT
void
glmc_frustum_box(vec4 corners[8], mat4 m, vec3 box[2]) {
glm_frustum_box(corners, m, box);
}
CGLM_EXPORT
void
glmc_frustum_corners_at(vec4 corners[8],
float splitDist,
float farDist,
vec4 planeCorners[4]) {
glm_frustum_corners_at(corners, splitDist, farDist, planeCorners);
}

15
src/plane.c Normal file
View File

@@ -0,0 +1,15 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#include "../include/cglm/cglm.h"
#include "../include/cglm/call.h"
CGLM_EXPORT
void
glmc_plane_normalize(vec4 plane) {
glm_plane_normalize(plane);
}

View File

@@ -127,3 +127,15 @@ float
glmc_vec_distance(vec3 v1, vec3 v2) { glmc_vec_distance(vec3 v1, vec3 v2) {
return glm_vec_distance(v1, v2); return glm_vec_distance(v1, v2);
} }
CGLM_EXPORT
void
glmc_vec_maxv(vec3 v1, vec3 v2, vec3 dest) {
glm_vec_minv(v1, v2, dest);
}
CGLM_EXPORT
void
glmc_vec_minv(vec3 v1, vec3 v2, vec3 dest) {
glm_vec_maxv(v1, v2, dest);
}

View File

@@ -97,3 +97,15 @@ float
glmc_vec4_distance(vec4 v1, vec4 v2) { glmc_vec4_distance(vec4 v1, vec4 v2) {
return glm_vec4_distance(v1, v2); return glm_vec4_distance(v1, v2);
} }
CGLM_EXPORT
void
glmc_vec4_maxv(vec4 v1, vec4 v2, vec4 dest) {
glm_vec4_minv(v1, v2, dest);
}
CGLM_EXPORT
void
glmc_vec4_minv(vec4 v1, vec4 v2, vec4 dest) {
glm_vec4_maxv(v1, v2, dest);
}

54
test/src/test_cam.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* 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_camera_lookat(void **state) {
mat4 view1, view2;
vec3 center,
eye = {0.024f, 14.6f, 67.04f},
dir = {0.0f, 0.0f, -1.0f},
up = {0.0f, 1.0f, 0.0f}
;
glm_vec_add(eye, dir, center);
glm_lookat(eye, center, up, view1);
glm_look(eye, dir, up, view2);
test_assert_mat4_eq(view1, view2);
}
void
test_camera_decomp(void **state) {
mat4 proj, proj2;
vec4 sizes;
float aspect, fovy, nearVal, farVal;
aspect = 0.782f;
fovy = glm_rad(49.984f);
nearVal = 0.1f;
farVal = 100.0f;
glm_perspective(fovy, aspect, nearVal, farVal, proj);
assert_true(fabsf(aspect - glm_persp_aspect(proj)) < FLT_EPSILON);
assert_true(fabsf(fovy - glm_persp_fovy(proj)) < FLT_EPSILON);
assert_true(fabsf(49.984f - glm_deg(glm_persp_fovy(proj))) < FLT_EPSILON);
glm_persp_sizes(proj, fovy, sizes);
glm_frustum(-sizes[0] * 0.5,
sizes[0] * 0.5,
-sizes[1] * 0.5,
sizes[1] * 0.5,
nearVal,
farVal,
proj2);
test_assert_mat4_eq(proj, proj2);
}

View File

@@ -11,9 +11,11 @@ main(int argc, const char * argv[]) {
const struct CMUnitTest tests[] = { const struct CMUnitTest tests[] = {
/* mat4 */ /* mat4 */
cmocka_unit_test(test_mat4), cmocka_unit_test(test_mat4),
/* camera */
cmocka_unit_test(test_camera_lookat),
cmocka_unit_test(test_camera_decomp)
}; };
return cmocka_run_group_tests(tests, return cmocka_run_group_tests(tests, NULL, NULL);
NULL,
NULL);
} }

View File

@@ -9,4 +9,11 @@
/* mat4 */ /* mat4 */
void test_mat4(void **state); void test_mat4(void **state);
/* camera */
void
test_camera_lookat(void **state);
void
test_camera_decomp(void **state);
#endif /* test_tests_h */ #endif /* test_tests_h */

View File

@@ -20,12 +20,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\src\affine.c" /> <ClCompile Include="..\src\affine.c" />
<ClCompile Include="..\src\box.c" />
<ClCompile Include="..\src\cam.c" /> <ClCompile Include="..\src\cam.c" />
<ClCompile Include="..\src\dllmain.c" /> <ClCompile Include="..\src\dllmain.c" />
<ClCompile Include="..\src\euler.c" /> <ClCompile Include="..\src\euler.c" />
<ClCompile Include="..\src\frustum.c" />
<ClCompile Include="..\src\io.c" /> <ClCompile Include="..\src\io.c" />
<ClCompile Include="..\src\mat3.c" /> <ClCompile Include="..\src\mat3.c" />
<ClCompile Include="..\src\mat4.c" /> <ClCompile Include="..\src\mat4.c" />
<ClCompile Include="..\src\plane.c" />
<ClCompile Include="..\src\quat.c" /> <ClCompile Include="..\src\quat.c" />
<ClCompile Include="..\src\vec3.c" /> <ClCompile Include="..\src\vec3.c" />
<ClCompile Include="..\src\vec4.c" /> <ClCompile Include="..\src\vec4.c" />
@@ -33,23 +36,30 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="..\include\cglm\affine-mat.h" /> <ClInclude Include="..\include\cglm\affine-mat.h" />
<ClInclude Include="..\include\cglm\affine.h" /> <ClInclude Include="..\include\cglm\affine.h" />
<ClInclude Include="..\include\cglm\box.h" />
<ClInclude Include="..\include\cglm\call.h" /> <ClInclude Include="..\include\cglm\call.h" />
<ClInclude Include="..\include\cglm\call\affine.h" /> <ClInclude Include="..\include\cglm\call\affine.h" />
<ClInclude Include="..\include\cglm\call\box.h" />
<ClInclude Include="..\include\cglm\call\cam.h" /> <ClInclude Include="..\include\cglm\call\cam.h" />
<ClInclude Include="..\include\cglm\call\euler.h" /> <ClInclude Include="..\include\cglm\call\euler.h" />
<ClInclude Include="..\include\cglm\call\frustum.h" />
<ClInclude Include="..\include\cglm\call\io.h" /> <ClInclude Include="..\include\cglm\call\io.h" />
<ClInclude Include="..\include\cglm\call\mat3.h" /> <ClInclude Include="..\include\cglm\call\mat3.h" />
<ClInclude Include="..\include\cglm\call\mat4.h" /> <ClInclude Include="..\include\cglm\call\mat4.h" />
<ClInclude Include="..\include\cglm\call\plane.h" />
<ClInclude Include="..\include\cglm\call\quat.h" /> <ClInclude Include="..\include\cglm\call\quat.h" />
<ClInclude Include="..\include\cglm\call\vec3.h" /> <ClInclude Include="..\include\cglm\call\vec3.h" />
<ClInclude Include="..\include\cglm\call\vec4.h" /> <ClInclude Include="..\include\cglm\call\vec4.h" />
<ClInclude Include="..\include\cglm\cam.h" /> <ClInclude Include="..\include\cglm\cam.h" />
<ClInclude Include="..\include\cglm\cglm.h" /> <ClInclude Include="..\include\cglm\cglm.h" />
<ClInclude Include="..\include\cglm\color.h" />
<ClInclude Include="..\include\cglm\common.h" /> <ClInclude Include="..\include\cglm\common.h" />
<ClInclude Include="..\include\cglm\euler.h" /> <ClInclude Include="..\include\cglm\euler.h" />
<ClInclude Include="..\include\cglm\frustum.h" />
<ClInclude Include="..\include\cglm\io.h" /> <ClInclude Include="..\include\cglm\io.h" />
<ClInclude Include="..\include\cglm\mat3.h" /> <ClInclude Include="..\include\cglm\mat3.h" />
<ClInclude Include="..\include\cglm\mat4.h" /> <ClInclude Include="..\include\cglm\mat4.h" />
<ClInclude Include="..\include\cglm\plane.h" />
<ClInclude Include="..\include\cglm\quat.h" /> <ClInclude Include="..\include\cglm\quat.h" />
<ClInclude Include="..\include\cglm\simd\avx\affine.h" /> <ClInclude Include="..\include\cglm\simd\avx\affine.h" />
<ClInclude Include="..\include\cglm\simd\avx\mat4.h" /> <ClInclude Include="..\include\cglm\simd\avx\mat4.h" />
@@ -73,7 +83,7 @@
<ProjectGuid>{CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}</ProjectGuid> <ProjectGuid>{CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<RootNamespace>cglm</RootNamespace> <RootNamespace>cglm</RootNamespace>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@@ -66,6 +66,15 @@
<ClCompile Include="..\src\vec4.c"> <ClCompile Include="..\src\vec4.c">
<Filter>src</Filter> <Filter>src</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\frustum.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\plane.c">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\box.c">
<Filter>src</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\config.h"> <ClInclude Include="..\src\config.h">
@@ -176,5 +185,26 @@
<ClInclude Include="..\include\cglm\version.h"> <ClInclude Include="..\include\cglm\version.h">
<Filter>include\cglm</Filter> <Filter>include\cglm</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\include\cglm\call\frustum.h">
<Filter>include\cglm\call</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\call\plane.h">
<Filter>include\cglm\call</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\frustum.h">
<Filter>include\cglm</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\plane.h">
<Filter>include\cglm</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\call\box.h">
<Filter>include\cglm\call</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\box.h">
<Filter>include\cglm</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\color.h">
<Filter>include\cglm</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>