Compare commits

...

248 Commits

Author SHA1 Message Date
Recep Aslantas
da5c66d735 update affine-post.h 2022-10-23 14:27:34 +03:00
Recep Aslantas
c4b45a0917 remove redundant comments 2022-10-23 14:22:16 +03:00
Recep Aslantas
8034073965 Merge pull request #260 from recp/new-affine
new affine transform functions 🚀
2022-10-23 14:06:34 +03:00
Recep Aslantas
53009d69c0 update build files 2022-10-23 12:09:44 +03:00
Recep Aslantas
7c62ad965b add missing call functions 2022-10-23 12:08:37 +03:00
Recep Aslantas
878e829767 update docs 2022-10-23 12:00:17 +03:00
Recep Aslantas
7c7ac8b82e add missing impl for project_z 2022-10-22 23:06:46 +03:00
Recep Aslantas
ba66459708 new project function for projecting Z
someitmes we need to project z only. this function reduces a few calculations and parameters.
2022-10-21 10:20:03 +03:00
Recep Aslantas
45e176680f post rotation operaqtions 2022-10-18 15:43:07 +03:00
Recep Aslantas
c0bd65027a add missing spin impl 2022-10-18 07:38:06 +03:00
Recep Aslantas
03d5699f32 new rotation function: spin; rotate around self at any position 2022-10-17 23:57:41 +03:00
Recep Aslantas
199d1fa031 Merge pull request #259 from bobvanderlinden/pr-cmake-pkgconfig-fix
fix: simplified pkgconfig generation
2022-09-20 16:38:48 +03:00
Bob van der Linden
c7393f75c3 fix: simplified pkgconfig generation 2022-09-16 16:45:12 +02:00
Recep Aslantas
a3186a7f32 Merge pull request #257 from Rokannon/patch-1
Added missing include in io.h which adds GLM_MAX macro
2022-09-11 11:33:46 +03:00
Vladimir Atamanov
5a89faafff Added missing include in io.h which adds GLM_MAX macro 2022-09-11 00:49:24 +02:00
Recep Aslantas
51853db559 Merge pull request #256 from ogtn/master
Fix typo in comment
2022-09-04 07:25:27 +03:00
Olivier Guittonneau
8f8417a883 Fix typo in comment 2022-09-04 01:08:50 +02:00
Recep Aslantas
2238fd127c win: suppress warnings for tests 2022-08-23 18:01:05 +03:00
Recep Aslantas
073a11a6b8 win: add missing files to visual studio project 2022-08-23 16:01:40 +03:00
Recep Aslantas
2d348ceba0 build: add missing files to meson and cmake lists 2022-08-23 15:43:04 +03:00
Recep Aslantas
ce69ecaa5a struct: project_no and project_zo apis for struct api 2022-08-23 15:31:55 +03:00
Recep Aslantas
5ad0f1c6f3 fix MIT License links 2022-08-23 15:30:09 +03:00
Recep Aslantas
aea75bbe7c build: update Makefile.am 2022-08-23 14:13:00 +03:00
Recep Aslantas
7dfe67cdde Update .gitignore 2022-08-07 11:49:13 +03:00
Recep Aslantas
84f64a5b65 Update FUNDING.yml 2022-08-01 05:10:14 +03:00
Recep Aslantas
7df8ffa7fe Merge pull request #254 from Chris-F5/fix-readme-notes
Update README to show that integer types are supported
2022-07-16 12:01:00 +03:00
Christopher Lang
dc5558d8f4 Fix readme supported types note 2022-07-15 20:17:58 +01:00
Recep Aslantas
63990be905 Merge pull request #251 from Chris-F5/add-basic-ivec-functions
Add basic ivec functions
2022-05-22 21:06:07 +03:00
Christopher Lang
cd0ae19459 Add ivec[2|3|4] sources to meson.build 2022-05-21 11:11:34 +01:00
Christopher Lang
838124af49 Declare varables at top of scope for ivec[2|3|4] 2022-05-20 17:30:54 +01:00
Christopher Lang
e3981b6d96 Add ivec[3|4] docs 2022-05-20 17:16:41 +01:00
Christopher Lang
7bb765367e Small ivec2 docs fix 2022-05-20 17:16:09 +01:00
Christopher Lang
82982abaef Add ivec2 documentation 2022-05-20 17:07:16 +01:00
Christopher Lang
dbe3b719c7 Fix ivec[2|3|4]_clamp doc comments 2022-05-20 16:53:02 +01:00
Christopher Lang
09155986fe Update ivec[2|3|4]_distance2 doc comments 2022-05-20 16:49:23 +01:00
Christopher Lang
1b3e2fdaec Improve ivec[2|3|4] documentation comments 2022-05-20 15:24:36 +01:00
Christopher Lang
4aef2510e9 Init ivec[2|3|4] docs 2022-05-20 15:02:58 +01:00
Chris-F5
2432970f90 Merge branch 'recp:master' into add-basic-ivec-functions 2022-05-20 14:45:57 +01:00
Christopher Lang
d1bdfde48d Add ivec4 tests 2022-05-20 14:42:42 +01:00
Christopher Lang
f27e26f632 Fix glm_ivec3 test 2022-05-20 14:41:59 +01:00
Christopher Lang
a3265ebe84 Fix glm_ivec3_one test 2022-05-20 14:27:30 +01:00
Christopher Lang
57ec29bd31 Update glm_ivec3 test 2022-05-20 14:26:49 +01:00
Recep Aslantas
1b217c3dd0 Merge pull request #250 from alexshpilkin/fix-pkg-config
Fix pkg-config generation when CMAKE_INSTALL_*DIR is absolute
2022-05-19 22:23:10 +03:00
Christopher Lang
94a1e6f6e1 Add ivec4 functions 2022-05-19 17:43:17 +01:00
Christopher Lang
a1a2a046a4 Fix ivec[2|3]_clamp comment docs 2022-05-19 17:32:01 +01:00
Christopher Lang
bffaa13bd5 Add ivec3 tests 2022-05-19 17:12:38 +01:00
Christopher Lang
cd4d0a1efe Update glm_ivec2_copy test 2022-05-19 17:11:58 +01:00
Christopher Lang
8916c50a3d Update glm_ivec2 test 2022-05-19 16:52:55 +01:00
Christopher Lang
7a19b8f8a3 Fix glmc_ivec3 naming 2022-05-19 16:52:10 +01:00
Alexander Shpilkin
f587c00f26 allow absolute paths in CMAKE_INSTALL_*DIR 2022-05-19 18:47:00 +03:00
Christopher Lang
65409bcda1 Add ivec3 functions 2022-05-18 18:05:17 +01:00
Christopher Lang
d2957e6275 Fix ivec2 function list comment 2022-05-18 17:55:25 +01:00
Christopher Lang
04bd1bd633 Fix ivec2 doc comment 2022-05-17 23:03:26 +01:00
Christopher Lang
db1a23d13c Add ivec2 tests 2022-05-17 22:27:38 +01:00
Christopher Lang
a85744430a Add ivec2 functions 2022-05-17 22:25:10 +01:00
Christopher Lang
d582146d9a Add ivec3 and ivec4 files 2022-05-17 16:04:47 +01:00
Christopher Lang
ee09707c1c Fix ivec2 test 2022-05-17 15:53:37 +01:00
Christopher Lang
4c85b970a9 Add ivec2 files 2022-05-16 22:41:04 +01:00
Christopher Lang
f7f0f66193 Reorder api docs 2022-05-16 22:14:57 +01:00
Christopher Lang
495b98a54d Fix tests.h comments 2022-05-16 20:51:44 +01:00
Recep Aslantas
aee47ce545 Merge pull request #247 from Chris-F5/improve-docs-index
Fix grammatical errors in docs index
2022-05-12 07:11:38 +03:00
Christopher Lang
52debe6a04 improve docs index 2022-05-08 21:49:30 +01:00
Recep Aslantas
cf7f4231f0 now working on v0.8.6 2022-03-20 22:19:31 +03:00
Recep Aslantas
7e5d1f435f Merge pull request #244 from geckor14/master
Remove unused variable
2022-03-18 12:39:29 +03:00
geckor14
851a58cedb Remove unused variable
The most recent version of Apple Clang (13.1.6) on macOS complains r3 is an unused variable. With -Werror enabled, this breaks the build.
2022-03-18 18:42:19 +11:00
Recep Aslantas
6fa1cefcc2 Merge pull request #243 from Sand3r-/patch-1
Fix a bug in glm_lookat_lh
2022-03-09 09:38:26 +03:00
Michał Gallus
7e211e1f49 Fix bug in view_lh.h #2
Reverse order of parameters in the second crossproduct
2022-03-08 01:42:43 +01:00
Michał Gallus
7d47b7f1fd Fix a bug in glm_lookat_lh
Fix the order of arguments passed to glm_vec3_crossn to avoid the negation of X axis.
2022-03-08 01:29:35 +01:00
Recep Aslantas
2a4748d452 fix glm_pickmatrix()'s param type 2022-01-31 02:56:39 +03:00
Recep Aslantas
f20bf0aaaf Merge pull request #236 from recp/ivec
add missing ivec types
2022-01-07 00:23:32 +03:00
Recep Aslantas
3a141b7cc8 extend unions for struct api 2022-01-06 18:12:46 +03:00
Recep Aslantas
5cd1a4ab44 add missing ivec types 2022-01-06 18:01:35 +03:00
Recep Aslantas
897f2afd88 Merge pull request #234 from madebr/sse3_header
Header containing sse3 intrinsics is pmmintrin.h
2021-12-31 17:51:30 +03:00
Anonymous Maarten
68e3a072e8 Header containing sse3 intrinsics is pmmintrin.h 2021-12-29 08:48:55 +01:00
Recep Aslantas
282ea84dc0 Merge pull request #231 from omar-polo/master
set PACKAGE_VERSION so it gets substituted in cglm.pc.in by cmake
2021-11-22 11:20:20 +03:00
Omar Polo
2d5506d15d set PACKAGE_VERSION so it gets substituted in cglm.pc.in by cmake
otherwise it ends up being an empty string and the installed pc has a
bogus line:

	Version:
2021-11-21 21:04:59 +01:00
Recep Aslantas
87f561fb06 Merge pull request #229 from mxi/vec2-ext-complex
Add complex routines to `vec2-ext`
2021-11-10 10:09:09 +03:00
Maxim Kasyanenko
522b18bda9 Add tests 2021-11-08 17:53:39 -08:00
Maxim Kasyanenko
b7178749ee Forgot to add the dynamic implementation file itself 2021-11-08 17:53:27 -08:00
Maxim Kasyanenko
98c708281f Syntax errors 2021-11-08 17:52:47 -08:00
Maxim Kasyanenko
896ba0a0f9 Add dynamic/struct versions of routines 2021-11-08 17:52:31 -08:00
Maxim Kasyanenko
4603816330 Forgot return type 2021-11-08 17:09:28 -08:00
Maxim Kasyanenko
9f5cc3a745 Implement a few complex routines 2021-11-08 16:28:55 -08:00
Recep Aslantas
bde653b607 Update CMakeLists.txt 2021-10-28 19:10:19 +03:00
Recep Aslantas
ede72ca412 Merge pull request #225 from podsvirov/fix-win32-shared
win: fix shared library name and destination
2021-10-17 18:09:18 +03:00
Konstantin Podsvirov
8e784e762f win: fix shared library name and destination 2021-10-10 12:02:44 +03:00
Recep Aslantas
82d1050c63 update GLM_FLT_EPSILON to use 1e-5 instead of 1e-6 2021-10-06 21:08:55 +03:00
Recep Aslantas
0631598d08 now working on v0.8.5 2021-08-18 05:03:59 +03:00
Recep Aslantas
34e5704fe8 bump version to v0.8.4 2021-08-18 04:47:11 +03:00
Recep Aslantas
672523e5af Merge pull request #219 from recp/project_zo
extend glm_project() to support ZERO_TO_ONE
2021-08-16 16:55:19 +03:00
Recep Aslantas
8427d02a9b pick matrix helper (aka gluPickMatrix) 2021-08-16 16:53:46 +03:00
Recep Aslantas
a2bd00df32 fix including headers, and suppress warnings 2021-08-16 15:51:52 +03:00
Recep Aslantas
4c8f7f310c Update project_zo.h 2021-08-16 14:27:20 +03:00
Recep Aslantas
9096fa6bab fix include paths 2021-08-16 14:27:12 +03:00
Recep Aslantas
29c3837672 implement project zo 2021-08-16 14:16:43 +03:00
Recep Aslantas
4530e0381b build: add missing files 2021-08-16 01:10:29 +03:00
Recep Aslantas
6cf1fb8992 Update .gitignore 2021-08-16 01:10:19 +03:00
Recep Aslantas
9ed4e41afd call version for clipspace-project 2021-08-16 01:08:11 +03:00
Recep Aslantas
28d24da6df build: add missing files 2021-08-16 00:55:19 +03:00
Recep Aslantas
ef22e2063f win: fix build error and comment style 2021-08-16 00:54:37 +03:00
Recep Aslantas
5a48aad1b0 Merge pull request #218 from Nairou/master
Add CGLM_FORCE_DEPTH_ZERO_TO_ONE support to glm_unprojecti
2021-08-16 00:45:22 +03:00
Caleb Gingles
07aee82125 Add CGLM_FORCE_DEPTH_ZERO_TO_ONE support to glm_unprojecti 2021-08-15 17:34:26 -04:00
Recep Aslantas
abbeb274c5 Merge pull request #214 from bubba2k/patch-1
Note that radians is expected in glm_perspective()
2021-08-09 10:54:02 +03:00
bubba2k
814adf11de Note that radians is expected in glm_perspective()
The `fovy` parameter is expected in radians, which isn't mentioned anywhere in the docs. Causes unnecessary confusion. Might as well point it out.
2021-08-09 03:02:47 +02:00
Recep Aslantas
d0d1e46533 Merge pull request #210 from legends2k/quat_rot_vecs 2021-06-15 19:59:45 +03:00
Sundaram Ramaswamy
03b4594d9e quat_from_vecs: incorporate PR comments
* C89-style comments
* Move all variable declarations to function start
* Remove constant variables
* Remove newline for ‘else’
2021-06-15 19:11:41 +05:30
Sundaram Ramaswamy
01e2b74a29 Update documentation for qaut_from_vecs 2021-06-10 23:52:09 +05:30
Sundaram Ramaswamy
ee5050f43c Tests for quaternion from two vec3 2021-06-10 23:15:10 +05:30
Sundaram Ramaswamy
b5802b99b2 Compute quaternion rotating a vector into another
Both `vec3` inputs should be of unit length; returns a unit quaternion.
2021-06-10 23:10:54 +05:30
Recep Aslantas
8b958e9600 Merge pull request #209 from legends2k/fix_vec3_cross
Fix cross product when an operand is also dest
2021-06-10 16:49:17 +03:00
Sundaram Ramaswamy
aa071b2a6b Fix cross product when operand is also dest 2021-06-10 17:20:50 +05:30
Recep Aslantas
479e7d4240 Merge pull request #207 from legends2k/fix_vec3_ortho
Fix vec3_ortho
2021-06-10 10:15:12 +03:00
Recep Aslantas
38c6188e12 Update vec3.h 2021-06-10 10:13:51 +03:00
Sundaram Ramaswamy
c330b47ded Remove debug printf statements 2021-06-10 10:27:28 +05:30
Sundaram Ramaswamy
2e8162b133 Fix vec3_ortho 2021-06-09 23:18:32 +05:30
Recep Aslantas
afdcae08dd Merge pull request #205 from legends2k/master
Include affine.h in quat.h; remove needless decls
2021-06-07 11:45:54 +03:00
Sundaram Ramaswamy
32d1c96dc0 Include affine.h in quat.h; remove needless decls
* affine.h is needed for glm_translate_make
* Remove function declarations
  - glm_mat4_mulv since mat4.h is already included
  - glm_mul_rot as affine-mat.h is already include
  - glm_translate as affine.h is included with this change
2021-06-07 11:35:56 +05:30
Recep Aslantas
4d2ba464a0 Update README.md 2021-05-30 18:11:17 +03:00
Recep Aslantas
398e47070b Update README.md 2021-05-30 18:09:17 +03:00
Recep Aslantas
619ac4ce9a Update README.md 2021-05-30 18:03:33 +03:00
Recep Aslantas
e83940f3b1 Create cglm.png 2021-05-30 17:48:29 +03:00
Recep Aslantas
e5d88f22a0 Update README.md 2021-05-30 15:31:06 +03:00
Recep Aslantas
8e10ab2b49 Update features.rst 2021-05-30 15:30:55 +03:00
Recep Aslantas
4ede0815d4 Update features.rst 2021-05-30 15:28:38 +03:00
Recep Aslantas
7d16e3583f Merge branch 'master' of https://github.com/recp/cglm 2021-05-30 15:23:38 +03:00
Recep Aslantas
6011baff06 Update opt.rst 2021-05-30 15:23:30 +03:00
Recep Aslantas
af92df4e84 ci: migrate cglm from tavis-ci.org to travis-ci.com 2021-05-30 15:17:33 +03:00
Recep Aslantas
94381d3067 struct: fix glms_perspective_resize
since struct param is copy-by-value, result was noop
2021-05-30 13:06:49 +03:00
Recep Aslantas
0e794f8f8f struct: fix glms_persp_move_far
since struct param is copy-by-value, result was noop
2021-05-30 13:02:10 +03:00
Recep Aslantas
b895e424b0 docs: add docs about clipspace configuration 2021-05-30 12:53:04 +03:00
Recep Aslantas
a2b8858e36 win: suppress warnings 2021-05-30 12:50:30 +03:00
Recep Aslantas
9d08407897 win: suppress warnings 2021-05-30 12:46:26 +03:00
Recep Aslantas
8898c3b471 win: add missing files to build 2021-05-30 12:43:17 +03:00
Recep Aslantas
f0c2860179 Merge pull request #203 from bwhmather/meson-fixes
Update lists of source files in meson.build
2021-05-29 14:31:41 +03:00
Ben Mather
f142e8e16e build: rebuild list of test files in meson.build 2021-05-29 10:43:29 +01:00
Ben Mather
5ac916236c build: fix lists broken by missing commas in meson.build 2021-05-29 10:43:29 +01:00
Ben Mather
4327935b9f style: fix trailing whitespace in meson.build 2021-05-29 10:43:23 +01:00
Recep Aslantas
086b40bf6a Merge pull request #201 from hartenfels/master
Add struct clipspace files to autoconf build
2021-05-24 22:31:33 +03:00
Carsten Hartenfels
af3b356762 Add struct clipspace files to autoconf build
They weren't being installed.

Fixes #200.
2021-05-24 21:20:27 +02:00
Recep Aslantas
9ac291c673 Merge pull request #198 from raedwulf/clipspace
Clipspace implementations for left/righted-handed coordinate systems and [-1,1] and [0,1] clipspace
2021-05-23 18:59:01 +03:00
Tai Chi Minh Ralph Eastwood
7f7e9f69da clipspace: add struct API implementations 2021-05-22 22:41:03 +02:00
Tai Chi Minh Ralph Eastwood
8ddb5d5740 build: fix incorrect include paths for libcglm 2021-05-14 16:58:48 +02:00
Tai Chi Minh Ralph Eastwood
56ec058c7d style: fix documentation consistency for describing clipspace 2021-05-14 16:55:16 +02:00
Tai Chi Minh Ralph Eastwood
a5af9e5eac build: fix Makefile.am missing clipspace source files 2021-05-14 16:49:18 +02:00
Tai Chi Minh Ralph Eastwood
4d20f97275 clipspace: fix typo'd clip control define 2021-05-14 16:33:16 +02:00
Tai Chi Minh Ralph Eastwood
89e8c352ec style: fix missing whitespace for alignment
Co-authored-by: Michael <michael.guyver@gmail.com>
2021-05-14 15:44:10 +02:00
Tai Chi Minh Ralph Eastwood
403097d56c build: fix duplicate line in CMakeLists.txt 2021-05-14 15:27:28 +02:00
Tai Chi Minh Ralph Eastwood
eddaf464ff style: fix missing whitespace for alignment
Co-authored-by: Michael <michael.guyver@gmail.com>
2021-05-14 15:25:29 +02:00
Tai Chi Minh Ralph Eastwood
7065011bf3 clipspace: add initial implementations LH, RH and NO, ZO
Add the initial implementations of the left-handed and right-handed
coordinate systems as well as clipspace depth values of [-1, 0] and
[0, 1].
2021-05-13 23:22:58 +02:00
michaelg
db46ea110a Updated README.md to remove ref to glm_cmp stub 2021-05-13 23:18:05 +02:00
michaelg
c013bd462c Add LH & RH_NO perspective functions
This commit adds functions `glm_perspective_lh_no` and
`glm_perspective_rh_no` to the code. Unit tests are added and this
commit follows the new pattern of adding the a new file per
coordinate-system and clip-space tuple.

. Makefile.am updated
. removed test/glm_cmp project stub
. unit tests include naive implementations to as well as magic number
  ref-data generated by the corresponding GLM functions.

No tests run yet on Windows or Mac.
2021-05-13 23:18:05 +02:00
michaelg
b3a18b8a15 Add glm_perspective_rh_zo function + tests
This commit adds the RH/ZO perspective function. It does so in the new
file `cam_rh_zo.h` and further refactors the LH variant into new file
`cam_lh_zo.h`. This creates some churn in the tests and configuration
files as new test files were added as well, and all these changes found
their way into the build files.

Tests passing on Linux.
2021-05-13 23:18:05 +02:00
michaelg
1bce62c371 Add function glm_perspective_lh_zo
This commit adds the function `glm_perspective_lh_zo`, modelled on the
implementation of glm_perspective, but amended to provide a left-hand
coordinate system expected by DirectX, Metal and Vulkan (per the GLM
project's `glm/detail/setup.hpp`). It uses a clip-space of zero-to-one.

The function is tested against a longhand version of the algorithm it
seeks to implement as well as against the output of the GLM project's
`glm::perspectiveLH_ZO` function. This commit adds a new subdirectory
`test/glm_cmp` which contains a basic CMake file and `main.cpp`. An
interested user should link or copy or clone the GLM project into this
directory. The `main` function can be used to print the reference data
used so others can verify behaviour in the future, or add new literal
reference values.
2021-05-13 23:18:05 +02:00
Recep Aslantas
a242d83805 style: rename nearVal, farVal to nearZ and farZ 2021-05-08 22:42:44 +03:00
Recep Aslantas
7760c709da build, meson: add so version to meson build 2021-05-08 15:44:14 +03:00
Recep Aslantas
919e3bcf4a Merge pull request #193 from recp/simd-3
SIMD and ILP Update
2021-05-08 14:14:22 +03:00
Recep Aslantas
607182982d Merge branch 'master' into simd-3 2021-05-07 14:08:56 +03:00
Recep Aslantas
ad17f38934 Merge pull request #195 from legends2k/master
Add nlerp for quaternions
2021-05-07 12:58:05 +03:00
Sundaram Ramaswamy
8302f78484 Update documentation with nlerp 2021-05-07 14:26:31 +05:30
Sundaram Ramaswamy
9665be3138 Add struct API wrapper 2021-05-07 13:49:44 +05:30
Recep Aslantas
5c22ca3abb arrm, neon: use negate instruction instead of xor in glm_inv_tr_neon() 2021-05-07 01:52:12 +03:00
Recep Aslantas
7f9585ca72 arrm, neon: impove hadd performance 2021-05-07 01:46:24 +03:00
Recep Aslantas
d0ab3aaa2e arm, neon: util macros 2021-05-07 01:46:03 +03:00
Sundaram Ramaswamy
83dbdcc4a9 Add nlerp tests 2021-05-07 01:21:28 +05:30
Sundaram Ramaswamy
8ce45b4303 Add call and struct interfaces 2021-05-07 00:35:20 +05:30
Sundaram Ramaswamy
f19ff5d064 Use scale for both cases 2021-05-06 23:47:03 +05:30
Sundaram Ramaswamy
d6b93f052e Add nlerp for quaternions
Normalized linear interpolation for quaterions are a cheaper
alternative to slerp.  This PR adds nlerp operaiton for quaternions.
2021-05-06 23:38:26 +05:30
Recep Aslantas
28705be5a3 simd, sse: reduce some computation at glm_mul_rot_sse2() 2021-05-01 23:16:03 +03:00
Recep Aslantas
e1b142bce7 add todo to quat.h 2021-05-01 23:03:41 +03:00
Recep Aslantas
0f96eaad20 sse2: optimize glm_mat3_mul_sse2() with sse2
* reduce memory access for dest[2][2]
* the speed is increased ;)
2021-05-01 22:55:19 +03:00
Recep Aslantas
d5d3178ae0 Merge pull request #192 from Winter091/fixing-typo
fix typo: vec3 -> vec4
2021-05-01 21:24:31 +03:00
winter091
13269f4af8 fix typo: vec3 -> vec4 2021-05-01 16:48:31 +03:00
Recep Aslantas
faf6186c29 sse: optimize glm_mat2_mul_sse2 with sse 2021-05-01 03:44:04 +03:00
Recep Aslantas
2be6ac949b sse: optimize glm_quat_mul with sse 2021-05-01 03:18:26 +03:00
Recep Aslantas
5b7bc522ac sse: optimize affine with sse
* re-oder instructions for ILP
2021-05-01 02:58:14 +03:00
Recep Aslantas
376cf31ee7 armi neon: optimize affine with neon 2021-05-01 02:46:14 +03:00
Recep Aslantas
d28b381dd6 armi neon: optimize mat4 mul with neon 2021-05-01 02:45:15 +03:00
Recep Aslantas
3673622cc3 simd, sse: optimize mat4 mul-v with sse
* re-oder instructions for ILP
2021-05-01 02:17:34 +03:00
Recep Aslantas
a90f706e12 simd, sse: optimize mat4 mul with sse
* re-oder instructions for ILP
2021-05-01 02:17:08 +03:00
Recep Aslantas
c065d71a2f simd, sse: optimize mat4 inv with sse
* reduce a few shufflees
* re-oder instructions for ILP
2021-04-30 21:12:17 +03:00
Recep Aslantas
1b3b91fe0b Merge pull request #191 from quadroli/master
very minor correction in readme
2021-04-30 20:35:15 +03:00
quadroli
17560a0687 very minor correction in readme 2021-04-30 18:03:50 +03:00
Recep Aslantas
ba634d6c83 simd: optimize glm_mat4_zero() with simd 2021-04-30 04:04:27 +03:00
Recep Aslantas
f35badd436 now working on v0.8.3 2021-04-30 01:00:42 +03:00
Recep Aslantas
04eaf9c535 arm, neon: neon/fma support for glm_quat_mul() 2021-04-29 01:12:00 +03:00
Recep Aslantas
bd6641bd0a build: add missing files to build files 2021-04-28 22:45:03 +03:00
Recep Aslantas
4e4bff418d arm, neon: neon/fma support for glm_mat2_mul() 2021-04-28 22:06:46 +03:00
Recep Aslantas
55ebbdbe40 arm, neon: neon/fma support for glm_inv_tr() 2021-04-28 14:46:14 +03:00
Recep Aslantas
e4c35e32fc Merge pull request #190 from ylecuyer/patch-3
Minor typo in doc
2021-04-27 23:52:40 +03:00
Yoann Lecuyer
ec467fef1f Minor typo in doc
I stumbled upon while reading the doc
2021-04-27 22:09:13 +02:00
Recep Aslantas
1e8865233b Merge pull request #189 from recp/simd-2
ARM Neon Update
2021-04-25 15:20:24 +03:00
Recep Aslantas
155eb109a8 arm, neon: neon/fma support for glm_mul_rot() 2021-04-25 03:49:35 +03:00
Recep Aslantas
2903813765 arm, neon: neon/fma support for glm_mul() 2021-04-25 03:45:00 +03:00
Recep Aslantas
0ab50f7208 arm, neon: update mat4_mul to use FMA 2021-04-25 03:41:39 +03:00
Recep Aslantas
701e015bfd avoid loading vec3 by glmm_load()
* use glmm_set1() for each for now
2021-04-25 02:36:06 +03:00
Recep Aslantas
1fb941a41b drop swizzling helpers fro now for simplicity 2021-04-25 02:35:55 +03:00
Recep Aslantas
92151c6328 arm, neon: use div instead of mul by 1 / det for mat4_inv 2021-04-24 18:02:47 +03:00
Recep Aslantas
afac887850 arm, neon: implement mat4 inv with neon 2021-04-24 17:54:01 +03:00
Recep Aslantas
a111693b6b arm, neon: implement mat4 determinant with neon 2021-04-24 15:45:36 +03:00
Recep Aslantas
ce9e5f5575 arm: update glmm swizzling func names 2021-04-24 01:38:04 +03:00
Recep Aslantas
d13842e7de arm: optimize vec4 div with NEON 2021-04-24 00:51:09 +03:00
Recep Aslantas
059e5010e6 arm: define CGLM_ARM64 for identify arm64 2021-04-24 00:44:07 +03:00
Recep Aslantas
65292a94a6 swizzling functions for NEON 2021-04-24 00:00:00 +03:00
Recep Aslantas
f303984aad use unified glmm api for vec4 2021-04-23 23:34:36 +03:00
Recep Aslantas
7d5c4da7cf optimize translate functions 2021-04-23 23:32:48 +03:00
Recep Aslantas
63988a515c glmm: new defines for splat 2021-04-23 23:32:21 +03:00
Recep Aslantas
9725b60d46 rename glmm_shuff1x() to glmm_splat()
* mark glmm_shuff1x() as DEPRECATED
2021-04-23 22:12:57 +03:00
Recep Aslantas
50c93f3d30 Merge pull request #188 from wdouglass/cmake-pkgconfig
configure and install cglm.pc with cmake
2021-04-23 17:12:04 +03:00
Recep Aslantas
f14ca0c3f2 now working on v0.8.2 2021-04-23 17:03:39 +03:00
Woodrow Douglass
0c165cba76 configure and install cglm.pc with cmake 2021-04-23 09:28:55 -04:00
Recep Aslantas
2de1133012 fix enabling FMA macro for MSVC 2021-04-19 06:04:22 +03:00
Recep Aslantas
12dc054e49 Merge pull request #186 from recp/fma
Optimizations with FMA
2021-04-19 04:32:01 +03:00
Recep Aslantas
ebba4eea8e win, msvc: enable FMA macro for MSVC 2021-04-19 04:14:14 +03:00
Recep Aslantas
aa2fa89e6c arm: fma msub and nmsub 2021-04-19 00:35:19 +03:00
Recep Aslantas
7b0eee497e arm: fix fmadd parameter order 2021-04-19 00:28:07 +03:00
Recep Aslantas
04008d9c3f arm: fix fma for glm_vec4_muladds 2021-04-19 00:21:04 +03:00
Recep Aslantas
11b1588105 glmm: missing FMA funcs for SSE and AVX 2021-04-19 00:20:47 +03:00
Recep Aslantas
7c81482248 avx: implement scale matrix using AVX 2021-04-19 00:11:43 +03:00
Recep Aslantas
f3f29bd383 vec4: optimize muladd and muladds with fma 2021-04-18 16:24:29 +03:00
Recep Aslantas
0d0d22f96c opitimize affine matrix operations with fma 2021-04-18 13:51:22 +03:00
Recep Aslantas
7df5aa2e26 opitimize mat2 operations with fma 2021-04-18 13:51:09 +03:00
Recep Aslantas
7cc4c37afb opitimize mat3 operations with fma 2021-04-18 13:51:03 +03:00
Recep Aslantas
abe29a788a opitimize mat4 operations with fma 2021-04-18 13:50:51 +03:00
Recep Aslantas
c5655bbd2e glmm: define fma functions 2021-04-18 13:49:50 +03:00
Recep Aslantas
47e0045015 glmm, x86: define hadd function 2021-04-18 13:49:36 +03:00
Recep Aslantas
8f09cc8583 Merge pull request #183 from legends2k/master
Add CMake interface library target
2021-03-26 20:36:56 +03:00
Sundaram Ramaswamy
d6a0ac320b Update docs on CMake header-only usage 2021-03-26 12:32:36 +05:30
Sundaram Ramaswamy
616d38c13a Remove redundant header listing 2021-03-26 12:23:56 +05:30
Sundaram Ramaswamy
9e12908556 Add CMake interface library target
Projects using cglm as a header-only library needn’t build files under
src/. Provide a target which allows them to skip compiling them by

add_subdirectory(external/cglm EXCLUDE_FROM_ALL)
target_link_libraries(MyExe PRIVATE cglm_headers)
2021-03-25 17:47:43 +05:30
Recep Aslantas
405cda6ee9 now working on v0.8.1 2021-03-02 23:36:33 +03:00
Recep Aslantas
1b0322e51c Merge pull request #180 from recp/aabb-sphere-fix
fix aabb-sphere test (#179)
2021-03-01 10:48:04 +03:00
Recep Aslantas
4a308dcd9e fix aabb-sphere test (#179) 2021-02-28 23:12:06 +03:00
Recep Aslantas
fec396950b Merge pull request #178 from gaurapanasenko/master
Fixed cmake config install path
2021-02-22 10:31:06 +03:00
Yehor Panasenko
981af0565e Fixed cmake config install path
Now you can use library with
```cmake
find_package(cglm REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE ${CGLM_LIBRARY})
```
2021-02-22 04:46:22 +02:00
Recep Aslantas
1d215ef5f3 Merge pull request #177 from Winter091/master
remove wrong c standard bug
2021-01-25 20:05:58 +03:00
winter091
2b7cfde64f remove wrong c standard bug 2021-01-25 15:50:18 +03:00
Recep Aslantas
c783c42101 Merge pull request #174 from timgates42/bugfix_typo_assume
docs: fix simple typo, asume -> assume
2020-12-12 09:18:09 +03:00
Tim Gates
bddcfedead docs: fix simple typo, asume -> assume
There is a small typo in include/cglm/affine.h.

Should read `assume` rather than `asume`.
2020-12-12 12:13:48 +11:00
Recep Aslantas
34e7438271 Merge pull request #172 from SanderMertens/master
Replace hex floating point literals
2020-12-04 13:00:07 +03:00
Sander Mertens
485ff6bc46 Replace hex floating point literals 2020-12-01 21:49:35 -08:00
Recep Aslantas
4ab9ab4772 docs: fix/improve build documentation 2020-11-21 18:20:04 +03:00
Recep Aslantas
a5ff477fc8 doc: fix duplicate entry warning 2020-11-21 18:13:59 +03:00
Recep Aslantas
254570d006 Merge pull request #169 from podsvirov/docs-c-id-attribute-restrict
Fix Documentions WARNING for __restrict attribute
2020-11-21 18:11:28 +03:00
Konstantin Podsvirov
681f20d540 Fix Documentions WARNING for __restrict attribute
Add `__restrict` keyword to `c_id_attributes` added in `sphinx 3.0`.

Closes #167
2020-11-21 15:34:18 +03:00
Recep Aslantas
fd87f6e2c3 Merge pull request #168 from podsvirov/fix-fix-docs-for-vec2
Fix fix docs for glm_vec2()
2020-11-21 14:32:48 +03:00
Konstantin Podsvirov
2c12c6dce5 Fix fix docs for glm_vec2()
Remove extra `\` symbol.
2020-11-21 14:05:19 +03:00
Recep Aslantas
5619527fd3 Update cglm.podspec 2020-11-19 22:42:12 +03:00
Recep Aslantas
8b1c3c3fc4 now working on v0.8.0 2020-11-19 22:21:21 +03:00
171 changed files with 14050 additions and 1381 deletions

4
.github/FUNDING.yml vendored
View File

@@ -1,7 +1,7 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
github: [recp]
patreon: recp
open_collective: cglm
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel

4
.gitignore vendored
View File

@@ -76,3 +76,7 @@ build/
conftest.dir/*
confdefs.h
*.xcuserdatad
.idea
cmake-build-debug
*.o.tmp
xcode/*

View File

@@ -1,5 +1,10 @@
cmake_minimum_required(VERSION 3.8.2)
project(cglm VERSION 0.7.9 LANGUAGES C)
project(cglm
VERSION 0.8.6
HOMEPAGE_URL https://github.com/recp/cglm
DESCRIPTION "OpenGL Mathematics (glm) for C"
LANGUAGES C
)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED YES)
@@ -18,7 +23,7 @@ else(CGLM_STATIC)
endif()
if(CGLM_USE_C99)
set(C_STANDARD 99)
set(CMAKE_C_STANDARD 99)
endif()
if(MSVC)
@@ -47,7 +52,10 @@ include(GNUInstallDirs)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
if(NOT CPack_CMake_INCLUDED)
include(CPack)
endif()
# Target Start
add_library(${PROJECT_NAME}
@@ -58,8 +66,11 @@ add_library(${PROJECT_NAME}
src/quat.c
src/cam.c
src/vec2.c
src/ivec2.c
src/vec3.c
src/ivec3.c
src/vec4.c
src/ivec4.c
src/mat2.c
src/mat3.c
src/mat4.c
@@ -73,6 +84,20 @@ add_library(${PROJECT_NAME}
src/bezier.c
src/ray.c
src/affine2d.c
src/clipspace/ortho_lh_no.c
src/clipspace/ortho_lh_zo.c
src/clipspace/ortho_rh_no.c
src/clipspace/ortho_rh_zo.c
src/clipspace/persp_lh_no.c
src/clipspace/persp_lh_zo.c
src/clipspace/persp_rh_no.c
src/clipspace/persp_rh_zo.c
src/clipspace/view_lh_no.c
src/clipspace/view_lh_zo.c
src/clipspace/view_rh_no.c
src/clipspace/view_rh_zo.c
src/clipspace/project_no.c
src/clipspace/project_zo.c
)
if(CGLM_SHARED)
@@ -85,6 +110,12 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
if(WIN32)
# Because SOVERSION has no effect to file naming on Windows
set_target_properties(${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_NAME ${PROJECT_NAME}-${PROJECT_VERSION_MAJOR})
endif()
target_include_directories(${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:include>
@@ -93,6 +124,11 @@ target_include_directories(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Target for header-only usage
add_library(${PROJECT_NAME}_headers INTERFACE)
target_include_directories(${PROJECT_NAME}_headers INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/include)
# Test Configuration
if(CGLM_USE_TEST)
include(CTest)
@@ -105,7 +141,7 @@ install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR})
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY include/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
PATTERN ".*" EXCLUDE)
@@ -117,6 +153,11 @@ export(TARGETS ${PROJECT_NAME}
)
install(EXPORT ${PROJECT_NAME}
FILE "${PROJECT_NAME}Config.cmake"
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME}/cmake)
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
configure_file(cglm.pc.in cglm.pc @ONLY)
install(FILES ${CMAKE_BINARY_DIR}/cglm.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

View File

@@ -74,3 +74,11 @@ Link to paper: http://webserver2.tecgraf.puc-rio.br/~mgattass/cg/trbRR/Fast%20Mi
14. ARM NEON: Matrix Vector Multiplication
https://stackoverflow.com/a/57793352/2676533
16. ARM NEON Div
http://github.com/microsoft/DirectXMath
17. Pick Matrix
glu project -> project.c

View File

@@ -46,16 +46,19 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/mat3.h \
include/cglm/mat2.h \
include/cglm/affine.h \
include/cglm/affine-mat.h \
include/cglm/vec2.h \
include/cglm/vec2-ext.h \
include/cglm/ivec2.h \
include/cglm/vec3.h \
include/cglm/vec3-ext.h \
include/cglm/ivec3.h \
include/cglm/vec4.h \
include/cglm/vec4-ext.h \
include/cglm/ivec4.h \
include/cglm/euler.h \
include/cglm/util.h \
include/cglm/quat.h \
include/cglm/affine-mat.h \
include/cglm/plane.h \
include/cglm/frustum.h \
include/cglm/box.h \
@@ -69,6 +72,25 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/ray.h \
include/cglm/affine2d.h
cglm_clipspacedir=$(includedir)/cglm/clipspace
cglm_clipspace_HEADERS = include/cglm/clipspace/persp.h \
include/cglm/clipspace/persp_lh_no.h \
include/cglm/clipspace/persp_lh_zo.h \
include/cglm/clipspace/persp_rh_no.h \
include/cglm/clipspace/persp_rh_zo.h \
include/cglm/clipspace/ortho_lh_no.h \
include/cglm/clipspace/ortho_lh_zo.h \
include/cglm/clipspace/ortho_rh_no.h \
include/cglm/clipspace/ortho_rh_zo.h \
include/cglm/clipspace/view_lh.h \
include/cglm/clipspace/view_rh.h \
include/cglm/clipspace/view_lh_no.h \
include/cglm/clipspace/view_lh_zo.h \
include/cglm/clipspace/view_rh_no.h \
include/cglm/clipspace/view_rh_zo.h \
include/cglm/clipspace/project_no.h \
include/cglm/clipspace/project_zo.h
cglm_calldir=$(includedir)/cglm/call
cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/mat3.h \
@@ -76,7 +98,9 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/vec2.h \
include/cglm/call/vec3.h \
include/cglm/call/vec4.h \
include/cglm/call/affine.h \
include/cglm/call/ivec2.h \
include/cglm/call/ivec3.h \
include/cglm/call/ivec4.h \
include/cglm/call/io.h \
include/cglm/call/cam.h \
include/cglm/call/quat.h \
@@ -90,8 +114,25 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/curve.h \
include/cglm/call/bezier.h \
include/cglm/call/ray.h \
include/cglm/call/affine.h \
include/cglm/call/affine2d.h
cglm_call_clipspacedir=$(includedir)/cglm/call/clipspace
cglm_call_clipspace_HEADERS = include/cglm/call/clipspace/persp_lh_no.h \
include/cglm/call/clipspace/persp_lh_zo.h \
include/cglm/call/clipspace/persp_rh_no.h \
include/cglm/call/clipspace/persp_rh_zo.h \
include/cglm/call/clipspace/ortho_lh_no.h \
include/cglm/call/clipspace/ortho_lh_zo.h \
include/cglm/call/clipspace/ortho_rh_no.h \
include/cglm/call/clipspace/ortho_rh_zo.h \
include/cglm/call/clipspace/view_lh_no.h \
include/cglm/call/clipspace/view_lh_zo.h \
include/cglm/call/clipspace/view_rh_no.h \
include/cglm/call/clipspace/view_rh_zo.h \
include/cglm/call/clipspace/project_no.h \
include/cglm/call/clipspace/project_zo.h
cglm_simddir=$(includedir)/cglm/simd
cglm_simd_HEADERS = include/cglm/simd/intrin.h \
include/cglm/simd/x86.h \
@@ -109,19 +150,25 @@ cglm_simd_avx_HEADERS = include/cglm/simd/avx/mat4.h \
include/cglm/simd/avx/affine.h
cglm_simd_neondir=$(includedir)/cglm/simd/neon
cglm_simd_neon_HEADERS = include/cglm/simd/neon/mat4.h
cglm_simd_neon_HEADERS = include/cglm/simd/neon/affine.h \
include/cglm/simd/neon/mat2.h \
include/cglm/simd/neon/mat4.h \
include/cglm/simd/neon/quat.h
cglm_structdir=$(includedir)/cglm/struct
cglm_struct_HEADERS = include/cglm/struct/mat4.h \
include/cglm/struct/mat3.h \
include/cglm/struct/mat2.h \
include/cglm/struct/affine-pre.h \
include/cglm/struct/affine-post.h \
include/cglm/struct/affine.h \
include/cglm/struct/affine2d.h \
include/cglm/struct/vec2.h \
include/cglm/struct/vec2-ext.h \
include/cglm/struct/vec3.h \
include/cglm/struct/vec3-ext.h \
include/cglm/struct/vec4.h \
include/cglm/struct/vec4-ext.h \
include/cglm/struct/affine.h \
include/cglm/struct/io.h \
include/cglm/struct/cam.h \
include/cglm/struct/quat.h \
@@ -132,8 +179,23 @@ cglm_struct_HEADERS = include/cglm/struct/mat4.h \
include/cglm/struct/project.h \
include/cglm/struct/sphere.h \
include/cglm/struct/color.h \
include/cglm/struct/curve.h \
include/cglm/struct/affine2d.h
include/cglm/struct/curve.h
cglm_struct_clipspacedir=$(includedir)/cglm/struct/clipspace
cglm_struct_clipspace_HEADERS = include/cglm/struct/clipspace/persp_lh_no.h \
include/cglm/struct/clipspace/persp_lh_zo.h \
include/cglm/struct/clipspace/persp_rh_no.h \
include/cglm/struct/clipspace/persp_rh_zo.h \
include/cglm/struct/clipspace/ortho_lh_no.h \
include/cglm/struct/clipspace/ortho_lh_zo.h \
include/cglm/struct/clipspace/ortho_rh_no.h \
include/cglm/struct/clipspace/ortho_rh_zo.h \
include/cglm/struct/clipspace/view_lh_no.h \
include/cglm/struct/clipspace/view_lh_zo.h \
include/cglm/struct/clipspace/view_rh_no.h \
include/cglm/struct/clipspace/view_rh_zo.h \
include/cglm/struct/clipspace/project_no.h \
include/cglm/struct/clipspace/project_zo.h
libcglm_la_SOURCES=\
src/euler.c \
@@ -142,8 +204,11 @@ libcglm_la_SOURCES=\
src/quat.c \
src/cam.c \
src/vec2.c \
src/ivec2.c \
src/vec3.c \
src/ivec3.c \
src/vec4.c \
src/ivec4.c \
src/mat2.c \
src/mat3.c \
src/mat4.c \
@@ -156,13 +221,31 @@ libcglm_la_SOURCES=\
src/curve.c \
src/bezier.c \
src/ray.c \
src/affine2d.c
src/affine2d.c \
src/clipspace/ortho_lh_no.c \
src/clipspace/ortho_lh_zo.c \
src/clipspace/ortho_rh_no.c \
src/clipspace/ortho_rh_zo.c \
src/clipspace/persp_lh_no.c \
src/clipspace/persp_lh_zo.c \
src/clipspace/persp_rh_no.c \
src/clipspace/persp_rh_zo.c \
src/clipspace/view_lh_no.c \
src/clipspace/view_lh_zo.c \
src/clipspace/view_rh_no.c \
src/clipspace/view_rh_zo.c \
src/clipspace/project_no.c \
src/clipspace/project_zo.c
test_tests_SOURCES=\
test/runner.c \
test/src/test_common.c \
test/src/tests.c \
test/src/test_cam.c \
test/src/test_cam_lh_zo.c \
test/src/test_cam_rh_zo.c \
test/src/test_cam_lh_no.c \
test/src/test_cam_rh_no.c \
test/src/test_clamp.c \
test/src/test_euler.c \
test/src/test_bezier.c \

108
README.md
View File

@@ -1,19 +1,59 @@
# 🎥 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://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)
[![codecov](https://codecov.io/gh/recp/cglm/branch/master/graph/badge.svg)](https://codecov.io/gh/recp/cglm)
[![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)
[![Backers on Open Collective](https://opencollective.com/cglm/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/cglm/sponsors/badge.svg)](#sponsors)
#### Documentation
<p align="center">
<img alt="" src="cglm.png" width="550" />
</p>
<br>
<p align="center">
<a href="https://travis-ci.com/recp/cglm">
<img src="https://travis-ci.com/recp/cglm.svg?branch=master"
alt="Build Status">
</a>
<a href="https://ci.appveyor.com/project/recp/cglm/branch/master">
<img src="https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true"
alt="Windows Build Status">
</a>
<a href="http://cglm.readthedocs.io/en/latest/?badge=latest">
<img src="https://readthedocs.org/projects/cglm/badge/?version=latest"
alt="Documentation Status">
</a>
<a href="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">
<img src="https://api.codacy.com/project/badge/Grade/6a62b37d5f214f178ebef269dc4a6bf1"
alt="Codacy Badge"/>
</a>
<a href="https://coveralls.io/github/recp/cglm?branch=master">
<img src="https://coveralls.io/repos/github/recp/cglm/badge.svg?branch=master"
alt="Coverage Status"/>
</a>
<a href="https://codecov.io/gh/recp/cglm">
<img src="https://codecov.io/gh/recp/cglm/branch/master/graph/badge.svg"
alt="Coverage Status"/>
</a>
<br /><br />
<a href="#sponsors">
<img src="https://opencollective.com/cglm/sponsors/badge.svg"
alt="Sponsors on Open Collective"/>
</a>
<a href="#backers">
<img src="https://opencollective.com/cglm/backers/badge.svg"
alt="Backers on Open Collective"/>
</a>
</p>
<br>
<p align="center">
Highly optimized 2D|3D math library, also known as <b>OpenGL Mathematics (glm) for `C`</b>. <b>cglm</b> provides lot of utils to help math operations to be fast and quick to write. It is community friendly, feel free to bring any issues, bugs you faced.
</p>
---
#### 📚 Documentation
Almost all functions (inline versions) and parameters are documented inside the corresponding headers. <br />
Complete documentation: http://cglm.readthedocs.io
#### Note for previous versions:
#### 📌 Note for previous versions:
- _dup (duplicate) is changed to _copy. For instance `glm_vec_dup -> glm_vec3_copy`
- OpenGL related functions are dropped to make this lib platform/third-party independent
@@ -26,31 +66,29 @@ you have the latest version
- **[major change]** by starting v0.5.0, vec3 functions use **glm_vec3_** namespace, it was **glm_vec_** until v0.5.0
- **[major change]** by starting v0.5.1, built-in alignment is removed from **vec3** and **mat3** types
- **[major change]** by starting v0.7.3, inline print functions are disabled in release/production mode to eliminate print costs (see options in documentation). Print output also improved. You can disable colors if you need (see documentation)
- **[major change]** by starting v0.8.3, **cglm** supports alternative clipspace configuations e.g. Left Handed, Zero-to-One (_zo)... `CGLM_FORCE_DEPTH_ZERO_TO_ONE` and `CGLM_FORCE_LEFT_HANDED` is provided to control clipspace. You should be able to use **cglm** with Vulkan, DirectX and Metal now... see https://cglm.readthedocs.io/en/latest/opt.html#clipspace-option-s
#### Note for C++ developers:
#### 📌 Note for C++ developers:
If you are not aware of the original GLM library yet, you may also want to look at:
https://github.com/g-truc/glm
#### Note for new comers (Important):
#### 📌 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 include 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:
#### 📌 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?
#### 📌 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... ?
#### 📌 Returning vector or matrix... ?
**cglm** supports both *ARRAY API* and *STRUCT API*, so you can return structs if you utilize struct api (`glms_`).
#### 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>
@@ -68,7 +106,9 @@ Currently *cglm* uses default clip space configuration (-1, 1) for camera functi
</tbody>
</table>
## Features
## 🚀 Features
- **scalar** and **simd** (sse, avx, neon...) optimizations
- option to use different clipspaces e.g. Left Handed, Zero-to-One... (currrently right handed negative-one is default)
- array api and struct api, you can use arrays or structs.
- general purpose matrix operations (mat4, mat3)
- chain matrix multiplication (square only)
@@ -83,7 +123,7 @@ Currently *cglm* uses default clip space configuration (-1, 1) for camera functi
- extract euler angles
- inline or pre-compiled function call
- frustum (extract view frustum planes, corners...)
- bounding box (AABB in Frustum (culling), crop, merge...)
- bounding box (AABB in Frustum (culling), crop, merge...)
- bounding sphere
- project, unproject
- easing functions
@@ -95,9 +135,9 @@ Currently *cglm* uses default clip space configuration (-1, 1) for camera functi
<hr />
You have two option to call a function/operation: inline or library call (link)
You have two options to call a function/operation: inline or library call (link)
Almost all functions are marked inline (always_inline) so compiler will probably inline.
To call pre-compiled version, just use `glmc_` (c stands for 'call') instead of `glm_`.
To call pre-compiled versions, just use `glmc_` (c stands for 'call') instead of `glm_`.
```C
#include <cglm/cglm.h> /* for inline */
@@ -148,7 +188,7 @@ Struct functions generally take their parameters as *values* and *return* their
The types used are actually unions that allow access to the same data multiple ways. One of those ways involves anonymous structures, available since C11. MSVC also supports it for earlier C versions out of the box and GCC/Clang do if you enable `-fms-extensions`. To explicitly enable these anonymous structures, `#define CGLM_USE_ANONYMOUS_STRUCT` to `1`, to disable them, to `0`. For backward compatibility, you can also `#define CGLM_NO_ANONYMOUS_STRUCT` (value is irrelevant) to disable them. If you don't specify explicitly, cglm will do a best guess based on your compiler and the C version you're using.
## Build
## 🔨 Build
### CMake (All platforms)
```bash
@@ -168,6 +208,24 @@ option(CGLM_USE_C99 "" OFF) # C11
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
```
#### Use as header-only library with your CMake project
This requires no building or installation of cglm.
* Example:
``` cmake
cmake_minimum_required(VERSION 3.8.2)
project(<Your Project Name>)
add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${LIBRARY_NAME} PRIVATE
cglm_headers)
add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
```
#### Use with your CMake project
* Example:
```cmake
@@ -373,7 +431,7 @@ You can pass matrices the same way to other APIs e.g. Vulkan, DX...
## Notes
- This library uses float types only, does not support Integers, Double... yet
- This library does not support double type... yet
- If headers are not working properly with your compiler, IDE please open an issue, because I'm using GCC and clang to test it maybe sometimes MSVC
**TODO:**
@@ -382,7 +440,7 @@ You can pass matrices the same way to other APIs e.g. Vulkan, DX...
- [x] Add version info
- [ ] Unaligned operations (e.g. `glm_umat4_mul`)
- [x] Extra documentation
- [ ] ARM Neon Arch (In Progress)
- [x] ARM Neon Arch
## Contributors

View File

@@ -1,11 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix="${prefix}"
libdir="${exec_prefix}/lib"
includedir="${prefix}/include"
Name: @PACKAGE_NAME@
Description: OpenGL Mathematics (glm) for C
URL: https://github.com/recp/cglm
Version: @PACKAGE_VERSION@
Name: @PROJECT_NAME@
Description: @CMAKE_PROJECT_DESCRIPTION@
URL: @CMAKE_PROJECT_HOMEPAGE_URL@
Version: @PROJECT_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lcglm @LIBS@

BIN
cglm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

View File

@@ -2,10 +2,10 @@ Pod::Spec.new do |s|
# Description
s.name = "cglm"
s.version = "0.7.2"
s.summary = "📽 Optimized OpenGL/Graphics Math (glm) for C"
s.version = "0.8.4"
s.summary = "📽 Highly Optimized Graphics Math (glm) for C"
s.description = <<-DESC
cglm is math library for graphics programming for C. It is similar to original glm but it is written for C instead of C++ (you can use here too). See the documentation or README for all features.
cglm is math library for graphics programming for C. See the documentation or README for all features.
DESC
s.documentation_url = "http://cglm.readthedocs.io"
@@ -25,4 +25,13 @@ cglm is math library for graphics programming for C. It is similar to original g
# Linking
s.library = "m"
# Configuration
s.pod_target_xcconfig = {
'CLANG_ENABLE_MODULES' => 'NO',
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
'GCC_C_LANGUAGE_STANDARD' => 'gnu11',
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GLM_TESTS_NO_COLORFUL_OUTPUT'
}
end

View File

@@ -7,7 +7,7 @@
#*****************************************************************************
AC_PREREQ([2.69])
AC_INIT([cglm], [0.7.9], [info@recp.me])
AC_INIT([cglm], [0.8.6], [info@recp.me])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects serial-tests])
# Don't use the default cflags (-O2 -g), we set ours manually in Makefile.am.

View File

@@ -0,0 +1,129 @@
.. default-domain:: C
3D Affine Transforms (common)
================================================================================
Common transfrom functions.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_translate_make`
#. :c:func:`glm_scale_to`
#. :c:func:`glm_scale_make`
#. :c:func:`glm_scale`
#. :c:func:`glm_scale_uni`
#. :c:func:`glm_rotate_make`
#. :c:func:`glm_rotate_atm`
#. :c:func:`glm_decompose_scalev`
#. :c:func:`glm_uniscaled`
#. :c:func:`glm_decompose_rs`
#. :c:func:`glm_decompose`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_translate_make(mat4 m, vec3 v)
creates NEW translate transform matrix by *v* vector.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
scale existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
| *[out]* **dest** scaled matrix
.. c:function:: void glm_scale_make(mat4 m, vec3 v)
creates NEW scale matrix by v vector
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale(mat4 m, vec3 v)
scales existing transform matrix by v vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale_uni(mat4 m, float s)
applies uniform scale to existing transform matrix v = [s, s, s]
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale factor
.. c:function:: void glm_rotate_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_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
| creates NEW rotation matrix by angle and axis at given point
| this creates rotation matrix, it assumes you don't have a matrix
| this should work faster than glm_rotate_at because it reduces one glm_translate.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
decompose scale vector
Parameters:
| *[in]* **m** affine transform
| *[out]* **s** scale vector (Sx, Sy, Sz)
.. c:function:: bool glm_uniscaled(mat4 m)
returns true if matrix is uniform scaled.
This is helpful for creating normal matrix.
Parameters:
| *[in]* **m** matrix
.. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transform
| *[out]* **r** rotation matrix
| *[out]* **s** scale matrix
.. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
decompose affine transform, TODO: extract shear factors.
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transfrom
| *[out]* **t** translation vector
| *[out]* **r** rotation matrix (mat4)
| *[out]* **s** scaling vector [X, Y, Z]

129
docs/source/affine-post.rst Normal file
View File

@@ -0,0 +1,129 @@
.. default-domain:: C
3D Affine Transforms (post)
================================================================================
Post transfrom functions are similar to pre transform functions except order of application is reversed.
Post transform functions are applied after the object is transformed with given (model matrix) transfrom.
Ther are named af
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_translated_to`
#. :c:func:`glm_translated`
#. :c:func:`glm_translated_x`
#. :c:func:`glm_translated_y`
#. :c:func:`glm_translated_z`
#. :c:func:`glm_rotated_x`
#. :c:func:`glm_rotated_y`
#. :c:func:`glm_rotated_z`
#. :c:func:`glm_rotated`
#. :c:func:`glm_rotated_at`
#. :c:func:`glm_spinned`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_translated_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_translated(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_translated_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_translated_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_translated_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_rotated_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_rotated_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_rotated_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_rotated(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_rotated_at(mat4 m, vec3 pivot, float angle, vec3 axis)
rotate existing transform around given axis by angle at given pivot point (rotation center)
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_spinned(mat4 m, float angle, vec3 axis)
| rotate existing transform matrix around given axis by angle around self (doesn't affected by position)
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis

240
docs/source/affine-pre.rst Normal file
View File

@@ -0,0 +1,240 @@
.. default-domain:: C
3D Affine Transforms (pre)
================================================================================
Pre transfrom functions which are regular transfrom functions.
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_translate_to`
#. :c:func:`glm_translate`
#. :c:func:`glm_translate_x`
#. :c:func:`glm_translate_y`
#. :c:func:`glm_translate_z`
#. :c:func:`glm_translate_make`
#. :c:func:`glm_scale_to`
#. :c:func:`glm_scale_make`
#. :c:func:`glm_scale`
#. :c:func:`glm_scale_uni`
#. :c:func:`glm_rotate_x`
#. :c:func:`glm_rotate_y`
#. :c:func:`glm_rotate_z`
#. :c:func:`glm_rotate_make`
#. :c:func:`glm_rotate`
#. :c:func:`glm_rotate_at`
#. :c:func:`glm_rotate_atm`
#. :c:func:`glm_decompose_scalev`
#. :c:func:`glm_uniscaled`
#. :c:func:`glm_decompose_rs`
#. :c:func:`glm_decompose`
#. :c:func:`glm_spin`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_translate_to(mat4 m, vec3 v, mat4 dest)
translate existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
| *[out]* **dest** translated matrix
.. c:function:: void glm_translate(mat4 m, vec3 v)
translate existing transform matrix by *v* vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_translate_x(mat4 m, float x)
translate existing transform matrix by x factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** x factor
.. c:function:: void glm_translate_y(mat4 m, float y)
translate existing transform matrix by *y* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** y factor
.. c:function:: void glm_translate_z(mat4 m, float z)
translate existing transform matrix by *z* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** z factor
.. c:function:: void glm_translate_make(mat4 m, vec3 v)
creates NEW translate transform matrix by *v* vector.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
scale existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
| *[out]* **dest** scaled matrix
.. c:function:: void glm_scale_make(mat4 m, vec3 v)
creates NEW scale matrix by v vector
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale(mat4 m, vec3 v)
scales existing transform matrix by v vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale_uni(mat4 m, float s)
applies uniform scale to existing transform matrix v = [s, s, s]
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale factor
.. c:function:: void glm_rotate_x(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around X axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_y(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Y axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_z(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Z axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
creates NEW rotation matrix by angle and axis,
axis will be normalized so you don't need to normalize it
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **axis** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis)
rotate existing transform matrix around Z axis by angle and axis
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis)
rotate existing transform around given axis by angle at given pivot point (rotation center)
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
| creates NEW rotation matrix by angle and axis at given point
| this creates rotation matrix, it assumes you don't have a matrix
| this should work faster than glm_rotate_at because it reduces one glm_translate.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
decompose scale vector
Parameters:
| *[in]* **m** affine transform
| *[out]* **s** scale vector (Sx, Sy, Sz)
.. c:function:: bool glm_uniscaled(mat4 m)
returns true if matrix is uniform scaled.
This is helpful for creating normal matrix.
Parameters:
| *[in]* **m** matrix
.. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transform
| *[out]* **r** rotation matrix
| *[out]* **s** scale matrix
.. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
decompose affine transform, TODO: extract shear factors.
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transfrom
| *[out]* **t** translation vector
| *[out]* **r** rotation matrix (mat4)
| *[out]* **s** scaling vector [X, Y, Z]
.. c:function:: void glm_spin(mat4 m, float angle, vec3 axis)
| rotate existing transform matrix around given axis by angle around self (doesn't affected by position)
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis

View File

@@ -5,6 +5,18 @@
Header: cglm/affine.h
Before starting, **cglm** provides two kind of transform functions; pre and post.
Pre functions (`T' = Tnew * T`) are like `glm_translate`, `glm_rotate` which means it will translate the vector first and then apply the model transformation.
Post functions (`T' = T * Tnew`) are like `glm_translated`, `glm_rotated` which means it will apply the model transformation first and then translate the vector.
`glm_translate`, `glm_rotate` are pre functions and are similar to C++ **glm** which you are familiar with.
In new versions of **cglm** we added `glm_translated`, `glm_rotated`... which are post functions,
they are useful in some cases, e.g. append transform to existing transform (apply/append transform as last transfrom T' = T * Tnew).
Post functions are named after pre functions with `ed` suffix, e.g. `glm_translate` -> `glm_translated`. So don't mix them up.
Initialize Transform Matrices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions with **_make** prefix expect you don't have a matrix and they create
@@ -25,6 +37,9 @@ since scale factors are stored in rotation matrix, same may also true for scalli
cglm provides some functions for rotating around at given point e.g.
**glm_rotate_at**, **glm_quat_rotate_at**. Use them or follow next section for algorihm ("Rotate or Scale around specific Point (Pivot Point / Anchor Point)").
Also **cglm** provides :c:func:`glm_spin` and :c:func:`glm_spinned` functions to rotate around itself. No need to give pivot.
These functions are useful for rotating around center of object.
Rotate or Scale around specific Point (Anchor Point)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -35,6 +50,7 @@ If you want to rotate model around arbibtrary point follow these steps:
3. Move model back from origin to pivot (reverse of step-1): **translate(pivot.x, pivot.y, pivot.z)**
**glm_rotate_at**, **glm_quat_rotate_at** and their helper functions works that way.
So if you use them you don't need to do these steps manually which are done by **cglm**.
The implementation would be:
@@ -45,6 +61,13 @@ The implementation would be:
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv); /* pivotInv = -pivot */
or just:
.. code-block:: c
:linenos:
glm_rotate_at(m, pivot, angle, axis);
.. _TransformsOrder:
Transforms Order
@@ -54,7 +77,7 @@ It is important to understand this part especially if you call transform
functions multiple times
`glm_translate`, `glm_rotate`, `glm_scale` and `glm_quat_rotate` and their
helpers functions works like this (cglm may provide reverse order too as alternative in the future):
helpers functions works like this (cglm provides reverse order as `ed` suffix e.g `glm_translated`, `glm_rotated` see post transforms):
.. code-block:: c
:linenos:
@@ -147,199 +170,27 @@ Functions:
#. :c:func:`glm_decompose_rs`
#. :c:func:`glm_decompose`
Post functions (**NEW**):
1. :c:func:`glm_translated_to`
#. :c:func:`glm_translated`
#. :c:func:`glm_translated_x`
#. :c:func:`glm_translated_y`
#. :c:func:`glm_translated_z`
#. :c:func:`glm_rotated_x`
#. :c:func:`glm_rotated_y`
#. :c:func:`glm_rotated_z`
#. :c:func:`glm_rotated`
#. :c:func:`glm_rotated_at`
#. :c:func:`glm_spinned`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_translate_to(mat4 m, vec3 v, mat4 dest)
.. toctree::
:maxdepth: 1
:caption: Affine categories:
translate existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
| *[out]* **dest** translated matrix
.. c:function:: void glm_translate(mat4 m, vec3 v)
translate existing transform matrix by *v* vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_translate_x(mat4 m, float x)
translate existing transform matrix by x factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** x factor
.. c:function:: void glm_translate_y(mat4 m, float y)
translate existing transform matrix by *y* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** y factor
.. c:function:: void glm_translate_z(mat4 m, float z)
translate existing transform matrix by *z* factor
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** z factor
.. c:function:: void glm_translate_make(mat4 m, vec3 v)
creates NEW translate transform matrix by *v* vector.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** translate vector [x, y, z]
.. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
scale existing transform matrix by *v* vector and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
| *[out]* **dest** scaled matrix
.. c:function:: void glm_scale_make(mat4 m, vec3 v)
creates NEW scale matrix by v vector
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale(mat4 m, vec3 v)
scales existing transform matrix by v vector
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale vector [x, y, z]
.. c:function:: void glm_scale_uni(mat4 m, float s)
applies uniform scale to existing transform matrix v = [s, s, s]
and stores result in same matrix
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **v** scale factor
.. c:function:: void glm_rotate_x(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around X axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_y(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Y axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_z(mat4 m, float angle, mat4 dest)
rotate existing transform matrix around Z axis by angle
and store result in dest
Parameters:
| *[in]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[out]* **dest** rotated matrix
.. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
creates NEW rotation matrix by angle and axis,
axis will be normalized so you don't need to normalize it
Parameters:
| *[out]* **m** affine transfrom
| *[in]* **axis** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis)
rotate existing transform matrix around Z axis by angle and axis
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis)
rotate existing transform around given axis by angle at given pivot point (rotation center)
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
| creates NEW rotation matrix by angle and axis at given point
| this creates rotation matrix, it assumes you don't have a matrix
| this should work faster than glm_rotate_at because it reduces one glm_translate.
Parameters:
| *[in, out]* **m** affine transfrom
| *[in]* **pivot** pivot, anchor point, rotation center
| *[in]* **angle** angle (radians)
| *[in]* **axis** axis
.. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
decompose scale vector
Parameters:
| *[in]* **m** affine transform
| *[out]* **s** scale vector (Sx, Sy, Sz)
.. c:function:: bool glm_uniscaled(mat4 m)
returns true if matrix is uniform scaled.
This is helpful for creating normal matrix.
Parameters:
| *[in]* **m** matrix
.. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transform
| *[out]* **r** rotation matrix
| *[out]* **s** scale matrix
.. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
decompose affine transform, TODO: extract shear factors.
DON'T pass projected matrix here
Parameters:
| *[in]* **m** affine transfrom
| *[out]* **t** translation vector
| *[out]* **r** rotation matrix (mat4)
| *[out]* **s** scaling vector [X, Y, Z]
affine-common
affine-pre
affine-post

View File

@@ -34,15 +34,18 @@ Follow the :doc:`build` documentation for this
box
quat
euler
mat4
mat3
mat2
mat3
mat4
vec2
vec2-ext
vec3
vec3-ext
vec4
vec4-ext
vec2
vec2-ext
ivec2
ivec3
ivec4
color
plane
project

View File

@@ -32,6 +32,22 @@ If you don't want to install **cglm** to your system's folder you can get static
option(CGLM_USE_C99 "" OFF) # C11
option(CGLM_USE_TEST "Enable Tests" OFF) # for make check - make test
**Use as header-only library with your CMake project example**
This requires no building or installation of cglm.
.. code-block:: CMake
:linenos:
cmake_minimum_required(VERSION 3.8.2)
project(<Your Project Name>)
add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${LIBRARY_NAME} PRIVATE
cglm_headers)
add_subdirectory(external/cglm/ EXCLUDE_FROM_ALL)
**Use with your CMake project example**
.. code-block:: CMake
@@ -50,7 +66,7 @@ If you don't want to install **cglm** to your system's folder you can get static
Meson (All platforms):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash
.. code-block::
:linenos:
$ meson build # [Optional] --default-library=static
@@ -60,7 +76,7 @@ Meson (All platforms):
**Meson Options:**
.. code-block:: CMake
.. code-block::
:linenos:
c_std=c11
@@ -69,9 +85,9 @@ Meson (All platforms):
enable_tests=false # to run tests: ninja test
**Use with your CMake project example**
**Use with your Meson project**
.. code-block:: CMake
.. code-block::
:linenos:
# Clone cglm or create a cglm.wrap under <source_root>/subprojects

View File

@@ -140,7 +140,7 @@ Functions documentation
| set up perspective projection matrix
Parameters:
| *[in]* **fovy** field of view angle
| *[in]* **fovy** field of view angle (in radians)
| *[in]* **aspect** aspect ratio ( width / height )
| *[in]* **nearVal** near clipping plane
| *[in]* **farVal** far clipping planes

View File

@@ -25,7 +25,7 @@
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# needs_sphinx = '3.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -62,9 +62,9 @@ author = u'Recep Aslantas'
# built documents.
#
# The short X.Y version.
version = u'0.7.9'
version = u'0.8.6'
# The full version, including alpha/beta/rc tags.
release = u'0.7.9'
release = u'0.8.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -197,3 +197,7 @@ epub_exclude_files = ['search.html']
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for the C domain ------------------------------------------------
c_id_attributes = ['__restrict']

View File

@@ -1,6 +1,8 @@
Features
================================================================================
* **scalar** and **simd** (sse, avx, neon...) optimizations
* option to use different clipspaces e.g. Left Handed, Zero-to-One... (currrently right handed negative-one is default)
* array api and struct api, you can use arrays or structs.
* general purpose matrix operations (mat4, mat3)
* chain matrix multiplication (square only)

View File

@@ -6,13 +6,12 @@
cglm Documentation
================================
**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**
**cglm** is an optimized 3D math library written in C99 (compatible with C89).
It is similar to the original **glm** library, except **cglm** is mainly for
**C**.
This library stores matrices as column-major order but in the future row-major
is considered to be supported as optional.
Also currently only **float** type is supported for most operations.
**cglm** stores matrices as column-major order but in the future row-major is
considered to be supported as optional.
.. toctree::
:maxdepth: 2
@@ -46,8 +45,8 @@ Also currently only **float** type is supported for most operations.
troubleshooting
Indices and tables
==================
Indices and Tables:
===================
* :ref:`genindex`
* :ref:`modindex`

163
docs/source/ivec2.rst Normal file
View File

@@ -0,0 +1,163 @@
.. default-domain:: C
ivec2
=====
Header: cglm/ivec2.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_ivec2`
#. :c:func:`glm_ivec2_copy`
#. :c:func:`glm_ivec2_zero`
#. :c:func:`glm_ivec2_one`
#. :c:func:`glm_ivec2_add`
#. :c:func:`glm_ivec2_adds`
#. :c:func:`glm_ivec2_sub`
#. :c:func:`glm_ivec2_subs`
#. :c:func:`glm_ivec2_mul`
#. :c:func:`glm_ivec2_scale`
#. :c:func:`glm_ivec2_distance2`
#. :c:func:`glm_ivec2_distance`
#. :c:func:`glm_ivec2_maxv`
#. :c:func:`glm_ivec2_minv`
#. :c:func:`glm_ivec2_clamp`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_ivec2(int * v, ivec2 dest)
init ivec2 using vec3 or vec4
Parameters:
| *[in]* **v** vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_copy(ivec2 a, ivec2 dest)
copy all members of [a] to [dest]
Parameters:
| *[in]* **a** source vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_zero(ivec2 v)
set all members of [v] to zero
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec2_one(ivec2 v)
set all members of [v] to one
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec2_add(ivec2 a, ivec2 b, ivec2 dest)
add vector [a] to vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_adds(ivec2 v, int s, ivec2 dest)
add scalar s to vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_sub(ivec2 a, ivec2 b, ivec2 dest)
subtract vector [b] from vector [a] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_subs(ivec2 v, int s, ivec2 dest)
subtract scalar s from vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_mul(ivec2 a, ivec2 b, ivec2 dest)
multiply vector [a] with vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_scale(ivec2 v, int s, ivec2 dest)
multiply vector [a] with scalar s and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: int glm_ivec2_distance2(ivec2 a, ivec2 b)
squared distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
squared distance (distance * distance)
.. c:function:: float glm_ivec2_distance(ivec2 a, ivec2 b)
distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
distance
.. c:function:: void glm_ivec2_maxv(ivec2 a, ivec2 b, ivec2 dest)
set each member of dest to greater of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_minv(ivec2 a, ivec2 b, ivec2 dest)
set each member of dest to lesser of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec2_clamp(ivec2 v, int minVal, int maxVal)
clamp each member of [v] between minVal and maxVal (inclusive)
Parameters:
| *[in, out]* **v** vector
| *[in]* **minVal** minimum value
| *[in]* **maxVal** maximum value

163
docs/source/ivec3.rst Normal file
View File

@@ -0,0 +1,163 @@
.. default-domain:: C
ivec3
=====
Header: cglm/ivec3.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_ivec3`
#. :c:func:`glm_ivec3_copy`
#. :c:func:`glm_ivec3_zero`
#. :c:func:`glm_ivec3_one`
#. :c:func:`glm_ivec3_add`
#. :c:func:`glm_ivec3_adds`
#. :c:func:`glm_ivec3_sub`
#. :c:func:`glm_ivec3_subs`
#. :c:func:`glm_ivec3_mul`
#. :c:func:`glm_ivec3_scale`
#. :c:func:`glm_ivec3_distance2`
#. :c:func:`glm_ivec3_distance`
#. :c:func:`glm_ivec3_maxv`
#. :c:func:`glm_ivec3_minv`
#. :c:func:`glm_ivec3_clamp`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_ivec3(ivec4 v4, ivec3 dest)
init ivec3 using ivec4
Parameters:
| *[in]* **v** vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_copy(ivec3 a, ivec3 dest)
copy all members of [a] to [dest]
Parameters:
| *[in]* **a** source vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_zero(ivec3 v)
set all members of [v] to zero
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec3_one(ivec3 v)
set all members of [v] to one
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec3_add(ivec3 a, ivec3 b, ivec3 dest)
add vector [a] to vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_adds(ivec3 v, int s, ivec3 dest)
add scalar s to vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_sub(ivec3 a, ivec3 b, ivec3 dest)
subtract vector [b] from vector [a] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_subs(ivec3 v, int s, ivec3 dest)
subtract scalar s from vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_mul(ivec3 a, ivec3 b, ivec3 dest)
multiply vector [a] with vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_scale(ivec3 v, int s, ivec3 dest)
multiply vector [a] with scalar s and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: int glm_ivec3_distance2(ivec3 a, ivec3 b)
squared distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
squared distance (distance * distance)
.. c:function:: float glm_ivec3_distance(ivec3 a, ivec3 b)
distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
distance
.. c:function:: void glm_ivec3_maxv(ivec3 a, ivec3 b, ivec3 dest)
set each member of dest to greater of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_minv(ivec3 a, ivec3 b, ivec3 dest)
set each member of dest to lesser of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec3_clamp(ivec3 v, int minVal, int maxVal)
clamp each member of [v] between minVal and maxVal (inclusive)
Parameters:
| *[in, out]* **v** vector
| *[in]* **minVal** minimum value
| *[in]* **maxVal** maximum value

163
docs/source/ivec4.rst Normal file
View File

@@ -0,0 +1,163 @@
.. default-domain:: C
ivec4
=====
Header: cglm/ivec4.h
Table of contents (click to go):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions:
1. :c:func:`glm_ivec4`
#. :c:func:`glm_ivec4_copy`
#. :c:func:`glm_ivec4_zero`
#. :c:func:`glm_ivec4_one`
#. :c:func:`glm_ivec4_add`
#. :c:func:`glm_ivec4_adds`
#. :c:func:`glm_ivec4_sub`
#. :c:func:`glm_ivec4_subs`
#. :c:func:`glm_ivec4_mul`
#. :c:func:`glm_ivec4_scale`
#. :c:func:`glm_ivec4_distance2`
#. :c:func:`glm_ivec4_distance`
#. :c:func:`glm_ivec4_maxv`
#. :c:func:`glm_ivec4_minv`
#. :c:func:`glm_ivec4_clamp`
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_ivec4(ivec3 v3, int last, ivec4 dest)
init ivec4 using ivec3
Parameters:
| *[in]* **v** vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_copy(ivec4 a, ivec4 dest)
copy all members of [a] to [dest]
Parameters:
| *[in]* **a** source vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_zero(ivec4 v)
set all members of [v] to zero
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec4_one(ivec4 v)
set all members of [v] to one
Parameters:
| *[out]* **v** vector
.. c:function:: void glm_ivec4_add(ivec4 a, ivec4 b, ivec4 dest)
add vector [a] to vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_adds(ivec4 v, int s, ivec4 dest)
add scalar s to vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_sub(ivec4 a, ivec4 b, ivec4 dest)
subtract vector [b] from vector [a] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_subs(ivec4 v, int s, ivec4 dest)
subtract scalar s from vector [v] and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_mul(ivec4 a, ivec4 b, ivec4 dest)
multiply vector [a] with vector [b] and store result in [dest]
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_scale(ivec4 v, int s, ivec4 dest)
multiply vector [a] with scalar s and store result in [dest]
Parameters:
| *[in]* **v** vector
| *[in]* **s** scalar
| *[out]* **dest** destination
.. c:function:: int glm_ivec4_distance2(ivec4 a, ivec4 b)
squared distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
squared distance (distance * distance)
.. c:function:: float glm_ivec4_distance(ivec4 a, ivec4 b)
distance between two vectors
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
Returns:
distance
.. c:function:: void glm_ivec4_maxv(ivec4 a, ivec4 b, ivec4 dest)
set each member of dest to greater of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_minv(ivec4 a, ivec4 b, ivec4 dest)
set each member of dest to lesser of vector a and b
Parameters:
| *[in]* **a** first vector
| *[in]* **b** second vector
| *[out]* **dest** destination
.. c:function:: void glm_ivec4_clamp(ivec4 v, int minVal, int maxVal)
clamp each member of [v] between minVal and maxVal (inclusive)
Parameters:
| *[in, out]* **v** vector
| *[in]* **minVal** minimum value
| *[in]* **maxVal** maximum value

View File

@@ -2,7 +2,7 @@ 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
function which accepts pointer. But you may got warnings for matrix because it is
two dimensional array.
Passing / Uniforming Matrix to OpenGL:

View File

@@ -35,6 +35,45 @@ have to compile cglm with **CGLM_ALL_UNALIGNED** macro.
For instance if you set CGLM_ALL_UNALIGNED in a project then set it in other projects too
Clipspace Option[s]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By starting **v0.8.3** cglm provides options to switch between clipspace configurations.
Clipspace related files are located at `include/cglm/[struct]/clipspace.h` but
these are included in related files like `cam.h`. If you don't want to change your existing
clipspace configuration and want to use different clipspace function like `glm_lookat_zo` or `glm_lookat_lh_zo`...
then you can include individual headers or just define `CGLM_CLIPSPACE_INCLUDE_ALL` which will iclude all headers for you.
1. **CGLM_CLIPSPACE_INCLUDE_ALL**
2. **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
3. **CGLM_FORCE_LEFT_HANDED**
1. **CGLM_CLIPSPACE_INCLUDE_ALL**:
By defining this macro, **cglm** will include all clipspace functions for you by just using
`#include cglm/cglm.h` or `#include cglm/struct.h` or `#include cglm/call.h`
Otherwise you need to include header you want manually e.g. `#include cglm/clipspace/view_rh_zo.h`
2. **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
This is similar to **GLM**'s **GLM_FORCE_DEPTH_ZERO_TO_ONE** option.
This will set clip space between 0 to 1 which makes **cglm** Vulkan, Metal friendly.
You can use functions like `glm_lookat_lh_zo()` individually. By setting **CGLM_FORCE_DEPTH_ZERO_TO_ONE**
functions in cam.h for instance will use `_zo` versions.
3. **CGLM_FORCE_LEFT_HANDED**
Force **cglm** to use the left handed coordinate system by default, currently **cglm** uses right handed coordinate system as default,
you can change this behavior with this option.
**VERY VERY IMPORTANT:**
Be careful if you include **cglm** in multiple projects.
SSE and SSE2 Shuffle Option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**_mm_shuffle_ps** generates **shufps** instruction even if registers are same.

View File

@@ -21,14 +21,14 @@ Functions:
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest)
.. c:function:: void glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest)
| maps the specified viewport coordinates into specified space [1]
the matrix should contain projection matrix.
if you don't have ( and don't want to have ) an inverse matrix then use
glm_unproject version. You may use existing inverse of matrix in somewhere
else, this is why glm_unprojecti exists to save save inversion cost
:c:func:`glm_unproject` version. You may use existing inverse of matrix in somewhere
else, this is why **glm_unprojecti** exists to save inversion cost
[1] space:
- if m = invProj: View Space
@@ -57,7 +57,7 @@ Functions documentation
| maps the specified viewport coordinates into specified space [1]
the matrix should contain projection matrix.
this is same as glm_unprojecti except this function get inverse matrix for
this is same as :c:func:`glm_unprojecti` except this function get inverse matrix for
you.
[1] space:
@@ -80,7 +80,7 @@ Functions documentation
| *[in]* **vp** viewport as [x, y, width, height]
| *[out]* **dest** unprojected coordinates
.. c:function:: void glm_project(vec3 pos, mat4 m, vec4 vp, vec3 dest)
.. c:function:: void glm_project(vec3 pos, mat4 m, vec4 vp, vec3 dest)
| map object coordinates to window coordinates
@@ -91,12 +91,29 @@ Functions documentation
glm_mat4_mul(proj, view, viewProj);
glm_mat4_mul(viewProj, model, MVP);
this could be useful for gettng a bbox which fits with view frustum and
object bounding boxes. In this case you crop view frustum box with objects
box
Parameters:
| *[in]* **pos** object coordinates
| *[in]* **m** MVP matrix
| *[in]* **vp** viewport as [x, y, width, height]
| *[out]* **dest** projected coordinates
.. c:function:: float glm_project_z(vec3 pos, mat4 m)
| map object's z coordinate to window coordinates
this is same as :c:func:`glm_project` except this function projects only Z coordinate
which reduces a few calculations and parameters.
Computing MVP:
.. code-block:: c
glm_mat4_mul(proj, view, viewProj);
glm_mat4_mul(viewProj, model, MVP);
Parameters:
| *[in]* **pos** object coordinates
| *[in]* **m** MVP matrix
Returns:
projected z coordinate

View File

@@ -32,6 +32,7 @@ Functions:
#. :c:func:`glm_quat`
#. :c:func:`glm_quatv`
#. :c:func:`glm_quat_copy`
#. :c:func:`glm_quat_from_vecs`
#. :c:func:`glm_quat_norm`
#. :c:func:`glm_quat_normalize`
#. :c:func:`glm_quat_normalize_to`
@@ -52,6 +53,7 @@ Functions:
#. :c:func:`glm_quat_mat3`
#. :c:func:`glm_quat_mat3t`
#. :c:func:`glm_quat_lerp`
#. :c:func:`glm_quat_nlerp`
#. :c:func:`glm_quat_slerp`
#. :c:func:`glm_quat_look`
#. :c:func:`glm_quat_for`
@@ -122,6 +124,20 @@ Functions documentation
| *[in]* **q** source quaternion
| *[out]* **dest** destination quaternion
.. c:function:: void glm_quat_from_vecs(vec3 a, vec3 b, versor dest)
| compute unit quaternion needed to rotate a into b
References:
* `Finding quaternion representing the rotation from one vector to another <https://stackoverflow.com/a/11741520/183120>`_
* `Quaternion from two vectors <http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final>`_
* `Angle between vectors <http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/minorlogic.htm>`_
Parameters:
| *[in]* **a** unit vector
| *[in]* **b** unit vector
| *[in]* **dest** unit quaternion
.. c:function:: float glm_quat_norm(versor q)
| returns norm (magnitude) of quaternion
@@ -304,6 +320,25 @@ Functions documentation
| *[in]* **t** interpolant (amount) clamped between 0 and 1
| *[out]* **dest** result quaternion
.. c:function:: void glm_quat_nlerp(versor q, versor r, float t, versor dest)
| interpolates between two quaternions
| taking the shortest rotation path using
| normalized linear interpolation (NLERP)
| This is a cheaper alternative to slerp; most games use nlerp
| for animations as it visually makes little difference.
References:
* `Understanding Slerp, Then Not Using it <http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It>`_
* `Lerp, Slerp and Nlerp <https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/>`_
Parameters:
| *[in]* **from** from
| *[in]* **to** to
| *[in]* **t** interpolant (amount) clamped between 0 and 1
| *[out]* **dest** result quaternion
.. c:function:: void glm_quat_slerp(versor q, versor r, float t, versor dest)
| interpolates between two quaternions
@@ -374,7 +409,7 @@ Functions documentation
| *[in]* **q** quaternion
| *[in]* **pivot** pivot
.. c:function:: void glm_quat_rotate(mat4 m, versor q, mat4 dest)
.. c:function:: void glm_quat_rotate_atm(mat4 m, versor q, vec3 pivot)
| rotate NEW transform matrix using quaternion at pivot point
| this creates rotation matrix, it assumes you don't have a matrix

View File

@@ -55,7 +55,7 @@ Functions:
Functions documentation
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: void glm_vec2(float \*v, vec2 dest)
.. c:function:: void glm_vec2(float * v, vec2 dest)
init vec2 using vec3 or vec4

View File

@@ -474,6 +474,9 @@ Functions documentation
possible orthogonal/perpendicular vector
References:
* `On picking an orthogonal vector (and combing coconuts) <http://lolengine.net/blog/2013/09/21/picking-orthogonal-vector-combing-coconuts>`_
Parameters:
| *[in]* **v** vector
| *[out]* **dest** orthogonal/perpendicular vector

View File

@@ -26,6 +26,10 @@
# include "simd/avx/affine.h"
#endif
#ifdef CGLM_NEON_FP
# include "simd/neon/affine.h"
#endif
/*!
* @brief this is similar to glm_mat4_mul but specialized to affine transform
*
@@ -49,6 +53,8 @@ glm_mul(mat4 m1, mat4 m2, mat4 dest) {
glm_mul_avx(m1, m2, dest);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mul_sse2(m1, m2, dest);
#elif defined(CGLM_NEON_FP)
glm_mul_neon(m1, m2, dest);
#else
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
@@ -103,6 +109,8 @@ void
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_mul_rot_sse2(m1, m2, dest);
#elif defined(CGLM_NEON_FP)
glm_mul_rot_neon(m1, m2, dest);
#else
float a00 = m1[0][0], a01 = m1[0][1], a02 = m1[0][2], a03 = m1[0][3],
a10 = m1[1][0], a11 = m1[1][1], a12 = m1[1][2], a13 = m1[1][3],
@@ -150,6 +158,8 @@ void
glm_inv_tr(mat4 mat) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_inv_tr_sse2(mat);
#elif defined(CGLM_NEON_FP)
glm_inv_tr_neon(mat);
#else
CGLM_ALIGN_MAT mat3 r;
CGLM_ALIGN(8) vec3 t;

247
include/cglm/affine-post.h Normal file
View File

@@ -0,0 +1,247 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_affine_post_h
#define cglm_affine_post_h
/*
Functions:
CGLM_INLINE void glm_translated_to(mat4 m, vec3 v, mat4 dest);
CGLM_INLINE void glm_translated(mat4 m, vec3 v);
CGLM_INLINE void glm_translated_x(mat4 m, float to);
CGLM_INLINE void glm_translated_y(mat4 m, float to);
CGLM_INLINE void glm_translated_z(mat4 m, float to);
CGLM_INLINE void glm_rotated_x(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotated_y(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotated_z(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotated(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotated_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_spinned(mat4 m, float angle, vec3 axis);
*/
#include "common.h"
#include "util.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
#include "affine-mat.h"
/*!
* @brief translate existing transform matrix by v vector
* and stores result in same matrix
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] v translate vector [x, y, z]
*/
CGLM_INLINE
void
glm_translated(mat4 m, vec3 v) {
glm_vec3_add(m[3], v, m[3]);
}
/*!
* @brief translate existing transform matrix by v vector
* and store result in dest
*
* source matrix will remain same
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in] m affine transfrom
* @param[in] v translate vector [x, y, z]
* @param[out] dest translated matrix
*/
CGLM_INLINE
void
glm_translated_to(mat4 m, vec3 v, mat4 dest) {
glm_mat4_copy(m, dest);
glm_translated(dest, v);
}
/*!
* @brief translate existing transform matrix by x factor
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] x x factor
*/
CGLM_INLINE
void
glm_translated_x(mat4 m, float x) {
m[3][0] += x;
}
/*!
* @brief translate existing transform matrix by y factor
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] y y factor
*/
CGLM_INLINE
void
glm_translated_y(mat4 m, float y) {
m[3][1] += y;
}
/*!
* @brief translate existing transform matrix by z factor
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] z z factor
*/
CGLM_INLINE
void
glm_translated_z(mat4 m, float z) {
m[3][2] += z;
}
/*!
* @brief rotate existing transform matrix around X axis by angle
* and store result in dest
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE
void
glm_rotated_x(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[1][1] = c;
t[1][2] = s;
t[2][1] = -s;
t[2][2] = c;
glm_mul_rot(t, m, dest);
}
/*!
* @brief rotate existing transform matrix around Y axis by angle
* and store result in dest
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE
void
glm_rotated_y(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][2] = -s;
t[2][0] = s;
t[2][2] = c;
glm_mul_rot(t, m, dest);
}
/*!
* @brief rotate existing transform matrix around Z axis by angle
* and store result in dest
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in] m affine transfrom
* @param[in] angle angle (radians)
* @param[out] dest rotated matrix
*/
CGLM_INLINE
void
glm_rotated_z(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][1] = s;
t[1][0] = -s;
t[1][1] = c;
glm_mul_rot(t, m, dest);
}
/*!
* @brief rotate existing transform matrix around given axis by angle
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotated(mat4 m, float angle, vec3 axis) {
CGLM_ALIGN_MAT mat4 rot;
glm_rotate_make(rot, angle, axis);
glm_mul_rot(rot, m, m);
}
/*!
* @brief rotate existing transform
* around given axis by angle at given pivot point (rotation center)
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotated_at(mat4 m, vec3 pivot, float angle, vec3 axis) {
CGLM_ALIGN(8) vec3 pivotInv;
glm_vec3_negate_to(pivot, pivotInv);
glm_translated(m, pivot);
glm_rotated(m, angle, axis);
glm_translated(m, pivotInv);
}
/*!
* @brief rotate existing transform matrix around given axis by angle around self (doesn't affected by position)
*
* this is POST transform, applies to existing transform as last transfrom
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_spinned(mat4 m, float angle, vec3 axis) {
CGLM_ALIGN_MAT mat4 rot;
glm_rotate_atm(rot, m[3], angle, axis);
glm_mat4_mul(rot, m, m);
}
#endif /* cglm_affine_post_h */

285
include/cglm/affine-pre.h Normal file
View File

@@ -0,0 +1,285 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_affine_pre_h
#define cglm_affine_pre_h
/*
Functions:
CGLM_INLINE void glm_translate_to(mat4 m, vec3 v, mat4 dest);
CGLM_INLINE void glm_translate(mat4 m, vec3 v);
CGLM_INLINE void glm_translate_x(mat4 m, float to);
CGLM_INLINE void glm_translate_y(mat4 m, float to);
CGLM_INLINE void glm_translate_z(mat4 m, float to);
CGLM_INLINE void glm_rotate_x(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_y(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate_z(mat4 m, float angle, mat4 dest);
CGLM_INLINE void glm_rotate(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_spin(mat4 m, float angle, vec3 axis);
*/
#include "common.h"
#include "util.h"
#include "vec3.h"
#include "vec4.h"
#include "mat4.h"
#include "affine-mat.h"
/*!
* @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
void
glm_translate(mat4 m, vec3 v) {
#if defined(CGLM_SIMD)
glmm_128 m0, m1, m2, m3;
m0 = glmm_load(m[0]);
m1 = glmm_load(m[1]);
m2 = glmm_load(m[2]);
m3 = glmm_load(m[3]);
glmm_store(m[3],
glmm_fmadd(m0, glmm_set1(v[0]),
glmm_fmadd(m1, glmm_set1(v[1]),
glmm_fmadd(m2, glmm_set1(v[2]), m3))));
#else
glm_vec4_muladds(m[0], v[0], m[3]);
glm_vec4_muladds(m[1], v[1], m[3]);
glm_vec4_muladds(m[2], v[2], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by v vector
* and store result in dest
*
* source matrix will remain same
*
* @param[in] m affine transfrom
* @param[in] v translate vector [x, y, z]
* @param[out] dest translated matrix
*/
CGLM_INLINE
void
glm_translate_to(mat4 m, vec3 v, mat4 dest) {
glm_mat4_copy(m, dest);
glm_translate(dest, v);
}
/*!
* @brief translate existing transform matrix by x factor
*
* @param[in, out] m affine transfrom
* @param[in] x x factor
*/
CGLM_INLINE
void
glm_translate_x(mat4 m, float x) {
#if defined(CGLM_SIMD)
glmm_store(m[3], glmm_fmadd(glmm_load(m[0]), glmm_set1(x), glmm_load(m[3])));
#else
vec4 v1;
glm_vec4_scale(m[0], x, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by y factor
*
* @param[in, out] m affine transfrom
* @param[in] y y factor
*/
CGLM_INLINE
void
glm_translate_y(mat4 m, float y) {
#if defined(CGLM_SIMD)
glmm_store(m[3], glmm_fmadd(glmm_load(m[1]), glmm_set1(y), glmm_load(m[3])));
#else
vec4 v1;
glm_vec4_scale(m[1], y, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by z factor
*
* @param[in, out] m affine transfrom
* @param[in] z z factor
*/
CGLM_INLINE
void
glm_translate_z(mat4 m, float z) {
#if defined(CGLM_SIMD)
glmm_store(m[3], glmm_fmadd(glmm_load(m[2]), glmm_set1(z), glmm_load(m[3])));
#else
vec4 v1;
glm_vec4_scale(m[2], z, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @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) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[1][1] = c;
t[1][2] = s;
t[2][1] = -s;
t[2][2] = c;
glm_mul_rot(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
void
glm_rotate_y(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][2] = -s;
t[2][0] = s;
t[2][2] = c;
glm_mul_rot(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
void
glm_rotate_z(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][1] = s;
t[1][0] = -s;
t[1][1] = c;
glm_mul_rot(m, t, dest);
}
/*!
* @brief rotate existing transform matrix around given axis by angle
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate(mat4 m, float angle, vec3 axis) {
CGLM_ALIGN_MAT mat4 rot;
glm_rotate_make(rot, angle, axis);
glm_mul_rot(m, rot, m);
}
/*!
* @brief rotate existing transform
* around given axis by angle at given pivot point (rotation center)
*
* @param[in, out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) {
CGLM_ALIGN(8) vec3 pivotInv;
glm_vec3_negate_to(pivot, pivotInv);
glm_translate(m, pivot);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
}
/*!
* @brief creates NEW rotation matrix by angle and axis at given point
*
* this creates rotation matrix, it assumes you don't have a matrix
*
* this should work faster than glm_rotate_at because it reduces
* one glm_translate.
*
* @param[out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) {
CGLM_ALIGN(8) vec3 pivotInv;
glm_vec3_negate_to(pivot, pivotInv);
glm_translate_make(m, pivot);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
}
/*!
* @brief rotate existing transform matrix around given axis by angle around self (doesn't affected by position)
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_spin(mat4 m, float angle, vec3 axis) {
CGLM_ALIGN_MAT mat4 rot;
glm_rotate_atm(rot, m[3], angle, axis);
glm_mat4_mul(m, rot, m);
}
#endif /* cglm_affine_pre_h */

View File

@@ -24,6 +24,7 @@
CGLM_INLINE void glm_rotate(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_INLINE void glm_spin(mat4 m, float angle, vec3 axis);
CGLM_INLINE void glm_decompose_scalev(mat4 m, vec3 s);
CGLM_INLINE bool glm_uniscaled(mat4 m);
CGLM_INLINE void glm_decompose_rs(mat4 m, mat4 r, vec3 s);
@@ -40,122 +41,6 @@
#include "mat4.h"
#include "affine-mat.h"
/*!
* @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
void
glm_translate(mat4 m, vec3 v) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(m[3],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_load(m[0]),
_mm_set1_ps(v[0])),
_mm_mul_ps(glmm_load(m[1]),
_mm_set1_ps(v[1]))),
_mm_add_ps(_mm_mul_ps(glmm_load(m[2]),
_mm_set1_ps(v[2])),
glmm_load(m[3]))))
;
#else
vec4 v1, v2, v3;
glm_vec4_scale(m[0], v[0], v1);
glm_vec4_scale(m[1], v[1], v2);
glm_vec4_scale(m[2], v[2], v3);
glm_vec4_add(v1, m[3], m[3]);
glm_vec4_add(v2, m[3], m[3]);
glm_vec4_add(v3, m[3], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by v vector
* and store result in dest
*
* source matrix will remain same
*
* @param[in] m affine transfrom
* @param[in] v translate vector [x, y, z]
* @param[out] dest translated matrix
*/
CGLM_INLINE
void
glm_translate_to(mat4 m, vec3 v, mat4 dest) {
glm_mat4_copy(m, dest);
glm_translate(dest, v);
}
/*!
* @brief translate existing transform matrix by x factor
*
* @param[in, out] m affine transfrom
* @param[in] x x factor
*/
CGLM_INLINE
void
glm_translate_x(mat4 m, float x) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(m[3],
_mm_add_ps(_mm_mul_ps(glmm_load(m[0]),
_mm_set1_ps(x)),
glmm_load(m[3])))
;
#else
vec4 v1;
glm_vec4_scale(m[0], x, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by y factor
*
* @param[in, out] m affine transfrom
* @param[in] y y factor
*/
CGLM_INLINE
void
glm_translate_y(mat4 m, float y) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(m[3],
_mm_add_ps(_mm_mul_ps(glmm_load(m[1]),
_mm_set1_ps(y)),
glmm_load(m[3])))
;
#else
vec4 v1;
glm_vec4_scale(m[1], y, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @brief translate existing transform matrix by z factor
*
* @param[in, out] m affine transfrom
* @param[in] z z factor
*/
CGLM_INLINE
void
glm_translate_z(mat4 m, float z) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glmm_store(m[3],
_mm_add_ps(_mm_mul_ps(glmm_load(m[2]),
_mm_set1_ps(z)),
glmm_load(m[3])))
;
#else
vec4 v1;
glm_vec4_scale(m[2], z, v1);
glm_vec4_add(v1, m[3], m[3]);
#endif
}
/*!
* @brief creates NEW translate transform matrix by v vector
*
@@ -229,81 +114,6 @@ glm_scale_uni(mat4 m, float 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) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[1][1] = c;
t[1][2] = s;
t[2][1] = -s;
t[2][2] = c;
glm_mul_rot(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
void
glm_rotate_y(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][2] = -s;
t[2][0] = s;
t[2][2] = c;
glm_mul_rot(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
void
glm_rotate_z(mat4 m, float angle, mat4 dest) {
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_IDENTITY_INIT;
float c, s;
c = cosf(angle);
s = sinf(angle);
t[0][0] = c;
t[0][1] = s;
t[1][0] = -s;
t[1][1] = c;
glm_mul_rot(m, t, dest);
}
/*!
* @brief creates NEW rotation matrix by angle and axis
*
@@ -337,67 +147,6 @@ glm_rotate_make(mat4 m, float angle, vec3 axis) {
m[3][3] = 1.0f;
}
/*!
* @brief rotate existing transform matrix around given axis by angle
*
* @param[in, out] m affine transfrom
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate(mat4 m, float angle, vec3 axis) {
CGLM_ALIGN_MAT mat4 rot;
glm_rotate_make(rot, angle, axis);
glm_mul_rot(m, rot, m);
}
/*!
* @brief rotate existing transform
* around given axis by angle at given pivot point (rotation center)
*
* @param[in, out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) {
CGLM_ALIGN(8) vec3 pivotInv;
glm_vec3_negate_to(pivot, pivotInv);
glm_translate(m, pivot);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
}
/*!
* @brief creates NEW rotation matrix by angle and axis at given point
*
* this creates rotation matrix, it assumes you don't have a matrix
*
* this should work faster than glm_rotate_at because it reduces
* one glm_translate.
*
* @param[out] m affine transfrom
* @param[in] pivot rotation center
* @param[in] angle angle (radians)
* @param[in] axis axis
*/
CGLM_INLINE
void
glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) {
CGLM_ALIGN(8) vec3 pivotInv;
glm_vec3_negate_to(pivot, pivotInv);
glm_translate_make(m, pivot);
glm_rotate(m, angle, axis);
glm_translate(m, pivotInv);
}
/*!
* @brief decompose scale vector
*
@@ -455,7 +204,7 @@ glm_decompose_rs(mat4 m, mat4 r, vec3 s) {
glm_vec4_scale(r[1], 1.0f/s[1], r[1]);
glm_vec4_scale(r[2], 1.0f/s[2], r[2]);
/* Note from Apple Open Source (asume that the matrix is orthonormal):
/* Note from Apple Open Source (assume that the matrix is orthonormal):
check for a coordinate system flip. If the determinant
is -1, then negate the matrix and the scaling factors. */
glm_vec3_cross(m[0], m[1], v);
@@ -483,4 +232,7 @@ glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s) {
glm_decompose_rs(m, r, s);
}
#include "affine-pre.h"
#include "affine-post.h"
#endif /* cglm_affine_h */

View File

@@ -228,6 +228,8 @@ glm_aabb_aabb(vec3 box[2], vec3 other[2]) {
* https://github.com/erich666/GraphicsGems/blob/master/gems/BoxSphere.c
* Solid Box - Solid Sphere test.
*
* Sphere Representation in cglm: [center.x, center.y, center.z, radii]
*
* @param[in] box solid bounding box
* @param[in] s solid sphere
*/
@@ -237,13 +239,13 @@ glm_aabb_sphere(vec3 box[2], vec4 s) {
float dmin;
int a, b, c;
a = s[0] >= box[0][0];
b = s[1] >= box[0][1];
c = s[2] >= box[0][2];
a = (s[0] < box[0][0]) + (s[0] > box[1][0]);
b = (s[1] < box[0][1]) + (s[1] > box[1][1]);
c = (s[2] < box[0][2]) + (s[2] > box[1][2]);
dmin = glm_pow2(s[0] - box[a][0])
+ glm_pow2(s[1] - box[b][1])
+ glm_pow2(s[2] - box[c][2]);
dmin = glm_pow2((s[0] - box[!(a - 1)][0]) * (a != 0))
+ glm_pow2((s[1] - box[!(b - 1)][1]) * (b != 0))
+ glm_pow2((s[2] - box[!(c - 1)][2]) * (c != 0));
return dmin <= glm_pow2(s[3]);
}

View File

@@ -15,6 +15,9 @@ extern "C" {
#include "call/vec2.h"
#include "call/vec3.h"
#include "call/vec4.h"
#include "call/ivec2.h"
#include "call/ivec3.h"
#include "call/ivec4.h"
#include "call/mat2.h"
#include "call/mat3.h"
#include "call/mat4.h"

View File

@@ -81,6 +81,10 @@ CGLM_EXPORT
void
glmc_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_spin(mat4 m, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_decompose_scalev(mat4 m, vec3 s);
@@ -97,6 +101,52 @@ CGLM_EXPORT
void
glmc_decompose(mat4 m, vec4 t, mat4 r, vec3 s);
/* affine-post */
CGLM_EXPORT
void
glmc_translated(mat4 m, vec3 v);
CGLM_EXPORT
void
glmc_translated_to(mat4 m, vec3 v, mat4 dest);
CGLM_EXPORT
void
glmc_translated_x(mat4 m, float x);
CGLM_EXPORT
void
glmc_translated_y(mat4 m, float y);
CGLM_EXPORT
void
glmc_translated_z(mat4 m, float z);
CGLM_EXPORT
void
glmc_rotated_x(mat4 m, float angle, mat4 dest);
CGLM_EXPORT
void
glmc_rotated_y(mat4 m, float angle, mat4 dest);
CGLM_EXPORT
void
glmc_rotated_z(mat4 m, float angle, mat4 dest);
CGLM_EXPORT
void
glmc_rotated(mat4 m, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_rotated_at(mat4 m, vec3 pivot, float angle, vec3 axis);
CGLM_EXPORT
void
glmc_spinned(mat4 m, float angle, vec3 axis);
/* affine-mat */
CGLM_EXPORT

View File

@@ -15,23 +15,17 @@ extern "C" {
CGLM_EXPORT
void
glmc_frustum(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
mat4 dest);
glmc_frustum(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_ortho(float left,
float right,
float bottom,
float top,
float nearVal,
float farVal,
mat4 dest);
glmc_ortho(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
@@ -55,11 +49,7 @@ glmc_ortho_default_s(float aspect, float size, mat4 dest);
CGLM_EXPORT
void
glmc_perspective(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest);
glmc_perspective(float fovy, float aspect, float nearZ, float farZ, mat4 dest);
CGLM_EXPORT
void
@@ -88,8 +78,8 @@ glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest);
CGLM_EXPORT
void
glmc_persp_decomp(mat4 proj,
float * __restrict nearVal,
float * __restrict farVal,
float * __restrict nearZ,
float * __restrict farZ,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
@@ -114,16 +104,16 @@ glmc_persp_decomp_y(mat4 proj,
CGLM_EXPORT
void
glmc_persp_decomp_z(mat4 proj,
float * __restrict nearVal,
float * __restrict farVal);
float * __restrict nearZ,
float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_far(mat4 proj, float * __restrict farVal);
glmc_persp_decomp_far(mat4 proj, float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_near(mat4 proj, float * __restrict nearVal);
glmc_persp_decomp_near(mat4 proj, float * __restrict nearZ);
CGLM_EXPORT
float

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ortho_lh_no_h
#define cglmc_ortho_lh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_ortho_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_lh_no(vec3 box[2], mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_p_lh_no(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_pz_lh_no(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_lh_no(float aspect, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_s_lh_no(float aspect, float size, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ortho_lh_no_h */

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ortho_lh_zo_h
#define cglmc_ortho_lh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_ortho_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_lh_zo(vec3 box[2], mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_p_lh_zo(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_pz_lh_zo(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_lh_zo(float aspect, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_s_lh_zo(float aspect, float size, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ortho_lh_zo_h */

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ortho_rh_no_h
#define cglmc_ortho_rh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_ortho_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_rh_no(vec3 box[2], mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_p_rh_no(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_pz_rh_no(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_rh_no(float aspect, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_s_rh_no(float aspect, float size, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ortho_rh_no_h */

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ortho_rh_zo_h
#define cglmc_ortho_rh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_ortho_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_rh_zo(vec3 box[2], mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_p_rh_zo(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_aabb_pz_rh_zo(vec3 box[2], float padding, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_rh_zo(float aspect, mat4 dest);
CGLM_EXPORT
void
glmc_ortho_default_s_rh_zo(float aspect, float size, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ortho_rh_zo_h */

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_persp_lh_no_h
#define cglmc_persp_lh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_frustum_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_perspective_lh_no(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest);
CGLM_EXPORT
void
glmc_persp_move_far_lh_no(mat4 proj, float deltaFar);
CGLM_EXPORT
void
glmc_persp_decomp_lh_no(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decompv_lh_no(mat4 proj, float dest[6]);
CGLM_EXPORT
void
glmc_persp_decomp_x_lh_no(mat4 proj,
float * __restrict left,
float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decomp_y_lh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom);
CGLM_EXPORT
void
glmc_persp_decomp_z_lh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ);
CGLM_EXPORT
void
glmc_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest);
CGLM_EXPORT
float
glmc_persp_fovy_lh_no(mat4 proj);
CGLM_EXPORT
float
glmc_persp_aspect_lh_no(mat4 proj);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_persp_lh_no_h */

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_persp_lh_zo_h
#define cglmc_persp_lh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_frustum_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_perspective_lh_zo(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest);
CGLM_EXPORT
void
glmc_persp_move_far_lh_zo(mat4 proj, float deltaFar);
CGLM_EXPORT
void
glmc_persp_decomp_lh_zo(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decompv_lh_zo(mat4 proj, float dest[6]);
CGLM_EXPORT
void
glmc_persp_decomp_x_lh_zo(mat4 proj,
float * __restrict left,
float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decomp_y_lh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom);
CGLM_EXPORT
void
glmc_persp_decomp_z_lh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_far_lh_zo(mat4 proj, float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_near_lh_zo(mat4 proj, float * __restrict nearZ);
CGLM_EXPORT
void
glmc_persp_sizes_lh_zo(mat4 proj, float fovy, vec4 dest);
CGLM_EXPORT
float
glmc_persp_fovy_lh_zo(mat4 proj);
CGLM_EXPORT
float
glmc_persp_aspect_lh_zo(mat4 proj);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_persp_lh_zo_h */

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_persp_rh_no_h
#define cglmc_persp_rh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_frustum_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_perspective_rh_no(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest);
CGLM_EXPORT
void
glmc_persp_move_far_rh_no(mat4 proj, float deltaFar);
CGLM_EXPORT
void
glmc_persp_decomp_rh_no(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decompv_rh_no(mat4 proj, float dest[6]);
CGLM_EXPORT
void
glmc_persp_decomp_x_rh_no(mat4 proj,
float * __restrict left,
float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decomp_y_rh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom);
CGLM_EXPORT
void
glmc_persp_decomp_z_rh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_far_rh_no(mat4 proj, float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_near_rh_no(mat4 proj, float * __restrict nearZ);
CGLM_EXPORT
void
glmc_persp_sizes_rh_no(mat4 proj, float fovy, vec4 dest);
CGLM_EXPORT
float
glmc_persp_fovy_rh_no(mat4 proj);
CGLM_EXPORT
float
glmc_persp_aspect_rh_no(mat4 proj);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_persp_rh_no_h */

View File

@@ -0,0 +1,87 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_persp_rh_zo_h
#define cglmc_persp_rh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_frustum_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest);
CGLM_EXPORT
void
glmc_perspective_rh_zo(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest);
CGLM_EXPORT
void
glmc_persp_move_far_rh_zo(mat4 proj, float deltaFar);
CGLM_EXPORT
void
glmc_persp_decomp_rh_zo(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decompv_rh_zo(mat4 proj, float dest[6]);
CGLM_EXPORT
void
glmc_persp_decomp_x_rh_zo(mat4 proj,
float * __restrict left,
float * __restrict right);
CGLM_EXPORT
void
glmc_persp_decomp_y_rh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom);
CGLM_EXPORT
void
glmc_persp_decomp_z_rh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_far_rh_zo(mat4 proj, float * __restrict farZ);
CGLM_EXPORT
void
glmc_persp_decomp_near_rh_zo(mat4 proj, float * __restrict nearZ);
CGLM_EXPORT
void
glmc_persp_sizes_rh_zo(mat4 proj, float fovy, vec4 dest);
CGLM_EXPORT
float
glmc_persp_fovy_rh_zo(mat4 proj);
CGLM_EXPORT
float
glmc_persp_aspect_rh_zo(mat4 proj);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_persp_rh_zo_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_project_no_h
#define cglmc_project_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_unprojecti_no(vec3 pos, mat4 invMat, vec4 vp, vec3 dest);
CGLM_EXPORT
void
glmc_project_no(vec3 pos, mat4 m, vec4 vp, vec3 dest);
CGLM_EXPORT
float
glmc_project_z_no(vec3 pos, mat4 m);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_project_no_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_project_zo_h
#define cglmc_project_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_unprojecti_zo(vec3 pos, mat4 invMat, vec4 vp, vec3 dest);
CGLM_EXPORT
void
glmc_project_zo(vec3 pos, mat4 m, vec4 vp, vec3 dest);
CGLM_EXPORT
float
glmc_project_z_zo(vec3 pos, mat4 m);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_project_zo_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_view_lh_no_h
#define cglmc_view_lh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_lookat_lh_no(vec3 eye, vec3 center, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_lh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_anyup_lh_no(vec3 eye, vec3 dir, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_view_lh_no_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_view_lh_zo_h
#define cglmc_view_lh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_lookat_lh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_lh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_anyup_lh_zo(vec3 eye, vec3 dir, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_view_lh_zo_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_view_rh_no_h
#define cglmc_view_rh_no_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_lookat_rh_no(vec3 eye, vec3 center, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_rh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_anyup_rh_no(vec3 eye, vec3 dir, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_view_rh_no_h */

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_view_rh_zo_h
#define cglmc_view_rh_zo_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../../cglm.h"
CGLM_EXPORT
void
glmc_lookat_rh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_rh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest);
CGLM_EXPORT
void
glmc_look_anyup_rh_zo(vec3 eye, vec3 dir, mat4 dest);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_view_rh_zo_h */

79
include/cglm/call/ivec2.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ivec2_h
#define cglmc_ivec2_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_ivec2(int * __restrict v, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_copy(ivec2 a, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_zero(ivec2 v);
CGLM_EXPORT
void
glmc_ivec2_one(ivec2 v);
CGLM_EXPORT
void
glmc_ivec2_add(ivec2 a, ivec2 b, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_adds(ivec2 v, int s, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_sub(ivec2 a, ivec2 b, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_subs(ivec2 v, int s, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_mul(ivec2 a, ivec2 b, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_scale(ivec2 v, int s, ivec2 dest);
CGLM_EXPORT
int
glmc_ivec2_distance2(ivec2 a, ivec2 b);
CGLM_EXPORT
float
glmc_ivec2_distance(ivec2 a, ivec2 b);
CGLM_EXPORT
void
glmc_ivec2_maxv(ivec2 a, ivec2 b, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_minv(ivec2 a, ivec2 b, ivec2 dest);
CGLM_EXPORT
void
glmc_ivec2_clamp(ivec2 v, int minVal, int maxVal);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ivec2_h */

79
include/cglm/call/ivec3.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright (c);, Recep Aslantas.
*
* MIT License (MIT);, http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ivec3_h
#define cglmc_ivec3_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_ivec3(ivec4 v4, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_copy(ivec3 a, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_zero(ivec3 v);
CGLM_EXPORT
void
glmc_ivec3_one(ivec3 v);
CGLM_EXPORT
void
glmc_ivec3_add(ivec3 a, ivec3 b, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_adds(ivec3 v, int s, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_sub(ivec3 a, ivec3 b, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_subs(ivec3 v, int s, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_mul(ivec3 a, ivec3 b, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_scale(ivec3 v, int s, ivec3 dest);
CGLM_EXPORT
int
glmc_ivec3_distance2(ivec3 a, ivec3 b);
CGLM_EXPORT
float
glmc_ivec3_distance(ivec3 a, ivec3 b);
CGLM_EXPORT
void
glmc_ivec3_maxv(ivec3 a, ivec3 b, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_minv(ivec3 a, ivec3 b, ivec3 dest);
CGLM_EXPORT
void
glmc_ivec3_clamp(ivec3 v, int minVal, int maxVal);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ivec3_h */

79
include/cglm/call/ivec4.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglmc_ivec4_h
#define cglmc_ivec4_h
#ifdef __cplusplus
extern "C" {
#endif
#include "../cglm.h"
CGLM_EXPORT
void
glmc_ivec4(ivec3 v3, int last, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_copy(ivec4 a, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_zero(ivec4 v);
CGLM_EXPORT
void
glmc_ivec4_one(ivec4 v);
CGLM_EXPORT
void
glmc_ivec4_add(ivec4 a, ivec4 b, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_adds(ivec4 v, int s, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_sub(ivec4 a, ivec4 b, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_subs(ivec4 v, int s, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_mul(ivec4 a, ivec4 b, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_scale(ivec4 v, int s, ivec4 dest);
CGLM_EXPORT
int
glmc_ivec4_distance2(ivec4 a, ivec4 b);
CGLM_EXPORT
float
glmc_ivec4_distance(ivec4 a, ivec4 b);
CGLM_EXPORT
void
glmc_ivec4_maxv(ivec4 a, ivec4 b, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_minv(ivec4 a, ivec4 b, ivec4 dest);
CGLM_EXPORT
void
glmc_ivec4_clamp(ivec4 v, int minVal, int maxVal);
#ifdef __cplusplus
}
#endif
#endif /* cglmc_ivec4_h */

View File

@@ -25,6 +25,14 @@ CGLM_EXPORT
void
glmc_project(vec3 pos, mat4 m, vec4 vp, vec3 dest);
CGLM_EXPORT
float
glmc_project_z(vec3 pos, mat4 m);
CGLM_EXPORT
void
glmc_pickmatrix(vec2 center, vec2 size, vec4 vp, mat4 dest);
#ifdef __cplusplus
}
#endif

View File

@@ -37,6 +37,10 @@ CGLM_EXPORT
void
glmc_quat_copy(versor q, versor dest);
CGLM_EXPORT
void
glmc_quat_from_vecs(vec3 a, vec3 b, versor dest);
CGLM_EXPORT
float
glmc_quat_norm(versor q);
@@ -121,6 +125,10 @@ CGLM_EXPORT
void
glmc_quat_lerpc(versor from, versor to, float t, versor dest);
CGLM_EXPORT
void
glmc_quat_nlerp(versor q, versor r, float t, versor dest);
CGLM_EXPORT
void
glmc_quat_slerp(versor q, versor r, float t, versor dest);

View File

@@ -149,6 +149,18 @@ CGLM_EXPORT
void
glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest);
CGLM_EXPORT
void
glmc_vec2_complex_mul(vec2 a, vec2 b, vec2 dest);
CGLM_EXPORT
void
glmc_vec2_complex_div(vec2 a, vec2 b, vec2 dest);
CGLM_EXPORT
void
glmc_vec2_complex_conjugate(vec2 a, vec2 dest);
#ifdef __cplusplus
}
#endif

View File

@@ -99,7 +99,7 @@ glmc_vec4_scale(vec4 v, float s, vec4 dest);
CGLM_EXPORT
void
glmc_vec4_scale_as(vec3 v, float s, vec3 dest);
glmc_vec4_scale_as(vec4 v, float s, vec4 dest);
CGLM_EXPORT
void

View File

@@ -7,13 +7,13 @@
/*
Functions:
CGLM_INLINE void glm_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal,
CGLM_INLINE void glm_frustum(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal,
CGLM_INLINE void glm_ortho(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest)
@@ -22,8 +22,8 @@
CGLM_INLINE void glm_ortho_default_s(float aspect, float size, mat4 dest)
CGLM_INLINE void glm_perspective(float fovy,
float aspect,
float nearVal,
float farVal,
float nearZ,
float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_default(float aspect, mat4 dest)
CGLM_INLINE void glm_perspective_resize(float aspect, mat4 proj)
@@ -31,26 +31,61 @@
CGLM_INLINE void glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup(vec3 eye, vec3 dir, mat4 dest)
CGLM_INLINE void glm_persp_decomp(mat4 proj,
float *nearVal, float *farVal,
float *top, float *bottom,
float *left, float *right)
float *nearZ, float *farZ,
float *top, float *bottom,
float *left, float *right)
CGLM_INLINE void glm_persp_decompv(mat4 proj, float dest[6])
CGLM_INLINE void glm_persp_decomp_x(mat4 proj, float *left, float *right)
CGLM_INLINE void glm_persp_decomp_y(mat4 proj, float *top, float *bottom)
CGLM_INLINE void glm_persp_decomp_z(mat4 proj, float *nearv, float *farv)
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float *farVal)
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float *nearVal)
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float *farZ)
CGLM_INLINE void glm_persp_decomp_near(mat4 proj, float *nearZ)
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
#define cglm_vcam_h
#ifndef cglm_cam_h
#define cglm_cam_h
#include "common.h"
#include "plane.h"
#include "clipspace/persp.h"
#ifndef CGLM_CLIPSPACE_INCLUDE_ALL
# if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
# include "clipspace/ortho_lh_zo.h"
# include "clipspace/persp_lh_zo.h"
# include "clipspace/view_lh_zo.h"
# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
# include "clipspace/ortho_lh_no.h"
# include "clipspace/persp_lh_no.h"
# include "clipspace/view_lh_no.h"
# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
# include "clipspace/ortho_rh_zo.h"
# include "clipspace/persp_rh_zo.h"
# include "clipspace/view_rh_zo.h"
# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
# include "clipspace/ortho_rh_no.h"
# include "clipspace/persp_rh_no.h"
# include "clipspace/view_rh_no.h"
# endif
#else
# include "clipspace/ortho_lh_zo.h"
# include "clipspace/persp_lh_zo.h"
# include "clipspace/ortho_lh_no.h"
# include "clipspace/persp_lh_no.h"
# include "clipspace/ortho_rh_zo.h"
# include "clipspace/persp_rh_zo.h"
# include "clipspace/ortho_rh_no.h"
# include "clipspace/persp_rh_no.h"
# include "clipspace/view_lh_zo.h"
# include "clipspace/view_lh_no.h"
# include "clipspace/view_rh_zo.h"
# include "clipspace/view_rh_no.h"
#endif
/*!
* @brief set up perspective peprojection matrix
*
@@ -58,32 +93,25 @@
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearVal near clipping plane
* @param[in] farVal far clipping plane
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_frustum(float left, float right,
float bottom, float top,
float nearVal, float farVal,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn, nv;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farVal - nearVal);
nv = 2.0f * nearVal;
dest[0][0] = nv * rl;
dest[1][1] = nv * tb;
dest[2][0] = (right + left) * rl;
dest[2][1] = (top + bottom) * tb;
dest[2][2] = (farVal + nearVal) * fn;
dest[2][3] =-1.0f;
dest[3][2] = farVal * nv * fn;
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_frustum_lh_zo(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_frustum_lh_no(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_frustum_rh_zo(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_frustum_rh_no(left, right, bottom, top, nearZ, farZ, dest);
#endif
}
/*!
@@ -93,31 +121,25 @@ glm_frustum(float left, float right,
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearVal near clipping plane
* @param[in] farVal far clipping plane
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho(float left, float right,
float bottom, float top,
float nearVal, float farVal,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farVal - nearVal);
dest[0][0] = 2.0f * rl;
dest[1][1] = 2.0f * tb;
dest[2][2] = 2.0f * fn;
dest[3][0] =-(right + left) * rl;
dest[3][1] =-(top + bottom) * tb;
dest[3][2] = (farVal + nearVal) * fn;
dest[3][3] = 1.0f;
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_lh_zo(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_lh_no(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_rh_zo(left, right, bottom, top, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_rh_no(left, right, bottom, top, nearZ, farZ, dest);
#endif
}
/*!
@@ -131,10 +153,15 @@ glm_ortho(float left, float right,
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);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_aabb_lh_zo(box, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_aabb_lh_no(box, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_aabb_rh_zo(box, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_aabb_rh_no(box, dest);
#endif
}
/*!
@@ -149,10 +176,15 @@ glm_ortho_aabb(vec3 box[2], mat4 dest) {
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);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_aabb_p_lh_zo(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_aabb_p_lh_no(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_aabb_p_rh_zo(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_aabb_p_rh_no(box, padding, dest);
#endif
}
/*!
@@ -167,10 +199,15 @@ glm_ortho_aabb_p(vec3 box[2], float padding, mat4 dest) {
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);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_aabb_pz_lh_zo(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_aabb_pz_lh_no(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_aabb_pz_rh_zo(box, padding, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_aabb_pz_rh_no(box, padding, dest);
#endif
}
/*!
@@ -182,14 +219,15 @@ glm_ortho_aabb_pz(vec3 box[2], float padding, mat4 dest) {
CGLM_INLINE
void
glm_ortho_default(float aspect, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho(-aspect, aspect, -1.0f, 1.0f, -100.0f, 100.0f, dest);
return;
}
aspect = 1.0f / aspect;
glm_ortho(-1.0f, 1.0f, -aspect, aspect, -100.0f, 100.0f, dest);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_default_lh_zo(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_default_lh_no(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_default_rh_zo(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_default_rh_no(aspect, dest);
#endif
}
/*!
@@ -202,24 +240,15 @@ glm_ortho_default(float aspect, mat4 dest) {
CGLM_INLINE
void
glm_ortho_default_s(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho(-size * aspect,
size * aspect,
-size,
size,
-size - 100.0f,
size + 100.0f,
dest);
return;
}
glm_ortho(-size,
size,
-size / aspect,
size / aspect,
-size - 100.0f,
size + 100.0f,
dest);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_ortho_default_s_lh_zo(aspect, size, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_ortho_default_s_lh_no(aspect, size, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_ortho_default_s_rh_zo(aspect, size, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_ortho_default_s_rh_no(aspect, size, dest);
#endif
}
/*!
@@ -227,29 +256,22 @@ glm_ortho_default_s(float aspect, float size, mat4 dest) {
*
* @param[in] fovy field of view angle
* @param[in] aspect aspect ratio ( width / height )
* @param[in] nearVal near clipping plane
* @param[in] farVal far clipping planes
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping planes
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective(float fovy,
float aspect,
float nearVal,
float farVal,
mat4 dest) {
float f, fn;
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearVal - farVal);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] = (nearVal + farVal) * fn;
dest[2][3] =-1.0f;
dest[3][2] = 2.0f * nearVal * farVal * fn;
glm_perspective(float fovy, float aspect, float nearZ, float farZ, mat4 dest) {
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_perspective_lh_zo(fovy, aspect, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_perspective_lh_no(fovy, aspect, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_perspective_rh_zo(fovy, aspect, nearZ, farZ, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_perspective_rh_no(fovy, aspect, nearZ, farZ, dest);
#endif
}
/*!
@@ -263,17 +285,15 @@ glm_perspective(float fovy,
CGLM_INLINE
void
glm_persp_move_far(mat4 proj, float deltaFar) {
float fn, farVal, nearVal, p22, p32;
p22 = proj[2][2];
p32 = proj[3][2];
nearVal = p32 / (p22 - 1.0f);
farVal = p32 / (p22 + 1.0f) + deltaFar;
fn = 1.0f / (nearVal - farVal);
proj[2][2] = (nearVal + farVal) * fn;
proj[3][2] = 2.0f * nearVal * farVal * fn;
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_move_far_lh_zo(proj, deltaFar);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_move_far_lh_no(proj, deltaFar);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_move_far_rh_zo(proj, deltaFar);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_move_far_rh_no(proj, deltaFar);
#endif
}
/*!
@@ -286,7 +306,15 @@ glm_persp_move_far(mat4 proj, float deltaFar) {
CGLM_INLINE
void
glm_perspective_default(float aspect, mat4 dest) {
glm_perspective(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_perspective_default_lh_zo(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_perspective_default_lh_no(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_perspective_default_rh_zo(aspect, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_perspective_default_rh_no(aspect, dest);
#endif
}
/*!
@@ -320,28 +348,11 @@ glm_perspective_resize(float aspect, mat4 proj) {
CGLM_INLINE
void
glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 f, u, s;
glm_vec3_sub(center, eye, f);
glm_vec3_normalize(f);
glm_vec3_crossn(f, up, s);
glm_vec3_cross(s, f, u);
dest[0][0] = s[0];
dest[0][1] = u[0];
dest[0][2] =-f[0];
dest[1][0] = s[1];
dest[1][1] = u[1];
dest[1][2] =-f[1];
dest[2][0] = s[2];
dest[2][1] = u[2];
dest[2][2] =-f[2];
dest[3][0] =-glm_vec3_dot(s, eye);
dest[3][1] =-glm_vec3_dot(u, eye);
dest[3][2] = glm_vec3_dot(f, eye);
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
dest[3][3] = 1.0f;
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_LH_BIT
glm_lookat_lh(eye, center, up, dest);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_RH_BIT
glm_lookat_rh(eye, center, up, dest);
#endif
}
/*!
@@ -361,9 +372,11 @@ glm_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest) {
CGLM_INLINE
void
glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 target;
glm_vec3_add(eye, dir, target);
glm_lookat(eye, target, up, dest);
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_LH_BIT
glm_look_lh(eye, dir, up, dest);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_RH_BIT
glm_look_rh(eye, dir, up, dest);
#endif
}
/*!
@@ -379,17 +392,19 @@ glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
CGLM_INLINE
void
glm_look_anyup(vec3 eye, vec3 dir, mat4 dest) {
CGLM_ALIGN(8) vec3 up;
glm_vec3_ortho(dir, up);
glm_look(eye, dir, up, dest);
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_LH_BIT
glm_look_anyup_lh(eye, dir, dest);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_RH_BIT
glm_look_anyup_rh(eye, dir, dest);
#endif
}
/*!
* @brief decomposes frustum values of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
* @param[out] farVal far
* @param[out] nearZ near
* @param[out] farZ far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
@@ -398,31 +413,18 @@ glm_look_anyup(vec3 eye, vec3 dir, mat4 dest) {
CGLM_INLINE
void
glm_persp_decomp(mat4 proj,
float * __restrict nearVal, float * __restrict farVal,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;
m00 = proj[0][0];
m11 = proj[1][1];
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);
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_lh_zo(proj, nearZ, farZ, top, bottom, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_lh_no(proj, nearZ, farZ, top, bottom, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_rh_zo(proj, nearZ, farZ, top, bottom, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_rh_no(proj, nearZ, farZ, top, bottom, left, right);
#endif
}
/*!
@@ -435,8 +437,15 @@ glm_persp_decomp(mat4 proj,
CGLM_INLINE
void
glm_persp_decompv(mat4 proj, float dest[6]) {
glm_persp_decomp(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]);
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decompv_lh_zo(proj, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decompv_lh_no(proj, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decompv_rh_zo(proj, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decompv_rh_no(proj, dest);
#endif
}
/*!
@@ -452,14 +461,15 @@ void
glm_persp_decomp_x(mat4 proj,
float * __restrict left,
float * __restrict right) {
float nearVal, m20, m00;
m00 = proj[0][0];
m20 = proj[2][0];
nearVal = proj[3][2] / (proj[3][3] - 1.0f);
*left = nearVal * (m20 - 1.0f) / m00;
*right = nearVal * (m20 + 1.0f) / m00;
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_x_lh_zo(proj, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_x_lh_no(proj, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_x_rh_zo(proj, left, right);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_x_rh_no(proj, left, right);
#endif
}
/*!
@@ -475,14 +485,15 @@ void
glm_persp_decomp_y(mat4 proj,
float * __restrict top,
float * __restrict bottom) {
float nearVal, m21, m11;
m21 = proj[2][1];
m11 = proj[1][1];
nearVal = proj[3][2] / (proj[3][3] - 1.0f);
*bottom = nearVal * (m21 - 1) / m11;
*top = nearVal * (m21 + 1) / m11;
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_y_lh_zo(proj, top, bottom);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_y_lh_no(proj, top, bottom);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_y_rh_zo(proj, top, bottom);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_y_rh_no(proj, top, bottom);
#endif
}
/*!
@@ -490,70 +501,61 @@ glm_persp_decomp_y(mat4 proj,
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
* @param[out] farVal far
* @param[out] nearZ near
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_z(mat4 proj,
float * __restrict nearVal,
float * __restrict farVal) {
float m32, m22;
m32 = proj[3][2];
m22 = proj[2][2];
*nearVal = m32 / (m22 - 1.0f);
*farVal = m32 / (m22 + 1.0f);
glm_persp_decomp_z(mat4 proj, float * __restrict nearZ, float * __restrict farZ) {
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_z_lh_zo(proj, nearZ, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_z_lh_no(proj, nearZ, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_z_rh_zo(proj, nearZ, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_z_rh_no(proj, nearZ, farZ);
#endif
}
/*!
* @brief decomposes far value of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] farVal far
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_far(mat4 proj, float * __restrict farVal) {
*farVal = proj[3][2] / (proj[2][2] + 1.0f);
glm_persp_decomp_far(mat4 proj, float * __restrict farZ) {
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_far_lh_zo(proj, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_far_lh_no(proj, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_far_rh_zo(proj, farZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_far_rh_no(proj, farZ);
#endif
}
/*!
* @brief decomposes near value of perspective projection.
*
* @param[in] proj perspective projection matrix
* @param[out] nearVal near
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
*/
CGLM_INLINE
void
glm_persp_decomp_near(mat4 proj, float * __restrict nearVal) {
*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];
glm_persp_decomp_near(mat4 proj, float * __restrict nearZ) {
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_decomp_near_lh_zo(proj, nearZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_decomp_near_lh_no(proj, nearZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_decomp_near_rh_zo(proj, nearZ);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_decomp_near_rh_no(proj, nearZ);
#endif
}
/*!
@@ -566,17 +568,15 @@ glm_persp_aspect(mat4 proj) {
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];
#if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO
glm_persp_sizes_lh_zo(proj, fovy, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO
glm_persp_sizes_lh_no(proj, fovy, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO
glm_persp_sizes_rh_zo(proj, fovy, dest);
#elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO
glm_persp_sizes_rh_no(proj, fovy, dest);
#endif
}
#endif /* cglm_vcam_h */
#endif /* cglm_cam_h */

View File

@@ -12,6 +12,9 @@
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "ivec2.h"
#include "ivec3.h"
#include "ivec4.h"
#include "mat4.h"
#include "mat3.h"
#include "mat2.h"

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_ortho_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_lh_no(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p_lh_no(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_pz_lh_no(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_default_lh_no(float aspect,
mat4 dest)
CGLM_INLINE void glm_ortho_default_s_lh_no(float aspect,
float size,
mat4 dest)
*/
#ifndef cglm_ortho_lh_no_h
#define cglm_ortho_lh_no_h
#include "../common.h"
#include "../plane.h"
#include "../mat4.h"
/*!
* @brief set up orthographic projection matrix
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
dest[0][0] = 2.0f * rl;
dest[1][1] = 2.0f * tb;
dest[2][2] =-2.0f * fn;
dest[3][0] =-(right + left) * rl;
dest[3][1] =-(top + bottom) * tb;
dest[3][2] = (farZ + nearZ) * fn;
dest[3][3] = 1.0f;
}
/*!
* @brief set up orthographic projection matrix using bounding box
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_lh_no(vec3 box[2], mat4 dest) {
glm_ortho_lh_no(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
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* 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_lh_no(vec3 box[2], float padding, mat4 dest) {
glm_ortho_lh_no(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
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* 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_lh_no(vec3 box[2], float padding, mat4 dest) {
glm_ortho_lh_no(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
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ration ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_lh_no(float aspect, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_lh_no(-aspect, aspect, -1.0f, 1.0f, -100.0f, 100.0f, dest);
return;
}
aspect = 1.0f / aspect;
glm_ortho_lh_no(-1.0f, 1.0f, -aspect, aspect, -100.0f, 100.0f, dest);
}
/*!
* @brief set up orthographic projection matrix with given CUBE size
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in] size cube size
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_s_lh_no(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_lh_no(-size * aspect,
size * aspect,
-size,
size,
-size - 100.0f,
size + 100.0f,
dest);
return;
}
glm_ortho_lh_no(-size,
size,
-size / aspect,
size / aspect,
-size - 100.0f,
size + 100.0f,
dest);
}
#endif /*cglm_ortho_lh_no_h*/

View File

@@ -0,0 +1,177 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_ortho_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_lh_zo(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p_lh_zo(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_pz_lh_zo(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_default_lh_zo(float aspect,
mat4 dest)
CGLM_INLINE void glm_ortho_default_s_lh_zo(float aspect,
float size,
mat4 dest)
*/
#ifndef cglm_ortho_lh_zo_h
#define cglm_ortho_lh_zo_h
#include "../common.h"
#include "../plane.h"
#include "../mat4.h"
/*!
* @brief set up orthographic projection matrix with a left-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
dest[0][0] = 2.0f * rl;
dest[1][1] = 2.0f * tb;
dest[2][2] =-fn;
dest[3][0] =-(right + left) * rl;
dest[3][1] =-(top + bottom) * tb;
dest[3][2] = nearZ * fn;
dest[3][3] = 1.0f;
}
/*!
* @brief set up orthographic projection matrix using bounding box
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_lh_zo(vec3 box[2], mat4 dest) {
glm_ortho_lh_zo(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
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* 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_lh_zo(vec3 box[2], float padding, mat4 dest) {
glm_ortho_lh_zo(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
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* 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_lh_zo(vec3 box[2], float padding, mat4 dest) {
glm_ortho_lh_zo(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
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* @param[in] aspect aspect ration ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_lh_zo(float aspect, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_lh_zo(-aspect, aspect, -1.0f, 1.0f, -100.0f, 100.0f, dest);
return;
}
aspect = 1.0f / aspect;
glm_ortho_lh_zo(-1.0f, 1.0f, -aspect, aspect, -100.0f, 100.0f, dest);
}
/*!
* @brief set up orthographic projection matrix with given CUBE size
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in] size cube size
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_s_lh_zo(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_lh_zo(-size * aspect,
size * aspect,
-size,
size,
-size - 100.0f,
size + 100.0f,
dest);
return;
}
glm_ortho_lh_zo(-size,
size,
-size / aspect,
size / aspect,
-size - 100.0f,
size + 100.0f,
dest);
}
#endif /*cglm_ortho_lh_zo_h*/

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_ortho_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_rh_no(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p_rh_no(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_pz_rh_no(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_default_rh_no(float aspect,
mat4 dest)
CGLM_INLINE void glm_ortho_default_s_rh_no(float aspect,
float size,
mat4 dest)
*/
#ifndef cglm_ortho_rh_no_h
#define cglm_ortho_rh_no_h
#include "../common.h"
#include "../plane.h"
#include "../mat4.h"
/*!
* @brief set up orthographic projection matrix
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
dest[0][0] = 2.0f * rl;
dest[1][1] = 2.0f * tb;
dest[2][2] = 2.0f * fn;
dest[3][0] =-(right + left) * rl;
dest[3][1] =-(top + bottom) * tb;
dest[3][2] = (farZ + nearZ) * fn;
dest[3][3] = 1.0f;
}
/*!
* @brief set up orthographic projection matrix using bounding box
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_rh_no(vec3 box[2], mat4 dest) {
glm_ortho_rh_no(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
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* 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_rh_no(vec3 box[2], float padding, mat4 dest) {
glm_ortho_rh_no(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
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* 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_rh_no(vec3 box[2], float padding, mat4 dest) {
glm_ortho_rh_no(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
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ration ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_rh_no(float aspect, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_rh_no(-aspect, aspect, -1.0f, 1.0f, -100.0f, 100.0f, dest);
return;
}
aspect = 1.0f / aspect;
glm_ortho_rh_no(-1.0f, 1.0f, -aspect, aspect, -100.0f, 100.0f, dest);
}
/*!
* @brief set up orthographic projection matrix with given CUBE size
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in] size cube size
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_s_rh_no(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_rh_no(-size * aspect,
size * aspect,
-size,
size,
-size - 100.0f,
size + 100.0f,
dest);
return;
}
glm_ortho_rh_no(-size,
size,
-size / aspect,
size / aspect,
-size - 100.0f,
size + 100.0f,
dest);
}
#endif /*cglm_ortho_rh_no_h*/

View File

@@ -0,0 +1,181 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_ortho_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_rh_zo(vec3 box[2], mat4 dest)
CGLM_INLINE void glm_ortho_aabb_p_rh_zo(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_aabb_pz_rh_zo(vec3 box[2],
float padding,
mat4 dest)
CGLM_INLINE void glm_ortho_default_rh_zo(float aspect,
mat4 dest)
CGLM_INLINE void glm_ortho_default_s_rh_zo(float aspect,
float size,
mat4 dest)
*/
#ifndef cglm_ortho_rh_zo_h
#define cglm_ortho_rh_zo_h
#include "../common.h"
#include "../plane.h"
#include "../mat4.h"
/*!
* @brief set up orthographic projection matrix with a right-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
dest[0][0] = 2.0f * rl;
dest[1][1] = 2.0f * tb;
dest[2][2] = fn;
dest[3][0] =-(right + left) * rl;
dest[3][1] =-(top + bottom) * tb;
dest[3][2] = nearZ * fn;
dest[3][3] = 1.0f;
}
/*!
* @brief set up orthographic projection matrix using bounding box
* with a right-hand coordinate system and a clip-space with depth
* values from zero to one.
*
* bounding box (AABB) must be in view space
*
* @param[in] box AABB
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_aabb_rh_zo(vec3 box[2], mat4 dest) {
glm_ortho_rh_zo(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
* with a right-hand coordinate system and a clip-space with depth
* values from zero to one.
*
* 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_rh_zo(vec3 box[2], float padding, mat4 dest) {
glm_ortho_rh_zo(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
* with a right-hand coordinate system and a clip-space with depth
* values from zero to one.
*
* 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_rh_zo(vec3 box[2], float padding, mat4 dest) {
glm_ortho_rh_zo(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 with a right-hand
* coordinate system and a clip-space of [0, 1].
*
* @param[in] aspect aspect ration ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_rh_zo(float aspect, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_rh_zo(-aspect, aspect, -1.0f, 1.0f, -100.0f, 100.0f, dest);
return;
}
aspect = 1.0f / aspect;
glm_ortho_rh_zo(-1.0f, 1.0f, -aspect, aspect, -100.0f, 100.0f, dest);
}
/*!
* @brief set up orthographic projection matrix with given CUBE size
* with a right-hand coordinate system and a clip-space with depth
* values from zero to one.
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in] size cube size
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_ortho_default_s_rh_zo(float aspect, float size, mat4 dest) {
if (aspect >= 1.0f) {
glm_ortho_rh_zo(-size * aspect,
size * aspect,
-size,
size,
-size - 100.0f,
size + 100.0f,
dest);
return;
}
glm_ortho_rh_zo(-size,
size,
-size / aspect,
size / aspect,
-size - 100.0f,
size + 100.0f,
dest);
}
#endif /*cglm_ortho_rh_zo_h*/

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_persp_decomp_far(mat4 proj, float *farZ)
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_persp_h
#define cglm_persp_h
#include "../common.h"
#include "../plane.h"
#include "../mat4.h"
/*!
* @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];
}
#endif /* cglm_persp_h */

View File

@@ -0,0 +1,395 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_frustum_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_lh_no(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_default_lh_no(float aspect, mat4 dest)
CGLM_INLINE void glm_perspective_resize_lh_no(float aspect, mat4 proj)
CGLM_INLINE void glm_persp_move_far_lh_no(mat4 proj,
float deltaFar)
CGLM_INLINE void glm_persp_decomp_lh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decompv_lh_no(mat4 proj,
float dest[6])
CGLM_INLINE void glm_persp_decomp_x_lh_no(mat4 proj,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decomp_y_lh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom)
CGLM_INLINE void glm_persp_decomp_z_lh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ)
CGLM_INLINE void glm_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest)
*/
#ifndef cglm_persp_lh_no_h
#define cglm_persp_lh_no_h
#include "../common.h"
#include "persp.h"
/*!
* @brief set up perspective peprojection matrix
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_frustum_lh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn, nv;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
nv = 2.0f * nearZ;
dest[0][0] = nv * rl;
dest[1][1] = nv * tb;
dest[2][0] = (right + left) * rl;
dest[2][1] = (top + bottom) * tb;
dest[2][2] =-(farZ + nearZ) * fn;
dest[2][3] = 1.0f;
dest[3][2] = farZ * nv * fn;
}
/*!
* @brief set up perspective projection matrix
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] fovy field of view angle
* @param[in] aspect aspect ratio ( width / height )
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping planes
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_lh_no(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest) {
float f, fn;
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearZ - farZ);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] =-(nearZ + farZ) * fn;
dest[2][3] = 1.0f;
dest[3][2] = 2.0f * nearZ * farZ * fn;
}
/*!
* @brief set up perspective projection matrix with default near/far
* and angle values with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_default_lh_no(float aspect, mat4 dest) {
glm_perspective_lh_no(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
}
/*!
* @brief resize perspective matrix by aspect ratio ( width / height )
* this makes very easy to resize proj matrix when window /viewport
* resized with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in, out] proj perspective projection matrix
*/
CGLM_INLINE
void
glm_perspective_resize_lh_no(float aspect, mat4 proj) {
if (proj[0][0] == 0.0f)
return;
proj[0][0] = proj[1][1] / aspect;
}
/*!
* @brief extend perspective projection matrix's far distance
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* this function does not guarantee far >= near, be aware of that!
*
* @param[in, out] proj projection matrix to extend
* @param[in] deltaFar distance from existing far (negative to shink)
*/
CGLM_INLINE
void
glm_persp_move_far_lh_no(mat4 proj, float deltaFar) {
float fn, farZ, nearZ, p22, p32;
p22 = -proj[2][2];
p32 = proj[3][2];
nearZ = p32 / (p22 - 1.0f);
farZ = p32 / (p22 + 1.0f) + deltaFar;
fn = 1.0f / (nearZ - farZ);
proj[2][2] = -(farZ + nearZ) * fn;
proj[3][2] = 2.0f * nearZ * farZ * fn;
}
/*!
* @brief decomposes frustum values of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_lh_no(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;
m00 = proj[0][0];
m11 = proj[1][1];
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;
*nearZ = n;
*farZ = 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);
}
/*!
* @brief decomposes frustum values of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
* this makes easy to get all values at once
*
* @param[in] proj perspective projection matrix
* @param[out] dest array
*/
CGLM_INLINE
void
glm_persp_decompv_lh_no(mat4 proj, float dest[6]) {
glm_persp_decomp_lh_no(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]);
}
/*!
* @brief decomposes left and right values of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
* x stands for x axis (left / right axis)
*
* @param[in] proj perspective projection matrix
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_x_lh_no(mat4 proj,
float * __restrict left,
float * __restrict right) {
float nearZ, m20, m00, m22;
m00 = proj[0][0];
m20 = proj[2][0];
m22 =-proj[2][2];
nearZ = proj[3][2] / (m22 - 1.0f);
*left = nearZ * (m20 - 1.0f) / m00;
*right = nearZ * (m20 + 1.0f) / m00;
}
/*!
* @brief decomposes top and bottom values of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
* y stands for y axis (top / botom axis)
*
* @param[in] proj perspective projection matrix
* @param[out] top top
* @param[out] bottom bottom
*/
CGLM_INLINE
void
glm_persp_decomp_y_lh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom) {
float nearZ, m21, m11, m22;
m21 = proj[2][1];
m11 = proj[1][1];
m22 =-proj[2][2];
nearZ = proj[3][2] / (m22 - 1.0f);
*bottom = nearZ * (m21 - 1.0f) / m11;
*top = nearZ * (m21 + 1.0f) / m11;
}
/*!
* @brief decomposes near and far values of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_z_lh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ) {
float m32, m22;
m32 = proj[3][2];
m22 =-proj[2][2];
*nearZ = m32 / (m22 - 1.0f);
*farZ = m32 / (m22 + 1.0f);
}
/*!
* @brief decomposes far value of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ) {
*farZ = proj[3][2] / (-proj[2][2] + 1.0f);
}
/*!
* @brief decomposes near value of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
*/
CGLM_INLINE
void
glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ) {
*nearZ = proj[3][2] / (-proj[2][2] - 1.0f);
}
/*!
* @brief returns sizes of near and far planes of perspective projection
* with a left-hand coordinate system and a
* clip-space of [-1, 1].
*
* @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_lh_no(mat4 proj, float fovy, vec4 dest) {
float t, a, nearZ, farZ;
t = 2.0f * tanf(fovy * 0.5f);
a = glm_persp_aspect(proj);
glm_persp_decomp_z_lh_no(proj, &nearZ, &farZ);
dest[1] = t * nearZ;
dest[3] = t * farZ;
dest[0] = a * dest[1];
dest[2] = a * dest[3];
}
/*!
* @brief returns field of view angle along the Y-axis (in radians)
* with a left-hand coordinate system and a clip-space of [-1, 1].
*
* 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_lh_no(mat4 proj) {
return glm_persp_fovy(proj);
}
/*!
* @brief returns aspect ratio of perspective projection
* with a left-hand coordinate system and a clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_aspect_lh_no(mat4 proj) {
return glm_persp_aspect(proj);
}
#endif /*cglm_cam_lh_no_h*/

View File

@@ -0,0 +1,387 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_frustum_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_lh_zo(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_default_lh_zo(float aspect, mat4 dest)
CGLM_INLINE void glm_perspective_resize_lh_zo(float aspect, mat4 proj)
CGLM_INLINE void glm_persp_move_far_lh_zo(mat4 proj,
float deltaFar)
CGLM_INLINE void glm_persp_decomp_lh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decompv_lh_zo(mat4 proj,
float dest[6])
CGLM_INLINE void glm_persp_decomp_x_lh_zo(mat4 proj,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decomp_y_lh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom)
CGLM_INLINE void glm_persp_decomp_z_lh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_far_lh_zo(mat4 proj, float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_near_lh_zo(mat4 proj, float * __restrict nearZ)
CGLM_INLINE void glm_persp_sizes_lh_zo(mat4 proj, float fovy, vec4 dest)
*/
#ifndef cglm_persp_lh_zo_h
#define cglm_persp_lh_zo_h
#include "../common.h"
#include "persp.h"
/*!
* @brief set up perspective peprojection matrix with a left-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_frustum_lh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn, nv;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
nv = 2.0f * nearZ;
dest[0][0] = nv * rl;
dest[1][1] = nv * tb;
dest[2][0] = (right + left) * rl;
dest[2][1] = (top + bottom) * tb;
dest[2][2] =-farZ * fn;
dest[2][3] = 1.0f;
dest[3][2] = farZ * nearZ * fn;
}
/*!
* @brief set up perspective projection matrix with a left-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] fovy field of view angle
* @param[in] aspect aspect ratio ( width / height )
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping planes
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_lh_zo(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest) {
float f, fn;
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearZ - farZ);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] =-farZ * fn;
dest[2][3] = 1.0f;
dest[3][2] = nearZ * farZ * fn;
}
/*!
* @brief extend perspective projection matrix's far distance with a
* left-hand coordinate system and a clip-space with depth values
* from zero to one.
*
* this function does not guarantee far >= near, be aware of that!
*
* @param[in, out] proj projection matrix to extend
* @param[in] deltaFar distance from existing far (negative to shink)
*/
CGLM_INLINE
void
glm_persp_move_far_lh_zo(mat4 proj, float deltaFar) {
float fn, farZ, nearZ, p22, p32;
p22 = -proj[2][2];
p32 = proj[3][2];
nearZ = p32 / p22;
farZ = p32 / (p22 + 1.0f) + deltaFar;
fn = 1.0f / (nearZ - farZ);
proj[2][2] = -farZ * fn;
proj[3][2] = nearZ * farZ * fn;
}
/*!
* @brief set up perspective projection matrix with default near/far
* and angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_default_lh_zo(float aspect, mat4 dest) {
glm_perspective_lh_zo(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
}
/*!
* @brief resize perspective matrix by aspect ratio ( width / height )
* this makes very easy to resize proj matrix when window /viewport
* reized
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in, out] proj perspective projection matrix
*/
CGLM_INLINE
void
glm_perspective_resize_lh_zo(float aspect, mat4 proj) {
if (proj[0][0] == 0.0f)
return;
proj[0][0] = proj[1][1] / aspect;
}
/*!
* @brief decomposes frustum values of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_lh_zo(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;
m00 = proj[0][0];
m11 = proj[1][1];
m20 = proj[2][0];
m21 = proj[2][1];
m22 =-proj[2][2];
m32 = proj[3][2];
n = m32 / m22;
f = m32 / (m22 + 1.0f);
n_m11 = n / m11;
n_m00 = n / m00;
*nearZ = n;
*farZ = 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);
}
/*!
* @brief decomposes frustum values of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
* this makes easy to get all values at once
*
* @param[in] proj perspective projection matrix
* @param[out] dest array
*/
CGLM_INLINE
void
glm_persp_decompv_lh_zo(mat4 proj, float dest[6]) {
glm_persp_decomp_lh_zo(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]);
}
/*!
* @brief decomposes left and right values of perspective projection (ZO).
* x stands for x axis (left / right axis)
*
* @param[in] proj perspective projection matrix
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_x_lh_zo(mat4 proj,
float * __restrict left,
float * __restrict right) {
float nearZ, m20, m00;
m00 = proj[0][0];
m20 = proj[2][0];
nearZ = proj[3][2] / (proj[3][3]);
*left = nearZ * (m20 - 1.0f) / m00;
*right = nearZ * (m20 + 1.0f) / m00;
}
/*!
* @brief decomposes top and bottom values of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
* y stands for y axis (top / bottom axis)
*
* @param[in] proj perspective projection matrix
* @param[out] top top
* @param[out] bottom bottom
*/
CGLM_INLINE
void
glm_persp_decomp_y_lh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom) {
float nearZ, m21, m11;
m21 = proj[2][1];
m11 = proj[1][1];
nearZ = proj[3][2] / (proj[3][3]);
*bottom = nearZ * (m21 - 1) / m11;
*top = nearZ * (m21 + 1) / m11;
}
/*!
* @brief decomposes near and far values of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_z_lh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ) {
float m32, m22;
m32 = proj[3][2];
m22 = -proj[2][2];
*nearZ = m32 / m22;
*farZ = m32 / (m22 + 1.0f);
}
/*!
* @brief decomposes far value of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_far_lh_zo(mat4 proj, float * __restrict farZ) {
*farZ = proj[3][2] / (-proj[2][2] + 1.0f);
}
/*!
* @brief decomposes near value of perspective projection
* with angle values with a left-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
*/
CGLM_INLINE
void
glm_persp_decomp_near_lh_zo(mat4 proj, float * __restrict nearZ) {
*nearZ = proj[3][2] / -proj[2][2];
}
/*!
* @brief returns sizes of near and far planes of perspective projection
* with a left-hand coordinate system and a
* clip-space of [0, 1].
*
* @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_lh_zo(mat4 proj, float fovy, vec4 dest) {
float t, a, nearZ, farZ;
t = 2.0f * tanf(fovy * 0.5f);
a = glm_persp_aspect(proj);
glm_persp_decomp_z_lh_zo(proj, &nearZ, &farZ);
dest[1] = t * nearZ;
dest[3] = t * farZ;
dest[0] = a * dest[1];
dest[2] = a * dest[3];
}
/*!
* @brief returns field of view angle along the Y-axis (in radians)
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* 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_lh_zo(mat4 proj) {
return glm_persp_fovy(proj);
}
/*!
* @brief returns aspect ratio of perspective projection
* with a left-hand coordinate system and a clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_aspect_lh_zo(mat4 proj) {
return glm_persp_aspect(proj);
}
#endif /*cglm_persp_lh_zo_h*/

View File

@@ -0,0 +1,395 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_frustum_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_rh_no(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_default_rh_no(float aspect, mat4 dest)
CGLM_INLINE void glm_perspective_resize_rh_no(float aspect, mat4 proj)
CGLM_INLINE void glm_persp_move_far_rh_no(mat4 proj,
float deltaFar)
CGLM_INLINE void glm_persp_decomp_rh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decompv_rh_no(mat4 proj,
float dest[6])
CGLM_INLINE void glm_persp_decomp_x_rh_no(mat4 proj,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decomp_y_rh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom)
CGLM_INLINE void glm_persp_decomp_z_rh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_far_rh_no(mat4 proj, float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_near_rh_no(mat4 proj, float * __restrict nearZ)
CGLM_INLINE void glm_persp_sizes_rh_no(mat4 proj, float fovy, vec4 dest)
*/
#ifndef cglm_persp_rh_no_h
#define cglm_persp_rh_no_h
#include "../common.h"
#include "persp.h"
/*!
* @brief set up perspective peprojection matrix
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_frustum_rh_no(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn, nv;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
nv = 2.0f * nearZ;
dest[0][0] = nv * rl;
dest[1][1] = nv * tb;
dest[2][0] = (right + left) * rl;
dest[2][1] = (top + bottom) * tb;
dest[2][2] = (farZ + nearZ) * fn;
dest[2][3] =-1.0f;
dest[3][2] = farZ * nv * fn;
}
/*!
* @brief set up perspective projection matrix
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] fovy field of view angle
* @param[in] aspect aspect ratio ( width / height )
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping planes
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_rh_no(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest) {
float f, fn;
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearZ - farZ);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] = (nearZ + farZ) * fn;
dest[2][3] =-1.0f;
dest[3][2] = 2.0f * nearZ * farZ * fn;
}
/*!
* @brief set up perspective projection matrix with default near/far
* and angle values with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_default_rh_no(float aspect, mat4 dest) {
glm_perspective_rh_no(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
}
/*!
* @brief resize perspective matrix by aspect ratio ( width / height )
* this makes very easy to resize proj matrix when window /viewport
* resized with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in, out] proj perspective projection matrix
*/
CGLM_INLINE
void
glm_perspective_resize_rh_no(float aspect, mat4 proj) {
if (proj[0][0] == 0.0f)
return;
proj[0][0] = proj[1][1] / aspect;
}
/*!
* @brief extend perspective projection matrix's far distance
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* this function does not guarantee far >= near, be aware of that!
*
* @param[in, out] proj projection matrix to extend
* @param[in] deltaFar distance from existing far (negative to shink)
*/
CGLM_INLINE
void
glm_persp_move_far_rh_no(mat4 proj, float deltaFar) {
float fn, farZ, nearZ, p22, p32;
p22 = proj[2][2];
p32 = proj[3][2];
nearZ = p32 / (p22 - 1.0f);
farZ = p32 / (p22 + 1.0f) + deltaFar;
fn = 1.0f / (nearZ - farZ);
proj[2][2] = (farZ + nearZ) * fn;
proj[3][2] = 2.0f * nearZ * farZ * fn;
}
/*!
* @brief decomposes frustum values of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_rh_no(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;
m00 = proj[0][0];
m11 = proj[1][1];
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;
*nearZ = n;
*farZ = 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);
}
/*!
* @brief decomposes frustum values of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
* this makes easy to get all values at once
*
* @param[in] proj perspective projection matrix
* @param[out] dest array
*/
CGLM_INLINE
void
glm_persp_decompv_rh_no(mat4 proj, float dest[6]) {
glm_persp_decomp_rh_no(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]);
}
/*!
* @brief decomposes left and right values of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
* x stands for x axis (left / right axis)
*
* @param[in] proj perspective projection matrix
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_x_rh_no(mat4 proj,
float * __restrict left,
float * __restrict right) {
float nearZ, m20, m00, m22;
m00 = proj[0][0];
m20 = proj[2][0];
m22 = proj[2][2];
nearZ = proj[3][2] / (m22 - 1.0f);
*left = nearZ * (m20 - 1.0f) / m00;
*right = nearZ * (m20 + 1.0f) / m00;
}
/*!
* @brief decomposes top and bottom values of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
* y stands for y axis (top / botom axis)
*
* @param[in] proj perspective projection matrix
* @param[out] top top
* @param[out] bottom bottom
*/
CGLM_INLINE
void
glm_persp_decomp_y_rh_no(mat4 proj,
float * __restrict top,
float * __restrict bottom) {
float nearZ, m21, m11, m22;
m21 = proj[2][1];
m11 = proj[1][1];
m22 = proj[2][2];
nearZ = proj[3][2] / (m22 - 1.0f);
*bottom = nearZ * (m21 - 1.0f) / m11;
*top = nearZ * (m21 + 1.0f) / m11;
}
/*!
* @brief decomposes near and far values of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_z_rh_no(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ) {
float m32, m22;
m32 = proj[3][2];
m22 = proj[2][2];
*nearZ = m32 / (m22 - 1.0f);
*farZ = m32 / (m22 + 1.0f);
}
/*!
* @brief decomposes far value of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_far_rh_no(mat4 proj, float * __restrict farZ) {
*farZ = proj[3][2] / (proj[2][2] + 1.0f);
}
/*!
* @brief decomposes near value of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
*/
CGLM_INLINE
void
glm_persp_decomp_near_rh_no(mat4 proj, float * __restrict nearZ) {
*nearZ = proj[3][2] / (proj[2][2] - 1.0f);
}
/*!
* @brief returns sizes of near and far planes of perspective projection
* with a right-hand coordinate system and a
* clip-space of [-1, 1].
*
* @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_rh_no(mat4 proj, float fovy, vec4 dest) {
float t, a, nearZ, farZ;
t = 2.0f * tanf(fovy * 0.5f);
a = glm_persp_aspect(proj);
glm_persp_decomp_z_rh_no(proj, &nearZ, &farZ);
dest[1] = t * nearZ;
dest[3] = t * farZ;
dest[0] = a * dest[1];
dest[2] = a * dest[3];
}
/*!
* @brief returns field of view angle along the Y-axis (in radians)
* with a right-hand coordinate system and a clip-space of [-1, 1].
*
* 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_rh_no(mat4 proj) {
return glm_persp_fovy(proj);
}
/*!
* @brief returns aspect ratio of perspective projection
* with a right-hand coordinate system and a clip-space of [-1, 1].
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_aspect_rh_no(mat4 proj) {
return glm_persp_aspect(proj);
}
#endif /*cglm_cam_rh_no_h*/

View File

@@ -0,0 +1,389 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_frustum_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_rh_zo(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest)
CGLM_INLINE void glm_perspective_default_rh_zo(float aspect, mat4 dest)
CGLM_INLINE void glm_perspective_resize_rh_zo(float aspect, mat4 proj)
CGLM_INLINE void glm_persp_move_far_rh_zo(mat4 proj,
float deltaFar)
CGLM_INLINE void glm_persp_decomp_rh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ,
float * __restrict top,
float * __restrict bottom,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decompv_rh_zo(mat4 proj,
float dest[6])
CGLM_INLINE void glm_persp_decomp_x_rh_zo(mat4 proj,
float * __restrict left,
float * __restrict right)
CGLM_INLINE void glm_persp_decomp_y_rh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom)
CGLM_INLINE void glm_persp_decomp_z_rh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_far_rh_zo(mat4 proj, float * __restrict farZ)
CGLM_INLINE void glm_persp_decomp_near_rh_zo(mat4 proj, float * __restrict nearZ)
CGLM_INLINE void glm_persp_sizes_rh_zo(mat4 proj, float fovy, vec4 dest)
*/
#ifndef cglm_persp_rh_zo_h
#define cglm_persp_rh_zo_h
#include "../common.h"
#include "persp.h"
/*!
* @brief set up perspective peprojection matrix with a right-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] left viewport.left
* @param[in] right viewport.right
* @param[in] bottom viewport.bottom
* @param[in] top viewport.top
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping plane
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_frustum_rh_zo(float left, float right,
float bottom, float top,
float nearZ, float farZ,
mat4 dest) {
float rl, tb, fn, nv;
glm_mat4_zero(dest);
rl = 1.0f / (right - left);
tb = 1.0f / (top - bottom);
fn =-1.0f / (farZ - nearZ);
nv = 2.0f * nearZ;
dest[0][0] = nv * rl;
dest[1][1] = nv * tb;
dest[2][0] = (right + left) * rl;
dest[2][1] = (top + bottom) * tb;
dest[2][2] = farZ * fn;
dest[2][3] =-1.0f;
dest[3][2] = farZ * nearZ * fn;
}
/*!
* @brief set up perspective projection matrix with a right-hand coordinate
* system and a clip-space of [0, 1].
*
* @param[in] fovy field of view angle
* @param[in] aspect aspect ratio ( width / height )
* @param[in] nearZ near clipping plane
* @param[in] farZ far clipping planes
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_rh_zo(float fovy,
float aspect,
float nearZ,
float farZ,
mat4 dest) {
float f, fn;
glm_mat4_zero(dest);
f = 1.0f / tanf(fovy * 0.5f);
fn = 1.0f / (nearZ - farZ);
dest[0][0] = f / aspect;
dest[1][1] = f;
dest[2][2] = farZ * fn;
dest[2][3] =-1.0f;
dest[3][2] = nearZ * farZ * fn;
}
/*!
* @brief set up perspective projection matrix with default near/far
* and angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_perspective_default_rh_zo(float aspect, mat4 dest) {
glm_perspective_rh_zo(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
}
/*!
* @brief resize perspective matrix by aspect ratio ( width / height )
* this makes very easy to resize proj matrix when window /viewport
* resized with a right-hand coordinate system and a clip-space of
* [0, 1].
*
* @param[in] aspect aspect ratio ( width / height )
* @param[in, out] proj perspective projection matrix
*/
CGLM_INLINE
void
glm_perspective_resize_rh_zo(float aspect, mat4 proj) {
if (proj[0][0] == 0.0f)
return;
proj[0][0] = proj[1][1] / aspect;
}
/*!
* @brief extend perspective projection matrix's far distance with a
* right-hand coordinate system and a clip-space of [0, 1].
*
* this function does not guarantee far >= near, be aware of that!
*
* @param[in, out] proj projection matrix to extend
* @param[in] deltaFar distance from existing far (negative to shink)
*/
CGLM_INLINE
void
glm_persp_move_far_rh_zo(mat4 proj, float deltaFar) {
float fn, farZ, nearZ, p22, p32;
p22 = proj[2][2];
p32 = proj[3][2];
nearZ = p32 / p22;
farZ = p32 / (p22 + 1.0f) + deltaFar;
fn = 1.0f / (nearZ - farZ);
proj[2][2] = farZ * fn;
proj[3][2] = nearZ * farZ * fn;
}
/*!
* @brief decomposes frustum values of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
* @param[out] top top
* @param[out] bottom bottom
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_rh_zo(mat4 proj,
float * __restrict nearZ, float * __restrict farZ,
float * __restrict top, float * __restrict bottom,
float * __restrict left, float * __restrict right) {
float m00, m11, m20, m21, m22, m32, n, f;
float n_m11, n_m00;
m00 = proj[0][0];
m11 = proj[1][1];
m20 = proj[2][0];
m21 = proj[2][1];
m22 = proj[2][2];
m32 = proj[3][2];
n = m32 / m22;
f = m32 / (m22 + 1.0f);
n_m11 = n / m11;
n_m00 = n / m00;
*nearZ = n;
*farZ = 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);
}
/*!
* @brief decomposes frustum values of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
* this makes easy to get all values at once
*
* @param[in] proj perspective projection matrix
* @param[out] dest array
*/
CGLM_INLINE
void
glm_persp_decompv_rh_zo(mat4 proj, float dest[6]) {
glm_persp_decomp_rh_zo(proj, &dest[0], &dest[1], &dest[2],
&dest[3], &dest[4], &dest[5]);
}
/*!
* @brief decomposes left and right values of perspective projection (ZO).
* x stands for x axis (left / right axis)
*
* @param[in] proj perspective projection matrix
* @param[out] left left
* @param[out] right right
*/
CGLM_INLINE
void
glm_persp_decomp_x_rh_zo(mat4 proj,
float * __restrict left,
float * __restrict right) {
float nearZ, m20, m00, m22;
m00 = proj[0][0];
m20 = proj[2][0];
m22 = proj[2][2];
nearZ = proj[3][2] / m22;
*left = nearZ * (m20 - 1.0f) / m00;
*right = nearZ * (m20 + 1.0f) / m00;
}
/*!
* @brief decomposes top and bottom values of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
* y stands for y axis (top / bottom axis)
*
* @param[in] proj perspective projection matrix
* @param[out] top top
* @param[out] bottom bottom
*/
CGLM_INLINE
void
glm_persp_decomp_y_rh_zo(mat4 proj,
float * __restrict top,
float * __restrict bottom) {
float nearZ, m21, m11, m22;
m21 = proj[2][1];
m11 = proj[1][1];
m22 = proj[2][2];
nearZ = proj[3][2] / m22;
*bottom = nearZ * (m21 - 1) / m11;
*top = nearZ * (m21 + 1) / m11;
}
/*!
* @brief decomposes near and far values of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
* z stands for z axis (near / far axis)
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_z_rh_zo(mat4 proj,
float * __restrict nearZ,
float * __restrict farZ) {
float m32, m22;
m32 = proj[3][2];
m22 = proj[2][2];
*nearZ = m32 / m22;
*farZ = m32 / (m22 + 1.0f);
}
/*!
* @brief decomposes far value of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] farZ far
*/
CGLM_INLINE
void
glm_persp_decomp_far_rh_zo(mat4 proj, float * __restrict farZ) {
*farZ = proj[3][2] / (proj[2][2] + 1.0f);
}
/*!
* @brief decomposes near value of perspective projection
* with angle values with a right-hand coordinate system and a
* clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
* @param[out] nearZ near
*/
CGLM_INLINE
void
glm_persp_decomp_near_rh_zo(mat4 proj, float * __restrict nearZ) {
*nearZ = proj[3][2] / proj[2][2];
}
/*!
* @brief returns sizes of near and far planes of perspective projection
* with a right-hand coordinate system and a
* clip-space of [0, 1].
*
* @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_rh_zo(mat4 proj, float fovy, vec4 dest) {
float t, a, nearZ, farZ;
t = 2.0f * tanf(fovy * 0.5f);
a = glm_persp_aspect(proj);
glm_persp_decomp_z_rh_zo(proj, &nearZ, &farZ);
dest[1] = t * nearZ;
dest[3] = t * farZ;
dest[0] = a * dest[1];
dest[2] = a * dest[3];
}
/*!
* @brief returns field of view angle along the Y-axis (in radians)
* with a right-hand coordinate system and a clip-space of [0, 1].
*
* 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_rh_zo(mat4 proj) {
return glm_persp_fovy(proj);
}
/*!
* @brief returns aspect ratio of perspective projection
* with a right-hand coordinate system and a clip-space of [0, 1].
*
* @param[in] proj perspective projection matrix
*/
CGLM_INLINE
float
glm_persp_aspect_rh_zo(mat4 proj) {
return glm_persp_aspect(proj);
}
#endif /*cglm_persp_rh_zo_h*/

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_project_no_h
#define cglm_project_no_h
#include "../common.h"
#include "../vec3.h"
#include "../vec4.h"
#include "../mat4.h"
/*!
* @brief maps the specified viewport coordinates into specified space [1]
* the matrix should contain projection matrix.
*
* if you don't have ( and don't want to have ) an inverse matrix then use
* glm_unproject version. You may use existing inverse of matrix in somewhere
* else, this is why glm_unprojecti exists to save save inversion cost
*
* [1] space:
* 1- if m = invProj: View Space
* 2- if m = invViewProj: World Space
* 3- if m = invMVP: Object Space
*
* You probably want to map the coordinates into object space
* so use invMVP as m
*
* Computing viewProj:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
* glm_mat4_inv(viewProj, invMVP);
*
* @param[in] pos point/position in viewport coordinates
* @param[in] invMat matrix (see brief)
* @param[in] vp viewport as [x, y, width, height]
* @param[out] dest unprojected coordinates
*/
CGLM_INLINE
void
glm_unprojecti_no(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) {
vec4 v;
v[0] = 2.0f * (pos[0] - vp[0]) / vp[2] - 1.0f;
v[1] = 2.0f * (pos[1] - vp[1]) / vp[3] - 1.0f;
v[2] = 2.0f * pos[2] - 1.0f;
v[3] = 1.0f;
glm_mat4_mulv(invMat, v, v);
glm_vec4_scale(v, 1.0f / v[3], v);
glm_vec3(v, dest);
}
/*!
* @brief map object coordinates to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] pos object coordinates
* @param[in] m MVP matrix
* @param[in] vp viewport as [x, y, width, height]
* @param[out] dest projected coordinates
*/
CGLM_INLINE
void
glm_project_no(vec3 pos, mat4 m, vec4 vp, vec3 dest) {
CGLM_ALIGN(16) vec4 pos4;
glm_vec4(pos, 1.0f, pos4);
glm_mat4_mulv(m, pos4, pos4);
glm_vec4_scale(pos4, 1.0f / pos4[3], pos4); /* pos = pos / pos.w */
glm_vec4_scale(pos4, 0.5f, pos4);
glm_vec4_adds(pos4, 0.5f, pos4);
dest[0] = pos4[0] * vp[2] + vp[0];
dest[1] = pos4[1] * vp[3] + vp[1];
dest[2] = pos4[2];
}
/*!
* @brief map object's z coordinate to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] v object coordinates
* @param[in] m MVP matrix
*
* @returns projected z coordinate
*/
CGLM_INLINE
float
glm_project_z_no(vec3 v, mat4 m) {
float z, w;
z = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2];
w = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3];
return 0.5f * (z / w) + 0.5f;
}
#endif /* cglm_project_no_h */

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_project_zo_h
#define cglm_project_zo_h
#include "../common.h"
#include "../vec3.h"
#include "../vec4.h"
#include "../mat4.h"
/*!
* @brief maps the specified viewport coordinates into specified space [1]
* the matrix should contain projection matrix.
*
* if you don't have ( and don't want to have ) an inverse matrix then use
* glm_unproject version. You may use existing inverse of matrix in somewhere
* else, this is why glm_unprojecti exists to save save inversion cost
*
* [1] space:
* 1- if m = invProj: View Space
* 2- if m = invViewProj: World Space
* 3- if m = invMVP: Object Space
*
* You probably want to map the coordinates into object space
* so use invMVP as m
*
* Computing viewProj:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
* glm_mat4_inv(viewProj, invMVP);
*
* @param[in] pos point/position in viewport coordinates
* @param[in] invMat matrix (see brief)
* @param[in] vp viewport as [x, y, width, height]
* @param[out] dest unprojected coordinates
*/
CGLM_INLINE
void
glm_unprojecti_zo(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) {
vec4 v;
v[0] = 2.0f * (pos[0] - vp[0]) / vp[2] - 1.0f;
v[1] = 2.0f * (pos[1] - vp[1]) / vp[3] - 1.0f;
v[2] = pos[2];
v[3] = 1.0f;
glm_mat4_mulv(invMat, v, v);
glm_vec4_scale(v, 1.0f / v[3], v);
glm_vec3(v, dest);
}
/*!
* @brief map object coordinates to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] pos object coordinates
* @param[in] m MVP matrix
* @param[in] vp viewport as [x, y, width, height]
* @param[out] dest projected coordinates
*/
CGLM_INLINE
void
glm_project_zo(vec3 pos, mat4 m, vec4 vp, vec3 dest) {
CGLM_ALIGN(16) vec4 pos4;
glm_vec4(pos, 1.0f, pos4);
glm_mat4_mulv(m, pos4, pos4);
glm_vec4_scale(pos4, 1.0f / pos4[3], pos4); /* pos = pos / pos.w */
dest[2] = pos4[2];
glm_vec4_scale(pos4, 0.5f, pos4);
glm_vec4_adds(pos4, 0.5f, pos4);
dest[0] = pos4[0] * vp[2] + vp[0];
dest[1] = pos4[1] * vp[3] + vp[1];
}
/*!
* @brief map object's z coordinate to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] v object coordinates
* @param[in] m MVP matrix
*
* @returns projected z coordinate
*/
CGLM_INLINE
float
glm_project_z_zo(vec3 v, mat4 m) {
float z, w;
z = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2];
w = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3];
return z / w;
}
#endif /* cglm_project_zo_h */

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_lh(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_lh(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_lh(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_lh_h
#define cglm_view_lh_h
#include "../common.h"
#include "../plane.h"
/*!
* @brief set up view matrix (LH)
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_lh(vec3 eye, vec3 center, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 f, u, s;
glm_vec3_sub(center, eye, f);
glm_vec3_normalize(f);
glm_vec3_crossn(up, f, s);
glm_vec3_cross(f, s, u);
dest[0][0] = s[0];
dest[0][1] = u[0];
dest[0][2] = f[0];
dest[1][0] = s[1];
dest[1][1] = u[1];
dest[1][2] = f[1];
dest[2][0] = s[2];
dest[2][1] = u[2];
dest[2][2] = f[2];
dest[3][0] =-glm_vec3_dot(s, eye);
dest[3][1] =-glm_vec3_dot(u, eye);
dest[3][2] =-glm_vec3_dot(f, eye);
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
dest[3][3] = 1.0f;
}
/*!
* @brief set up view matrix with left handed coordinate system
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_lh(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 target;
glm_vec3_add(eye, dir, target);
glm_lookat_lh(eye, target, up, dest);
}
/*!
* @brief set up view matrix with left handed coordinate system
*
* 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_lh(vec3 eye, vec3 dir, mat4 dest) {
CGLM_ALIGN(8) vec3 up;
glm_vec3_ortho(dir, up);
glm_look_lh(eye, dir, up, dest);
}
#endif /*cglm_view_lh_h*/

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_lh_no(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_lh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_lh_no(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_lh_no_h
#define cglm_view_lh_no_h
#include "../common.h"
#include "view_lh.h"
/*!
* @brief set up view matrix with left handed coordinate system.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_lh_no(vec3 eye, vec3 center, vec3 up, mat4 dest) {
glm_lookat_lh(eye, center, up, dest);
}
/*!
* @brief set up view matrix with left handed coordinate system.
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_lh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
glm_look_lh(eye, dir, up, dest);
}
/*!
* @brief set up view matrix with left handed coordinate system.
*
* 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_lh_no(vec3 eye, vec3 dir, mat4 dest) {
glm_look_anyup_lh(eye, dir, dest);
}
#endif /*cglm_view_lh_no_h*/

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_lh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_lh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_lh_zo(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_lh_zo_h
#define cglm_view_lh_zo_h
#include "../common.h"
#include "view_lh.h"
/*!
* @brief set up view matrix with left handed coordinate system.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_lh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest) {
glm_lookat_lh(eye, center, up, dest);
}
/*!
* @brief set up view matrix with left handed coordinate system.
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_lh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
glm_look_lh(eye, dir, up, dest);
}
/*!
* @brief set up view matrix with left handed coordinate system.
*
* 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_lh_zo(vec3 eye, vec3 dir, mat4 dest) {
glm_look_anyup_lh(eye, dir, dest);
}
#endif /*cglm_view_lh_zo_h*/

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_rh(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_rh(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_rh(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_rh_h
#define cglm_view_rh_h
#include "../common.h"
#include "../plane.h"
/*!
* @brief set up view matrix with right handed coordinate system.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_rh(vec3 eye, vec3 center, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 f, u, s;
glm_vec3_sub(center, eye, f);
glm_vec3_normalize(f);
glm_vec3_crossn(f, up, s);
glm_vec3_cross(s, f, u);
dest[0][0] = s[0];
dest[0][1] = u[0];
dest[0][2] =-f[0];
dest[1][0] = s[1];
dest[1][1] = u[1];
dest[1][2] =-f[1];
dest[2][0] = s[2];
dest[2][1] = u[2];
dest[2][2] =-f[2];
dest[3][0] =-glm_vec3_dot(s, eye);
dest[3][1] =-glm_vec3_dot(u, eye);
dest[3][2] = glm_vec3_dot(f, eye);
dest[0][3] = dest[1][3] = dest[2][3] = 0.0f;
dest[3][3] = 1.0f;
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_rh(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
CGLM_ALIGN(8) vec3 target;
glm_vec3_add(eye, dir, target);
glm_lookat_rh(eye, target, up, dest);
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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_rh(vec3 eye, vec3 dir, mat4 dest) {
CGLM_ALIGN(8) vec3 up;
glm_vec3_ortho(dir, up);
glm_look_rh(eye, dir, up, dest);
}
#endif /*cglm_view_rh_h*/

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_rh_no(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_rh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_rh_no(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_rh_no_h
#define cglm_view_rh_no_h
#include "../common.h"
#include "view_rh.h"
/*!
* @brief set up view matrix with right handed coordinate system.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_rh_no(vec3 eye, vec3 center, vec3 up, mat4 dest) {
glm_lookat_rh(eye, center, up, dest);
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_rh_no(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
glm_look_rh(eye, dir, up, dest);
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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_rh_no(vec3 eye, vec3 dir, mat4 dest) {
glm_look_anyup_rh(eye, dir, dest);
}
#endif /*cglm_view_rh_no_h*/

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
Functions:
CGLM_INLINE void glm_lookat_rh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_rh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest)
CGLM_INLINE void glm_look_anyup_rh_zo(vec3 eye, vec3 dir, mat4 dest)
*/
#ifndef cglm_view_rh_zo_h
#define cglm_view_rh_zo_h
#include "../common.h"
#include "view_rh.h"
/*!
* @brief set up view matrix with right handed coordinate system.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @param[in] eye eye vector
* @param[in] center center vector
* @param[in] up up vector
* @param[out] dest result matrix
*/
CGLM_INLINE
void
glm_lookat_rh_zo(vec3 eye, vec3 center, vec3 up, mat4 dest) {
glm_lookat_rh(eye, center, up, dest);
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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.
*
* NOTE: The UP vector must not be parallel to the line of sight from
* the eye point to the reference point
*
* @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_rh_zo(vec3 eye, vec3 dir, vec3 up, mat4 dest) {
glm_look_rh(eye, dir, up, dest);
}
/*!
* @brief set up view matrix with right handed coordinate system.
*
* 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_rh_zo(vec3 eye, vec3 dir, mat4 dest) {
glm_look_anyup_rh(eye, dir, dest);
}
#endif /*cglm_view_rh_zo_h*/

View File

@@ -44,10 +44,41 @@
#ifndef CGLM_USE_DEFAULT_EPSILON
# ifndef GLM_FLT_EPSILON
# define GLM_FLT_EPSILON 1e-6
# define GLM_FLT_EPSILON 1e-5
# endif
#else
# define GLM_FLT_EPSILON FLT_EPSILON
#endif
/*
* Clip control: define CGLM_FORCE_DEPTH_ZERO_TO_ONE before including
* CGLM to use a clip space between 0 to 1.
* Coordinate system: define CGLM_FORCE_LEFT_HANDED before including
* CGLM to use the left handed coordinate system by default.
*/
#define CGLM_CLIP_CONTROL_ZO_BIT (1 << 0) /* ZERO_TO_ONE */
#define CGLM_CLIP_CONTROL_NO_BIT (1 << 1) /* NEGATIVE_ONE_TO_ONE */
#define CGLM_CLIP_CONTROL_LH_BIT (1 << 2) /* LEFT_HANDED, For DirectX, Metal, Vulkan */
#define CGLM_CLIP_CONTROL_RH_BIT (1 << 3) /* RIGHT_HANDED, For OpenGL, default in GLM */
#define CGLM_CLIP_CONTROL_LH_ZO (CGLM_CLIP_CONTROL_LH_BIT | CGLM_CLIP_CONTROL_ZO_BIT)
#define CGLM_CLIP_CONTROL_LH_NO (CGLM_CLIP_CONTROL_LH_BIT | CGLM_CLIP_CONTROL_NO_BIT)
#define CGLM_CLIP_CONTROL_RH_ZO (CGLM_CLIP_CONTROL_RH_BIT | CGLM_CLIP_CONTROL_ZO_BIT)
#define CGLM_CLIP_CONTROL_RH_NO (CGLM_CLIP_CONTROL_RH_BIT | CGLM_CLIP_CONTROL_NO_BIT)
#ifdef CGLM_FORCE_DEPTH_ZERO_TO_ONE
# ifdef CGLM_FORCE_LEFT_HANDED
# define CGLM_CONFIG_CLIP_CONTROL CGLM_CLIP_CONTROL_LH_ZO
# else
# define CGLM_CONFIG_CLIP_CONTROL CGLM_CLIP_CONTROL_RH_ZO
# endif
#else
# ifdef CGLM_FORCE_LEFT_HANDED
# define CGLM_CONFIG_CLIP_CONTROL CGLM_CLIP_CONTROL_LH_NO
# else
# define CGLM_CONFIG_CLIP_CONTROL CGLM_CLIP_CONTROL_RH_NO
# endif
#endif
#endif /* cglm_common_h */

View File

@@ -39,6 +39,7 @@
|| defined(CGLM_NO_PRINTS_NOOP)
#include "common.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>

242
include/cglm/ivec2.h Normal file
View File

@@ -0,0 +1,242 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
FUNCTIONS:
CGLM_INLINE void glm_ivec2(int * __restrict v, ivec2 dest)
CGLM_INLINE void glm_ivec2_copy(ivec2 a, ivec2 dest)
CGLM_INLINE void glm_ivec2_zero(ivec2 v)
CGLM_INLINE void glm_ivec2_one(ivec2 v)
CGLM_INLINE void glm_ivec2_add(ivec2 a, ivec2 b, ivec2 dest)
CGLM_INLINE void glm_ivec2_adds(ivec2 v, int s, ivec2 dest)
CGLM_INLINE void glm_ivec2_sub(ivec2 a, ivec2 b, ivec2 dest)
CGLM_INLINE void glm_ivec2_subs(ivec2 v, int s, ivec2 dest)
CGLM_INLINE void glm_ivec2_mul(ivec2 a, ivec2 b, ivec2 dest)
CGLM_INLINE void glm_ivec2_scale(ivec2 v, int s, ivec2 dest)
CGLM_INLINE int glm_ivec2_distance2(ivec2 a, ivec2 b)
CGLM_INLINE float glm_ivec2_distance(ivec2 a, ivec2 b)
CGLM_INLINE void glm_ivec2_maxv(ivec2 a, ivec2 b, ivec2 dest)
CGLM_INLINE void glm_ivec2_minv(ivec2 a, ivec2 b, ivec2 dest)
CGLM_INLINE void glm_ivec2_clamp(ivec2 v, int minVal, int maxVal)
*/
#ifndef cglm_ivec2_h
#define cglm_ivec2_h
#include "common.h"
/*!
* @brief init ivec2 using vec3 or vec4
*
* @param[in] v vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2(int * __restrict v, ivec2 dest) {
dest[0] = v[0];
dest[1] = v[1];
}
/*!
* @brief copy all members of [a] to [dest]
*
* @param[in] a source vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_copy(ivec2 a, ivec2 dest) {
dest[0] = a[0];
dest[1] = a[1];
}
/*!
* @brief set all members of [v] to zero
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec2_zero(ivec2 v) {
v[0] = v[1] = 0;
}
/*!
* @brief set all members of [v] to one
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec2_one(ivec2 v) {
v[0] = v[1] = 1;
}
/*!
* @brief add vector [a] to vector [b] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_add(ivec2 a, ivec2 b, ivec2 dest) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
}
/*!
* @brief add scalar s to vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_adds(ivec2 v, int s, ivec2 dest) {
dest[0] = v[0] + s;
dest[1] = v[1] + s;
}
/*!
* @brief subtract vector [b] from vector [a] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_sub(ivec2 a, ivec2 b, ivec2 dest) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
}
/*!
* @brief subtract scalar s from vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_subs(ivec2 v, int s, ivec2 dest) {
dest[0] = v[0] - s;
dest[1] = v[1] - s;
}
/*!
* @brief multiply vector [a] with vector [b] and store result in [dest]
*
* @param[in] a frist vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_mul(ivec2 a, ivec2 b, ivec2 dest) {
dest[0] = a[0] * b[0];
dest[1] = a[1] * b[1];
}
/*!
* @brief multiply vector [a] with scalar s and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_scale(ivec2 v, int s, ivec2 dest) {
dest[0] = v[0] * s;
dest[1] = v[1] * s;
}
/*!
* @brief squared distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns squared distance (distance * distance)
*/
CGLM_INLINE
int
glm_ivec2_distance2(ivec2 a, ivec2 b) {
int xd, yd;
xd = a[0] - b[0];
yd = a[1] - b[1];
return xd * xd + yd * yd;
}
/*!
* @brief distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns distance
*/
CGLM_INLINE
float
glm_ivec2_distance(ivec2 a, ivec2 b) {
return sqrtf((float)glm_ivec2_distance2(a, b));
}
/*!
* @brief set each member of dest to greater of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_maxv(ivec2 a, ivec2 b, ivec2 dest) {
dest[0] = a[0] > b[0] ? a[0] : b[0];
dest[1] = a[1] > b[1] ? a[1] : b[1];
}
/*!
* @brief set each member of dest to lesser of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec2_minv(ivec2 a, ivec2 b, ivec2 dest) {
dest[0] = a[0] < b[0] ? a[0] : b[0];
dest[1] = a[1] < b[1] ? a[1] : b[1];
}
/*!
* @brief clamp each member of [v] between minVal and maxVal (inclusive)
*
* @param[in, out] v vector
* @param[in] minVal minimum value
* @param[in] maxVal maximum value
*/
CGLM_INLINE
void
glm_ivec2_clamp(ivec2 v, int minVal, int maxVal) {
if (v[0] < minVal)
v[0] = minVal;
else if(v[0] > maxVal)
v[0] = maxVal;
if (v[1] < minVal)
v[1] = minVal;
else if(v[1] > maxVal)
v[1] = maxVal;
}
#endif /* cglm_ivec2_h */

258
include/cglm/ivec3.h Normal file
View File

@@ -0,0 +1,258 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
FUNCTIONS:
CGLM_INLINE void glm_ivec3(ivec4 v4, ivec3 dest)
CGLM_INLINE void glm_ivec3_copy(ivec3 a, ivec3 dest)
CGLM_INLINE void glm_ivec3_zero(ivec3 v)
CGLM_INLINE void glm_ivec3_one(ivec3 v)
CGLM_INLINE void glm_ivec3_add(ivec3 a, ivec3 b, ivec3 dest)
CGLM_INLINE void glm_ivec3_adds(ivec3 v, int s, ivec3 dest)
CGLM_INLINE void glm_ivec3_sub(ivec3 a, ivec3 b, ivec3 dest)
CGLM_INLINE void glm_ivec3_subs(ivec3 v, int s, ivec3 dest)
CGLM_INLINE void glm_ivec3_mul(ivec3 a, ivec3 b, ivec3 dest)
CGLM_INLINE void glm_ivec3_scale(ivec3 v, int s, ivec3 dest)
CGLM_INLINE int glm_ivec3_distance2(ivec3 a, ivec3 b)
CGLM_INLINE float glm_ivec3_distance(ivec3 a, ivec3 b)
CGLM_INLINE void glm_ivec3_maxv(ivec3 a, ivec3 b, ivec3 dest)
CGLM_INLINE void glm_ivec3_minv(ivec3 a, ivec3 b, ivec3 dest)
CGLM_INLINE void glm_ivec3_clamp(ivec3 v, int minVal, int maxVal)
*/
#ifndef cglm_ivec3_h
#define cglm_ivec3_h
#include "common.h"
/*!
* @brief init ivec3 using ivec4
*
* @param[in] v4 vector4
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3(ivec4 v4, ivec3 dest) {
dest[0] = v4[0];
dest[1] = v4[1];
dest[2] = v4[2];
}
/*!
* @brief copy all members of [a] to [dest]
*
* @param[in] a source vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_copy(ivec3 a, ivec3 dest) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
}
/*!
* @brief set all members of [v] to zero
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec3_zero(ivec3 v) {
v[0] = v[1] = v[2] = 0;
}
/*!
* @brief set all members of [v] to one
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec3_one(ivec3 v) {
v[0] = v[1] = v[2] = 1;
}
/*!
* @brief add vector [a] to vector [b] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_add(ivec3 a, ivec3 b, ivec3 dest) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
}
/*!
* @brief add scalar s to vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_adds(ivec3 v, int s, ivec3 dest) {
dest[0] = v[0] + s;
dest[1] = v[1] + s;
dest[2] = v[2] + s;
}
/*!
* @brief subtract vector [b] from vector [a] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_sub(ivec3 a, ivec3 b, ivec3 dest) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
}
/*!
* @brief subtract scalar s from vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_subs(ivec3 v, int s, ivec3 dest) {
dest[0] = v[0] - s;
dest[1] = v[1] - s;
dest[2] = v[2] - s;
}
/*!
* @brief multiply vector [a] with vector [b] and store result in [dest]
*
* @param[in] a frist vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_mul(ivec3 a, ivec3 b, ivec3 dest) {
dest[0] = a[0] * b[0];
dest[1] = a[1] * b[1];
dest[2] = a[2] * b[2];
}
/*!
* @brief multiply vector [a] with scalar s and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_scale(ivec3 v, int s, ivec3 dest) {
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
}
/*!
* @brief squared distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns squared distance (distance * distance)
*/
CGLM_INLINE
int
glm_ivec3_distance2(ivec3 a, ivec3 b) {
int xd, yd, zd;
xd = a[0] - b[0];
yd = a[1] - b[1];
zd = a[2] - b[2];
return xd * xd + yd * yd + zd * zd;
}
/*!
* @brief distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns distance
*/
CGLM_INLINE
float
glm_ivec3_distance(ivec3 a, ivec3 b) {
return sqrtf((float)glm_ivec3_distance2(a, b));
}
/*!
* @brief set each member of dest to greater of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_maxv(ivec3 a, ivec3 b, ivec3 dest) {
dest[0] = a[0] > b[0] ? a[0] : b[0];
dest[1] = a[1] > b[1] ? a[1] : b[1];
dest[2] = a[2] > b[2] ? a[2] : b[2];
}
/*!
* @brief set each member of dest to lesser of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec3_minv(ivec3 a, ivec3 b, ivec3 dest) {
dest[0] = a[0] < b[0] ? a[0] : b[0];
dest[1] = a[1] < b[1] ? a[1] : b[1];
dest[2] = a[2] < b[2] ? a[2] : b[2];
}
/*!
* @brief clamp each member of [v] between minVal and maxVal (inclusive)
*
* @param[in, out] v vector
* @param[in] minVal minimum value
* @param[in] maxVal maximum value
*/
CGLM_INLINE
void
glm_ivec3_clamp(ivec3 v, int minVal, int maxVal) {
if (v[0] < minVal)
v[0] = minVal;
else if(v[0] > maxVal)
v[0] = maxVal;
if (v[1] < minVal)
v[1] = minVal;
else if(v[1] > maxVal)
v[1] = maxVal;
if (v[2] < minVal)
v[2] = minVal;
else if(v[2] > maxVal)
v[2] = maxVal;
}
#endif /* cglm_ivec3_h */

275
include/cglm/ivec4.h Normal file
View File

@@ -0,0 +1,275 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
/*
FUNCTIONS:
CGLM_INLINE void glm_ivec4(ivec3 v3, int last, ivec4 dest)
CGLM_INLINE void glm_ivec4_copy(ivec4 a, ivec4 dest)
CGLM_INLINE void glm_ivec4_zero(ivec4 v)
CGLM_INLINE void glm_ivec4_one(ivec4 v)
CGLM_INLINE void glm_ivec4_add(ivec4 a, ivec4 b, ivec4 dest)
CGLM_INLINE void glm_ivec4_adds(ivec4 v, int s, ivec4 dest)
CGLM_INLINE void glm_ivec4_sub(ivec4 a, ivec4 b, ivec4 dest)
CGLM_INLINE void glm_ivec4_subs(ivec4 v, int s, ivec4 dest)
CGLM_INLINE void glm_ivec4_mul(ivec4 a, ivec4 b, ivec4 dest)
CGLM_INLINE void glm_ivec4_scale(ivec4 v, int s, ivec4 dest)
CGLM_INLINE int glm_ivec4_distance2(ivec4 a, ivec4 b)
CGLM_INLINE float glm_ivec4_distance(ivec4 a, ivec4 b)
CGLM_INLINE void glm_ivec4_maxv(ivec4 a, ivec4 b, ivec4 dest)
CGLM_INLINE void glm_ivec4_minv(ivec4 a, ivec4 b, ivec4 dest)
CGLM_INLINE void glm_ivec4_clamp(ivec4 v, int minVal, int maxVal)
*/
#ifndef cglm_ivec4_h
#define cglm_ivec4_h
#include "common.h"
/*!
* @brief init ivec4 using ivec3
*
* @param[in] v3 vector3
* @param[in] last last item
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4(ivec3 v3, int last, ivec4 dest) {
dest[0] = v3[0];
dest[1] = v3[1];
dest[2] = v3[2];
dest[3] = last;
}
/*!
* @brief copy all members of [a] to [dest]
*
* @param[in] a source vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_copy(ivec4 a, ivec4 dest) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
dest[3] = a[3];
}
/*!
* @brief set all members of [v] to zero
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec4_zero(ivec4 v) {
v[0] = v[1] = v[2] = v[3] = 0;
}
/*!
* @brief set all members of [v] to one
*
* @param[out] v vector
*/
CGLM_INLINE
void
glm_ivec4_one(ivec4 v) {
v[0] = v[1] = v[2] = v[3] = 1;
}
/*!
* @brief add vector [a] to vector [b] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_add(ivec4 a, ivec4 b, ivec4 dest) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
dest[3] = a[3] + b[3];
}
/*!
* @brief add scalar s to vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_adds(ivec4 v, int s, ivec4 dest) {
dest[0] = v[0] + s;
dest[1] = v[1] + s;
dest[2] = v[2] + s;
dest[3] = v[3] + s;
}
/*!
* @brief subtract vector [b] from vector [a] and store result in [dest]
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_sub(ivec4 a, ivec4 b, ivec4 dest) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
dest[3] = a[3] - b[3];
}
/*!
* @brief subtract scalar s from vector [v] and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_subs(ivec4 v, int s, ivec4 dest) {
dest[0] = v[0] - s;
dest[1] = v[1] - s;
dest[2] = v[2] - s;
dest[3] = v[3] - s;
}
/*!
* @brief multiply vector [a] with vector [b] and store result in [dest]
*
* @param[in] a frist vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_mul(ivec4 a, ivec4 b, ivec4 dest) {
dest[0] = a[0] * b[0];
dest[1] = a[1] * b[1];
dest[2] = a[2] * b[2];
dest[3] = a[3] * b[3];
}
/*!
* @brief multiply vector [a] with scalar s and store result in [dest]
*
* @param[in] v vector
* @param[in] s scalar
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_scale(ivec4 v, int s, ivec4 dest) {
dest[0] = v[0] * s;
dest[1] = v[1] * s;
dest[2] = v[2] * s;
dest[3] = v[3] * s;
}
/*!
* @brief squared distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns squared distance (distance * distance)
*/
CGLM_INLINE
int
glm_ivec4_distance2(ivec4 a, ivec4 b) {
int xd, yd, zd, wd;
xd = a[0] - b[0];
yd = a[1] - b[1];
zd = a[2] - b[2];
wd = a[3] - b[3];
return xd * xd + yd * yd + zd * zd + wd * wd;
}
/*!
* @brief distance between two vectors
*
* @param[in] a first vector
* @param[in] b second vector
* @return returns distance
*/
CGLM_INLINE
float
glm_ivec4_distance(ivec4 a, ivec4 b) {
return sqrtf((float)glm_ivec4_distance2(a, b));
}
/*!
* @brief set each member of dest to greater of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_maxv(ivec4 a, ivec4 b, ivec4 dest) {
dest[0] = a[0] > b[0] ? a[0] : b[0];
dest[1] = a[1] > b[1] ? a[1] : b[1];
dest[2] = a[2] > b[2] ? a[2] : b[2];
dest[3] = a[3] > b[3] ? a[3] : b[3];
}
/*!
* @brief set each member of dest to lesser of vector a and b
*
* @param[in] a first vector
* @param[in] b second vector
* @param[out] dest destination
*/
CGLM_INLINE
void
glm_ivec4_minv(ivec4 a, ivec4 b, ivec4 dest) {
dest[0] = a[0] < b[0] ? a[0] : b[0];
dest[1] = a[1] < b[1] ? a[1] : b[1];
dest[2] = a[2] < b[2] ? a[2] : b[2];
dest[3] = a[3] < b[3] ? a[3] : b[3];
}
/*!
* @brief clamp each member of [v] between minVal and maxVal (inclusive)
*
* @param[in, out] v vector
* @param[in] minVal minimum value
* @param[in] maxVal maximum value
*/
CGLM_INLINE
void
glm_ivec4_clamp(ivec4 v, int minVal, int maxVal) {
if (v[0] < minVal)
v[0] = minVal;
else if(v[0] > maxVal)
v[0] = maxVal;
if (v[1] < minVal)
v[1] = minVal;
else if(v[1] > maxVal)
v[1] = maxVal;
if (v[2] < minVal)
v[2] = minVal;
else if(v[2] > maxVal)
v[2] = maxVal;
if (v[3] < minVal)
v[3] = minVal;
else if(v[3] > maxVal)
v[3] = maxVal;
}
#endif /* cglm_ivec4_h */

View File

@@ -40,6 +40,10 @@
# include "simd/sse2/mat2.h"
#endif
#ifdef CGLM_NEON_FP
# include "simd/neon/mat2.h"
#endif
#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}}
#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}}
@@ -130,6 +134,8 @@ void
glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_mat2_mul_sse2(m1, m2, dest);
#elif defined(CGLM_NEON_FP)
glm_mat2_mul_neon(m1, m2, dest);
#else
float a00 = m1[0][0], a01 = m1[0][1],
a10 = m1[1][0], a11 = m1[1][1],

View File

@@ -187,8 +187,29 @@ glm_mat4_identity_array(mat4 * __restrict mat, size_t count) {
CGLM_INLINE
void
glm_mat4_zero(mat4 mat) {
#ifdef __AVX__
__m256 y0;
y0 = _mm256_setzero_ps();
glmm_store256(mat[0], y0);
glmm_store256(mat[2], y0);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glmm_128 x0;
x0 = _mm_setzero_ps();
glmm_store(mat[0], x0);
glmm_store(mat[1], x0);
glmm_store(mat[2], x0);
glmm_store(mat[3], x0);
#elif defined(CGLM_NEON_FP)
glmm_128 x0;
x0 = vdupq_n_f32(0.0f);
vst1q_f32(mat[0], x0);
vst1q_f32(mat[1], x0);
vst1q_f32(mat[2], x0);
vst1q_f32(mat[3], x0);
#else
CGLM_ALIGN_MAT mat4 t = GLM_MAT4_ZERO_INIT;
glm_mat4_copy(t, mat);
#endif
}
/*!
@@ -539,7 +560,9 @@ glm_mat4_scale_p(mat4 m, float s) {
CGLM_INLINE
void
glm_mat4_scale(mat4 m, float s) {
#if defined( __SSE__ ) || defined( __SSE2__ )
#ifdef __AVX__
glm_mat4_scale_avx(m, s);
#elif defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_scale_sse2(m, s);
#elif defined(CGLM_NEON_FP)
glm_mat4_scale_neon(m, s);
@@ -560,6 +583,8 @@ float
glm_mat4_det(mat4 mat) {
#if defined( __SSE__ ) || defined( __SSE2__ )
return glm_mat4_det_sse2(mat);
#elif defined(CGLM_NEON_FP)
return glm_mat4_det_neon(mat);
#else
/* [square] det(A) = det(At) */
float t[6];
@@ -593,6 +618,8 @@ void
glm_mat4_inv(mat4 mat, mat4 dest) {
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_mat4_inv_sse2(mat, dest);
#elif defined(CGLM_NEON_FP)
glm_mat4_inv_neon(mat, dest);
#else
float t[6];
float det;

View File

@@ -9,6 +9,7 @@
#define cglm_plane_h
#include "common.h"
#include "vec3.h"
#include "vec4.h"
/*

View File

@@ -13,6 +13,17 @@
#include "vec4.h"
#include "mat4.h"
#ifndef CGLM_CLIPSPACE_INCLUDE_ALL
# if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT
# include "clipspace/project_zo.h"
# elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT
# include "clipspace/project_no.h"
# endif
#else
# include "clipspace/project_zo.h"
# include "clipspace/project_no.h"
#endif
/*!
* @brief maps the specified viewport coordinates into specified space [1]
* the matrix should contain projection matrix.
@@ -42,16 +53,11 @@
CGLM_INLINE
void
glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) {
vec4 v;
v[0] = 2.0f * (pos[0] - vp[0]) / vp[2] - 1.0f;
v[1] = 2.0f * (pos[1] - vp[1]) / vp[3] - 1.0f;
v[2] = 2.0f * pos[2] - 1.0f;
v[3] = 1.0f;
glm_mat4_mulv(invMat, v, v);
glm_vec4_scale(v, 1.0f / v[3], v);
glm_vec3(v, dest);
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT
glm_unprojecti_zo(pos, invMat, vp, dest);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT
glm_unprojecti_no(pos, invMat, vp, dest);
#endif
}
/*!
@@ -101,18 +107,66 @@ glm_unproject(vec3 pos, mat4 m, vec4 vp, vec3 dest) {
CGLM_INLINE
void
glm_project(vec3 pos, mat4 m, vec4 vp, vec3 dest) {
CGLM_ALIGN(16) vec4 pos4, vone = GLM_VEC4_ONE_INIT;
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT
glm_project_zo(pos, m, vp, dest);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT
glm_project_no(pos, m, vp, dest);
#endif
}
glm_vec4(pos, 1.0f, pos4);
/*!
* @brief map object's z coordinate to window coordinates
*
* Computing MVP:
* glm_mat4_mul(proj, view, viewProj);
* glm_mat4_mul(viewProj, model, MVP);
*
* @param[in] v object coordinates
* @param[in] m MVP matrix
*
* @returns projected z coordinate
*/
CGLM_INLINE
float
glm_project_z(vec3 v, mat4 m) {
#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT
return glm_project_z_zo(v, m);
#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT
return glm_project_z_no(v, m);
#endif
}
glm_mat4_mulv(m, pos4, pos4);
glm_vec4_scale(pos4, 1.0f / pos4[3], pos4); /* pos = pos / pos.w */
glm_vec4_add(pos4, vone, pos4);
glm_vec4_scale(pos4, 0.5f, pos4);
/*!
* @brief define a picking region
*
* @param[in] center center [x, y] of a picking region in window coordinates
* @param[in] size size [width, height] of the picking region in window coordinates
* @param[in] vp viewport as [x, y, width, height]
* @param[out] dest projected coordinates
*/
CGLM_INLINE
void
glm_pickmatrix(vec2 center, vec2 size, vec4 vp, mat4 dest) {
mat4 res;
vec3 v;
dest[0] = pos4[0] * vp[2] + vp[0];
dest[1] = pos4[1] * vp[3] + vp[1];
dest[2] = pos4[2];
if (size[0] <= 0.0f || size[1] <= 0.0f)
return;
/* Translate and scale the picked region to the entire window */
v[0] = (vp[2] - 2.0f * (center[0] - vp[0])) / size[0];
v[1] = (vp[3] - 2.0f * (center[1] - vp[1])) / size[1];
v[2] = 0.0f;
glm_translate_make(res, v);
v[0] = vp[2] / size[0];
v[1] = vp[3] / size[1];
v[2] = 1.0f;
glm_scale(res, v);
glm_mat4_copy(res, dest);
}
#endif /* cglm_project_h */

View File

@@ -16,6 +16,7 @@
CGLM_INLINE void glm_quat(versor q, float angle, float x, float y, float z);
CGLM_INLINE void glm_quatv(versor q, float angle, vec3 axis);
CGLM_INLINE void glm_quat_copy(versor q, versor dest);
CGLM_INLINE void glm_quat_from_vecs(vec3 a, vec3 b, versor dest);
CGLM_INLINE float glm_quat_norm(versor q);
CGLM_INLINE void glm_quat_normalize(versor q);
CGLM_INLINE void glm_quat_normalize_to(versor q, versor dest);
@@ -38,6 +39,7 @@
CGLM_INLINE void glm_quat_lerp(versor from, versor to, float t, versor dest);
CGLM_INLINE void glm_quat_lerpc(versor from, versor to, float t, versor dest);
CGLM_INLINE void glm_quat_slerp(versor q, versor r, float t, versor dest);
CGLM_INLINE void glm_quat_nlerp(versor q, versor r, float t, versor dest);
CGLM_INLINE void glm_quat_look(vec3 eye, versor ori, mat4 dest);
CGLM_INLINE void glm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest);
CGLM_INLINE void glm_quat_forp(vec3 from,
@@ -58,22 +60,17 @@
#include "mat4.h"
#include "mat3.h"
#include "affine-mat.h"
#include "affine.h"
#ifdef CGLM_SSE_FP
# include "simd/sse2/quat.h"
#endif
CGLM_INLINE
void
glm_mat4_mulv(mat4 m, vec4 v, vec4 dest);
#ifdef CGLM_NEON_FP
# include "simd/neon/quat.h"
#endif
CGLM_INLINE
void
glm_mul_rot(mat4 m1, mat4 m2, mat4 dest);
CGLM_INLINE
void
glm_translate(mat4 m, vec3 v);
CGLM_INLINE void glm_quat_normalize(versor q);
/*
* IMPORTANT:
@@ -190,10 +187,41 @@ glm_quat_copy(versor q, versor dest) {
glm_vec4_copy(q, dest);
}
/*!
* @brief compute quaternion rotating vector A to vector B
*
* @param[in] a vec3 (must have unit length)
* @param[in] b vec3 (must have unit length)
* @param[out] dest quaternion (of unit length)
*/
CGLM_INLINE
void
glm_quat_from_vecs(vec3 a, vec3 b, versor dest) {
CGLM_ALIGN(8) vec3 axis;
float cos_theta;
float cos_half_theta;
cos_theta = glm_vec3_dot(a, b);
if (cos_theta >= 1.f - GLM_FLT_EPSILON) { /* a ∥ b */
glm_quat_identity(dest);
return;
}
if (cos_theta < -1.f + GLM_FLT_EPSILON) { /* angle(a, b) = π */
glm_vec3_ortho(a, axis);
cos_half_theta = 0.f; /* cos π/2 */
} else {
glm_vec3_cross(a, b, axis);
cos_half_theta = 1.0f + cos_theta; /* cos 0 + cos θ */
}
glm_quat_init(dest, axis[0], axis[1], axis[2], cos_half_theta);
glm_quat_normalize(dest);
}
/*!
* @brief returns norm (magnitude) of quaternion
*
* @param[out] q quaternion
* @param[in] q quaternion
*/
CGLM_INLINE
float
@@ -412,6 +440,8 @@ glm_quat_mul(versor p, versor q, versor dest) {
*/
#if defined( __SSE__ ) || defined( __SSE2__ )
glm_quat_mul_sse2(p, q, dest);
#elif defined(CGLM_NEON_FP)
glm_quat_mul_neon(p, q, dest);
#else
dest[0] = p[3] * q[0] + p[0] * q[3] + p[1] * q[2] - p[2] * q[1];
dest[1] = p[3] * q[1] - p[0] * q[2] + p[1] * q[3] + p[2] * q[0];
@@ -622,6 +652,29 @@ glm_quat_lerpc(versor from, versor to, float t, versor dest) {
glm_vec4_lerpc(from, to, t, dest);
}
/*!
* @brief interpolates between two quaternions
* taking the shortest rotation path using
* normalized linear interpolation (NLERP)
*
* @param[in] from from
* @param[in] to to
* @param[in] t interpolant (amount)
* @param[out] dest result quaternion
*/
CGLM_INLINE
void
glm_quat_nlerp(versor from, versor to, float t, versor dest) {
versor target;
float dot;
dot = glm_vec4_dot(from, to);
glm_vec4_scale(to, (dot >= 0) ? 1.0f : -1.0f, target);
glm_quat_lerp(from, target, t, dest);
glm_quat_normalize(dest);
}
/*!
* @brief interpolates between two quaternions
* using spherical linear interpolation (SLERP)

View File

@@ -10,19 +10,56 @@
#include "intrin.h"
#ifdef CGLM_SIMD_ARM
#if defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64) || defined(_M_ARM64EC) || defined(__aarch64__)
# define CGLM_ARM64 1
#endif
#define glmm_load(p) vld1q_f32(p)
#define glmm_store(p, a) vst1q_f32(p, a)
#define glmm_set1(x) vdupq_n_f32(x)
#define glmm_128 float32x4_t
#define glmm_splat_x(x) vdupq_lane_f32(vget_low_f32(x), 0)
#define glmm_splat_y(x) vdupq_lane_f32(vget_low_f32(x), 1)
#define glmm_splat_z(x) vdupq_lane_f32(vget_high_f32(x), 0)
#define glmm_splat_w(x) vdupq_lane_f32(vget_high_f32(x), 1)
#define glmm_xor(a, b) \
vreinterpretq_f32_s32(veorq_s32(vreinterpretq_s32_f32(a), \
vreinterpretq_s32_f32(b)))
#define glmm_swplane(v) vextq_f32(v, v, 2)
#define glmm_low(x) vget_low_f32(x)
#define glmm_high(x) vget_high_f32(x)
#define glmm_combine_ll(x, y) vcombine_f32(vget_low_f32(x), vget_low_f32(y))
#define glmm_combine_hl(x, y) vcombine_f32(vget_high_f32(x), vget_low_f32(y))
#define glmm_combine_lh(x, y) vcombine_f32(vget_low_f32(x), vget_high_f32(y))
#define glmm_combine_hh(x, y) vcombine_f32(vget_high_f32(x), vget_high_f32(y))
static inline
float32x4_t
glmm_abs(float32x4_t v) {
return vabsq_f32(v);
}
static inline
float32x4_t
glmm_vhadd(float32x4_t v) {
return vaddq_f32(vaddq_f32(glmm_splat_x(v), glmm_splat_y(v)),
vaddq_f32(glmm_splat_z(v), glmm_splat_w(v)));
/*
this seems slower:
v = vaddq_f32(v, vrev64q_f32(v));
return vaddq_f32(v, vcombine_f32(vget_high_f32(v), vget_low_f32(v)));
*/
}
static inline
float
glmm_hadd(float32x4_t v) {
#if defined(__aarch64__)
#if CGLM_ARM64
return vaddvq_f32(v);
#else
v = vaddq_f32(v, vrev64q_f32(v));
@@ -79,5 +116,58 @@ glmm_norm_inf(float32x4_t a) {
return glmm_hmax(glmm_abs(a));
}
static inline
float32x4_t
glmm_div(float32x4_t a, float32x4_t b) {
#if CGLM_ARM64
return vdivq_f32(a, b);
#else
/* 2 iterations of Newton-Raphson refinement of reciprocal */
float32x4_t r0, r1;
r0 = vrecpeq_f32(b);
r1 = vrecpsq_f32(r0, b);
r0 = vmulq_f32(r1, r0);
r1 = vrecpsq_f32(r0, b);
r0 = vmulq_f32(r1, r0);
return vmulq_f32(a, r0);
#endif
}
static inline
float32x4_t
glmm_fmadd(float32x4_t a, float32x4_t b, float32x4_t c) {
#if CGLM_ARM64
return vfmaq_f32(c, a, b); /* why vfmaq_f32 is slower than vmlaq_f32 ??? */
#else
return vmlaq_f32(c, a, b);
#endif
}
static inline
float32x4_t
glmm_fnmadd(float32x4_t a, float32x4_t b, float32x4_t c) {
#if CGLM_ARM64
return vfmsq_f32(c, a, b);
#else
return vmlsq_f32(c, a, b);
#endif
}
static inline
float32x4_t
glmm_fmsub(float32x4_t a, float32x4_t b, float32x4_t c) {
#if CGLM_ARM64
return vfmsq_f32(c, a, b);
#else
return vmlsq_f32(c, a, b);
#endif
}
static inline
float32x4_t
glmm_fnmsub(float32x4_t a, float32x4_t b, float32x4_t c) {
return vsubq_f32(vdupq_n_f32(0.0f), glmm_fmadd(a, b, c));
}
#endif
#endif /* cglm_simd_arm_h */

View File

@@ -14,6 +14,16 @@
#include <immintrin.h>
CGLM_INLINE
void
glm_mat4_scale_avx(mat4 m, float s) {
__m256 y0;
y0 = _mm256_set1_ps(s);
glmm_store256(m[0], _mm256_mul_ps(y0, glmm_load256(m[0])));
glmm_store256(m[2], _mm256_mul_ps(y0, glmm_load256(m[2])));
}
CGLM_INLINE
void
glm_mat4_mul_avx(mat4 m1, mat4 m2, mat4 dest) {

View File

@@ -34,7 +34,7 @@
#endif
#if defined(__SSE3__)
# include <x86intrin.h>
# include <pmmintrin.h>
# ifndef CGLM_SIMD_x86
# define CGLM_SIMD_x86
# endif

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_affine_neon_h
#define cglm_affine_neon_h
#if defined(__ARM_NEON_FP)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
v0 = vmulq_f32(glmm_splat_x(r0), l);
v1 = vmulq_f32(glmm_splat_x(r1), l);
v2 = vmulq_f32(glmm_splat_x(r2), l);
v3 = vmulq_f32(glmm_splat_x(r3), l);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
v3 = glmm_fmadd(glmm_splat_w(r3), glmm_load(m1[3]), v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
void
glm_mul_rot_neon(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
glmm_128 l, r0, r1, r2, v0, v1, v2;
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
v0 = vmulq_f32(glmm_splat_x(r0), l);
v1 = vmulq_f32(glmm_splat_x(r1), l);
v2 = vmulq_f32(glmm_splat_x(r2), l);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], glmm_load(m1[3]));
}
CGLM_INLINE
void
glm_inv_tr_neon(mat4 mat) {
float32x4x4_t vmat;
glmm_128 r0, r1, r2, x0;
vmat = vld4q_f32(mat[0]);
r0 = vmat.val[0];
r1 = vmat.val[1];
r2 = vmat.val[2];
x0 = glmm_fmadd(r0, glmm_splat_w(r0),
glmm_fmadd(r1, glmm_splat_w(r1),
vmulq_f32(r2, glmm_splat_w(r2))));
x0 = vnegq_f32(x0);
glmm_store(mat[0], r0);
glmm_store(mat[1], r1);
glmm_store(mat[2], r2);
glmm_store(mat[3], x0);
mat[0][3] = 0.0f;
mat[1][3] = 0.0f;
mat[2][3] = 0.0f;
mat[3][3] = 1.0f;
/* TODO: ?
zo = vget_high_f32(r3);
vst1_lane_f32(&mat[0][3], zo, 0);
vst1_lane_f32(&mat[1][3], zo, 0);
vst1_lane_f32(&mat[2][3], zo, 0);
vst1_lane_f32(&mat[3][3], zo, 1);
*/
}
#endif
#endif /* cglm_affine_neon_h */

View File

@@ -0,0 +1,44 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_mat2_neon_h
#define cglm_mat2_neon_h
#if defined(__ARM_NEON_FP)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_mat2_mul_neon(mat2 m1, mat2 m2, mat2 dest) {
float32x4x2_t a1;
glmm_128 x0, x1, x2;
float32x2_t dc, ba;
x1 = glmm_load(m1[0]); /* d c b a */
x2 = glmm_load(m2[0]); /* h g f e */
dc = vget_high_f32(x1);
ba = vget_low_f32(x1);
/* g g e e, h h f f */
a1 = vtrnq_f32(x2, x2);
/*
dest[0][0] = a * e + c * f;
dest[0][1] = b * e + d * f;
dest[1][0] = a * g + c * h;
dest[1][1] = b * g + d * h;
*/
x0 = glmm_fmadd(vcombine_f32(ba, ba), a1.val[0],
vmulq_f32(vcombine_f32(dc, dc), a1.val[1]));
glmm_store(dest[0], x0);
}
#endif
#endif /* cglm_mat2_neon_h */

View File

@@ -42,41 +42,42 @@ CGLM_INLINE
void
glm_mat4_mul_neon(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
float32x4_t l0, l1, l2, l3, r, d0, d1, d2, d3;
l0 = vld1q_f32(m2[0]);
l1 = vld1q_f32(m2[1]);
l2 = vld1q_f32(m2[2]);
l3 = vld1q_f32(m2[3]);
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
r = vld1q_f32(m1[0]);
d0 = vmulq_lane_f32(r, vget_low_f32(l0), 0);
d1 = vmulq_lane_f32(r, vget_low_f32(l1), 0);
d2 = vmulq_lane_f32(r, vget_low_f32(l2), 0);
d3 = vmulq_lane_f32(r, vget_low_f32(l3), 0);
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
r = vld1q_f32(m1[1]);
d0 = vmlaq_lane_f32(d0, r, vget_low_f32(l0), 1);
d1 = vmlaq_lane_f32(d1, r, vget_low_f32(l1), 1);
d2 = vmlaq_lane_f32(d2, r, vget_low_f32(l2), 1);
d3 = vmlaq_lane_f32(d3, r, vget_low_f32(l3), 1);
v0 = vmulq_f32(glmm_splat_x(r0), l);
v1 = vmulq_f32(glmm_splat_x(r1), l);
v2 = vmulq_f32(glmm_splat_x(r2), l);
v3 = vmulq_f32(glmm_splat_x(r3), l);
r = vld1q_f32(m1[2]);
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 0);
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 0);
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 0);
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 0);
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
r = vld1q_f32(m1[3]);
d0 = vmlaq_lane_f32(d0, r, vget_high_f32(l0), 1);
d1 = vmlaq_lane_f32(d1, r, vget_high_f32(l1), 1);
d2 = vmlaq_lane_f32(d2, r, vget_high_f32(l2), 1);
d3 = vmlaq_lane_f32(d3, r, vget_high_f32(l3), 1);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
vst1q_f32(dest[0], d0);
vst1q_f32(dest[1], d1);
vst1q_f32(dest[2], d2);
vst1q_f32(dest[3], d3);
l = glmm_load(m1[3]);
v0 = glmm_fmadd(glmm_splat_w(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_w(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_w(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
@@ -101,5 +102,216 @@ glm_mat4_mulv_neon(mat4 m, vec4 v, vec4 dest) {
vst1q_f32(dest, l0);
}
CGLM_INLINE
float
glm_mat4_det_neon(mat4 mat) {
float32x4_t r0, r1, r2, r3, x0, x1, x2;
float32x2_t ij, op, mn, kl, nn, mm, jj, ii, gh, ef, t12, t34;
float32x4x2_t a1;
float32x4_t x3 = { 0.f, -0.f, 0.f, -0.f };
/* 127 <- 0, [square] det(A) = det(At) */
r0 = glmm_load(mat[0]); /* d c b a */
r1 = vrev64q_f32(glmm_load(mat[1])); /* g h e f */
r2 = vrev64q_f32(glmm_load(mat[2])); /* l k i j */
r3 = vrev64q_f32(glmm_load(mat[3])); /* o p m n */
gh = vget_high_f32(r1);
ef = vget_low_f32(r1);
kl = vget_high_f32(r2);
ij = vget_low_f32(r2);
op = vget_high_f32(r3);
mn = vget_low_f32(r3);
mm = vdup_lane_f32(mn, 1);
nn = vdup_lane_f32(mn, 0);
ii = vdup_lane_f32(ij, 1);
jj = vdup_lane_f32(ij, 0);
/*
t[1] = j * p - n * l;
t[2] = j * o - n * k;
t[3] = i * p - m * l;
t[4] = i * o - m * k;
*/
x0 = glmm_fnmadd(vcombine_f32(kl, kl), vcombine_f32(nn, mm),
vmulq_f32(vcombine_f32(op, op), vcombine_f32(jj, ii)));
t12 = vget_low_f32(x0);
t34 = vget_high_f32(x0);
/* 1 3 1 3 2 4 2 4 */
a1 = vuzpq_f32(x0, x0);
/*
t[0] = k * p - o * l;
t[0] = k * p - o * l;
t[5] = i * n - m * j;
t[5] = i * n - m * j;
*/
x1 = glmm_fnmadd(vcombine_f32(vdup_lane_f32(kl, 0), jj),
vcombine_f32(vdup_lane_f32(op, 1), mm),
vmulq_f32(vcombine_f32(vdup_lane_f32(op, 0), nn),
vcombine_f32(vdup_lane_f32(kl, 1), ii)));
/*
a * (f * t[0] - g * t[1] + h * t[2])
- b * (e * t[0] - g * t[3] + h * t[4])
+ c * (e * t[1] - f * t[3] + h * t[5])
- d * (e * t[2] - f * t[4] + g * t[5])
*/
x2 = glmm_fnmadd(vcombine_f32(vdup_lane_f32(gh, 1), vdup_lane_f32(ef, 0)),
vcombine_f32(vget_low_f32(a1.val[0]), t34),
vmulq_f32(vcombine_f32(ef, vdup_lane_f32(ef, 1)),
vcombine_f32(vget_low_f32(x1), t12)));
x2 = glmm_fmadd(vcombine_f32(vdup_lane_f32(gh, 0), gh),
vcombine_f32(vget_low_f32(a1.val[1]), vget_high_f32(x1)), x2);
x2 = glmm_xor(x2, x3);
return glmm_hadd(vmulq_f32(x2, r0));
}
CGLM_INLINE
void
glm_mat4_inv_neon(mat4 mat, mat4 dest) {
float32x4_t r0, r1, r2, r3,
v0, v1, v2, v3,
t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7, x8;
float32x4x2_t a1;
float32x2_t lp, ko, hg, jn, im, fe, ae, bf, cg, dh;
float32x4_t x9 = { -0.f, 0.f, -0.f, 0.f };
x8 = vrev64q_f32(x9);
/* 127 <- 0 */
r0 = glmm_load(mat[0]); /* d c b a */
r1 = glmm_load(mat[1]); /* h g f e */
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
/* l p k o, j n i m */
a1 = vzipq_f32(r3, r2);
jn = vget_high_f32(a1.val[0]);
im = vget_low_f32(a1.val[0]);
lp = vget_high_f32(a1.val[1]);
ko = vget_low_f32(a1.val[1]);
hg = vget_high_f32(r1);
x1 = vcombine_f32(vdup_lane_f32(lp, 0), lp); /* l p p p */
x2 = vcombine_f32(vdup_lane_f32(ko, 0), ko); /* k o o o */
x0 = vcombine_f32(vdup_lane_f32(lp, 1), vdup_lane_f32(hg, 1)); /* h h l l */
x3 = vcombine_f32(vdup_lane_f32(ko, 1), vdup_lane_f32(hg, 0)); /* g g k k */
/* t1[0] = k * p - o * l;
t1[0] = k * p - o * l;
t2[0] = g * p - o * h;
t3[0] = g * l - k * h; */
t0 = glmm_fnmadd(x2, x0, vmulq_f32(x3, x1));
fe = vget_low_f32(r1);
x4 = vcombine_f32(vdup_lane_f32(jn, 0), jn); /* j n n n */
x5 = vcombine_f32(vdup_lane_f32(jn, 1), vdup_lane_f32(fe, 1)); /* f f j j */
/* t1[1] = j * p - n * l;
t1[1] = j * p - n * l;
t2[1] = f * p - n * h;
t3[1] = f * l - j * h; */
t1 = glmm_fnmadd(x4, x0, vmulq_f32(x5, x1));
/* t1[2] = j * o - n * k
t1[2] = j * o - n * k;
t2[2] = f * o - n * g;
t3[2] = f * k - j * g; */
t2 = glmm_fnmadd(x4, x3, vmulq_f32(x5, x2));
x6 = vcombine_f32(vdup_lane_f32(im, 1), vdup_lane_f32(fe, 0)); /* e e i i */
x7 = vcombine_f32(vdup_lane_f32(im, 0), im); /* i m m m */
/* t1[3] = i * p - m * l;
t1[3] = i * p - m * l;
t2[3] = e * p - m * h;
t3[3] = e * l - i * h; */
t3 = glmm_fnmadd(x7, x0, vmulq_f32(x6, x1));
/* t1[4] = i * o - m * k;
t1[4] = i * o - m * k;
t2[4] = e * o - m * g;
t3[4] = e * k - i * g; */
t4 = glmm_fnmadd(x7, x3, vmulq_f32(x6, x2));
/* t1[5] = i * n - m * j;
t1[5] = i * n - m * j;
t2[5] = e * n - m * f;
t3[5] = e * j - i * f; */
t5 = glmm_fnmadd(x7, x5, vmulq_f32(x6, x4));
/* h d f b, g c e a */
a1 = vtrnq_f32(r0, r1);
x4 = vrev64q_f32(a1.val[0]); /* c g a e */
x5 = vrev64q_f32(a1.val[1]); /* d h b f */
ae = vget_low_f32(x4);
cg = vget_high_f32(x4);
bf = vget_low_f32(x5);
dh = vget_high_f32(x5);
x0 = vcombine_f32(ae, vdup_lane_f32(ae, 1)); /* a a a e */
x1 = vcombine_f32(bf, vdup_lane_f32(bf, 1)); /* b b b f */
x2 = vcombine_f32(cg, vdup_lane_f32(cg, 1)); /* c c c g */
x3 = vcombine_f32(dh, vdup_lane_f32(dh, 1)); /* d d d h */
/*
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
v0 = glmm_xor(glmm_fmadd(x3, t2, glmm_fnmadd(x2, t1, vmulq_f32(x1, t0))), x8);
/*
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
v2 = glmm_xor(glmm_fmadd(x3, t5, glmm_fnmadd(x1, t3, vmulq_f32(x0, t1))), x8);
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = glmm_xor(glmm_fmadd(x3, t4, glmm_fnmadd(x2, t3, vmulq_f32(x0, t0))), x9);
/*
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
v3 = glmm_xor(glmm_fmadd(x2, t5, glmm_fnmadd(x1, t4, vmulq_f32(x0, t2))), x9);
/* determinant */
x0 = vcombine_f32(vget_low_f32(vzipq_f32(v0, v1).val[0]),
vget_low_f32(vzipq_f32(v2, v3).val[0]));
/*
x0 = glmm_div(glmm_set1(1.0f), glmm_vhadd(vmulq_f32(x0, r0)));
glmm_store(dest[0], vmulq_f32(v0, x0));
glmm_store(dest[1], vmulq_f32(v1, x0));
glmm_store(dest[2], vmulq_f32(v2, x0));
glmm_store(dest[3], vmulq_f32(v3, x0));
*/
x0 = glmm_vhadd(vmulq_f32(x0, r0));
glmm_store(dest[0], glmm_div(v0, x0));
glmm_store(dest[1], glmm_div(v1, x0));
glmm_store(dest[2], glmm_div(v2, x0));
glmm_store(dest[3], glmm_div(v3, x0));
}
#endif
#endif /* cglm_mat4_neon_h */

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglm_quat_neon_h
#define cglm_quat_neon_h
#if defined(__ARM_NEON_FP)
#include "../../common.h"
#include "../intrin.h"
CGLM_INLINE
void
glm_quat_mul_neon(versor p, versor q, versor dest) {
/*
+ (a1 b2 + b1 a2 + c1 d2 d1 c2)i
+ (a1 c2 b1 d2 + c1 a2 + d1 b2)j
+ (a1 d2 + b1 c2 c1 b2 + d1 a2)k
a1 a2 b1 b2 c1 c2 d1 d2
*/
glmm_128 xp, xq, xqr, r, x, y, z, s2, s3;
glmm_128 s1 = {-0.f, 0.f, 0.f, -0.f};
float32x2_t qh, ql;
xp = glmm_load(p); /* 3 2 1 0 */
xq = glmm_load(q);
r = vmulq_f32(glmm_splat_w(xp), xq);
x = glmm_splat_x(xp);
y = glmm_splat_y(xp);
z = glmm_splat_z(xp);
ql = vget_high_f32(s1);
s3 = vcombine_f32(ql, ql);
s2 = vzipq_f32(s3, s3).val[0];
xqr = vrev64q_f32(xq);
qh = vget_high_f32(xqr);
ql = vget_low_f32(xqr);
r = glmm_fmadd(glmm_xor(x, s3), vcombine_f32(qh, ql), r);
r = glmm_fmadd(glmm_xor(y, s2), vcombine_f32(vget_high_f32(xq),
vget_low_f32(xq)), r);
r = glmm_fmadd(glmm_xor(z, s1), vcombine_f32(ql, qh), r);
glmm_store(dest, r);
}
#endif
#endif /* cglm_quat_neon_h */

View File

@@ -16,75 +16,76 @@ CGLM_INLINE
void
glm_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
__m128 l0, l1, l2, l3, r;
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
l0 = glmm_load(m1[0]);
l1 = glmm_load(m1[1]);
l2 = glmm_load(m1[2]);
l3 = glmm_load(m1[3]);
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
r = glmm_load(m2[0]);
glmm_store(dest[0],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
v3 = _mm_mul_ps(glmm_splat_x(r3), l);
r = glmm_load(m2[1]);
glmm_store(dest[1],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
r = glmm_load(m2[2]);
glmm_store(dest[2],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
r = glmm_load(m2[3]);
glmm_store(dest[3],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
l = glmm_load(m1[3]);
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
void
glm_mul_rot_sse2(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
__m128 l0, l1, l2, l3, r;
l0 = glmm_load(m1[0]);
l1 = glmm_load(m1[1]);
l2 = glmm_load(m1[2]);
l3 = glmm_load(m1[3]);
glmm_128 l, r0, r1, r2, v0, v1, v2;
r = glmm_load(m2[0]);
glmm_store(dest[0],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r = glmm_load(m2[1]);
glmm_store(dest[1],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
r = glmm_load(m2[2]);
glmm_store(dest[2],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_mul_ps(glmm_shuff1x(r, 2), l2)));
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
glmm_store(dest[3], l3);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], glmm_load(m1[3]));
}
CGLM_INLINE
void
glm_inv_tr_sse2(mat4 mat) {
__m128 r0, r1, r2, r3, x0, x1;
__m128 r0, r1, r2, r3, x0, x1, x2, x3, x4, x5;
r0 = glmm_load(mat[0]);
r1 = glmm_load(mat[1]);
@@ -94,10 +95,13 @@ glm_inv_tr_sse2(mat4 mat) {
_MM_TRANSPOSE4_PS(r0, r1, r2, x1);
x0 = _mm_add_ps(_mm_mul_ps(r0, glmm_shuff1(r3, 0, 0, 0, 0)),
_mm_mul_ps(r1, glmm_shuff1(r3, 1, 1, 1, 1)));
x0 = _mm_add_ps(x0, _mm_mul_ps(r2, glmm_shuff1(r3, 2, 2, 2, 2)));
x0 = _mm_xor_ps(x0, _mm_set1_ps(-0.f));
x2 = glmm_shuff1(r3, 0, 0, 0, 0);
x3 = glmm_shuff1(r3, 1, 1, 1, 1);
x4 = glmm_shuff1(r3, 2, 2, 2, 2);
x5 = _mm_set1_ps(-0.f);
x0 = glmm_fmadd(r0, x2, glmm_fmadd(r1, x3, _mm_mul_ps(r2, x4)));
x0 = _mm_xor_ps(x0, x5);
x0 = _mm_add_ps(x0, x1);

View File

@@ -15,22 +15,25 @@
CGLM_INLINE
void
glm_mat2_mul_sse2(mat2 m1, mat2 m2, mat2 dest) {
__m128 x0, x1, x2;
__m128 x0, x1, x2, x3, x4;
x1 = glmm_load(m1[0]); /* d c b a */
x2 = glmm_load(m2[0]); /* h g f e */
x3 = glmm_shuff1(x2, 2, 2, 0, 0);
x4 = glmm_shuff1(x2, 3, 3, 1, 1);
x0 = _mm_movelh_ps(x1, x1);
x2 = _mm_movehl_ps(x1, x1);
/*
dest[0][0] = a * e + c * f;
dest[0][1] = b * e + d * f;
dest[1][0] = a * g + c * h;
dest[1][1] = b * g + d * h;
*/
x0 = _mm_mul_ps(_mm_movelh_ps(x1, x1), glmm_shuff1(x2, 2, 2, 0, 0));
x1 = _mm_mul_ps(_mm_movehl_ps(x1, x1), glmm_shuff1(x2, 3, 3, 1, 1));
x1 = _mm_add_ps(x0, x1);
x0 = glmm_fmadd(x0, x3, _mm_mul_ps(x2, x4));
glmm_store(dest[0], x1);
glmm_store(dest[0], x0);
}
CGLM_INLINE

View File

@@ -15,44 +15,61 @@
CGLM_INLINE
void
glm_mat3_mul_sse2(mat3 m1, mat3 m2, mat3 dest) {
__m128 l0, l1, l2;
__m128 r0, r1, r2;
__m128 x0, x1, x2;
__m128 l0, l1, l2, r0, r1, r2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
l0 = _mm_loadu_ps(m1[0]);
l1 = _mm_loadu_ps(&m1[1][1]);
l2 = _mm_set1_ps(m1[2][2]);
r0 = _mm_loadu_ps(m2[0]);
r1 = _mm_loadu_ps(&m2[1][1]);
r2 = _mm_set1_ps(m2[2][2]);
x1 = glmm_shuff2(l0, l1, 1, 0, 3, 3, 0, 3, 2, 0);
x2 = glmm_shuff2(l1, l2, 0, 0, 3, 2, 0, 2, 1, 0);
x8 = glmm_shuff1(l0, 0, 2, 1, 0); /* a00 a02 a01 a00 */
x1 = glmm_shuff1(r0, 3, 0, 0, 0); /* b10 b00 b00 b00 */
x2 = _mm_shuffle_ps(l0, l1, _MM_SHUFFLE(1, 0, 3, 3)); /* a12 a11 a10 a10 */
x3 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 0, 3, 1)); /* b20 b11 b10 b01 */
x0 = _mm_mul_ps(x8, x1);
x0 = _mm_add_ps(_mm_mul_ps(glmm_shuff1(l0, 0, 2, 1, 0),
glmm_shuff1(r0, 3, 0, 0, 0)),
_mm_mul_ps(x1, glmm_shuff2(r0, r1, 0, 0, 1, 1, 2, 0, 0, 0)));
x6 = glmm_shuff1(l0, 1, 0, 2, 1); /* a01 a00 a02 a01 */
x7 = glmm_shuff1(x3, 3, 3, 1, 1); /* b20 b20 b10 b10 */
l2 = _mm_load_ss(&m1[2][2]);
r2 = _mm_load_ss(&m2[2][2]);
x1 = _mm_mul_ps(x6, x7);
l2 = glmm_shuff1(l2, 0, 0, 1, 0); /* a22 a22 0.f a22 */
r2 = glmm_shuff1(r2, 0, 0, 1, 0); /* b22 b22 0.f b22 */
x0 = _mm_add_ps(x0,
_mm_mul_ps(x2, glmm_shuff2(r0, r1, 1, 1, 2, 2, 2, 0, 0, 0)));
x4 = glmm_shuff1(x2, 0, 3, 2, 0); /* a10 a12 a11 a10 */
x5 = glmm_shuff1(x2, 2, 0, 3, 2); /* a11 a10 a12 a11 */
x6 = glmm_shuff1(x3, 2, 0, 0, 0); /* b11 b01 b01 b01 */
x2 = glmm_shuff1(r1, 3, 3, 0, 0); /* b21 b21 b11 b11 */
_mm_storeu_ps(dest[0], x0);
x8 = _mm_unpackhi_ps(x8, x4); /* a10 a00 a12 a02 */
x9 = _mm_unpackhi_ps(x7, x2); /* b21 b20 b21 b20 */
x0 = _mm_add_ps(_mm_mul_ps(glmm_shuff1(l0, 1, 0, 2, 1),
_mm_shuffle_ps(r0, r1, _MM_SHUFFLE(2, 2, 3, 3))),
_mm_mul_ps(glmm_shuff1(x1, 1, 0, 2, 1),
glmm_shuff1(r1, 3, 3, 0, 0)));
x0 = glmm_fmadd(x4, x6, x0);
x1 = glmm_fmadd(x5, x2, x1);
x0 = _mm_add_ps(x0,
_mm_mul_ps(glmm_shuff1(x2, 1, 0, 2, 1),
_mm_shuffle_ps(r1, r2, _MM_SHUFFLE(0, 0, 1, 1))));
x2 = _mm_movehl_ps(l2, l1); /* a22 a22 a21 a20 */
x3 = glmm_shuff1(x2, 0, 2, 1, 0); /* a20 a22 a21 a20 */
x2 = glmm_shuff1(x2, 1, 0, 2, 1); /* a21 a20 a22 a21 */
x4 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(1, 1, 2, 2)); /* b12 b12 b02 b02 */
_mm_storeu_ps(&dest[1][1], x0);
x5 = glmm_shuff1(x4, 3, 0, 0, 0); /* b12 b02 b02 b02 */
x4 = _mm_movehl_ps(r2, x4); /* b22 b22 b12 b12 */
x0 = glmm_fmadd(x3, x5, x0);
x1 = glmm_fmadd(x2, x4, x1);
dest[2][2] = m1[0][2] * m2[2][0]
+ m1[1][2] * m2[2][1]
+ m1[2][2] * m2[2][2];
/*
Dot Product : dest[2][2] = a02 * b20 +
a12 * b21 +
a22 * b22 +
0 * 00 */
x2 = _mm_movelh_ps(x8, l2); /* 0.f a22 a12 a02 */
x3 = _mm_movelh_ps(x9, r2); /* 0.f b22 b21 b20 */
x2 = glmm_vdots(x2, x3);
_mm_storeu_ps(&dest[0][0], x0);
_mm_storeu_ps(&dest[1][1], x1);
_mm_store_ss (&dest[2][2], x2);
}
#endif

View File

@@ -49,53 +49,65 @@ void
glm_mat4_mul_sse2(mat4 m1, mat4 m2, mat4 dest) {
/* D = R * L (Column-Major) */
__m128 l0, l1, l2, l3, r;
glmm_128 l, r0, r1, r2, r3, v0, v1, v2, v3;
l0 = glmm_load(m1[0]);
l1 = glmm_load(m1[1]);
l2 = glmm_load(m1[2]);
l3 = glmm_load(m1[3]);
l = glmm_load(m1[0]);
r0 = glmm_load(m2[0]);
r1 = glmm_load(m2[1]);
r2 = glmm_load(m2[2]);
r3 = glmm_load(m2[3]);
r = glmm_load(m2[0]);
glmm_store(dest[0],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
r = glmm_load(m2[1]);
glmm_store(dest[1],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
r = glmm_load(m2[2]);
glmm_store(dest[2],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
v0 = _mm_mul_ps(glmm_splat_x(r0), l);
v1 = _mm_mul_ps(glmm_splat_x(r1), l);
v2 = _mm_mul_ps(glmm_splat_x(r2), l);
v3 = _mm_mul_ps(glmm_splat_x(r3), l);
r = glmm_load(m2[3]);
glmm_store(dest[3],
_mm_add_ps(_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 0), l0),
_mm_mul_ps(glmm_shuff1x(r, 1), l1)),
_mm_add_ps(_mm_mul_ps(glmm_shuff1x(r, 2), l2),
_mm_mul_ps(glmm_shuff1x(r, 3), l3))));
l = glmm_load(m1[1]);
v0 = glmm_fmadd(glmm_splat_y(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_y(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_y(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_y(r3), l, v3);
l = glmm_load(m1[2]);
v0 = glmm_fmadd(glmm_splat_z(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_z(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_z(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_z(r3), l, v3);
l = glmm_load(m1[3]);
v0 = glmm_fmadd(glmm_splat_w(r0), l, v0);
v1 = glmm_fmadd(glmm_splat_w(r1), l, v1);
v2 = glmm_fmadd(glmm_splat_w(r2), l, v2);
v3 = glmm_fmadd(glmm_splat_w(r3), l, v3);
glmm_store(dest[0], v0);
glmm_store(dest[1], v1);
glmm_store(dest[2], v2);
glmm_store(dest[3], v3);
}
CGLM_INLINE
void
glm_mat4_mulv_sse2(mat4 m, vec4 v, vec4 dest) {
__m128 x0, x1, x2;
__m128 x0, x1, m0, m1, m2, m3, v0, v1, v2, v3;
m0 = glmm_load(m[0]);
m1 = glmm_load(m[1]);
m2 = glmm_load(m[2]);
m3 = glmm_load(m[3]);
x0 = glmm_load(v);
x1 = _mm_add_ps(_mm_mul_ps(glmm_load(m[0]), glmm_shuff1x(x0, 0)),
_mm_mul_ps(glmm_load(m[1]), glmm_shuff1x(x0, 1)));
v0 = glmm_splat_x(x0);
v1 = glmm_splat_y(x0);
v2 = glmm_splat_z(x0);
v3 = glmm_splat_w(x0);
x2 = _mm_add_ps(_mm_mul_ps(glmm_load(m[2]), glmm_shuff1x(x0, 2)),
_mm_mul_ps(glmm_load(m[3]), glmm_shuff1x(x0, 3)));
x1 = _mm_mul_ps(m3, v3);
x1 = glmm_fmadd(m2, v2, x1);
x1 = glmm_fmadd(m1, v1, x1);
x1 = glmm_fmadd(m0, v0, x1);
glmm_store(dest, _mm_add_ps(x1, x2));
glmm_store(dest, x1);
}
CGLM_INLINE
@@ -115,20 +127,18 @@ glm_mat4_det_sse2(mat4 mat) {
t[3] = i * p - m * l;
t[4] = i * o - m * k;
*/
x0 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r2, 0, 0, 1, 1),
glmm_shuff1(r3, 2, 3, 2, 3)),
_mm_mul_ps(glmm_shuff1(r3, 0, 0, 1, 1),
glmm_shuff1(r2, 2, 3, 2, 3)));
x0 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 1, 1), glmm_shuff1(r2, 2, 3, 2, 3),
_mm_mul_ps(glmm_shuff1(r2, 0, 0, 1, 1),
glmm_shuff1(r3, 2, 3, 2, 3)));
/*
t[0] = k * p - o * l;
t[0] = k * p - o * l;
t[5] = i * n - m * j;
t[5] = i * n - m * j;
*/
x1 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r2, 0, 0, 2, 2),
glmm_shuff1(r3, 1, 1, 3, 3)),
_mm_mul_ps(glmm_shuff1(r3, 0, 0, 2, 2),
glmm_shuff1(r2, 1, 1, 3, 3)));
x1 = glmm_fnmadd(glmm_shuff1(r3, 0, 0, 2, 2), glmm_shuff1(r2, 1, 1, 3, 3),
_mm_mul_ps(glmm_shuff1(r2, 0, 0, 2, 2),
glmm_shuff1(r3, 1, 1, 3, 3)));
/*
a * (f * t[0] - g * t[1] + h * t[2])
@@ -136,21 +146,16 @@ glm_mat4_det_sse2(mat4 mat) {
+ c * (e * t[1] - f * t[3] + h * t[5])
- d * (e * t[2] - f * t[4] + g * t[5])
*/
x2 = _mm_sub_ps(_mm_mul_ps(glmm_shuff1(r1, 0, 0, 0, 1),
_mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0))),
_mm_mul_ps(glmm_shuff1(r1, 1, 1, 2, 2),
glmm_shuff1(x0, 3, 2, 2, 0)));
x2 = glmm_fnmadd(glmm_shuff1(r1, 1, 1, 2, 2), glmm_shuff1(x0, 3, 2, 2, 0),
_mm_mul_ps(glmm_shuff1(r1, 0, 0, 0, 1),
_mm_shuffle_ps(x1, x0, _MM_SHUFFLE(1, 0, 0, 0))));
x2 = glmm_fmadd(glmm_shuff1(r1, 2, 3, 3, 3),
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1)),
x2);
x2 = _mm_add_ps(x2,
_mm_mul_ps(glmm_shuff1(r1, 2, 3, 3, 3),
_mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 2, 3, 1))));
x2 = _mm_xor_ps(x2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
x0 = _mm_mul_ps(r0, x2);
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 3, 3, 1));
return _mm_cvtss_f32(x0);
return glmm_hadd(_mm_mul_ps(x2, r0));
}
CGLM_INLINE
@@ -159,7 +164,10 @@ glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) {
__m128 r0, r1, r2, r3,
v0, v1, v2, v3,
t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7;
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f);
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */
r0 = glmm_load(mat[0]); /* d c b a */
@@ -167,109 +175,118 @@ glm_mat4_inv_fast_sse2(mat4 mat, mat4 dest) {
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
x1 = glmm_shuff1(x0, 1, 3, 3, 3); /* l p p p */
x0 = _mm_movehl_ps(r3, r2); /* p o l k */
x3 = _mm_movelh_ps(r2, r3); /* n m j i */
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
t0 = _mm_mul_ps(x3, x1);
t1 = _mm_mul_ps(x5, x1);
t2 = _mm_mul_ps(x5, x2);
t3 = _mm_mul_ps(x6, x1);
t4 = _mm_mul_ps(x6, x2);
t5 = _mm_mul_ps(x6, x4);
/* t1[0] = k * p - o * l;
t1[0] = k * p - o * l;
t2[0] = g * p - o * h;
t3[0] = g * l - k * h; */
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
x4 = glmm_shuff1(x4, 0, 2, 2, 2); /* j n n n */
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
t0 = glmm_fnmadd(x2, x0, t0);
/* t1[1] = j * p - n * l;
t1[1] = j * p - n * l;
t2[1] = f * p - n * h;
t3[1] = f * l - j * h; */
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
t1 = glmm_fnmadd(x4, x0, t1);
/* t1[2] = j * o - n * k
t1[2] = j * o - n * k;
t2[2] = f * o - n * g;
t3[2] = f * k - j * g; */
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
x7 = glmm_shuff2(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
t2 = glmm_fnmadd(x4, x3, t2);
/* t1[3] = i * p - m * l;
t1[3] = i * p - m * l;
t2[3] = e * p - m * h;
t3[3] = e * l - i * h; */
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
t3 = glmm_fnmadd(x7, x0, t3);
/* t1[4] = i * o - m * k;
t1[4] = i * o - m * k;
t2[4] = e * o - m * g;
t3[4] = e * k - i * g; */
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
t4 = glmm_fnmadd(x7, x3, t4);
/* t1[5] = i * n - m * j;
t1[5] = i * n - m * j;
t2[5] = e * n - m * f;
t3[5] = e * j - i * f; */
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
t5 = glmm_fnmadd(x7, x5, t5);
x0 = glmm_shuff2(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
x1 = glmm_shuff2(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
x2 = glmm_shuff2(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
x3 = glmm_shuff2(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
x4 = _mm_movelh_ps(r0, r1); /* f e b a */
x5 = _mm_movehl_ps(r1, r0); /* h g d c */
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
v2 = _mm_mul_ps(x0, t1);
v1 = _mm_mul_ps(x0, t0);
v3 = _mm_mul_ps(x0, t2);
v0 = _mm_mul_ps(x1, t0);
v2 = glmm_fnmadd(x1, t3, v2);
v3 = glmm_fnmadd(x1, t4, v3);
v0 = glmm_fnmadd(x2, t1, v0);
v1 = glmm_fnmadd(x2, t3, v1);
v3 = glmm_fmadd(x2, t5, v3);
v0 = glmm_fmadd(x3, t2, v0);
v2 = glmm_fmadd(x3, t5, v2);
v1 = glmm_fmadd(x3, t4, v1);
/*
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
_mm_sub_ps(_mm_mul_ps(x1, t0),
_mm_mul_ps(x2, t1)));
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
_mm_sub_ps(_mm_mul_ps(x0, t0),
_mm_mul_ps(x2, t3)));
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
v0 = _mm_xor_ps(v0, x8);
/*
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
_mm_sub_ps(_mm_mul_ps(x0, t1),
_mm_mul_ps(x1, t3)));
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
v2 = _mm_xor_ps(v2, x8);
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = _mm_xor_ps(v1, x9);
/*
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
_mm_sub_ps(_mm_mul_ps(x0, t2),
_mm_mul_ps(x1, t4)));
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
v3 = _mm_xor_ps(v3, x9);
/* determinant */
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
x0 = _mm_mul_ps(x0, r0);
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
x0 = _mm_rcp_ps(x0);
x0 = _mm_rcp_ps(glmm_vhadd(_mm_mul_ps(x0, r0)));
glmm_store(dest[0], _mm_mul_ps(v0, x0));
glmm_store(dest[1], _mm_mul_ps(v1, x0));
@@ -283,7 +300,10 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) {
__m128 r0, r1, r2, r3,
v0, v1, v2, v3,
t0, t1, t2, t3, t4, t5,
x0, x1, x2, x3, x4, x5, x6, x7;
x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
x8 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f);
x9 = glmm_shuff1(x8, 2, 1, 2, 1);
/* 127 <- 0 */
r0 = glmm_load(mat[0]); /* d c b a */
@@ -291,109 +311,118 @@ glm_mat4_inv_sse2(mat4 mat, mat4 dest) {
r2 = glmm_load(mat[2]); /* l k j i */
r3 = glmm_load(mat[3]); /* p o n m */
x0 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(3, 2, 3, 2)); /* p o l k */
x1 = glmm_shuff1(x0, 1, 3, 3, 3); /* l p p p */
x0 = _mm_movehl_ps(r3, r2); /* p o l k */
x3 = _mm_movelh_ps(r2, r3); /* n m j i */
x1 = glmm_shuff1(x0, 1, 3, 3 ,3); /* l p p p */
x2 = glmm_shuff1(x0, 0, 2, 2, 2); /* k o o o */
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
x4 = glmm_shuff1(x3, 1, 3, 3, 3); /* j n n n */
x7 = glmm_shuff1(x3, 0, 2, 2, 2); /* i m m m */
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
x3 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(2, 2, 2, 2)); /* g g k k */
x0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(3, 3, 3, 3)); /* h h l l */
t0 = _mm_mul_ps(x3, x1);
t1 = _mm_mul_ps(x5, x1);
t2 = _mm_mul_ps(x5, x2);
t3 = _mm_mul_ps(x6, x1);
t4 = _mm_mul_ps(x6, x2);
t5 = _mm_mul_ps(x6, x4);
/* t1[0] = k * p - o * l;
t1[0] = k * p - o * l;
t2[0] = g * p - o * h;
t3[0] = g * l - k * h; */
t0 = _mm_sub_ps(_mm_mul_ps(x3, x1), _mm_mul_ps(x2, x0));
x4 = _mm_shuffle_ps(r2, r3, _MM_SHUFFLE(2, 1, 2, 1)); /* o n k j */
x4 = glmm_shuff1(x4, 0, 2, 2, 2); /* j n n n */
x5 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(1, 1, 1, 1)); /* f f j j */
t0 = glmm_fnmadd(x2, x0, t0);
/* t1[1] = j * p - n * l;
t1[1] = j * p - n * l;
t2[1] = f * p - n * h;
t3[1] = f * l - j * h; */
t1 = _mm_sub_ps(_mm_mul_ps(x5, x1), _mm_mul_ps(x4, x0));
t1 = glmm_fnmadd(x4, x0, t1);
/* t1[2] = j * o - n * k
t1[2] = j * o - n * k;
t2[2] = f * o - n * g;
t3[2] = f * k - j * g; */
t2 = _mm_sub_ps(_mm_mul_ps(x5, x2), _mm_mul_ps(x4, x3));
x6 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 0)); /* e e i i */
x7 = glmm_shuff2(r3, r2, 0, 0, 0, 0, 2, 0, 0, 0); /* i m m m */
t2 = glmm_fnmadd(x4, x3, t2);
/* t1[3] = i * p - m * l;
t1[3] = i * p - m * l;
t2[3] = e * p - m * h;
t3[3] = e * l - i * h; */
t3 = _mm_sub_ps(_mm_mul_ps(x6, x1), _mm_mul_ps(x7, x0));
t3 = glmm_fnmadd(x7, x0, t3);
/* t1[4] = i * o - m * k;
t1[4] = i * o - m * k;
t2[4] = e * o - m * g;
t3[4] = e * k - i * g; */
t4 = _mm_sub_ps(_mm_mul_ps(x6, x2), _mm_mul_ps(x7, x3));
t4 = glmm_fnmadd(x7, x3, t4);
/* t1[5] = i * n - m * j;
t1[5] = i * n - m * j;
t2[5] = e * n - m * f;
t3[5] = e * j - i * f; */
t5 = _mm_sub_ps(_mm_mul_ps(x6, x4), _mm_mul_ps(x7, x5));
t5 = glmm_fnmadd(x7, x5, t5);
x0 = glmm_shuff2(r1, r0, 0, 0, 0, 0, 2, 2, 2, 0); /* a a a e */
x1 = glmm_shuff2(r1, r0, 1, 1, 1, 1, 2, 2, 2, 0); /* b b b f */
x2 = glmm_shuff2(r1, r0, 2, 2, 2, 2, 2, 2, 2, 0); /* c c c g */
x3 = glmm_shuff2(r1, r0, 3, 3, 3, 3, 2, 2, 2, 0); /* d d d h */
x4 = _mm_movelh_ps(r0, r1); /* f e b a */
x5 = _mm_movehl_ps(r1, r0); /* h g d c */
x0 = glmm_shuff1(x4, 0, 0, 0, 2); /* a a a e */
x1 = glmm_shuff1(x4, 1, 1, 1, 3); /* b b b f */
x2 = glmm_shuff1(x5, 0, 0, 0, 2); /* c c c g */
x3 = glmm_shuff1(x5, 1, 1, 1, 3); /* d d d h */
v2 = _mm_mul_ps(x0, t1);
v1 = _mm_mul_ps(x0, t0);
v3 = _mm_mul_ps(x0, t2);
v0 = _mm_mul_ps(x1, t0);
v2 = glmm_fnmadd(x1, t3, v2);
v3 = glmm_fnmadd(x1, t4, v3);
v0 = glmm_fnmadd(x2, t1, v0);
v1 = glmm_fnmadd(x2, t3, v1);
v3 = glmm_fmadd(x2, t5, v3);
v0 = glmm_fmadd(x3, t2, v0);
v2 = glmm_fmadd(x3, t5, v2);
v1 = glmm_fmadd(x3, t4, v1);
/*
dest[0][0] = f * t1[0] - g * t1[1] + h * t1[2];
dest[0][1] =-(b * t1[0] - c * t1[1] + d * t1[2]);
dest[0][2] = b * t2[0] - c * t2[1] + d * t2[2];
dest[0][3] =-(b * t3[0] - c * t3[1] + d * t3[2]); */
v0 = _mm_add_ps(_mm_mul_ps(x3, t2),
_mm_sub_ps(_mm_mul_ps(x1, t0),
_mm_mul_ps(x2, t1)));
v0 = _mm_xor_ps(v0, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = _mm_add_ps(_mm_mul_ps(x3, t4),
_mm_sub_ps(_mm_mul_ps(x0, t0),
_mm_mul_ps(x2, t3)));
v1 = _mm_xor_ps(v1, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
v0 = _mm_xor_ps(v0, x8);
/*
dest[2][0] = e * t1[1] - f * t1[3] + h * t1[5];
dest[2][1] =-(a * t1[1] - b * t1[3] + d * t1[5]);
dest[2][2] = a * t2[1] - b * t2[3] + d * t2[5];
dest[2][3] =-(a * t3[1] - b * t3[3] + d * t3[5]);*/
v2 = _mm_add_ps(_mm_mul_ps(x3, t5),
_mm_sub_ps(_mm_mul_ps(x0, t1),
_mm_mul_ps(x1, t3)));
v2 = _mm_xor_ps(v2, _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
v2 = _mm_xor_ps(v2, x8);
/*
dest[1][0] =-(e * t1[0] - g * t1[3] + h * t1[4]);
dest[1][1] = a * t1[0] - c * t1[3] + d * t1[4];
dest[1][2] =-(a * t2[0] - c * t2[3] + d * t2[4]);
dest[1][3] = a * t3[0] - c * t3[3] + d * t3[4]; */
v1 = _mm_xor_ps(v1, x9);
/*
dest[3][0] =-(e * t1[2] - f * t1[4] + g * t1[5]);
dest[3][1] = a * t1[2] - b * t1[4] + c * t1[5];
dest[3][2] =-(a * t2[2] - b * t2[4] + c * t2[5]);
dest[3][3] = a * t3[2] - b * t3[4] + c * t3[5]; */
v3 = _mm_add_ps(_mm_mul_ps(x2, t5),
_mm_sub_ps(_mm_mul_ps(x0, t2),
_mm_mul_ps(x1, t4)));
v3 = _mm_xor_ps(v3, _mm_set_ps(0.f, -0.f, 0.f, -0.f));
v3 = _mm_xor_ps(v3, x9);
/* determinant */
x0 = _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(0, 0, 0, 0));
x1 = _mm_shuffle_ps(v2, v3, _MM_SHUFFLE(0, 0, 0, 0));
x0 = _mm_shuffle_ps(x0, x1, _MM_SHUFFLE(2, 0, 2, 0));
x0 = _mm_mul_ps(x0, r0);
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 0, 1, 2, 3));
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
x0 = _mm_div_ps(_mm_set1_ps(1.0f), x0);
x0 = _mm_div_ps(_mm_set1_ps(1.0f), glmm_vhadd(_mm_mul_ps(x0, r0)));
glmm_store(dest[0], _mm_mul_ps(v0, x0));
glmm_store(dest[1], _mm_mul_ps(v1, x0));

View File

@@ -22,25 +22,33 @@ glm_quat_mul_sse2(versor p, versor q, versor dest) {
a1 a2 b1 b2 c1 c2 d1 d2
*/
__m128 xp, xq, x0, r;
__m128 xp, xq, x1, x2, x3, r, x, y, z;
xp = glmm_load(p); /* 3 2 1 0 */
xq = glmm_load(q);
x1 = _mm_set_ps(-0.f, 0.f, -0.f, 0.f); /* TODO: _mm_set1_ss() + shuff ? */
r = _mm_mul_ps(glmm_splat_w(xp), xq);
r = _mm_mul_ps(glmm_shuff1x(xp, 3), xq);
x2 = _mm_unpackhi_ps(x1, x1);
x3 = glmm_shuff1(x1, 3, 2, 0, 1);
x = glmm_splat_x(xp);
y = glmm_splat_y(xp);
z = glmm_splat_z(xp);
x0 = _mm_xor_ps(glmm_shuff1x(xp, 0), _mm_set_ps(-0.f, 0.f, -0.f, 0.f));
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 0, 1, 2, 3)));
x = _mm_xor_ps(x, x1);
y = _mm_xor_ps(y, x2);
z = _mm_xor_ps(z, x3);
x0 = _mm_xor_ps(glmm_shuff1x(xp, 1), _mm_set_ps(-0.f, -0.f, 0.f, 0.f));
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 1, 0, 3, 2)));
x1 = glmm_shuff1(xq, 0, 1, 2, 3);
x2 = glmm_shuff1(xq, 1, 0, 3, 2);
x3 = glmm_shuff1(xq, 2, 3, 0, 1);
x0 = _mm_xor_ps(glmm_shuff1x(xp, 2), _mm_set_ps(-0.f, 0.f, 0.f, -0.f));
r = _mm_add_ps(r, _mm_mul_ps(x0, glmm_shuff1(xq, 2, 3, 0, 1)));
r = glmm_fmadd(x, x1, r);
r = glmm_fmadd(y, x2, r);
r = glmm_fmadd(z, x3, r);
glmm_store(dest, r);
}
#endif
#endif /* cglm_quat_simd_h */

View File

@@ -18,6 +18,9 @@
# define glmm_store(p, a) _mm_store_ps(p, a)
#endif
#define glmm_set1(x) _mm_set1_ps(x)
#define glmm_128 __m128
#ifdef CGLM_USE_INT_DOMAIN
# define glmm_shuff1(xmm, z, y, x, w) \
_mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(xmm), \
@@ -27,7 +30,16 @@
_mm_shuffle_ps(xmm, xmm, _MM_SHUFFLE(z, y, x, w))
#endif
#define glmm_splat(x, lane) glmm_shuff1(x, lane, lane, lane, lane)
#define glmm_splat_x(x) glmm_splat(x, 0)
#define glmm_splat_y(x) glmm_splat(x, 1)
#define glmm_splat_z(x) glmm_splat(x, 2)
#define glmm_splat_w(x) glmm_splat(x, 3)
/* glmm_shuff1x() is DEPRECATED!, use glmm_splat() */
#define glmm_shuff1x(xmm, x) glmm_shuff1(xmm, x, x, x, x)
#define glmm_shuff2(a, b, z0, y0, x0, w0, z1, y1, x1, w1) \
glmm_shuff1(_mm_shuffle_ps(a, b, _MM_SHUFFLE(z0, y0, x0, w0)), \
z1, y1, x1, w1)
@@ -48,6 +60,15 @@ glmm_abs(__m128 x) {
return _mm_andnot_ps(_mm_set1_ps(-0.0f), x);
}
static inline
__m128
glmm_vhadd(__m128 v) {
__m128 x0;
x0 = _mm_add_ps(v, glmm_shuff1(v, 0, 1, 2, 3));
x0 = _mm_add_ps(x0, glmm_shuff1(x0, 1, 0, 0, 1));
return x0;
}
static inline
__m128
glmm_vhadds(__m128 v) {
@@ -80,7 +101,7 @@ glmm_vhmin(__m128 v) {
__m128 x0, x1, x2;
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
x1 = _mm_min_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
x2 = glmm_shuff1x(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
return _mm_min_ss(x1, x2);
}
@@ -96,7 +117,7 @@ glmm_vhmax(__m128 v) {
__m128 x0, x1, x2;
x0 = _mm_movehl_ps(v, v); /* [2, 3, 2, 3] */
x1 = _mm_max_ps(x0, v); /* [0|2, 1|3, 2|2, 3|3] */
x2 = glmm_shuff1x(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
x2 = glmm_splat(x1, 1); /* [1|3, 1|3, 1|3, 1|3] */
return _mm_max_ss(x1, x2);
}
@@ -188,5 +209,99 @@ glmm_store3(float v[3], __m128 vx) {
_mm_store_ss(&v[2], glmm_shuff1(vx, 2, 2, 2, 2));
}
static inline
__m128
glmm_div(__m128 a, __m128 b) {
return _mm_div_ps(a, b);
}
/* enable FMA macro for MSVC? */
#if defined(_MSC_VER) && !defined(__FMA__) && defined(__AVX2__)
# define __FMA__ 1
#endif
static inline
__m128
glmm_fmadd(__m128 a, __m128 b, __m128 c) {
#ifdef __FMA__
return _mm_fmadd_ps(a, b, c);
#else
return _mm_add_ps(c, _mm_mul_ps(a, b));
#endif
}
static inline
__m128
glmm_fnmadd(__m128 a, __m128 b, __m128 c) {
#ifdef __FMA__
return _mm_fnmadd_ps(a, b, c);
#else
return _mm_sub_ps(c, _mm_mul_ps(a, b));
#endif
}
static inline
__m128
glmm_fmsub(__m128 a, __m128 b, __m128 c) {
#ifdef __FMA__
return _mm_fmsub_ps(a, b, c);
#else
return _mm_sub_ps(_mm_mul_ps(a, b), c);
#endif
}
static inline
__m128
glmm_fnmsub(__m128 a, __m128 b, __m128 c) {
#ifdef __FMA__
return _mm_fnmsub_ps(a, b, c);
#else
return _mm_xor_ps(_mm_add_ps(_mm_mul_ps(a, b), c), _mm_set1_ps(-0.0f));
#endif
}
#if defined(__AVX__)
static inline
__m256
glmm256_fmadd(__m256 a, __m256 b, __m256 c) {
#ifdef __FMA__
return _mm256_fmadd_ps(a, b, c);
#else
return _mm256_add_ps(c, _mm256_mul_ps(a, b));
#endif
}
static inline
__m256
glmm256_fnmadd(__m256 a, __m256 b, __m256 c) {
#ifdef __FMA__
return _mm256_fnmadd_ps(a, b, c);
#else
return _mm256_sub_ps(c, _mm256_mul_ps(a, b));
#endif
}
static inline
__m256
glmm256_fmsub(__m256 a, __m256 b, __m256 c) {
#ifdef __FMA__
return _mm256_fmsub_ps(a, b, c);
#else
return _mm256_sub_ps(_mm256_mul_ps(a, b), c);
#endif
}
static inline
__m256
glmm256_fnmsub(__m256 a, __m256 b, __m256 c) {
#ifdef __FMA__
return _mm256_fmsub_ps(a, b, c);
#else
return _mm256_xor_ps(_mm256_sub_ps(_mm256_mul_ps(a, b), c),
_mm256_set1_ps(-0.0f));
#endif
}
#endif
#endif
#endif /* cglm_simd_x86_h */

Some files were not shown because too many files have changed in this diff Show More