Compare commits

...

65 commits

Author SHA1 Message Date
Christophe
2d4c4b4dd3
Update ci.yml to run CI on master branch PRs 2025-02-07 20:32:38 +01:00
Jeff Burnett
69b130c162 Fix uninitialized in constexpr warning
Matrix multiplication functions that were recently marked as 'constexpr'
in commit '1cc8e80e3ba140239196d9a4597a2ea8139a4aa5' can throw warnings
about an "uninitialized variable 'Result' in constexpr function".

Change-Id: I95396da9ac8a6e0dd1b6ae4e782f75446cfa70a3
2025-01-23 09:10:55 +01:00
christophe
af86309663 Fix missing newline 2025-01-22 21:40:13 +01:00
ZXShady
e54e16f3da Add C++17 structureed binding support
Add C++17 Structured Bindings support for vec,mat,quat types
2025-01-22 21:40:13 +01:00
Christophe
5847dd91b2
Merge pull request #1305 from steimich96/master
Fixed nvcc compile warnings for default constructor
2025-01-22 12:00:51 +01:00
steimich96
edc3607b39 Fixed nvcc compile warnings for default constructor 2025-01-22 12:00:05 +01:00
Christophe
624090a855
Merge pull request #1339 from g-truc/rebase-1.0.2
Fixed master branch C.I.
2025-01-22 11:51:18 +01:00
christophe
af69cb1a6e Fix macOS C.I. 2025-01-22 10:20:01 +01:00
christophe
c11bff7853 Fix macOS latest 2025-01-22 09:54:31 +01:00
Christophe
6dddbfb066
Merge pull request #1322 from ivansouzamf/master
Add support for sse4.2 when using msvc
2025-01-22 09:37:15 +01:00
Payn
57738871cc msvc now supports sse4.2 2025-01-22 09:36:31 +01:00
christophe
fe26a526cd Fix macOS C.I. 2025-01-22 09:12:28 +01:00
christophe
242233ea20 Fix macOS C.I. test 2025-01-22 00:43:36 +01:00
christophe
97995f4713 Fix intrinsics test 2025-01-22 00:36:32 +01:00
Christophe
08a6421adb Fix macOS C.I. issue 2025-01-21 23:58:25 +01:00
Christophe
44c0039c7c Revert "Fix a wrong macro for tdualquat ctor"
This reverts commit 9b15c54c8c.
2025-01-21 19:05:55 +01:00
christophe
abcc96b4b9 Fix macOS C.I. 2025-01-21 18:50:33 +01:00
christophe
a036baa4d8 Fix MacOS C.I. 2025-01-21 17:42:41 +01:00
christophe
303a9d79ed Fix C.I. failure 2025-01-21 17:42:41 +01:00
Christophe
9e6f0ec1f6 Disable GTX test failing on Ubuntu latest GCC 13.3.0 2025-01-21 17:42:41 +01:00
Marcin Konowalczyk
c8132b31f7 Prepare 1.0.2 release
- Update noise link to newer version
2025-01-21 17:42:41 +01:00
Marcin Konowalczyk
7a878c2372 link to newer version 2025-01-16 15:58:34 +01:00
Marcin Konowalczyk
e7d5bdafa7 updated paper link too 2025-01-16 15:58:34 +01:00
Marcin Konowalczyk
f27f0e0026 Update noise.inl 2025-01-16 15:58:34 +01:00
Christophe
18feaec455
Merge pull request #1311 from alusch/neon-compile-error
Fix build error with GLM_FORCE_INTRINSICS and NEON #1311
2025-01-05 12:56:26 +01:00
Christophe
5221557360
Merge pull request #1315 from gdh1995/fix/dahan_macro_name
Fix a wrong macro for tdualquat ctor #1315
2025-01-04 09:44:32 +01:00
Christophe
f6341a1feb
Merge pull request #1317 from Zuzu-Typ/fix-matrix-clip-space
Fixed infinitePerspective declarations and definitions
2025-01-04 09:39:24 +01:00
Christophe
5b295d8a45
Merge pull request #1312 from qbojj/patch-1
fix levels() calculation for scalars #1312
2025-01-04 09:37:56 +01:00
Christophe
3c18b0f815
Merge pull request #1328 from helynranta/fix-missing-functions
Fix module interface missing some gtx quaternion functions
2024-12-25 12:32:24 +01:00
Christophe
86bdcc44e8
Merge pull request #1309 from ClemensX/master
typo in natvis name #1309
2024-12-25 12:28:18 +01:00
Christophe
7d3e3cdd62
Merge pull request #1330 from GeorgH93/fix_policy_warning
Specify CMake policy range to avoid deprecation warning
2024-12-25 12:26:55 +01:00
Christophe
37112e419c
Merge pull request #1318 from nlutsenko/patch-1
Remove Android-specific detection of GLM_HAS_CXX11_STL
2024-12-25 12:25:14 +01:00
GeorgH93
f7485100cb
Specify CMake policy range to avoid deprecation warning 2024-12-19 11:44:28 +01:00
Lassi Helynranta
3adb4236fe Fix module interface missing some gtx quaternion functions 2024-12-11 20:17:37 +02:00
Nikita Lutsenko
4006273cb3
Remove Android-specific detection of GLM_HAS_CXX11_STL
Android NDK starting from r18 has libcxx, and it's the only STL available. (reference: https://developer.android.com/ndk/guides/cpp-support#cs)

r18 is ~6 years old at this point.
This check dates to ~8 years ago (predating r18) and was important at that time.

Right now, it can be clearly stated that given the C++11 requirement stated in README for GLM, as well as (unless you are building with very outdated toolchain) - all modern Android is built with NDK toolchain that is newer than r18 - this check can be removed, and all the functionality can by default delegate to general detection for STL compatibility.
2024-10-29 16:53:18 -07:00
Zuzu-Typ
d03194c053 Fixed infinitePerspective declarations and definitions
+ infinitePerspectiveLH_ZO, RH_NO, etc. now have a declaration
+ infinitePerspectiveLH and RH now have a definition again.
2024-10-11 14:40:31 +02:00
gongdahan
9b15c54c8c Fix a wrong macro for tdualquat ctor 2024-10-08 11:09:42 +08:00
Janeczko Jakub
23551ae74e
fix levels() calculation for scalars 2024-09-09 02:27:13 +02:00
Adam Lusch
b30313ac30 Fix unused argument warning 2024-09-03 17:35:27 -05:00
Adam Lusch
437fe63665 Add missing template parameter 2024-09-03 17:35:11 -05:00
Adam Lusch
1926a11cac Test to reproduce build failure 2024-09-03 17:34:19 -05:00
Clemens Fehr
0d8637447c typo in natvis name 2024-08-10 09:36:26 +02:00
scribam
33b4a621a6 Update GitHub Actions 2024-06-07 18:08:04 +02:00
Forest Fox
45008b225e Fixed vec equality check function from the compute_vector_decl.hpp file 2024-04-21 20:20:02 +02:00
Tobias Markus
a2844eede8 Use [[deprecated]] when CXX standard is at least 14
Fixes #1269
2024-04-12 10:35:07 +02:00
Tom Kneiphof
0904870e37 Fix log2 func. qualifier 2024-04-08 14:50:51 +02:00
Laurent Caumont
4137519418 Simd improvement
- Add simd aligned_vec3 (and sse aligned_dvec3 - 2 x xmm)
- Fast packed_vec3 <=> aligned_vec3 and packed_vec4 <=> aligned_vec4 conversion
- Fast aligned_vec3 <=> aligned_vec4 conversion
- Optimized aligned_mat x aligned_mat and aligned_mat x aligned_vec
- Inverse aligned_mat3 simd version (actually slower than ssid on my computer even it has 30% less instruction ?)
2024-03-19 15:00:13 +01:00
Tom Kneiphof
ab913bbdd0 Add value_ptr method for vec1 types 2024-03-12 15:57:53 +01:00
Tom Kneiphof
c32a481dd4 Fix additional clang issues 2024-03-12 15:57:53 +01:00
Tom Kneiphof
05c93eeae0 Use value_ptr in packing.inl 2024-03-12 15:57:53 +01:00
Tom Kneiphof
0df8dcb454 Supporess unused-variable warnings 2024-03-12 15:57:53 +01:00
Tom Kneiphof
08a11905cf Fix sign-compare warnings 2024-03-12 15:57:53 +01:00
Tom Kneiphof
c48d16b911 Fix sequence-point warnings 2024-03-12 15:57:53 +01:00
Christophe
7a812397a2 Disable unit tests by default to avoid C.I. time out 2024-03-06 15:43:46 +01:00
Christophe
61caae4d05 Fix GTX_norm cyclic include 2024-03-06 10:58:47 +01:00
Aaron Brady
e009bcbe7c Update hash.hpp to detect msvc
this causes errors when building on windows with cl
2024-03-06 10:58:32 +01:00
Christophe
ab2d7b4291 Release: Light releases are 'normal' release packages 2024-03-05 18:41:36 +01:00
Noah Hitz
49942a611c Fixed typos 2024-03-05 00:21:20 +01:00
Dmitry Marakasov
dcc5cfdc4a Cast clock_t to match printf format specifier
This is needed since clock_t type is unspecified and may differ from unsigned int.
2024-03-05 00:20:29 +01:00
Christophe
f8df2f3e2e Trying to fix C.I. timeout... 2024-02-28 11:45:24 +01:00
Christophe
be3beb7788 Disable test that time out on C.I.? 2024-02-28 11:45:24 +01:00
Christophe
0892ccd214 Quicker tests for C.I. 2024-02-28 11:45:24 +01:00
Christophe
1f25000a30 Quicker unit tests 2024-02-28 11:45:24 +01:00
Christophe
b9424441b1 Add automatic release 2024-02-28 11:45:24 +01:00
Christophe
3ac3589ed2 Fix GTX_number_precision build #1258 2024-02-28 11:45:24 +01:00
86 changed files with 4461 additions and 1973 deletions

View file

@ -2,6 +2,9 @@ name: ci
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on:
pull_request:
branches:
- master
push:
workflow_dispatch:
@ -50,55 +53,55 @@ jobs:
- name: Run with automagic detection
run: |
cmake -S. -B ./build_auto -T ${{matrix.toolkit}}
cmake -S. -B ./build_auto -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON
cmake --build ./build_auto --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_auto
- name: Run with GLM_FORCE_PURE
run: |
cmake -S. -B ./build_pure_std -T ${{matrix.toolkit}} -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_pure_std -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_pure_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_std
- name: Run with GLM_FORCE_PURE and language extensions
run: |
cmake -S. -B ./build_pure_ext -T ${{matrix.toolkit}} -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_pure_ext -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_pure_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_ext
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -T ${{matrix.toolkit}} -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_sse2_std -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_sse2_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_std
- name: Run with GLM_ENABLE_SIMD_SSE2 and language extensions
run: |
cmake -S. -B ./build_sse2_ext -T ${{matrix.toolkit}} -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_sse2_ext -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_sse2_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_ext
- name: Run with GLM_ENABLE_SIMD_AVX
run: |
cmake -S. -B ./build_avx1_std -T ${{matrix.toolkit}} -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_avx1_std -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_avx1_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_std
- name: Run with GLM_ENABLE_SIMD_AVX and language extensions
run: |
cmake -S. -B ./build_avx1_ext -T ${{matrix.toolkit}} -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_avx1_ext -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx1_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_ext
- name: Run with GLM_ENABLE_SIMD_AVX2
run: |
cmake -S. -B ./build_avx2_std -T ${{matrix.toolkit}} -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_avx2_std -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_avx2_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx2_std
- name: Run with GLM_ENABLE_SIMD_AVX2 and language extensions
run: |
cmake -S. -B ./build_avx2_ext -T ${{matrix.toolkit}} -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_avx2_ext -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx2_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx2_ext
@ -113,6 +116,8 @@ jobs:
exclude:
- os: ubuntu-20.04
std: 20
- os: ubuntu-latest
std: 98
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
@ -130,65 +135,62 @@ jobs:
run: cmake --version
- name: Run with automagic detection
run: |
cmake -S. -B ./build_auto
cmake -S. -B ./build_auto -DGLM_BUILD_TESTS=ON
cmake --build ./build_auto --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_auto
- name: Run with GLM_FORCE_PURE
run: |
cmake -S. -B ./build_pure_std -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_pure_std -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_pure_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_std
- name: Run with GLM_FORCE_PURE and language extensions
run: |
cmake -S. -B ./build_pure_ext -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_pure_ext -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_pure_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_ext
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_sse2_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_sse2_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_std
- name: Run with GLM_ENABLE_SIMD_SSE2 and language extensions
run: |
cmake -S. -B ./build_sse2_ext -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_sse2_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_sse2_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_ext
- name: Run with GLM_ENABLE_SIMD_AVX
run: |
cmake -S. -B ./build_avx1_std -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_avx1_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_avx1_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_std
- name: Run with GLM_ENABLE_SIMD_AVX and language extensions
run: |
cmake -S. -B ./build_avx1_ext -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_avx1_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx1_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_ext
- name: Run with GLM_ENABLE_SIMD_AVX2
run: |
cmake -S. -B ./build_avx2_std -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_avx2_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_avx2_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx2_std
- name: Run with GLM_ENABLE_SIMD_AVX2 and language extensions
run: |
cmake -S. -B ./build_avx2_ext -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_avx2_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx2_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx2_ext
macos:
macos-13:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, macos-11]
os: [macos-13]
std: [98, 11, 14, 17, 20]
config: [Debug, Release]
exclude:
- os: macos-11
std: 20
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
@ -206,40 +208,92 @@ jobs:
run: cmake --version
- name: Run with automagic detection
run: |
cmake -S. -B ./build_auto
cmake -S. -B ./build_auto -DGLM_BUILD_TESTS=ON
cmake --build ./build_auto --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_auto
- name: Run with GLM_FORCE_PURE
run: |
cmake -S. -B ./build_pure_std -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_pure_std -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_pure_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_std
- name: Run with GLM_FORCE_PURE and language extensions
run: |
cmake -S. -B ./build_pure_ext -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_pure_ext -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_pure_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_ext
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_sse2_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_sse2_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_std
- name: Run with GLM_ENABLE_SIMD_SSE2 and language extensions
run: |
cmake -S. -B ./build_sse2_ext -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_sse2_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_SSE2=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_sse2_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_sse2_ext
- name: Run with GLM_ENABLE_SIMD_AVX
run: |
cmake -S. -B ./build_avx1_std -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake -S. -B ./build_avx1_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_avx1_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_std
- name: Run with GLM_ENABLE_SIMD_AVX and language extensions
run: |
cmake -S. -B ./build_avx1_ext -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake -S. -B ./build_avx1_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx1_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_ext
macos-latest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest]
std: [98, 11, 14, 17, 20]
config: [Debug, Release]
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: CMake Version
run: cmake --version
- name: Run with automagic detection
run: |
cmake -S. -B ./build_auto -DGLM_BUILD_TESTS=ON
cmake --build ./build_auto --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_auto
- name: Run with GLM_FORCE_PURE
run: |
cmake -S. -B ./build_pure_std -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_pure_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_std
- name: Run with GLM_FORCE_PURE and language extensions
run: |
cmake -S. -B ./build_pure_ext -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_pure_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_ext
- name: Run with GLM_ENABLE_SIMD_NEON
run: |
cmake -S. -B ./build_neon_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_NEON=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_neon_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_neon_std
- name: Run with GLM_ENABLE_SIMD_NEON and language extensions
run: |
cmake -S. -B ./build_neon_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_NEON=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_neon_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_neon_ext

View file

@ -15,28 +15,28 @@ jobs:
run: sudo apt-get update -y && sudo apt-get install -y zip p7zip
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Prepare layout
run: mv copying.txt glm
# - name: Prepare layout
# run: mv copying.txt glm
- name: Create zip archive
run: zip -r glm-${{ env.RELEASE_VERSION }}-light.zip glm
run: zip -r glm-${{ env.RELEASE_VERSION }}.zip .
- name: Create 7z archive
run: 7z a glm-${{ env.RELEASE_VERSION }}-light.7z glm
run: 7z a glm-${{ env.RELEASE_VERSION }}.7z .
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: glm-${{ env.RELEASE_VERSION }}-light
path: glm-${{ env.RELEASE_VERSION }}-light.*
name: glm-${{ env.RELEASE_VERSION }}
path: glm-${{ env.RELEASE_VERSION }}.*
- name: Add to Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
files: |
glm-${{ env.RELEASE_VERSION }}-light.zip
glm-${{ env.RELEASE_VERSION }}-light.7z
glm-${{ env.RELEASE_VERSION }}.zip
glm-${{ env.RELEASE_VERSION }}.7z

View file

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
cmake_policy(VERSION 3.6)
# 3.6 is the actual minimun. 3.14 as the upper policy limit avoids CMake deprecation warnings.
cmake_minimum_required(VERSION 3.6...3.14 FATAL_ERROR)
cmake_policy(VERSION 3.6...3.14)
file(READ "glm/detail/setup.hpp" GLM_SETUP_FILE)
string(REGEX MATCH "#define[ ]+GLM_VERSION_MAJOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
@ -21,7 +22,7 @@ if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
endif()
option(GLM_BUILD_LIBRARY "Build dynamic/static library" ON)
option(GLM_BUILD_TESTS "Build the test programs" ${GLM_IS_MASTER_PROJECT})
option(GLM_BUILD_TESTS "Build the test programs" OFF)
option(GLM_BUILD_INSTALL "Generate the install target" ${GLM_IS_MASTER_PROJECT})
include(GNUInstallDirs)
@ -149,6 +150,7 @@ option(GLM_ENABLE_SIMD_SSE4_1 "Enable SSE 4.1 optimizations" OFF)
option(GLM_ENABLE_SIMD_SSE4_2 "Enable SSE 4.2 optimizations" OFF)
option(GLM_ENABLE_SIMD_AVX "Enable AVX optimizations" OFF)
option(GLM_ENABLE_SIMD_AVX2 "Enable AVX2 optimizations" OFF)
option(GLM_ENABLE_SIMD_NEON "Enable ARM NEON optimizations" OFF)
option(GLM_FORCE_PURE "Force 'pure' instructions" OFF)
if(GLM_FORCE_PURE)
@ -191,7 +193,7 @@ elseif(GLM_ENABLE_SIMD_SSE4_2)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
add_compile_options(/QxSSE4.2)
elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
add_compile_options(/arch:SSE2) # VC doesn't support SSE4.2
add_compile_options(/arch:SSE4.2)
endif()
message(STATUS "GLM: SSE4.2 instruction set")
@ -242,6 +244,10 @@ elseif(GLM_ENABLE_SIMD_SSE2)
add_compile_options(/arch:SSE2)
endif()
message(STATUS "GLM: SSE2 instruction set")
elseif(GLM_ENABLE_SIMD_NEON)
add_definitions(-DGLM_FORCE_INTRINSICS)
message(STATUS "GLM: ARM NEON instruction set")
endif()
add_subdirectory(glm)

View file

@ -17,25 +17,30 @@ namespace detail
char _buffer[1];
};
template<int N, typename T, qualifier Q, int E0, int E1, int E2, int E3, bool Aligned>
template<int N, typename T, qualifier Q, int E0, int E1, int E2, int E3, bool UseSimd>
struct _swizzle_base1 : public _swizzle_base0<T, N>
{
};
template<typename T, qualifier Q, int E0, int E1, bool Aligned>
struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, Aligned> : public _swizzle_base0<T, 2>
template<int N, typename T, qualifier Q, int E0, int E1, int E2, int E3>
struct _swizzle_base1<N, T, Q, E0, E1, E2, E3, false> : public _swizzle_base0<T, N>
{
};
template<typename T, qualifier Q, int E0, int E1>
struct _swizzle_base1<2, T, Q, E0,E1,-1,-2, false> : public _swizzle_base0<T, 2>
{
GLM_FUNC_QUALIFIER vec<2, T, Q> operator ()() const { return vec<2, T, Q>(this->elem(E0), this->elem(E1)); }
};
template<typename T, qualifier Q, int E0, int E1, int E2, bool Aligned>
struct _swizzle_base1<3, T, Q, E0,E1,E2,-1, Aligned> : public _swizzle_base0<T, 3>
template<typename T, qualifier Q, int E0, int E1, int E2>
struct _swizzle_base1<3, T, Q, E0,E1,E2,3, false> : public _swizzle_base0<T, 3>
{
GLM_FUNC_QUALIFIER vec<3, T, Q> operator ()() const { return vec<3, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2)); }
};
template<typename T, qualifier Q, int E0, int E1, int E2, int E3, bool Aligned>
struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, Aligned> : public _swizzle_base0<T, 4>
template<typename T, qualifier Q, int E0, int E1, int E2, int E3>
struct _swizzle_base1<4, T, Q, E0,E1,E2,E3, false> : public _swizzle_base0<T, 4>
{
GLM_FUNC_QUALIFIER vec<4, T, Q> operator ()() const { return vec<4, T, Q>(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
};
@ -350,33 +355,33 @@ namespace glm
struct { detail::_swizzle<2,T, Q, 2,2,-1,-2> E2 ## E2; };
#define GLM_SWIZZLE3_3_MEMBERS(T, Q ,E0,E1,E2) \
struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; };
struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; };
#define GLM_SWIZZLE3_4_MEMBERS(T, Q, E0,E1,E2) \
struct { detail::_swizzle<4,T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
@ -480,70 +485,70 @@ namespace glm
struct { detail::_swizzle<2,T, Q, 3,3,-1,-2> E3 ## E3; };
#define GLM_SWIZZLE4_3_MEMBERS(T, Q, E0,E1,E2,E3) \
struct { detail::_swizzle<3, T, Q, 0,0,0,-1> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,0,1,-1> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,0,2,-1> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,0,3,-1> E0 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,1,0,-1> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,1,1,-1> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,1,2,-1> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,1,3,-1> E0 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,2,0,-1> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,2,1,-1> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,2,2,-1> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,2,3,-1> E0 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,3,0,-1> E0 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,3,1,-1> E0 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,3,2,-1> E0 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,3,3,-1> E0 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,0,0,-1> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,0,1,-1> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,0,2,-1> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,0,3,-1> E1 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,1,0,-1> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,1,1,-1> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,1,2,-1> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,1,3,-1> E1 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,2,0,-1> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,2,1,-1> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,2,2,-1> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,2,3,-1> E1 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,3,0,-1> E1 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,3,1,-1> E1 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,3,2,-1> E1 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,3,3,-1> E1 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,0,0,-1> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,0,1,-1> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,0,2,-1> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,0,3,-1> E2 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,1,0,-1> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,1,1,-1> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,1,2,-1> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,1,3,-1> E2 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,2,0,-1> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,2,1,-1> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,2,2,-1> E2 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,2,3,-1> E2 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,3,0,-1> E2 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,3,1,-1> E2 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,3,2,-1> E2 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,3,3,-1> E2 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,0,0,-1> E3 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,0,1,-1> E3 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,0,2,-1> E3 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,0,3,-1> E3 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,1,0,-1> E3 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,1,1,-1> E3 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,1,2,-1> E3 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,1,3,-1> E3 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,2,0,-1> E3 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,2,1,-1> E3 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,2,2,-1> E3 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,2,3,-1> E3 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,3,0,-1> E3 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,3,1,-1> E3 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,3,2,-1> E3 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,3,3,-1> E3 ## E3 ## E3; };
struct { detail::_swizzle<3, T, Q, 0,0,0,3> E0 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,0,1,3> E0 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,0,2,3> E0 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,0,3,3> E0 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,1,0,3> E0 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,1,1,3> E0 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,1,2,3> E0 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,1,3,3> E0 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,2,0,3> E0 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,2,1,3> E0 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,2,2,3> E0 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,2,3,3> E0 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 0,3,0,3> E0 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 0,3,1,3> E0 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 0,3,2,3> E0 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 0,3,3,3> E0 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,0,0,3> E1 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,0,1,3> E1 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,0,2,3> E1 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,0,3,3> E1 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,1,0,3> E1 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,1,1,3> E1 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,1,2,3> E1 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,1,3,3> E1 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,2,0,3> E1 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,2,1,3> E1 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,2,2,3> E1 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,2,3,3> E1 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 1,3,0,3> E1 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 1,3,1,3> E1 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 1,3,2,3> E1 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 1,3,3,3> E1 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,0,0,3> E2 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,0,1,3> E2 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,0,2,3> E2 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,0,3,3> E2 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,1,0,3> E2 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,1,1,3> E2 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,1,2,3> E2 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,1,3,3> E2 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,2,0,3> E2 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,2,1,3> E2 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,2,2,3> E2 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,2,3,3> E2 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 2,3,0,3> E2 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 2,3,1,3> E2 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 2,3,2,3> E2 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 2,3,3,3> E2 ## E3 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,0,0,3> E3 ## E0 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,0,1,3> E3 ## E0 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,0,2,3> E3 ## E0 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,0,3,3> E3 ## E0 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,1,0,3> E3 ## E1 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,1,1,3> E3 ## E1 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,1,2,3> E3 ## E1 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,1,3,3> E3 ## E1 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,2,0,3> E3 ## E2 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,2,1,3> E3 ## E2 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,2,2,3> E3 ## E2 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,2,3,3> E3 ## E2 ## E3; }; \
struct { detail::_swizzle<3, T, Q, 3,3,0,3> E3 ## E3 ## E0; }; \
struct { detail::_swizzle<3, T, Q, 3,3,1,3> E3 ## E3 ## E1; }; \
struct { detail::_swizzle<3, T, Q, 3,3,2,3> E3 ## E3 ## E2; }; \
struct { detail::_swizzle<3, T, Q, 3,3,3,3> E3 ## E3 ## E3; };
#define GLM_SWIZZLE4_4_MEMBERS(T, Q, E0,E1,E2,E3) \
struct { detail::_swizzle<4, T, Q, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \

View file

@ -52,6 +52,12 @@ namespace detail
{
return vec<1, T, Q>(Func(a.x, b.x));
}
template<typename Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, T, Q> const& b)
{
return vec<1, T, Q>(Func(a.x, b.x));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -61,6 +67,12 @@ namespace detail
{
return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y));
}
template<typename Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, T, Q> const& b)
{
return vec<2, T, Q>(Func(a.x, b.x), Func(a.y, b.y));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -70,6 +82,12 @@ namespace detail
{
return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, T, Q> const& b)
{
return vec<3, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -79,6 +97,12 @@ namespace detail
{
return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, length_t L, typename T, qualifier Q>
@ -91,6 +115,11 @@ namespace detail
{
return vec<1, T, Q>(Func(a.x, b));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, T, Q> call(Fct Func, vec<1, T, Q> const& a, T b)
{
return vec<1, T, Q>(Func(a.x, b));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -100,6 +129,12 @@ namespace detail
{
return vec<2, T, Q>(Func(a.x, b), Func(a.y, b));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, T, Q> call(Fct Func, vec<2, T, Q> const& a, T b)
{
return vec<2, T, Q>(Func(a.x, b), Func(a.y, b));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -109,6 +144,12 @@ namespace detail
{
return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, T, Q> call(Fct Func, vec<3, T, Q> const& a, T b)
{
return vec<3, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b));
}
};
template<template<length_t L, typename T, qualifier Q> class vec, typename T, qualifier Q>
@ -118,6 +159,11 @@ namespace detail
{
return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(Fct Func, vec<4, T, Q> const& a, T b)
{
return vec<4, T, Q>(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b));
}
};
template<length_t L, typename T, qualifier Q>
@ -130,6 +176,12 @@ namespace detail
{
return vec<1, int, Q>(Func(a.x, b.x));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<1, int, Q> call(Fct Func, vec<1, T, Q> const& a, vec<1, int, Q> const& b)
{
return vec<1, int, Q>(Func(a.x, b.x));
}
};
template<typename T, qualifier Q>
@ -139,6 +191,11 @@ namespace detail
{
return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<2, int, Q> call(Fct Func, vec<2, T, Q> const& a, vec<2, int, Q> const& b)
{
return vec<2, int, Q>(Func(a.x, b.x), Func(a.y, b.y));
}
};
template<typename T, qualifier Q>
@ -148,6 +205,11 @@ namespace detail
{
return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<3, int, Q> call(Fct Func, vec<3, T, Q> const& a, vec<3, int, Q> const& b)
{
return vec<3, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z));
}
};
template<typename T, qualifier Q>
@ -157,6 +219,12 @@ namespace detail
{
return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
}
template<class Fct>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, int, Q> call(Fct Func, vec<4, T, Q> const& a, vec<4, int, Q> const& b)
{
return vec<4, int, Q>(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w));
}
};
}//namespace detail
}//namespace glm

View file

@ -159,8 +159,8 @@ namespace glm {
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2)
{
bool b = true;
for (length_t i = 0; i < L; ++i)
b = b && detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1.x, v2.x);
for (length_t i = 0; b && i < L; ++i)
b = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1[i], v2[i]);
return b;
}
};

View file

@ -20,6 +20,11 @@ namespace glm
return (y < x) ? y : x;
}
template<typename T>
struct TMin {
T operator()(const T& a, const T& b) { return min(a, b); }
};
// max
template<typename genType>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType max(genType x, genType y)
@ -29,6 +34,11 @@ namespace glm
return (x < y) ? y : x;
}
template<typename T>
struct TMax {
T operator()(const T& a, const T& b) { return max(a, b); }
};
// abs
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR int abs(int x)
@ -37,6 +47,11 @@ namespace glm
return (x ^ y) - y;
}
template<typename T>
struct TAbs {
T operator()(const T& a) { return abs(a); }
};
// round
# if GLM_HAS_CXX11_STL
using ::std::round;
@ -50,6 +65,11 @@ namespace glm
}
# endif
template<typename T>
struct TRound {
T operator()(const T& a) { return round(a); }
};
// trunc
# if GLM_HAS_CXX11_STL
using ::std::trunc;
@ -63,6 +83,16 @@ namespace glm
}
# endif
template<typename T>
struct TTrunc {
T operator()(const T& a) { return trunc(a); }
};
template<typename T>
struct TFmod {
T operator()(const T& a, const T& b) { return std::fmod(a, b); }
};
}//namespace glm
namespace glm{
@ -80,7 +110,7 @@ namespace detail
template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
struct compute_mix_vector
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
@ -91,7 +121,7 @@ namespace detail
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_mix_vector<L, T, bool, Q, Aligned>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, bool, Q> const& a)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, bool, Q> const& a)
{
vec<L, T, Q> Result(0);
for(length_t i = 0; i < x.length(); ++i)
@ -103,7 +133,7 @@ namespace detail
template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
struct compute_mix_scalar
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U const& a)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U const& a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
@ -114,7 +144,7 @@ namespace detail
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_mix_scalar<L, T, bool, Q, Aligned>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, bool const& a)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, bool const& a)
{
return a ? y : x;
}
@ -123,7 +153,7 @@ namespace detail
template<typename T, typename U>
struct compute_mix
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, U const& a)
GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, U const& a)
{
GLM_STATIC_ASSERT(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
@ -134,7 +164,7 @@ namespace detail
template<typename T>
struct compute_mix<T, bool>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, bool const& a)
GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, bool const& a)
{
return a ? y : x;
}
@ -143,7 +173,7 @@ namespace detail
template<length_t L, typename T, qualifier Q, bool isFloat, bool Aligned>
struct compute_sign
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
{
return vec<L, T, Q>(glm::lessThan(vec<L, T, Q>(0), x)) - vec<L, T, Q>(glm::lessThan(x, vec<L, T, Q>(0)));
}
@ -153,7 +183,7 @@ namespace detail
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_sign<L, T, Q, false, Aligned>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x)
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
{
T const Shift(static_cast<T>(sizeof(T) * 8 - 1));
vec<L, T, Q> const y(vec<L, typename detail::make_unsigned<T>::type, Q>(-x) >> typename detail::make_unsigned<T>::type(Shift));
@ -218,12 +248,21 @@ namespace detail
}
};
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_fma
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
{
return a * b + c;
}
};
template<length_t L, typename T, qualifier Q, bool Aligned>
struct compute_min_vector
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
{
return detail::functor2<vec, L, T, Q>::call(min, x, y);
return detail::functor2<vec, L, T, Q>::call(TMin<T>(), x, y);
}
};
@ -232,7 +271,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
{
return detail::functor2<vec, L, T, Q>::call(max, x, y);
return detail::functor2<vec, L, T, Q>::call(TMax<T>(), x, y);
}
};
@ -264,6 +303,56 @@ namespace detail
return tmp * tmp * (static_cast<T>(3) - static_cast<T>(2) * tmp);
}
};
template<typename T, qualifier Q, bool Aligned>
struct convert_vec3_to_vec4W0
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
{
return vec<4, T, Q>(a.x, a.y, a.z, 0.0f);
}
};
template<typename T, qualifier Q, bool Aligned>
struct convert_vec3_to_vec4WZ
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
{
return vec<4, T, Q>(a.x, a.y, a.z, a.z);
}
};
template<typename T, qualifier Q, bool Aligned>
struct convert_vec3_to_vec4W1
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
{
return vec<4, T, Q>(a.x, a.y, a.z, 1.0f);
}
};
template<typename T, qualifier Q, bool Aligned>
struct convert_vec4_to_vec3
{
GLM_FUNC_QUALIFIER static vec<4, T, Q> call(vec<3, T, Q> const& a)
{
return vec<4, T, Q>(a.x, a.y, a.z, 0.0f);
}
};
template<length_t L, typename T, qualifier Q, bool Aligned>
struct convert_splat {
template<int c>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& a)
{
vec<L, T, Q> v(0.0f);
for (int i = 0; i < L; ++i)
v[i] = a[c];
return v;
}
};
}//namespace detail
template<typename genFIType>
@ -422,6 +511,61 @@ namespace detail
return detail::compute_mod<L, T, Q, detail::is_aligned<Q>::value>::call(x, y);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> fma(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
{
return detail::compute_fma<L, T, Q, detail::is_aligned<Q>::value>::call(a, b, c);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> xyz0(vec<3, T, Q> const& a)
{
return detail::convert_vec3_to_vec4W0<T, Q, detail::is_aligned<Q>::value>::call(a);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> xyz1(vec<3, T, Q> const& a)
{
return detail::convert_vec3_to_vec4W1<T, Q, detail::is_aligned<Q>::value>::call(a);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<4, T, Q> xyzz(vec<3, T, Q> const& a)
{
return detail::convert_vec3_to_vec4WZ<T, Q, detail::is_aligned<Q>::value>::call(a);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<3, T, Q> xyz(vec<4, T, Q> const& a)
{
return detail::convert_vec4_to_vec3<T, Q, detail::is_aligned<Q>::value>::call(a);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> splatX(vec<L, T, Q> const& a)
{
return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<0>(a);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> splatY(vec<L, T, Q> const& a)
{
return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<1>(a);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> splatZ(vec<L, T, Q> const& a)
{
return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<2>(a);
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER vec<L, T, Q> splatW(vec<L, T, Q> const& a)
{
return detail::convert_splat<L, T, Q, detail::is_aligned<Q>::value>::template call<3>(a);
}
// modf
template<typename genType>
GLM_FUNC_QUALIFIER genType modf(genType x, genType & i)

View file

@ -225,7 +225,391 @@ namespace detail
return Result;
}
};
template<qualifier Q>
struct compute_fma<4, float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b, vec<4, float, Q> const& c)
{
vec<4, float, Q> Result;
Result.data = glm_vec4_fma(a.data, b.data, c.data);
return Result;
}
};
template<qualifier Q>
struct compute_fma<3, float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b, vec<3, float, Q> const& c)
{
vec<3, float, Q> Result;
Result.data = glm_vec4_fma(a.data, b.data, c.data);
return Result;
}
};
template<qualifier Q>
struct compute_fma<4, double, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b, vec<4, double, Q> const& c)
{
vec<4, double, Q> Result;
# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG)
Result.data = _mm256_fmadd_pd(a.data, b.data, c.data);
# elif (GLM_ARCH & GLM_ARCH_AVX_BIT)
Result.data = _mm256_add_pd(_mm256_mul_pd(a.data, b.data), c.data);
# else
Result.data.setv(0, _mm_add_pd(_mm_mul_pd(a.data.getv(0), b.data.getv(0)), c.data.getv(0)));
Result.data.setv(1, _mm_add_pd(_mm_mul_pd(a.data.getv(1), b.data.getv(1)), c.data.getv(1)));
# endif
return Result;
}
};
// copy vec3 to vec4 and set w to 0
template<qualifier Q>
struct convert_vec3_to_vec4W0<float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
{
vec<4, float, Q> v;
#if (GLM_ARCH & GLM_ARCH_SSE41_BIT)
v.data = _mm_blend_ps(a.data, _mm_setzero_ps(), 8);
#else
__m128i mask = _mm_set_epi32(0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
__m128 v0 = _mm_castsi128_ps(_mm_and_si128(_mm_castps_si128(a.data), mask));
v.data = v0;
#endif
return v;
}
};
// copy vec3 to vec4 and set w to 1
template<qualifier Q>
struct convert_vec3_to_vec4W1<float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
{
vec<4, float, Q> v;
#if (GLM_ARCH & GLM_ARCH_SSE41_BIT)
v.data = _mm_blend_ps(a.data, _mm_set1_ps(1.0f), 8);
#else
__m128 t1 = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w
__m128 t2 = _mm_move_ss(t1, _mm_set_ss(1.0f)); // set x to 1.0f
v.data = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(0, 2, 1, 3)); //permute x, w
#endif
return v;
}
};
// copy vec3 to vec4 and set w to vec3.z
template<qualifier Q>
struct convert_vec3_to_vec4WZ<float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
{
vec<4, float, Q> v;
v.data = _mm_shuffle_ps(a.data, a.data, _MM_SHUFFLE(2, 2, 1, 0));
return v;
}
};
// copy vec3 to vec4 and set w to 0
template<qualifier Q>
struct convert_vec3_to_vec4W0<double, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
{
vec<4, double, Q> v;
#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
v.data = _mm256_blend_pd(a.data, _mm256_setzero_pd(), 8);
#else
v.data.setv(0, a.data.getv(0));
glm_dvec2 av2 = a.data.getv(1);
av2 = _mm_shuffle_pd(av2, _mm_setzero_pd(), 2);
v.data.setv(1, av2);
#endif
return v;
}
};
// copy vec3 to vec4 and set w to vec3.z
template<qualifier Q>
struct convert_vec3_to_vec4WZ<double, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
{
vec<4, double, Q> v;
#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
v.data = _mm256_permute_pd(a.data, 2);
#else
v.data.setv(0, a.data.getv(0));
glm_dvec2 av2 = a.data.getv(1);
__m128d t1 = _mm_shuffle_pd(av2, av2, 0);
v.data.setv(1, t1);
#endif
return v;
}
};
// copy vec3 to vec4 and set w to 1
template<qualifier Q>
struct convert_vec3_to_vec4W1<double, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, double, Q> call(vec<3, double, Q> const& a)
{
vec<4, double, Q> v;
#if (GLM_ARCH & GLM_ARCH_AVX_BIT)
v.data = _mm256_blend_pd(a.data, _mm256_set1_pd(1.0), 8);
#else
v.data.setv(0, a.data.getv(0));
glm_dvec2 av2 = a.data.getv(1);
av2 = _mm_shuffle_pd(av2, _mm_set1_pd(1.), 2);
v.data.setv(1, av2);
#endif
return v;
}
};
template<qualifier Q>
struct convert_vec4_to_vec3<float, Q, true> {
GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a)
{
vec<3, float, Q> v;
v.data = a.data;
return v;
}
};
template<qualifier Q>
struct convert_vec4_to_vec3<double, Q, true> {
GLM_FUNC_QUALIFIER static vec<3, double, Q> call(vec<4, double, Q> const& a)
{
vec<3, double, Q> v;
#if GLM_ARCH & GLM_ARCH_AVX_BIT
v.data = a.data;
#else
v.data.setv(0, a.data.getv(0));
v.data.setv(1, a.data.getv(1));
#endif
return v;
}
};
// set all coordinates to same value vec[c]
template<length_t L, qualifier Q>
struct convert_splat<L, float, Q, true> {
template<int c>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call(vec<L, float, Q> const& a)
{
vec<L, float, Q> Result;
const int s = _MM_SHUFFLE(c, c, c, c);
glm_f32vec4 va = static_cast<glm_f32vec4>(a.data);
# if GLM_ARCH & GLM_ARCH_AVX_BIT
Result.data = _mm_permute_ps(va, s);
# else
Result.data = _mm_shuffle_ps(va, va, s);
# endif
return Result;
}
};
// set all coordinates to same value vec[c]
template<length_t L, qualifier Q>
struct convert_splat<L, double, Q, true> {
template<bool, int c>
struct detailSSE
{};
template<int c>
struct detailSSE<true, c>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1);
Result.data.setv(0, r0);
Result.data.setv(1, r0);
return Result;
}
};
template<int c>
struct detailSSE<false, c>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
const unsigned int d = static_cast<unsigned int>(c - 2);
glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1);
Result.data.setv(0, r0);
Result.data.setv(1, r0);
return Result;
}
};
#if GLM_ARCH & GLM_ARCH_AVX_BIT
template<bool, int c> //note: bool is useless but needed to compil on linux (gcc)
struct detailAVX
{};
template<bool b>
struct detailAVX<b, 0>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
__m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0);
Result.data = _mm256_permute_pd(t1, 0);
return Result;
}
};
template<bool b>
struct detailAVX<b, 1>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
__m256d t1 = _mm256_permute2f128_pd(a.data, a.data, 0x0);
Result.data = _mm256_permute_pd(t1, 0xf);
return Result;
}
};
template<bool b>
struct detailAVX<b, 2>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
__m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11);
Result.data = _mm256_permute_pd(t2, 0x0);
return Result;
}
};
template<bool b>
struct detailAVX<b, 3>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
vec<L, double, Q> Result;
__m256d t2 = _mm256_permute2f128_pd(a.data, a.data, 0x11);
Result.data = _mm256_permute_pd(t2, 0xf);
return Result;
}
};
#endif //GLM_ARCH & GLM_ARCH_AVX_BIT
template<int c>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, double, Q> call(vec<L, double, Q> const& a)
{
//return compute_splat<L, double, Q, false>::call<c>(a);
vec<L, double, Q> Result;
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
Result.data = _mm256_permute4x64_pd(a.data, _MM_SHUFFLE(c, c, c, c));
# elif GLM_ARCH & GLM_ARCH_AVX_BIT
Result = detailAVX<true, c>::call(a);
# else
#if 1 //detail<(c <= 1), c>::call2(a) is equivalent to following code but without if constexpr usage
Result = detailSSE<(c <= 1), c>::call(a);
#else
if constexpr (c <= 1)
{
glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(0), a.data.getv(0), c | c << 1);
Result.data.setv(0, r0);
Result.data.setv(1, r0);
}
else
{
const unsigned int d = (unsigned int)(c - 2);
glm_f64vec2 r0 = _mm_shuffle_pd(a.data.getv(1), a.data.getv(1), d | d << 1);
Result.data.setv(0, r0);
Result.data.setv(1, r0);
}
#endif
# endif
return Result;
}
};
}//namespace detail
}//namespace glm
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
#if GLM_ARCH & GLM_ARCH_NEON_BIT
namespace glm {
namespace detail {
template<qualifier Q>
struct convert_vec3_to_vec4W0<float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<3, float, Q> const& a)
{
vec<4, float, Q> v;
static const uint32x4_t mask = { 0, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
v.data = vbslq_f32(mask, a.data, vdupq_n_f32(0));
return v;
}
};
template<qualifier Q>
struct convert_vec4_to_vec3<float, Q, true> {
GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<4, float, Q> const& a)
{
vec<3, float, Q> v;
v.data = a.data;
return v;
}
};
template<length_t L, qualifier Q>
struct compute_splat<L, float, Q, true> {
template<int c>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call(vec<L, float, Q> const& a)
{
(void)a;
}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call<0>(vec<L, float, Q> const& a)
{
vec<L, float, Q> Result;
Result.data = vdupq_lane_f32(vget_low_f32(a.data), 0);
return Result;
}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call<1>(vec<L, float, Q> const& a)
{
vec<L, float, Q> Result;
Result.data = vdupq_lane_f32(vget_low_f32(a.data), 1);
return Result;
}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call<2>(vec<L, float, Q> const& a)
{
vec<L, float, Q> Result;
Result.data = vdupq_lane_f32(vget_high_f32(a.data), 0);
return Result;
}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, float, Q> call<3>(vec<L, float, Q> const& a)
{
vec<L, float, Q> Result;
Result.data = vdupq_lane_f32(vget_high_f32(a.data), 1);
return Result;
}
};
}//namespace detail
}//namespace glm
#endif //GLM_ARCH & GLM_ARCH_NEON_BIT

View file

@ -14,7 +14,7 @@ namespace detail
using std::log2;
# else
template<typename genType>
genType log2(genType Value)
GLM_FUNC_QUALIFIER genType log2(genType Value)
{
return std::log(Value) * static_cast<genType>(1.4426950408889634073599246810019);
}

View file

@ -59,8 +59,13 @@ namespace detail
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> tmp(a * b);
return (tmp.x + tmp.y) + (tmp.z + tmp.w);
// VS 17.7.4 generates longer assembly (~20 instructions vs 11 instructions)
#if defined(_MSC_VER)
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
#else
vec<4, T, Q> tmp(a * b);
return (tmp.x + tmp.y) + (tmp.z + tmp.w);
#endif
}
};
@ -76,6 +81,17 @@ namespace detail
x.z * y.x - y.z * x.x,
x.x * y.y - y.x * x.y);
}
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& x, vec<4, T, Q> const& y)
{
GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'cross' accepts only floating-point inputs");
return vec<4, T, Q>(
x.y * y.z - y.y * x.z,
x.z * y.x - y.z * x.x,
x.x * y.y - y.x * x.y,
0.0f);
}
};
template<length_t L, typename T, qualifier Q, bool Aligned>

View file

@ -35,18 +35,36 @@ namespace detail
}
};
template<qualifier Q>
struct compute_dot<vec<3, float, Q>, float, true>
{
GLM_FUNC_QUALIFIER static float call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
{
vec<4, float, Q> aa = xyz0(a);
vec<4, float, Q> bb = xyz0(b);
return _mm_cvtss_f32(glm_vec1_dot(aa.data, bb.data));
}
};
template<qualifier Q>
struct compute_cross<float, Q, true>
{
GLM_FUNC_QUALIFIER static vec<3, float, Q> call(vec<3, float, Q> const& a, vec<3, float, Q> const& b)
{
__m128 const set0 = _mm_set_ps(0.0f, a.z, a.y, a.x);
__m128 const set1 = _mm_set_ps(0.0f, b.z, b.y, b.x);
__m128 const xpd0 = glm_vec4_cross(set0, set1);
vec<4, float, Q> aa = xyzz(a);
vec<4, float, Q> bb = xyzz(b);
__m128 const xpd0 = glm_vec4_cross(aa.data, bb.data);
vec<4, float, Q> Result;
vec<3, float, Q> Result;
Result.data = xpd0;
return vec<3, float, Q>(Result);
return Result;
}
GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = glm_vec4_cross(a.data, b.data);
return Result;
}
};

View file

@ -318,28 +318,69 @@ namespace detail
}
};
template<typename T, qualifier Q, bool is_aligned>
struct inv3x3 {};
template<typename T, qualifier Q>
struct inv3x3<T, Q, true>
{
GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
{
// see: https://www.onlinemathstutor.org/post/3x3_inverses
vec<4, T, Q> a = xyz0(m[0]);
vec<4, T, Q> b = xyz0(m[1]);
vec<4, T, Q> c = xyz0(m[2]);
vec<4, T, Q> i0 = compute_cross<T, Q, true>::call(b, c);
vec<4, T, Q> i1 = compute_cross<T, Q, true>::call(c, a);
vec<4, T, Q> i2 = compute_cross<T, Q, true>::call(a, b);
mat<3, 3, T, Q> Inverse;
Inverse[0] = xyz(i0);
Inverse[1] = xyz(i1);
Inverse[2] = xyz(i2);
Inverse = transpose(Inverse);
T Determinant = compute_dot<vec<4, T, Q>, T, true>::call(a, compute_cross<T, Q, true>::call(b, c));
vec<3, T, Q> OneOverDeterminant(static_cast<T>(1) / Determinant);
Inverse *= OneOverDeterminant;
return Inverse;
}
};
template<typename T, qualifier Q>
struct inv3x3<T, Q, false>
{
GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
{
T OneOverDeterminant = static_cast<T>(1) / (
+m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
- m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]));
mat<3, 3, T, Q> Inverse;
Inverse[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]);
Inverse[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);
Inverse[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]);
Inverse[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);
Inverse[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]);
Inverse[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);
Inverse[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]);
Inverse[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);
Inverse[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]);
Inverse *= OneOverDeterminant;
return Inverse;
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_inverse<3, 3, T, Q, Aligned>
{
GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m)
{
T OneOverDeterminant = static_cast<T>(1) / (
+ m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
- m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+ m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]));
mat<3, 3, T, Q> Inverse;
Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDeterminant;
Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDeterminant;
Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDeterminant;
Inverse[0][1] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDeterminant;
Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDeterminant;
Inverse[2][1] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDeterminant;
Inverse[0][2] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDeterminant;
Inverse[1][2] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDeterminant;
Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDeterminant;
return Inverse;
return detail::inv3x3<T, Q, detail::is_aligned<Q>::value>::call(m);
}
};

View file

@ -37,6 +37,17 @@ namespace detail
}
};
template<qualifier Q>
struct compute_transpose<3, 3, float, Q, true>
{
GLM_FUNC_QUALIFIER static mat<3, 3, float, Q> call(mat<3, 3, float, Q> const& m)
{
mat<3, 3, float, Q> Result;
glm_mat3_transpose(&m[0].data, &Result[0].data);
return Result;
}
};
template<qualifier Q>
struct compute_determinant<4, 4, float, Q, true>
{

View file

@ -126,6 +126,24 @@ namespace detail
typedef glm_u32vec4 type;
};
template<>
struct storage<3, float, true>
{
typedef glm_f32vec4 type;
};
template<>
struct storage<3, int, true>
{
typedef glm_i32vec4 type;
};
template<>
struct storage<3, unsigned int, true>
{
typedef glm_i32vec4 type;
};
template<>
struct storage<2, double, true>
{
@ -143,13 +161,38 @@ namespace detail
{
typedef glm_u64vec2 type;
};
# endif
# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
template<>
struct storage<3, detail::uint64, true>
{
typedef glm_u64vec2 type;
};
template<>
struct storage<4, double, true>
{
# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
typedef glm_f64vec4 type;
# else
struct type
{
glm_f64vec2 data[2];
GLM_CONSTEXPR glm_f64vec2 getv(int i) const {
return data[i];
}
GLM_CONSTEXPR void setv(int i, const glm_f64vec2& v) {
data[i] = v;
}
};
# endif
};
template<>
struct storage<3, double, true> : public storage<4, double, true>
{};
# endif
# if (GLM_ARCH & GLM_ARCH_AVX2_BIT)
@ -173,17 +216,40 @@ namespace detail
typedef glm_f32vec4 type;
};
template<>
struct storage<3, float, true> : public storage<4, float, true>
{};
template<>
struct storage<4, int, true>
{
typedef glm_i32vec4 type;
};
template<>
struct storage<3, int, true> : public storage<4, int, true>
{};
template<>
struct storage<4, unsigned int, true>
{
typedef glm_u32vec4 type;
};
template<>
struct storage<3, unsigned int, true> : public storage<4, unsigned int, true>
{};
# if GLM_HAS_ALIGNOF
template<>
struct storage<3, double, true>
{
typedef struct alignas(4 * sizeof(double)) type {
double data[4];
} type;
};
# endif//GLM_HAS_ALIGNOF
# endif
enum genTypeEnum

View file

@ -5,10 +5,9 @@
#define GLM_VERSION_MAJOR 1
#define GLM_VERSION_MINOR 0
#define GLM_VERSION_PATCH 0
#define GLM_VERSION_PATCH 2
#define GLM_VERSION_REVISION 0 // Deprecated
#define GLM_VERSION 1000 // Deprecated
#define GLM_VERSION_MESSAGE "GLM: version 1.0.0"
#define GLM_MAKE_API_VERSION(variant, major, minor, patch) \
((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch)))
@ -149,10 +148,7 @@
// http://gcc.gnu.org/projects/cxx0x.html
// http://msdn.microsoft.com/en-us/library/vstudio/hh567368(v=vs.120).aspx
// Android has multiple STLs but C++11 STL detection doesn't always work #284 #564
#if GLM_PLATFORM == GLM_PLATFORM_ANDROID && !defined(GLM_LANG_STL11_FORCED)
# define GLM_HAS_CXX11_STL 0
#elif (GLM_COMPILER & GLM_COMPILER_CUDA_RTC) == GLM_COMPILER_CUDA_RTC
#if (GLM_COMPILER & GLM_COMPILER_CUDA_RTC) == GLM_COMPILER_CUDA_RTC
# define GLM_HAS_CXX11_STL 0
#elif (GLM_COMPILER & GLM_COMPILER_HIP)
# define GLM_HAS_CXX11_STL 0
@ -507,7 +503,7 @@
# define GLM_DEFAULTED_FUNC_QUALIFIER GLM_FUNC_QUALIFIER
#endif//GLM_HAS_DEFAULTED_FUNCTIONS
#if !defined(GLM_FORCE_CTOR_INIT)
# define GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_CUDA_FUNC_DECL
# define GLM_DEFAULTED_DEFAULT_CTOR_DECL
# define GLM_DEFAULTED_DEFAULT_CTOR_QUALIFIER GLM_DEFAULTED_FUNC_QUALIFIER
#else
# define GLM_DEFAULTED_DEFAULT_CTOR_DECL GLM_FUNC_DISCARD_DECL
@ -595,7 +591,11 @@
# define GLM_DEPRECATED __declspec(deprecated)
# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef __declspec(align(alignment)) type name
#elif GLM_COMPILER & (GLM_COMPILER_GCC | GLM_COMPILER_CLANG | GLM_COMPILER_INTEL)
# define GLM_DEPRECATED __attribute__((__deprecated__))
# if GLM_LANG & GLM_LANG_CXX14_FLAG
# define GLM_DEPRECATED [[deprecated]]
# else
# define GLM_DEPRECATED __attribute__((__deprecated__))
# endif
# define GLM_ALIGNED_TYPEDEF(type, name, alignment) typedef type name __attribute__((aligned(alignment)))
#elif (GLM_COMPILER & GLM_COMPILER_CUDA) || (GLM_COMPILER & GLM_COMPILER_HIP)
# define GLM_DEPRECATED
@ -977,7 +977,7 @@ namespace detail
# define GLM_STR(x) GLM_STR_HELPER(x)
// Report GLM version
# pragma message (GLM_STR(GLM_VERSION_MESSAGE))
# pragma message ("GLM: version " GLM_STR(GLM_VERSION_MAJOR) "." GLM_STR(GLM_VERSION_MINOR) "." GLM_STR(GLM_VERSION_PATCH))
// Report C++ language
# if (GLM_LANG & GLM_LANG_CXX20_FLAG) && (GLM_LANG & GLM_LANG_EXT)

View file

@ -433,31 +433,16 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<2, 3, T, Q> const& m1, mat<3, 2, T, Q> const& m2)
{
T SrcA00 = m1[0][0];
T SrcA01 = m1[0][1];
T SrcA02 = m1[0][2];
T SrcA10 = m1[1][0];
T SrcA11 = m1[1][1];
T SrcA12 = m1[1][2];
T SrcB00 = m2[0][0];
T SrcB01 = m2[0][1];
T SrcB10 = m2[1][0];
T SrcB11 = m2[1][1];
T SrcB20 = m2[2][0];
T SrcB21 = m2[2][1];
mat<3, 3, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
return Result;
return mat<3, 3, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1]);
}
template<typename T, qualifier Q>

View file

@ -418,42 +418,23 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<2, 4, T, Q> const& m1, mat<4, 2, T, Q> const& m2)
{
T SrcA00 = m1[0][0];
T SrcA01 = m1[0][1];
T SrcA02 = m1[0][2];
T SrcA03 = m1[0][3];
T SrcA10 = m1[1][0];
T SrcA11 = m1[1][1];
T SrcA12 = m1[1][2];
T SrcA13 = m1[1][3];
T SrcB00 = m2[0][0];
T SrcB01 = m2[0][1];
T SrcB10 = m2[1][0];
T SrcB11 = m2[1][1];
T SrcB20 = m2[2][0];
T SrcB21 = m2[2][1];
T SrcB30 = m2[3][0];
T SrcB31 = m2[3][1];
mat<4, 4, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11;
Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21;
Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31;
Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31;
Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31;
Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31;
return Result;
return mat<4, 4, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1],
m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1],
m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1],
m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1],
m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1],
m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1],
m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1],
m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1],
m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1],
m1[0][3] * m2[3][0] + m1[1][3] * m2[3][1]);
}
template<typename T, qualifier Q>

View file

@ -450,26 +450,11 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<3, 2, T, Q> const& m1, mat<2, 3, T, Q> const& m2)
{
const T SrcA00 = m1[0][0];
const T SrcA01 = m1[0][1];
const T SrcA10 = m1[1][0];
const T SrcA11 = m1[1][1];
const T SrcA20 = m1[2][0];
const T SrcA21 = m1[2][1];
const T SrcB00 = m2[0][0];
const T SrcB01 = m2[0][1];
const T SrcB02 = m2[0][2];
const T SrcB10 = m2[1][0];
const T SrcB11 = m2[1][1];
const T SrcB12 = m2[1][2];
mat<2, 2, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
return Result;
return mat<2, 2, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2]);
}
template<typename T, qualifier Q>

View file

@ -1,4 +1,5 @@
#include "../matrix.hpp"
#include "../common.hpp"
namespace glm
{
@ -307,9 +308,10 @@ namespace glm
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> & mat<3, 3, T, Q>::operator*=(U s)
{
this->value[0] *= s;
this->value[1] *= s;
this->value[2] *= s;
col_type sv(s);
this->value[0] *= sv;
this->value[1] *= sv;
this->value[2] *= sv;
return *this;
}
@ -468,54 +470,82 @@ namespace glm
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::col_type operator*(mat<3, 3, T, Q> const& m, typename mat<3, 3, T, Q>::row_type const& v)
{
return typename mat<3, 3, T, Q>::col_type(
m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z);
m[0] * splatX(v) + m[1] * splatY(v) + m[2] * splatZ(v));
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, T, Q>::row_type operator*(typename mat<3, 3, T, Q>::col_type const& v, mat<3, 3, T, Q> const& m)
{
return typename mat<3, 3, T, Q>::row_type(
m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
dot(m[0], v),
dot(m[1], v),
dot(m[2], v));
}
namespace detail
{
template<typename T, qualifier Q, bool is_aligned>
struct mul3x3 {};
#if GLM_CONFIG_SIMD == GLM_ENABLE
template<typename T, qualifier Q>
struct mul3x3<T, Q, true>
{
GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
{
typename mat<4, 4, T, Q>::col_type const SrcA0 = xyzz(m1[0]);
typename mat<4, 4, T, Q>::col_type const SrcA1 = xyzz(m1[1]);
typename mat<4, 4, T, Q>::col_type const SrcA2 = xyzz(m1[2]);
typename mat<4, 4, T, Q>::col_type const SrcB0 = xyzz(m2[0]);
typename mat<4, 4, T, Q>::col_type const SrcB1 = xyzz(m2[1]);
typename mat<4, 4, T, Q>::col_type const SrcB2 = xyzz(m2[2]);
typename mat<3, 3, T, Q>::col_type const tmp0 = xyz(glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
typename mat<3, 3, T, Q>::col_type const tmp1 = xyz(glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
typename mat<3, 3, T, Q>::col_type const tmp2 = xyz(glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
return mat<3, 3, T, Q>(tmp0, tmp1, tmp2);
}
};
#endif
template<typename T, qualifier Q>
struct mul3x3<T, Q, false>
{
GLM_FUNC_QUALIFIER static mat<3, 3, T, Q> call(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
{
typename mat<3, 3, T, Q>::col_type const& SrcA0 = m1[0];
typename mat<3, 3, T, Q>::col_type const& SrcA1 = m1[1];
typename mat<3, 3, T, Q>::col_type const& SrcA2 = m1[2];
typename mat<3, 3, T, Q>::col_type const& SrcB0 = m2[0];
typename mat<3, 3, T, Q>::col_type const& SrcB1 = m2[1];
typename mat<3, 3, T, Q>::col_type const& SrcB2 = m2[2];
// note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order)
//Result[0] = SrcA2 * SrcB0.z + SrcA1 * SrcB0.y + SrcA0 * SrcB0.x;
//Result[1] = SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x;
//Result[2] = SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x;
typename mat<3, 3, T, Q>::col_type tmp0 = SrcA0 * SrcB0.x;
tmp0 += SrcA1 * SrcB0.y;
tmp0 += SrcA2 * SrcB0.z;
typename mat<3, 3, T, Q>::col_type tmp1 = SrcA0 * SrcB1.x;
tmp1 += SrcA1 * SrcB1.y;
tmp1 += SrcA2 * SrcB1.z;
typename mat<3, 3, T, Q>::col_type tmp2 = SrcA0 * SrcB2.x;
tmp2 += SrcA1 * SrcB2.y;
tmp2 += SrcA2 * SrcB2.z;
return mat<3, 3, T, Q>(tmp0, tmp1, tmp2);
}
};
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<3, 3, T, Q> const& m1, mat<3, 3, T, Q> const& m2)
{
T const SrcA00 = m1[0][0];
T const SrcA01 = m1[0][1];
T const SrcA02 = m1[0][2];
T const SrcA10 = m1[1][0];
T const SrcA11 = m1[1][1];
T const SrcA12 = m1[1][2];
T const SrcA20 = m1[2][0];
T const SrcA21 = m1[2][1];
T const SrcA22 = m1[2][2];
T const SrcB00 = m2[0][0];
T const SrcB01 = m2[0][1];
T const SrcB02 = m2[0][2];
T const SrcB10 = m2[1][0];
T const SrcB11 = m2[1][1];
T const SrcB12 = m2[1][2];
T const SrcB20 = m2[2][0];
T const SrcB21 = m2[2][1];
T const SrcB22 = m2[2][2];
mat<3, 3, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
return Result;
return detail::mul3x3<T, Q, detail::is_aligned<Q>::value>::call(m1, m2);
}
template<typename T, qualifier Q>

View file

@ -466,50 +466,23 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<3, 4, T, Q> const& m1, mat<4, 3, T, Q> const& m2)
{
const T SrcA00 = m1[0][0];
const T SrcA01 = m1[0][1];
const T SrcA02 = m1[0][2];
const T SrcA03 = m1[0][3];
const T SrcA10 = m1[1][0];
const T SrcA11 = m1[1][1];
const T SrcA12 = m1[1][2];
const T SrcA13 = m1[1][3];
const T SrcA20 = m1[2][0];
const T SrcA21 = m1[2][1];
const T SrcA22 = m1[2][2];
const T SrcA23 = m1[2][3];
const T SrcB00 = m2[0][0];
const T SrcB01 = m2[0][1];
const T SrcB02 = m2[0][2];
const T SrcB10 = m2[1][0];
const T SrcB11 = m2[1][1];
const T SrcB12 = m2[1][2];
const T SrcB20 = m2[2][0];
const T SrcB21 = m2[2][1];
const T SrcB22 = m2[2][2];
const T SrcB30 = m2[3][0];
const T SrcB31 = m2[3][1];
const T SrcB32 = m2[3][2];
mat<4, 4, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12;
Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22;
Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32;
Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32;
Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32;
Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32;
return Result;
return mat<4, 4, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2],
m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2],
m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2],
m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2],
m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2],
m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2],
m1[0][0] * m2[3][0] + m1[1][0] * m2[3][1] + m1[2][0] * m2[3][2],
m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2],
m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2],
m1[0][3] * m2[3][0] + m1[1][3] * m2[3][1] + m1[2][3] * m2[3][2]);
}
template<typename T, qualifier Q>

View file

@ -486,30 +486,11 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<2, 2, T, Q> operator*(mat<4, 2, T, Q> const& m1, mat<2, 4, T, Q> const& m2)
{
T const SrcA00 = m1[0][0];
T const SrcA01 = m1[0][1];
T const SrcA10 = m1[1][0];
T const SrcA11 = m1[1][1];
T const SrcA20 = m1[2][0];
T const SrcA21 = m1[2][1];
T const SrcA30 = m1[3][0];
T const SrcA31 = m1[3][1];
T const SrcB00 = m2[0][0];
T const SrcB01 = m2[0][1];
T const SrcB02 = m2[0][2];
T const SrcB03 = m2[0][3];
T const SrcB10 = m2[1][0];
T const SrcB11 = m2[1][1];
T const SrcB12 = m2[1][2];
T const SrcB13 = m2[1][3];
mat<2, 2, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
return Result;
return mat<2, 2, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3]);
}
template<typename T, qualifier Q>

View file

@ -505,43 +505,16 @@ namespace glm
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, T, Q> operator*(mat<4, 3, T, Q> const& m1, mat<3, 4, T, Q> const& m2)
{
T const SrcA00 = m1[0][0];
T const SrcA01 = m1[0][1];
T const SrcA02 = m1[0][2];
T const SrcA10 = m1[1][0];
T const SrcA11 = m1[1][1];
T const SrcA12 = m1[1][2];
T const SrcA20 = m1[2][0];
T const SrcA21 = m1[2][1];
T const SrcA22 = m1[2][2];
T const SrcA30 = m1[3][0];
T const SrcA31 = m1[3][1];
T const SrcA32 = m1[3][2];
T const SrcB00 = m2[0][0];
T const SrcB01 = m2[0][1];
T const SrcB02 = m2[0][2];
T const SrcB03 = m2[0][3];
T const SrcB10 = m2[1][0];
T const SrcB11 = m2[1][1];
T const SrcB12 = m2[1][2];
T const SrcB13 = m2[1][3];
T const SrcB20 = m2[2][0];
T const SrcB21 = m2[2][1];
T const SrcB22 = m2[2][2];
T const SrcB23 = m2[2][3];
mat<3, 3, T, Q> Result;
Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03;
Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13;
Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23;
Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23;
Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23;
return Result;
return mat<3, 3, T, Q>(
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3],
m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3],
m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3],
m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3]);
}
template<typename T, qualifier Q>

View file

@ -1,4 +1,5 @@
#include "../matrix.hpp"
#include "../geometric.hpp"
namespace glm
{
@ -588,10 +589,10 @@ namespace glm
)
{
return typename mat<4, 4, T, Q>::row_type(
m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3],
m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3],
m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3],
m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]);
glm::dot(m[0], v),
glm::dot(m[1], v),
glm::dot(m[2], v),
glm::dot(m[3], v));
}
template<typename T, qualifier Q>
@ -626,25 +627,83 @@ namespace glm
m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]);
}
namespace detail
{
template<typename T, qualifier Q, bool is_aligned>
struct mul4x4 {};
template<typename T, qualifier Q>
struct mul4x4<T, Q, true>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
{
typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0];
typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1];
typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2];
typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3];
typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0];
typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1];
typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2];
typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3];
typename mat<4, 4, T, Q>::col_type const tmp0 = glm::fma(SrcA3, splatW(SrcB0), glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
typename mat<4, 4, T, Q>::col_type const tmp1 = glm::fma(SrcA3, splatW(SrcB1), glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
typename mat<4, 4, T, Q>::col_type const tmp2 = glm::fma(SrcA3, splatW(SrcB2), glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
typename mat<4, 4, T, Q>::col_type const tmp3 = glm::fma(SrcA3, splatW(SrcB3), glm::fma(SrcA2, splatZ(SrcB3), glm::fma(SrcA1, splatY(SrcB3), SrcA0 * splatX(SrcB3))));
return mat < 4, 4, T, Q > (tmp0, tmp1, tmp2, tmp3);
}
};
template<typename T, qualifier Q>
struct mul4x4<T, Q, false>
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static mat<4, 4, T, Q> call(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
{
typename mat<4, 4, T, Q>::col_type const& SrcA0 = m1[0];
typename mat<4, 4, T, Q>::col_type const& SrcA1 = m1[1];
typename mat<4, 4, T, Q>::col_type const& SrcA2 = m1[2];
typename mat<4, 4, T, Q>::col_type const& SrcA3 = m1[3];
typename mat<4, 4, T, Q>::col_type const& SrcB0 = m2[0];
typename mat<4, 4, T, Q>::col_type const& SrcB1 = m2[1];
typename mat<4, 4, T, Q>::col_type const& SrcB2 = m2[2];
typename mat<4, 4, T, Q>::col_type const& SrcB3 = m2[3];
// note: the following lines are decomposed to have consistent results between simd and non simd code (prevent rounding error because of operation order)
//Result[0] = SrcA3 * SrcB0.w + SrcA2 * SrcB0.z + SrcA1 * SrcB0.y + SrcA0 * SrcB0.x;
//Result[1] = SrcA3 * SrcB1.w + SrcA2 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x;
//Result[2] = SrcA3 * SrcB2.w + SrcA2 * SrcB2.z + SrcA1 * SrcB2.y + SrcA0 * SrcB2.x;
//Result[3] = SrcA3 * SrcB3.w + SrcA2 * SrcB3.z + SrcA1 * SrcB3.y + SrcA0 * SrcB3.x;
typename mat<4, 4, T, Q>::col_type tmp0 = SrcA0 * SrcB0.x;
tmp0 += SrcA1 * SrcB0.y;
tmp0 += SrcA2 * SrcB0.z;
tmp0 += SrcA3 * SrcB0.w;
typename mat<4, 4, T, Q>::col_type tmp1 = SrcA0 * SrcB1.x;
tmp1 += SrcA1 * SrcB1.y;
tmp1 += SrcA2 * SrcB1.z;
tmp1 += SrcA3 * SrcB1.w;
typename mat<4, 4, T, Q>::col_type tmp2 = SrcA0 * SrcB2.x;
tmp2 += SrcA1 * SrcB2.y;
tmp2 += SrcA2 * SrcB2.z;
tmp2 += SrcA3 * SrcB2.w;
typename mat<4, 4, T, Q>::col_type tmp3 = SrcA0 * SrcB3.x;
tmp3 += SrcA1 * SrcB3.y;
tmp3 += SrcA2 * SrcB3.z;
tmp3 += SrcA3 * SrcB3.w;
return mat<4, 4, T, Q>(tmp0, tmp1, tmp2, tmp3);
}
};
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<4, 4, T, Q> operator*(mat<4, 4, T, Q> const& m1, mat<4, 4, T, Q> const& m2)
{
typename mat<4, 4, T, Q>::col_type const SrcA0 = m1[0];
typename mat<4, 4, T, Q>::col_type const SrcA1 = m1[1];
typename mat<4, 4, T, Q>::col_type const SrcA2 = m1[2];
typename mat<4, 4, T, Q>::col_type const SrcA3 = m1[3];
typename mat<4, 4, T, Q>::col_type const SrcB0 = m2[0];
typename mat<4, 4, T, Q>::col_type const SrcB1 = m2[1];
typename mat<4, 4, T, Q>::col_type const SrcB2 = m2[2];
typename mat<4, 4, T, Q>::col_type const SrcB3 = m2[3];
mat<4, 4, T, Q> Result;
Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3];
Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3];
Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3];
Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3];
return Result;
return detail::mul4x4<T, Q, detail::is_aligned<Q>::value>::call(m1, m2);
}
template<typename T, qualifier Q>

View file

@ -21,6 +21,10 @@ namespace glm
typedef T value_type;
typedef vec<2, T, Q> type;
typedef vec<2, bool, Q> bool_type;
enum is_aligned
{
value = false
};
// -- Data --

View file

@ -22,6 +22,11 @@ namespace glm
typedef vec<3, T, Q> type;
typedef vec<3, bool, Q> bool_type;
enum is_aligned
{
value = detail::is_aligned<Q>::value
};
// -- Data --
# if GLM_SILENT_WARNINGS == GLM_ENABLE
@ -253,6 +258,8 @@ namespace glm
GLM_FUNC_DISCARD_DECL GLM_CONSTEXPR vec<3, T, Q> & operator>>=(vec<3, U, Q> const& v);
};
// -- Unary operators --
template<typename T, qualifier Q>
@ -429,6 +436,10 @@ namespace glm
template<qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<3, bool, Q> operator||(vec<3, bool, Q> const& v1, vec<3, bool, Q> const& v2);
}//namespace glm
#ifndef GLM_EXTERNAL_TEMPLATE

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,11 @@ namespace glm
typedef T value_type;
typedef vec<4, T, Q> type;
typedef vec<4, bool, Q> bool_type;
enum is_aligned
{
value = detail::is_aligned<Q>::value
};
// -- Data --
@ -235,13 +240,13 @@ namespace glm
}
template<int E0, int E1, int E2>
GLM_FUNC_DISCARD_DECL vec(detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v, T const& w)
GLM_FUNC_DISCARD_DECL vec(detail::_swizzle<3, T, Q, E0, E1, E2, 3> const& v, T const& w)
{
*this = vec<4, T, Q>(v(), w);
}
template<int E0, int E1, int E2>
GLM_FUNC_DISCARD_DECL vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, -1> const& v)
GLM_FUNC_DISCARD_DECL vec(T const& x, detail::_swizzle<3, T, Q, E0, E1, E2, 3> const& v)
{
*this = vec<4, T, Q>(x, v());
}
@ -325,6 +330,7 @@ namespace glm
GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> & operator>>=(vec<4, U, Q> const& v);
};
// -- Unary operators --
template<typename T, qualifier Q>

View file

@ -1,130 +1,12 @@
/// @ref core
#include "compute_vector_relational.hpp"
#include "compute_vector_decl.hpp"
namespace glm{
namespace detail
{
template<typename T, qualifier Q, bool Aligned>
struct compute_vec4_add
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_vec4_sub
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_vec4_mul
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_vec4_div
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
}
};
template<typename T, qualifier Q, bool Aligned>
struct compute_vec4_mod
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x % b.x, a.y % b.y, a.z % b.z, a.w % b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_and
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x & b.x, a.y & b.y, a.z & b.z, a.w & b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_or
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x | b.x, a.y | b.y, a.z | b.z, a.w | b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_xor
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x ^ b.x, a.y ^ b.y, a.z ^ b.z, a.w ^ b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_shift_left
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x << b.x, a.y << b.y, a.z << b.z, a.w << b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_shift_right
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
return vec<4, T, Q>(a.x >> b.x, a.y >> b.y, a.z >> b.z, a.w >> b.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_equal
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2)
{
return
detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1.x, v2.x) &&
detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1.y, v2.y) &&
detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1.z, v2.z) &&
detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(v1.w, v2.w);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_nequal
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2)
{
return !compute_vec4_equal<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
}
};
template<typename T, qualifier Q, int IsInt, std::size_t Size, bool Aligned>
struct compute_vec4_bitwise_not
{
GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(vec<4, T, Q> const& v)
{
return vec<4, T, Q>(~v.x, ~v.y, ~v.z, ~v.w);
}
};
}//namespace detail
// -- Implicit basic constructors --
@ -158,7 +40,7 @@ namespace detail
: x(scalar), y(scalar), z(scalar), w(scalar)
{}
template <typename T, qualifier Q>
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q>::vec(T _x, T _y, T _z, T _w)
: x(_x), y(_y), z(_z), w(_w)
{}
@ -473,13 +355,14 @@ namespace detail
, w(static_cast<T>(v.w))
{}
// -- Component accesses --
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i)
{
GLM_ASSERT_LENGTH(i, this->length());
switch(i)
switch (i)
{
default:
case 0:
@ -497,7 +380,7 @@ namespace detail
GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& vec<4, T, Q>::operator[](typename vec<4, T, Q>::length_type i) const
{
GLM_ASSERT_LENGTH(i, this->length());
switch(i)
switch (i)
{
default:
case 0:
@ -540,84 +423,84 @@ namespace detail
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(U scalar)
{
return (*this = detail::compute_vec4_add<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_add<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator+=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_add<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_add<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(U scalar)
{
return (*this = detail::compute_vec4_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator-=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_sub<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(U scalar)
{
return (*this = detail::compute_vec4_mul<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_mul<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator*=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_mul<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_mul<4,T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(U scalar)
{
return (*this = detail::compute_vec4_div<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_div<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v.x)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator/=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_div<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_div<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
// -- Increment and decrement operators --
@ -664,126 +547,126 @@ namespace detail
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(U scalar)
{
return (*this = detail::compute_vec4_mod<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_mod<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_mod<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_mod<3, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<3, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator%=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_mod<T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_mod<4, T, Q, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(U scalar)
{
return (*this = detail::compute_vec4_and<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_and<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_and<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_and<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator&=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_and<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_and<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(U scalar)
{
return (*this = detail::compute_vec4_or<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_or<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_or<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_or<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator|=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_or<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_or<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(U scalar)
{
return (*this = detail::compute_vec4_xor<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_xor<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator^=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_xor<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_xor<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(U scalar)
{
return (*this = detail::compute_vec4_shift_left<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_shift_left<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator<<=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_shift_left<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_shift_left<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(U scalar)
{
return (*this = detail::compute_vec4_shift_right<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(scalar)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<1, U, Q> const& v)
{
return (*this = detail::compute_vec4_shift_right<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
template<typename T, qualifier Q>
template<typename U>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> & vec<4, T, Q>::operator>>=(vec<4, U, Q> const& v)
{
return (*this = detail::compute_vec4_shift_right<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
return (*this = detail::compute_vec_shift_right<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<4, T, Q>(v)));
}
// -- Unary constant operators --
@ -1107,7 +990,7 @@ namespace detail
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator~(vec<4, T, Q> const& v)
{
return detail::compute_vec4_bitwise_not<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v);
return detail::compute_vec_bitwise_not<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v);
}
// -- Boolean operators --
@ -1115,13 +998,13 @@ namespace detail
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator==(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2)
{
return detail::compute_vec4_equal<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
return detail::compute_vec_equal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool operator!=(vec<4, T, Q> const& v1, vec<4, T, Q> const& v2)
{
return detail::compute_vec4_nequal<T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
return detail::compute_vec_nequal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
}
template<qualifier Q>
@ -1138,5 +1021,110 @@ namespace detail
}//namespace glm
#if GLM_CONFIG_SIMD == GLM_ENABLE
# include "type_vec4_simd.inl"
# include "type_vec_simd.inl"
namespace glm {
#if GLM_ARCH & GLM_ARCH_NEON_BIT && !GLM_CONFIG_XYZW_ONLY
CTORSL(4, CTOR_FLOAT);
CTORSL(4, CTOR_INT);
CTORSL(4, CTOR_UINT);
CTORSL(4, CTOR_VECF_INT4);
CTORSL(4, CTOR_VECF_UINT4);
CTORSL(4, CTOR_VECF_VECF);
CTORSL(4, CTOR_VECF_VECI);
CTORSL(4, CTOR_VECF_VECU);
#endif// GLM_ARCH & GLM_ARCH_NEON_BIT
#if GLM_ARCH & GLM_ARCH_SSE2_BIT
CTORSL(4, CTOR_FLOAT);
CTORSL(4, CTOR_DOUBLE);
CTORSL(4, CTOR_FLOAT4);
CTORSL(4, CTOR_DOUBLE4);
CTORSL(4, CTOR_INT);
CTORSL(4, CTOR_INT4);
CTORSL(4, CTOR_VECF_INT4);
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& v):
data(v.data)
{
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, packed_highp>& v)
{
data = _mm_loadu_ps(reinterpret_cast<const float*>(&v));
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, packed_highp>::vec(const vec<4, float, aligned_highp>& v)
{
_mm_storeu_ps(reinterpret_cast<float*>(this), v.data);
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(const vec<4, int, aligned_highp>& v) :
data(v.data)
{
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(const vec<4, int, packed_highp>& v)
{
data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&v));
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, packed_highp>::vec(const vec<4, int, aligned_highp>& v)
{
_mm_storeu_si128(reinterpret_cast<__m128i*>(this), v.data);
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(const vec<4, double, aligned_highp>& v)
{
# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
data = v.data;
#else
data.setv(0, v.data.getv(0));
data.setv(1, v.data.getv(1));
#endif
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(const vec<4, double, packed_highp>& v)
{
# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
data = _mm256_loadu_pd(reinterpret_cast<const double*>(&v));
#else
data.setv(0, _mm_loadu_pd(reinterpret_cast<const double*>(&v)));
data.setv(1, _mm_loadu_pd(reinterpret_cast<const double*>(&v)+2));
#endif
}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, packed_highp>::vec(const vec<4, double, aligned_highp>& v)
{
# if (GLM_ARCH & GLM_ARCH_AVX_BIT)
_mm256_storeu_pd(reinterpret_cast<double*>(this), v.data);
#else
_mm_storeu_pd(reinterpret_cast<double*>(this), v.data.getv(0));
_mm_storeu_pd(reinterpret_cast<double*>(this) + 2, v.data.getv(1));
#endif
}
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
}
#endif

View file

@ -1,788 +0,0 @@
#if GLM_ARCH & GLM_ARCH_SSE2_BIT
namespace glm {
namespace detail
{
# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
template<qualifier Q, int E0, int E1, int E2, int E3>
struct _swizzle_base1<4, float, Q, E0, E1, E2, E3, true> : public _swizzle_base0<float, 4>
{
GLM_FUNC_QUALIFIER vec<4, float, Q> operator ()() const
{
__m128 data = *reinterpret_cast<__m128 const*>(&this->_buffer);
vec<4, float, Q> Result;
# if GLM_ARCH & GLM_ARCH_AVX_BIT
Result.data = _mm_permute_ps(data, _MM_SHUFFLE(E3, E2, E1, E0));
# else
Result.data = _mm_shuffle_ps(data, data, _MM_SHUFFLE(E3, E2, E1, E0));
# endif
return Result;
}
};
template<qualifier Q, int E0, int E1, int E2, int E3>
struct _swizzle_base1<4, int, Q, E0, E1, E2, E3, true> : public _swizzle_base0<int, 4>
{
GLM_FUNC_QUALIFIER vec<4, int, Q> operator ()() const
{
__m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
vec<4, int, Q> Result;
Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
return Result;
}
};
template<qualifier Q, int E0, int E1, int E2, int E3>
struct _swizzle_base1<4, uint, Q, E0, E1, E2, E3, true> : public _swizzle_base0<uint, 4>
{
GLM_FUNC_QUALIFIER vec<4, uint, Q> operator ()() const
{
__m128i data = *reinterpret_cast<__m128i const*>(&this->_buffer);
vec<4, uint, Q> Result;
Result.data = _mm_shuffle_epi32(data, _MM_SHUFFLE(E3, E2, E1, E0));
return Result;
}
};
# endif// GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
template<qualifier Q>
struct compute_vec4_add<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = _mm_add_ps(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_vec4_add<double, Q, true>
{
static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
{
vec<4, double, Q> Result;
Result.data = _mm256_add_pd(a.data, b.data);
return Result;
}
};
# endif
template<qualifier Q>
struct compute_vec4_sub<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = _mm_sub_ps(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_vec4_sub<double, Q, true>
{
static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
{
vec<4, double, Q> Result;
Result.data = _mm256_sub_pd(a.data, b.data);
return Result;
}
};
# endif
template<qualifier Q>
struct compute_vec4_mul<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = _mm_mul_ps(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_vec4_mul<double, Q, true>
{
static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
{
vec<4, double, Q> Result;
Result.data = _mm256_mul_pd(a.data, b.data);
return Result;
}
};
# endif
template<qualifier Q>
struct compute_vec4_div<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = _mm_div_ps(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<qualifier Q>
struct compute_vec4_div<double, Q, true>
{
static vec<4, double, Q> call(vec<4, double, Q> const& a, vec<4, double, Q> const& b)
{
vec<4, double, Q> Result;
Result.data = _mm256_div_pd(a.data, b.data);
return Result;
}
};
# endif
template<>
struct compute_vec4_div<float, aligned_lowp, true>
{
static vec<4, float, aligned_lowp> call(vec<4, float, aligned_lowp> const& a, vec<4, float, aligned_lowp> const& b)
{
vec<4, float, aligned_lowp> Result;
Result.data = _mm_mul_ps(a.data, _mm_rcp_ps(b.data));
return Result;
}
};
template<typename T, qualifier Q>
struct compute_vec4_and<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm_and_si128(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_and<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm256_and_si256(a.data, b.data);
return Result;
}
};
# endif
template<typename T, qualifier Q>
struct compute_vec4_or<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm_or_si128(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_or<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm256_or_si256(a.data, b.data);
return Result;
}
};
# endif
template<typename T, qualifier Q>
struct compute_vec4_xor<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm_xor_si128(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_xor<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm256_xor_si256(a.data, b.data);
return Result;
}
};
# endif
template<typename T, qualifier Q>
struct compute_vec4_shift_left<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm_sll_epi32(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_shift_left<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm256_sll_epi64(a.data, b.data);
return Result;
}
};
# endif
template<typename T, qualifier Q>
struct compute_vec4_shift_right<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm_srl_epi32(a.data, b.data);
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_shift_right<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& a, vec<4, T, Q> const& b)
{
vec<4, T, Q> Result;
Result.data = _mm256_srl_epi64(a.data, b.data);
return Result;
}
};
# endif
template<typename T, qualifier Q>
struct compute_vec4_bitwise_not<T, Q, true, 32, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& v)
{
vec<4, T, Q> Result;
Result.data = _mm_xor_si128(v.data, _mm_set1_epi32(-1));
return Result;
}
};
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<typename T, qualifier Q>
struct compute_vec4_bitwise_not<T, Q, true, 64, true>
{
static vec<4, T, Q> call(vec<4, T, Q> const& v)
{
vec<4, T, Q> Result;
Result.data = _mm256_xor_si256(v.data, _mm_set1_epi32(-1));
return Result;
}
};
# endif
template<qualifier Q>
struct compute_vec4_equal<float, Q, false, 32, true>
{
static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
{
return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) == 0;
}
};
# if GLM_ARCH & GLM_ARCH_SSE41_BIT
template<qualifier Q>
struct compute_vec4_equal<int, Q, true, 32, true>
{
static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
{
//return _mm_movemask_epi8(_mm_cmpeq_epi32(v1.data, v2.data)) != 0;
__m128i neq = _mm_xor_si128(v1.data, v2.data);
return _mm_test_all_zeros(neq, neq) == 0;
}
};
# endif
template<qualifier Q>
struct compute_vec4_nequal<float, Q, false, 32, true>
{
static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
{
return _mm_movemask_ps(_mm_cmpneq_ps(v1.data, v2.data)) != 0;
}
};
# if GLM_ARCH & GLM_ARCH_SSE41_BIT
template<qualifier Q>
struct compute_vec4_nequal<int, Q, true, 32, true>
{
static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
{
//return _mm_movemask_epi8(_mm_cmpneq_epi32(v1.data, v2.data)) != 0;
__m128i neq = _mm_xor_si128(v1.data, v2.data);
return _mm_test_all_zeros(neq, neq) != 0;
}
};
# endif
}//namespace detail
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) :
data(_mm_set1_ps(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) :
data(_mm_set1_ps(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) :
data(_mm_set1_ps(_s))
{}
# if GLM_ARCH & GLM_ARCH_AVX_BIT
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_lowp>::vec(double _s) :
data(_mm256_set1_pd(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_mediump>::vec(double _s) :
data(_mm256_set1_pd(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, double, aligned_highp>::vec(double _s) :
data(_mm256_set1_pd(_s))
{}
# endif
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) :
data(_mm_set1_epi32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) :
data(_mm_set1_epi32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) :
data(_mm_set1_epi32(_s))
{}
# if GLM_ARCH & GLM_ARCH_AVX2_BIT
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_lowp>::vec(detail::int64 _s) :
data(_mm256_set1_epi64x(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_mediump>::vec(detail::int64 _s) :
data(_mm256_set1_epi64x(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, detail::int64, aligned_highp>::vec(detail::int64 _s) :
data(_mm256_set1_epi64x(_s))
{}
# endif
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _x, float _y, float _z, float _w) :
data(_mm_set_ps(_w, _z, _y, _x))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _x, float _y, float _z, float _w) :
data(_mm_set_ps(_w, _z, _y, _x))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _x, float _y, float _z, float _w) :
data(_mm_set_ps(_w, _z, _y, _x))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
data(_mm_set_epi32(_w, _z, _y, _x))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
data(_mm_set_epi32(_w, _z, _y, _x))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
data(_mm_set_epi32(_w, _z, _y, _x))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
data(_mm_cvtepi32_ps(_mm_set_epi32(_w, _z, _y, _x)))
{}
}//namespace glm
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
#if GLM_ARCH & GLM_ARCH_NEON_BIT
namespace glm {
namespace detail {
template<qualifier Q>
struct compute_vec4_add<float, Q, true>
{
static
vec<4, float, Q>
call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = vaddq_f32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_add<uint, Q, true>
{
static
vec<4, uint, Q>
call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
{
vec<4, uint, Q> Result;
Result.data = vaddq_u32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_add<int, Q, true>
{
static
vec<4, int, Q>
call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
{
vec<4, int, Q> Result;
Result.data = vaddq_s32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_sub<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = vsubq_f32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_sub<uint, Q, true>
{
static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
{
vec<4, uint, Q> Result;
Result.data = vsubq_u32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_sub<int, Q, true>
{
static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
{
vec<4, int, Q> Result;
Result.data = vsubq_s32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_mul<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
Result.data = vmulq_f32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_mul<uint, Q, true>
{
static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
{
vec<4, uint, Q> Result;
Result.data = vmulq_u32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_mul<int, Q, true>
{
static vec<4, int, Q> call(vec<4, int, Q> const& a, vec<4, int, Q> const& b)
{
vec<4, int, Q> Result;
Result.data = vmulq_s32(a.data, b.data);
return Result;
}
};
template<qualifier Q>
struct compute_vec4_div<float, Q, true>
{
static vec<4, float, Q> call(vec<4, float, Q> const& a, vec<4, float, Q> const& b)
{
vec<4, float, Q> Result;
#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
Result.data = vdivq_f32(a.data, b.data);
#else
/* Arm assembler reference:
*
* The Newton-Raphson iteration: x[n+1] = x[n] * (2 - d * x[n])
* converges to (1/d) if x0 is the result of VRECPE applied to d.
*
* Note: The precision usually improves with two interactions, but more than two iterations are not helpful. */
float32x4_t x = vrecpeq_f32(b.data);
x = vmulq_f32(vrecpsq_f32(b.data, x), x);
x = vmulq_f32(vrecpsq_f32(b.data, x), x);
Result.data = vmulq_f32(a.data, x);
#endif
return Result;
}
};
template<qualifier Q>
struct compute_vec4_equal<float, Q, false, 32, true>
{
static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
{
uint32x4_t cmp = vceqq_f32(v1.data, v2.data);
#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
cmp = vpminq_u32(cmp, cmp);
cmp = vpminq_u32(cmp, cmp);
uint32_t r = cmp[0];
#else
uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp));
cmpx2 = vpmin_u32(cmpx2, cmpx2);
uint32_t r = cmpx2[0];
#endif
return r == ~0u;
}
};
template<qualifier Q>
struct compute_vec4_equal<uint, Q, false, 32, true>
{
static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
{
uint32x4_t cmp = vceqq_u32(v1.data, v2.data);
#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
cmp = vpminq_u32(cmp, cmp);
cmp = vpminq_u32(cmp, cmp);
uint32_t r = cmp[0];
#else
uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp));
cmpx2 = vpmin_u32(cmpx2, cmpx2);
uint32_t r = cmpx2[0];
#endif
return r == ~0u;
}
};
template<qualifier Q>
struct compute_vec4_equal<int, Q, false, 32, true>
{
static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
{
uint32x4_t cmp = vceqq_s32(v1.data, v2.data);
#if GLM_ARCH & GLM_ARCH_ARMV8_BIT
cmp = vpminq_u32(cmp, cmp);
cmp = vpminq_u32(cmp, cmp);
uint32_t r = cmp[0];
#else
uint32x2_t cmpx2 = vpmin_u32(vget_low_u32(cmp), vget_high_u32(cmp));
cmpx2 = vpmin_u32(cmpx2, cmpx2);
uint32_t r = cmpx2[0];
#endif
return r == ~0u;
}
};
template<qualifier Q>
struct compute_vec4_nequal<float, Q, false, 32, true>
{
static bool call(vec<4, float, Q> const& v1, vec<4, float, Q> const& v2)
{
return !compute_vec4_equal<float, Q, false, 32, true>::call(v1, v2);
}
};
template<qualifier Q>
struct compute_vec4_nequal<uint, Q, false, 32, true>
{
static bool call(vec<4, uint, Q> const& v1, vec<4, uint, Q> const& v2)
{
return !compute_vec4_equal<uint, Q, false, 32, true>::call(v1, v2);
}
};
template<qualifier Q>
struct compute_vec4_nequal<int, Q, false, 32, true>
{
static bool call(vec<4, int, Q> const& v1, vec<4, int, Q> const& v2)
{
return !compute_vec4_equal<int, Q, false, 32, true>::call(v1, v2);
}
};
}//namespace detail
#if !GLM_CONFIG_XYZW_ONLY
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(float _s) :
data(vdupq_n_f32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(float _s) :
data(vdupq_n_f32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(float _s) :
data(vdupq_n_f32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_lowp>::vec(int _s) :
data(vdupq_n_s32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_mediump>::vec(int _s) :
data(vdupq_n_s32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, int, aligned_highp>::vec(int _s) :
data(vdupq_n_s32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_lowp>::vec(uint _s) :
data(vdupq_n_u32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_mediump>::vec(uint _s) :
data(vdupq_n_u32(_s))
{}
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, uint, aligned_highp>::vec(uint _s) :
data(vdupq_n_u32(_s))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, float, aligned_highp>& rhs) :
data(rhs.data)
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, int, aligned_highp>& rhs) :
data(vcvtq_f32_s32(rhs.data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(const vec<4, uint, aligned_highp>& rhs) :
data(vcvtq_f32_u32(rhs.data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(int _x, int _y, int _z, int _w) :
data(vcvtq_f32_s32(vec<4, int, aligned_lowp>(_x, _y, _z, _w).data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(int _x, int _y, int _z, int _w) :
data(vcvtq_f32_s32(vec<4, int, aligned_mediump>(_x, _y, _z, _w).data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(int _x, int _y, int _z, int _w) :
data(vcvtq_f32_s32(vec<4, int, aligned_highp>(_x, _y, _z, _w).data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_lowp>::vec(uint _x, uint _y, uint _z, uint _w) :
data(vcvtq_f32_u32(vec<4, uint, aligned_lowp>(_x, _y, _z, _w).data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_mediump>::vec(uint _x, uint _y, uint _z, uint _w) :
data(vcvtq_f32_u32(vec<4, uint, aligned_mediump>(_x, _y, _z, _w).data))
{}
template<>
template<>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, float, aligned_highp>::vec(uint _x, uint _y, uint _z, uint _w) :
data(vcvtq_f32_u32(vec<4, uint, aligned_highp>(_x, _y, _z, _w).data))
{}
#endif
}//namespace glm
#endif

1032
glm/detail/type_vec_simd.inl Normal file

File diff suppressed because it is too large Load diff

View file

@ -234,6 +234,7 @@
#include "./gtx/norm.hpp"
#include "./gtx/normal.hpp"
#include "./gtx/normalize_dot.hpp"
#include "./gtx/number_precision.hpp"
#include "./gtx/optimum_pow.hpp"
#include "./gtx/orthonormalize.hpp"
#include "./gtx/pca.hpp"

View file

@ -461,6 +461,56 @@ namespace glm
T fov, T width, T height, T near, T far);
/// Creates a matrix for a left-handed, symmetric perspective-view frustum with far plane at infinite.
/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
///
/// @tparam T A floating-point scalar type
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH_ZO(
T fovy, T aspect, T near);
/// Creates a matrix for a left-handed, symmetric perspective-view frustum with far plane at infinite.
/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
///
/// @tparam T A floating-point scalar type
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveLH_NO(
T fovy, T aspect, T near);
/// Creates a matrix for a right-handed, symmetric perspective-view frustum with far plane at infinite.
/// The near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
///
/// @tparam T A floating-point scalar type
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH_ZO(
T fovy, T aspect, T near);
/// Creates a matrix for a right-handed, symmetric perspective-view frustum with far plane at infinite.
/// The near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
/// @param near Specifies the distance from the viewer to the near clipping plane (always positive).
///
/// @tparam T A floating-point scalar type
template<typename T>
GLM_FUNC_DECL mat<4, 4, T, defaultp> infinitePerspectiveRH_NO(
T fovy, T aspect, T near);
/// Creates a matrix for a left-handed, symmetric perspective-view frustum with far plane at infinite.
/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
@ -472,6 +522,8 @@ namespace glm
T fovy, T aspect, T near);
/// Creates a matrix for a right-handed, symmetric perspective-view frustum with far plane at infinite.
/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
@ -483,6 +535,8 @@ namespace glm
T fovy, T aspect, T near);
/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite with default handedness.
/// If GLM_FORCE_DEPTH_ZERO_TO_ONE is defined, the near and far clip planes correspond to z normalized device coordinates of 0 and +1 respectively. (Direct3D clip volume definition)
/// Otherwise, the near and far clip planes correspond to z normalized device coordinates of -1 and +1 respectively. (OpenGL clip volume definition)
///
/// @param fovy Specifies the field of view angle, in degrees, in the y direction. Expressed in radians.
/// @param aspect Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).

View file

@ -554,6 +554,26 @@ namespace glm
return Result;
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveRH(T fovy, T aspect, T zNear)
{
# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
return infinitePerspectiveRH_ZO(fovy, aspect, zNear);
# else
return infinitePerspectiveRH_NO(fovy, aspect, zNear);
# endif
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspectiveLH(T fovy, T aspect, T zNear)
{
# if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
return infinitePerspectiveLH_ZO(fovy, aspect, zNear);
# else
return infinitePerspectiveLH_NO(fovy, aspect, zNear);
# endif
}
template<typename T>
GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear)
{

View file

@ -10,7 +10,7 @@ namespace glm
{
return equal(x, y, vec<L, T, Q>(Epsilon));
}
template<length_t L, typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& Epsilon)
{

View file

@ -2634,6 +2634,9 @@ export namespace glm {
using glm::tanh;
using glm::third;
using glm::three_over_two_pi;
using glm::toMat3;
using glm::toMat4;
using glm::toQuat;
using glm::translate;
using glm::transpose;
using glm::triangleNormal;

View file

@ -231,7 +231,7 @@ namespace detail
{
GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'mask' accepts only integer values");
return Bits >= sizeof(genIUType) * 8 ? ~static_cast<genIUType>(0) : (static_cast<genIUType>(1) << Bits) - static_cast<genIUType>(1);
return Bits >= static_cast<genIUType>(sizeof(genIUType) * 8) ? ~static_cast<genIUType>(0) : (static_cast<genIUType>(1) << Bits) - static_cast<genIUType>(1);
}
#if GLM_COMPILER & GLM_COMPILER_CLANG

View file

@ -1,9 +1,9 @@
/// @ref gtc_noise
///
// Based on the work of Stefan Gustavson and Ashima Arts on "webgl-noise":
// https://github.com/ashima/webgl-noise
// https://github.com/stegu/webgl-noise
// Following Stefan Gustavson's paper "Simplex noise demystified":
// http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
// https://itn-web.it.liu.se/~stegu76/simplexnoise/simplexnoise.pdf
namespace glm{
namespace detail

View file

@ -7,6 +7,7 @@
#include "../vec3.hpp"
#include "../vec4.hpp"
#include "../detail/type_half.hpp"
#include "type_ptr.hpp"
#include <cstring>
#include <limits>
@ -295,14 +296,14 @@ namespace detail
{
int16 const Unpack(detail::toFloat16(v.x));
u16vec1 Packed;
memcpy(&Packed, &Unpack, sizeof(Packed));
memcpy(value_ptr(Packed), &Unpack, sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<1, float, Q> unpack(vec<1, uint16, Q> const& v)
{
i16vec1 Unpack;
memcpy(&Unpack, &v, sizeof(Unpack));
memcpy(value_ptr(Unpack), value_ptr(v), sizeof(Unpack));
return vec<1, float, Q>(detail::toFloat32(v.x));
}
};
@ -314,14 +315,14 @@ namespace detail
{
vec<2, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y));
u16vec2 Packed;
memcpy(&Packed, &Unpack, sizeof(Packed));
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<2, float, Q> unpack(vec<2, uint16, Q> const& v)
{
i16vec2 Unpack;
memcpy(&Unpack, &v, sizeof(Unpack));
memcpy(value_ptr(Unpack), value_ptr(v), sizeof(Unpack));
return vec<2, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y));
}
};
@ -333,14 +334,14 @@ namespace detail
{
vec<3, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z));
u16vec3 Packed;
memcpy(&Packed, &Unpack, sizeof(Packed));
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<3, float, Q> unpack(vec<3, uint16, Q> const& v)
{
i16vec3 Unpack;
memcpy(&Unpack, &v, sizeof(Unpack));
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec<3, float, Q>(detail::toFloat32(v.x), detail::toFloat32(v.y), detail::toFloat32(v.z));
}
};
@ -352,14 +353,14 @@ namespace detail
{
vec<4, int16, Q> const Unpack(detail::toFloat16(v.x), detail::toFloat16(v.y), detail::toFloat16(v.z), detail::toFloat16(v.w));
u16vec4 Packed;
memcpy(&Packed, &Unpack, sizeof(Packed));
memcpy(value_ptr(Packed), value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER static vec<4, float, Q> unpack(vec<4, uint16, Q> const& v)
{
i16vec4 Unpack;
memcpy(&Unpack, &v, sizeof(Unpack));
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec<4, float, Q>(detail::toFloat32(Unpack.x), detail::toFloat32(Unpack.y), detail::toFloat32(Unpack.z), detail::toFloat32(Unpack.w));
}
};
@ -388,7 +389,7 @@ namespace detail
GLM_FUNC_QUALIFIER vec2 unpackUnorm2x8(uint16 p)
{
u8vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return vec2(Unpack) * float(0.0039215686274509803921568627451); // 1 / 255
}
@ -413,14 +414,14 @@ namespace detail
{
i8vec2 const Topack(round(clamp(v, -1.0f, 1.0f) * 127.0f));
uint16 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
memcpy(&Packed, value_ptr(Topack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER vec2 unpackSnorm2x8(uint16 p)
{
i8vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return clamp(
vec2(Unpack) * 0.00787401574803149606299212598425f, // 1.0f / 127.0f
-1.0f, 1.0f);
@ -448,7 +449,7 @@ namespace detail
GLM_FUNC_QUALIFIER vec4 unpackUnorm4x16(uint64 p)
{
u16vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return vec4(Unpack) * 1.5259021896696421759365224689097e-5f; // 1.0 / 65535.0
}
@ -473,14 +474,14 @@ namespace detail
{
i16vec4 const Topack(round(clamp(v ,-1.0f, 1.0f) * 32767.0f));
uint64 Packed = 0;
memcpy(&Packed, &Topack, sizeof(Packed));
memcpy(&Packed, value_ptr(Topack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER vec4 unpackSnorm4x16(uint64 p)
{
i16vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return clamp(
vec4(Unpack) * 3.0518509475997192297128208258309e-5f, //1.0f / 32767.0f,
-1.0f, 1.0f);
@ -509,14 +510,14 @@ namespace detail
detail::toFloat16(v.z),
detail::toFloat16(v.w));
uint64 Packed = 0;
memcpy(&Packed, &Unpack, sizeof(Packed));
memcpy(&Packed, value_ptr(Unpack), sizeof(Packed));
return Packed;
}
GLM_FUNC_QUALIFIER glm::vec4 unpackHalf4x16(uint64 v)
{
i16vec4 Unpack;
memcpy(&Unpack, &v, sizeof(Unpack));
memcpy(value_ptr(Unpack), &v, sizeof(Unpack));
return vec4(
detail::toFloat32(Unpack.x),
detail::toFloat32(Unpack.y),
@ -818,7 +819,7 @@ namespace detail
GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p)
{
i8vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -832,7 +833,7 @@ namespace detail
GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p)
{
u8vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -846,7 +847,7 @@ namespace detail
GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p)
{
i8vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -860,7 +861,7 @@ namespace detail
GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p)
{
u8vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -874,7 +875,7 @@ namespace detail
GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p)
{
i16vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -888,7 +889,7 @@ namespace detail
GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p)
{
i16vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -902,7 +903,7 @@ namespace detail
GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p)
{
u16vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -916,7 +917,7 @@ namespace detail
GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p)
{
u16vec4 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -930,7 +931,7 @@ namespace detail
GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p)
{
i32vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
@ -944,7 +945,7 @@ namespace detail
GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p)
{
u32vec2 Unpack;
memcpy(&Unpack, &p, sizeof(Unpack));
memcpy(value_ptr(Unpack), &p, sizeof(Unpack));
return Unpack;
}
}//namespace glm

View file

@ -69,7 +69,7 @@ namespace detail
{
return
(vec<L, uint16, Q>(compute_rand<L, uint8, Q>::call()) << static_cast<uint16>(8)) |
(vec<L, uint16, Q>(compute_rand<L, uint8, Q>::call()) << static_cast<uint16>(0));
(vec<L, uint16, Q>(compute_rand<L, uint8, Q>::call()));
}
};
@ -80,7 +80,7 @@ namespace detail
{
return
(vec<L, uint32, Q>(compute_rand<L, uint16, Q>::call()) << static_cast<uint32>(16)) |
(vec<L, uint32, Q>(compute_rand<L, uint16, Q>::call()) << static_cast<uint32>(0));
(vec<L, uint32, Q>(compute_rand<L, uint16, Q>::call()));
}
};
@ -91,7 +91,7 @@ namespace detail
{
return
(vec<L, uint64, Q>(compute_rand<L, uint32, Q>::call()) << static_cast<uint64>(32)) |
(vec<L, uint64, Q>(compute_rand<L, uint32, Q>::call()) << static_cast<uint64>(0));
(vec<L, uint64, Q>(compute_rand<L, uint32, Q>::call()));
}
};

View file

@ -7,6 +7,18 @@ namespace glm
/// @addtogroup gtc_type_ptr
/// @{
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(vec<1, T, Q> const& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T* value_ptr(vec<1, T, Q>& v)
{
return &(v.x);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER T const* value_ptr(vec<2, T, Q> const& v)
{

View file

@ -12,7 +12,7 @@ namespace detail
{
GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& a, vec<L, T, Q> const& b)
{
return detail::functor2<vec, L, T, Q>::call(std::fmod, a, b);
return detail::functor2<vec, L, T, Q>::call(TFmod<T>(), a, b);
}
};

View file

@ -40,8 +40,18 @@
#include "../mat4x3.hpp"
#include "../mat4x4.hpp"
#if __cplusplus < 201103L
#pragma message("GLM_GTX_hash requires C++11 standard library support")
#if defined(_MSC_VER)
// MSVC uses _MSVC_LANG instead of __cplusplus
#if _MSVC_LANG < 201103L
#pragma message("GLM_GTX_hash requires C++11 standard library support")
#endif
#elif defined(__GNUC__) || defined(__clang__)
// GNU and Clang use __cplusplus
#if __cplusplus < 201103L
#pragma message("GLM_GTX_hash requires C++11 standard library support")
#endif
#else
#error "Unknown compiler"
#endif
#if GLM_LANG & GLM_LANG_CXX11

View file

@ -16,7 +16,6 @@
// Dependency:
#include "../geometric.hpp"
#include "../gtx/quaternion.hpp"
#include "../gtx/component_wise.hpp"
#ifndef GLM_ENABLE_EXPERIMENTAL

View file

@ -42,4 +42,3 @@ namespace glm{
/// @}
}//namespace glm
#include "number_precision.inl"

View file

@ -2,9 +2,8 @@
#ifndef GLM_HAS_CXX11_STL
#include <algorithm>
#else
#include <utility>
#endif
#include <utility>
namespace glm {

View file

@ -0,0 +1,92 @@
/// @ref gtx_structured_bindings
/// @file glm/gtx/structured_bindings.hpp
///
/// @defgroup gtx_structured_bindings GLM_GTX_structured_bindings
/// @ingroup gtx
///
/// Include <glm/gtx/structured_bindings.hpp> to use the features of this extension.
#pragma once
// Dependency:
#include "../glm.hpp"
#include "../gtx/quaternion.hpp"
#ifdef __cpp_structured_bindings
#if __cpp_structured_bindings >= 201606L
#include <utility>
#include <cstddef>
namespace std {
template<glm::length_t L,typename T,glm::qualifier Q>
struct tuple_size<glm::vec<L, T, Q>> {
static constexpr size_t value = L;
};
template<glm::length_t C,glm::length_t R, typename T, glm::qualifier Q>
struct tuple_size<glm::mat<C,R, T, Q>> {
static constexpr size_t value = C;
};
template<typename T, glm::qualifier Q>
struct tuple_size<glm::qua<T, Q>> {
static constexpr size_t value = 4;
};
template<std::size_t I,glm::length_t L,typename T,glm::qualifier Q>
struct tuple_element<I, glm::vec<L,T,Q>>
{
GLM_STATIC_ASSERT(I < L,"Index out of bounds");
typedef T type;
};
template<std::size_t I, glm::length_t C, glm::length_t R, typename T, glm::qualifier Q>
struct tuple_element<I, glm::mat<C,R, T, Q>>
{
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
typedef glm::vec<R,T,Q> type;
};
template<std::size_t I, typename T, glm::qualifier Q>
struct tuple_element<I, glm::qua<T, Q>>
{
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
typedef T type;
};
}
#endif
#endif
#ifndef GLM_ENABLE_EXPERIMENTAL
# error "GLM: GLM_GTX_iteration is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
#elif GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
# pragma message("GLM: GLM_GTX_io extension included")
#endif
namespace glm
{
/// @addtogroup gtx_structured_bindings
/// @{
template<length_t I, length_t L, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T& get(vec<L, T, Q>& v);
template<length_t I, length_t L, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T const& get(vec<L, T, Q> const& v);
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<R, T, Q>& get(mat<C, R, T, Q>& m);
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<R, T, Q> const& get(mat<C, R, T, Q> const& m);
template<length_t I, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T& get(qua<T, Q>& q);
template<length_t I, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T const& get(qua<T, Q> const& q);
#if GLM_HAS_RVALUE_REFERENCES
template<length_t I, length_t L,typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T get(vec<L,T, Q> const&& v);
template<length_t I,length_t C,length_t R, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR vec<R,T,Q> get(mat<C,R,T, Q> const&& m);
template<length_t I, typename T, qualifier Q>
GLM_FUNC_DECL GLM_CONSTEXPR T get(qua<T, Q> const&& q);
#endif
/// @}
}//namespace glm
#include "structured_bindings.inl"

View file

@ -0,0 +1,55 @@
namespace glm
{
template<length_t I, length_t L, typename T, qualifier Q>
GLM_CONSTEXPR T& get(vec<L, T, Q>& v) {
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
return v[I];
}
template<length_t I, length_t L, typename T, qualifier Q>
GLM_CONSTEXPR T const& get(vec<L, T, Q> const& v) {
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
return v[I];
}
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
GLM_CONSTEXPR vec<R, T, Q>& get(mat<C, R, T, Q>& m) {
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
return m[I];
}
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
GLM_CONSTEXPR vec<R, T, Q> const& get(mat<C, R, T, Q> const& m) {
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
return m[I];
}
template<length_t I, typename T, qualifier Q>
GLM_CONSTEXPR T& get(qua<T, Q>& q) {
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
return q[I];
}
template<length_t I, typename T, qualifier Q>
GLM_CONSTEXPR T const& get(qua<T, Q> const& q) {
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
return q[I];
}
#if GLM_HAS_RVALUE_REFERENCES
template<length_t I, length_t L, typename T, qualifier Q>
GLM_CONSTEXPR T get(vec<L, T, Q> const&& v)
{
GLM_STATIC_ASSERT(I < L, "Index out of bounds");
return v[I];
}
template<length_t I, length_t C, length_t R, typename T, qualifier Q>
GLM_CONSTEXPR vec<R, T, Q> get(mat<C, R, T, Q> const&& m) {
GLM_STATIC_ASSERT(I < C, "Index out of bounds");
return m[I];
}
template<length_t I, typename T, qualifier Q>
GLM_CONSTEXPR T get(qua<T, Q> const&& q) {
GLM_STATIC_ASSERT(I < 4, "Index out of bounds");
return q[I];
}
#endif
}//namespace glm

View file

@ -11,7 +11,7 @@ namespace glm
template <typename T>
inline T levels(T Extent)
{
return vec<1, T, defaultp>(Extent).x;
return levels(vec<1, T, defaultp>(Extent));
}
}//namespace glm

View file

@ -282,11 +282,6 @@ namespace glm {
return glm::vec<3, T, Q>(v.x, v.y, v.z);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER glm::vec<3, T, Q> xyz(const glm::vec<4, T, Q> &v) {
return glm::vec<3, T, Q>(v.x, v.y, v.z);
}
// xyw
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER glm::vec<3, T, Q> xyw(const glm::vec<4, T, Q> &v) {
@ -1040,16 +1035,6 @@ namespace glm {
return glm::vec<4, T, Q>(v.x, v.y, v.z, v.y);
}
// xyzz
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER glm::vec<4, T, Q> xyzz(const glm::vec<3, T, Q> &v) {
return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z);
}
template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER glm::vec<4, T, Q> xyzz(const glm::vec<4, T, Q> &v) {
return glm::vec<4, T, Q>(v.x, v.y, v.z, v.z);
}
// xyzw
template<typename T, qualifier Q>

View file

@ -63,7 +63,7 @@ GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_swizzle_xyzw(glm_f32vec4 a)
GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c)
{
# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG)
# ifdef GLM_FORCE_FMA
return _mm_fmadd_ss(a, b, c);
# else
return _mm_add_ss(_mm_mul_ss(a, b), c);
@ -72,7 +72,16 @@ GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec1_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f3
GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c)
{
# if (GLM_ARCH & GLM_ARCH_AVX2_BIT) && !(GLM_COMPILER & GLM_COMPILER_CLANG)
# ifdef GLM_FORCE_FMA
return _mm_fmadd_ps(a, b, c);
# else
return glm_vec4_add(glm_vec4_mul(a, b), c);
# endif
}
GLM_FUNC_QUALIFIER glm_f32vec4 glm_vec4d_fma(glm_f32vec4 a, glm_f32vec4 b, glm_f32vec4 c)
{
# ifdef GLM_FORCE_FMA
return _mm_fmadd_ps(a, b, c);
# else
return glm_vec4_add(glm_vec4_mul(a, b), c);

View file

@ -166,6 +166,18 @@ GLM_FUNC_QUALIFIER void glm_mat4_transpose(glm_vec4 const in[4], glm_vec4 out[4]
out[3] = _mm_shuffle_ps(tmp2, tmp3, 0xDD);
}
GLM_FUNC_QUALIFIER void glm_mat3_transpose(glm_vec4 const in[3], glm_vec4 out[3])
{
__m128 tmp0 = _mm_shuffle_ps(in[0], in[1], 0x44);
__m128 tmp2 = _mm_shuffle_ps(in[0], in[1], 0xEE);
__m128 tmp1 = _mm_shuffle_ps(in[2], in[2], 0x44);
__m128 tmp3 = _mm_shuffle_ps(in[2], in[2], 0xEE);
out[0] = _mm_shuffle_ps(tmp0, tmp1, 0x88);
out[1] = _mm_shuffle_ps(tmp0, tmp1, 0xDD);
out[2] = _mm_shuffle_ps(tmp2, tmp3, 0x88);
}
GLM_FUNC_QUALIFIER glm_vec4 glm_mat4_determinant_highp(glm_vec4 const in[4])
{
__m128 Fac0;

View file

@ -22,7 +22,7 @@ namespace glm {
case 3: return vdupq_n_f32(vgetq_lane_f32(vsrc, 3));
#endif
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
return vdupq_n_f32(0.0f);
}
@ -40,7 +40,7 @@ namespace glm {
case 3: return vdup_n_f32(vgetq_lane_f32(vsrc, 3));
#endif
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
return vdup_n_f32(0.0f);
}
@ -54,7 +54,8 @@ namespace glm {
case 2: return vcopyq_laneq_f32(vdst, 0, vsrc, 2);
case 3: return vcopyq_laneq_f32(vdst, 0, vsrc, 3);
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
break;
case 1:
switch(slane) {
case 0: return vcopyq_laneq_f32(vdst, 1, vsrc, 0);
@ -62,7 +63,8 @@ namespace glm {
case 2: return vcopyq_laneq_f32(vdst, 1, vsrc, 2);
case 3: return vcopyq_laneq_f32(vdst, 1, vsrc, 3);
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
break;
case 2:
switch(slane) {
case 0: return vcopyq_laneq_f32(vdst, 2, vsrc, 0);
@ -70,7 +72,8 @@ namespace glm {
case 2: return vcopyq_laneq_f32(vdst, 2, vsrc, 2);
case 3: return vcopyq_laneq_f32(vdst, 2, vsrc, 3);
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
break;
case 3:
switch(slane) {
case 0: return vcopyq_laneq_f32(vdst, 3, vsrc, 0);
@ -78,7 +81,8 @@ namespace glm {
case 2: return vcopyq_laneq_f32(vdst, 3, vsrc, 2);
case 3: return vcopyq_laneq_f32(vdst, 3, vsrc, 3);
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
break;
}
#else
@ -89,7 +93,7 @@ namespace glm {
case 2: l = vgetq_lane_f32(vsrc, 2); break;
case 3: l = vgetq_lane_f32(vsrc, 3); break;
default:
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
}
switch(dlane) {
case 0: return vsetq_lane_f32(l, vdst, 0);
@ -98,7 +102,7 @@ namespace glm {
case 3: return vsetq_lane_f32(l, vdst, 3);
}
#endif
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
return vdupq_n_f32(0.0f);
}
@ -110,9 +114,9 @@ namespace glm {
case 2: return vmulq_laneq_f32(v, vlane, 2); break;
case 3: return vmulq_laneq_f32(v, vlane, 3); break;
default:
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
return vdupq_n_f32(0.0f);
#else
return vmulq_f32(v, dupq_lane(vlane, lane));
@ -141,9 +145,9 @@ namespace glm {
FMADD_LANE(acc, v, vlane, 3);
return acc;
default:
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
}
assert(!"Unreachable code executed!");
assert(false); //Unreachable code executed!
return vdupq_n_f32(0.0f);
# undef FMADD_LANE
#else

View file

@ -515,7 +515,7 @@ static_assert(glm::vec4::length() == 4, "Using GLM C++ 14 constexpr support for
#define GLM_FORCE_SIMD_AVX2
#include <glm/glm.hpp>
// If the compiler doesnt support AVX2 instrinsics, compiler errors will happen.
// If the compiler doesnt support AVX2 intrinsics, compiler errors will happen.
```
Additionally, GLM provides a low level SIMD API in glm/simd directory for users who are really interested in writing fast algorithms.
@ -1943,7 +1943,7 @@ To workaround the incompatibility with these macros, GLM will systematically und
### <a name="section7_13"></a> 7.13. Constant expressions support
GLM has some C++ [constant expressions](http://en.cppreference.com/w/cpp/language/constexpr) support. However, GLM automatically detects the use of SIMD instruction sets through compiler arguments to populate its implementation with SIMD intrinsics.
Unfortunately, GCC and Clang doesn't support SIMD instrinsics as constant expressions. To allow constant expressions on all vectors and matrices types, define `GLM_FORCE_PURE` before including GLM headers.
Unfortunately, GCC and Clang don't support SIMD intrinsics as constant expressions. To allow constant expressions on all vectors and matrices types, define `GLM_FORCE_PURE` before including GLM headers.
---
<div style="page-break-after: always;"> </div>
@ -2133,7 +2133,7 @@ We need to download a copy of our fork to our local machine. In the terminal, ty
This will clone our fork repository into the current folder.
We can find our repository git url on the Github reposotory page. The url looks like this: `https://github.com/<our-username>/<repository-name>.git`
We can find our repository git url on the Github repository page. The url looks like this: `https://github.com/<our-username>/<repository-name>.git`
#### Step 2: Synchronizing our fork

View file

@ -41,7 +41,7 @@ glm::mat4 camera(float Translate, glm::vec2 const& Rotate)
}
```
## [Lastest release](https://github.com/g-truc/glm/releases/latest)
## [Latest release](https://github.com/g-truc/glm/releases/latest)
## Project Health
@ -70,7 +70,7 @@ find_package(glm CONFIG REQUIRED)
target_link_libraries(main PRIVATE glm::glm)
```
If your perfer to use header-only version of GLM
If your prefer to use header-only version of GLM
```cmake
find_package(glm CONFIG REQUIRED)
@ -95,7 +95,7 @@ include(FetchContent)
FetchContent_Declare(
glm
GIT_REPOSITORY https://github.com/g-truc/glm.git
GIT_TAG bf71a834948186f4097caa076cd2663c69a10e1e #refs/tags/0.9.9.8
GIT_TAG bf71a834948186f4097caa076cd2663c69a10e1e #refs/tags/1.0.1
)
FetchContent_MakeAvailable(glm)
@ -105,7 +105,12 @@ target_link_libraries(main PRIVATE glm::glm)
## Release notes
### [GLM 1.0.1](https://github.com/g-truc/glm) - 2024-02-XX
### [GLM 1.0.2](https://github.com/g-truc/glm/tree/master) - 2025-0X-XX
#### Improvements:
- Unit tests are not build by default, `GLM_BUILD_TESTS` set to `ON` required.
### [GLM 1.0.1](https://github.com/g-truc/glm/releases/tag/1.0.1) - 2024-02-26
#### Features:
- Added C++17 [[nodiscard]] support
@ -150,7 +155,7 @@ target_link_libraries(main PRIVATE glm::glm)
- Added *GLM_EXT_matrix_intX* and *GLM_EXT_matrix_uintX* extensions
#### Improvements:
- Added `glm::clamp`, `glm::repeat`, `glm::mirrorClamp` and `glm::mirrorRepeat` function to `GLM_EXT_scalar_commond` and `GLM_EXT_vector_commond` extensions with tests
- Added `glm::clamp`, `glm::repeat`, `glm::mirrorClamp` and `glm::mirrorRepeat` function to `GLM_EXT_scalar_common` and `GLM_EXT_vector_common` extensions with tests
#### Fixes:
- Fixed unnecessary warnings from `matrix_projection.inl` #995
@ -193,7 +198,7 @@ target_link_libraries(main PRIVATE glm::glm)
- Fixed `glm::ldexp` and `glm::frexp` declaration #895
- Fixed missing const to quaternion conversion operators #890
- Fixed *GLM_EXT_scalar_ulp* and *GLM_EXT_vector_ulp* API coding style
- Fixed quaternion componant order: `w, {x, y, z}` #916
- Fixed quaternion component order: `w, {x, y, z}` #916
- Fixed `GLM_HAS_CXX11_STL` broken on Clang with Linux #926
- Fixed *Clang* or *GCC* build due to wrong `GLM_HAS_IF_CONSTEXPR` definition #907
- Fixed *CUDA* 9 build #910
@ -262,8 +267,8 @@ target_link_libraries(main PRIVATE glm::glm)
- Redesigned constexpr support which excludes both SIMD and `constexpr` #783
- Added detection of *Visual C++ 2017* toolsets
- Added identity functions #765
- Splitted headers into EXT extensions to improve compilation time #670
- Added separated performance tests
- Split headers into EXT extensions to improve compilation time #670
- Added separate performance tests
- Clarified refract valid range of the indices of refraction, between -1 and 1 inclusively #806
#### Fixes:
@ -294,7 +299,7 @@ target_link_libraries(main PRIVATE glm::glm)
- Added *GLM_EXT_vector_relational*: `glm::openBounded` and `glm::closeBounded`
- Added *GLM_EXT_vec1*: `*vec1` types
- Added *GLM_GTX_texture*: `levels` function
- Added spearate functions to use both nagative one and zero near clip plans #680
- Added separate functions to use both negative one and zero near clip plans #680
- Added `GLM_FORCE_SINGLE_ONLY` to use *GLM* on platforms that don't support double #627
- Added *GLM_GTX_easing* for interpolation functions #761
@ -331,7 +336,7 @@ target_link_libraries(main PRIVATE glm::glm)
- Fixed `glm::axisAngle` NaN #638
- Fixed integer pow from *GLM_GTX_integer* with null exponent #658
- Fixed `quat` `normalize` build error #656
- Fixed *Visual C++ 2017.2* warning regarding `__has_feature` definision #655
- Fixed *Visual C++ 2017.2* warning regarding `__has_feature` definition #655
- Fixed documentation warnings
- Fixed `GLM_HAS_OPENMP` when *OpenMP* is not enabled
- Fixed Better follow GLSL `min` and `max` specification #372
@ -499,7 +504,7 @@ target_link_libraries(main PRIVATE glm::glm)
#### Fixes:
- Fixed asinh and atanh warning with C++98 STL #484
- Fixed polar coordinates function latitude #485
- Fixed outerProduct defintions and operator signatures for mat2x4 and vec4 #475
- Fixed outerProduct definitions and operator signatures for mat2x4 and vec4 #475
- Fixed eulerAngles precision error, returns NaN #451
- Fixed undefined reference errors #489
- Fixed missing GLM_PLATFORM_CYGWIN declaration #495
@ -670,8 +675,8 @@ target_link_libraries(main PRIVATE glm::glm)
- Optimized bitfieldReverse and bitCount functions
- Optimized findLSB and findMSB functions.
- Optimized matrix-vector multiple performance with Cuda #257, #258
- Reduced integer type redifinitions #233
- Rewrited of GTX_fast_trigonometry #264 #265
- Reduced integer type redefinitions #233
- Rewrote GTX_fast_trigonometry #264 #265
- Made types trivially copyable #263
- Removed <iostream> in GLM tests
- Used std features within GLM without redeclaring
@ -953,7 +958,7 @@ generation distribution
- Added GLM_GTX_constants: provides useful constants
- Added extension versioning
- Removed many unused namespaces
- Fixed half based type contructors
- Fixed half based type constructors
- Added GLSL core noise functions
---
@ -1190,7 +1195,7 @@ generation distribution
---
### GLM 0.7.6 final - 2008-08-08
- Improved C++ standard comformance
- Improved C++ standard conformance
- Added Static assert for types checking
---
@ -1251,7 +1256,7 @@ generation distribution
---
### GLM 0.5.0 - 2007-01-06
- Upgrated to GLSL 1.2
- Upgraded to GLSL 1.2
- Added swizzle operators
- Added setup settings

View file

@ -3,6 +3,17 @@ option(GLM_QUIET "No CMake Message" OFF)
option(GLM_TEST_ENABLE "Build unit tests" ON)
option(GLM_PERF_TEST_ENABLE "Build perf tests" OFF)
if(GLM_PERF_TEST_ENABLE)
add_definitions(-DGLM_TEST_PERF)
endif()
if (GLM_TEST_ENABLE_SIMD_FMA)
add_definitions(-DGLM_FORCE_FMA)
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
add_compile_options(-mfma)
endif()
endif()
# Compiler and default options
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@ -10,6 +21,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message("GLM: Clang - ${CMAKE_CXX_COMPILER_ID} compiler")
endif()
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if(NOT GLM_DISABLE_AUTO_DETECTION)
add_compile_options(-Werror -Weverything)
endif()

View file

@ -3,7 +3,7 @@
#if GLM_CONFIG_ANONYMOUS_STRUCT == GLM_ENABLE
struct vec2;
struct _swizzle
struct swizzleStruct
{
char _buffer[1];
};
@ -27,7 +27,7 @@ struct vec2
union
{
struct { float x, y; };
struct { _swizzle xx; };
struct { swizzleStruct xx; };
};
#if GLM_COMPILER & GLM_COMPILER_CLANG

View file

@ -6,6 +6,7 @@ glmCreateTestGTC(core_force_arch_unknown)
glmCreateTestGTC(core_force_compiler_unknown)
glmCreateTestGTC(core_force_explicit_ctor)
glmCreateTestGTC(core_force_inline)
glmCreateTestGTC(core_force_intrinsics)
glmCreateTestGTC(core_force_platform_unknown)
glmCreateTestGTC(core_force_pure)
glmCreateTestGTC(core_force_unrestricted_gentype)

View file

@ -0,0 +1,442 @@
#ifndef GLM_FORCE_INTRINSICS
# define GLM_FORCE_INTRINSICS
#endif//GLM_FORCE_INTRINSICS
#define GLM_FORCE_SWIZZLE
#include <glm/ext/scalar_constants.hpp>
#include <glm/ext/vector_relational.hpp>
#include <glm/vector_relational.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <ctime>
#include <vector>
static int test_vec4_ctor()
{
int Error = 0;
{
glm::ivec4 A(1, 2, 3, 4);
glm::ivec4 B(A);
Error += glm::all(glm::equal(A, B)) ? 0 : 1;
}
# if GLM_HAS_TRIVIAL_QUERIES
// Error += std::is_trivially_default_constructible<glm::vec4>::value ? 0 : 1;
// Error += std::is_trivially_copy_assignable<glm::vec4>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::vec4>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::dvec4>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::ivec4>::value ? 0 : 1;
Error += std::is_trivially_copyable<glm::uvec4>::value ? 0 : 1;
Error += std::is_copy_constructible<glm::vec4>::value ? 0 : 1;
# endif
#if GLM_HAS_INITIALIZER_LISTS
{
glm::vec4 a{ 0, 1, 2, 3 };
Error += glm::all(glm::equal(a, glm::vec4(0, 1, 2, 3), glm::epsilon<float>())) ? 0 : 1;
std::vector<glm::vec4> v = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 0, 1}};
Error += glm::all(glm::equal(v[0], glm::vec4(0, 1, 2, 3), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v[1], glm::vec4(4, 5, 6, 7), glm::epsilon<float>())) ? 0 : 1;
Error += glm::all(glm::equal(v[2], glm::vec4(8, 9, 0, 1), glm::epsilon<float>())) ? 0 : 1;
}
{
glm::dvec4 a{ 0, 1, 2, 3 };
Error += glm::all(glm::equal(a, glm::dvec4(0, 1, 2, 3), glm::epsilon<double>())) ? 0 : 1;
std::vector<glm::dvec4> v = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 0, 1}};
Error += glm::all(glm::equal(v[0], glm::dvec4(0, 1, 2, 3), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v[1], glm::dvec4(4, 5, 6, 7), glm::epsilon<double>())) ? 0 : 1;
Error += glm::all(glm::equal(v[2], glm::dvec4(8, 9, 0, 1), glm::epsilon<double>())) ? 0 : 1;
}
#endif
# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
{
glm::ivec4 A = glm::vec4(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = A.xyzw;
glm::ivec4 C(A.xyzw);
glm::ivec4 D(A.xyzw());
glm::ivec4 E(A.x, A.yzw);
glm::ivec4 F(A.x, A.yzw());
glm::ivec4 G(A.xyz, A.w);
glm::ivec4 H(A.xyz(), A.w);
glm::ivec4 I(A.xy, A.zw);
glm::ivec4 J(A.xy(), A.zw());
glm::ivec4 K(A.x, A.y, A.zw);
glm::ivec4 L(A.x, A.yz, A.w);
glm::ivec4 M(A.xy, A.z, A.w);
Error += glm::all(glm::equal(A, B)) ? 0 : 1;
Error += glm::all(glm::equal(A, C)) ? 0 : 1;
Error += glm::all(glm::equal(A, D)) ? 0 : 1;
Error += glm::all(glm::equal(A, E)) ? 0 : 1;
Error += glm::all(glm::equal(A, F)) ? 0 : 1;
Error += glm::all(glm::equal(A, G)) ? 0 : 1;
Error += glm::all(glm::equal(A, H)) ? 0 : 1;
Error += glm::all(glm::equal(A, I)) ? 0 : 1;
Error += glm::all(glm::equal(A, J)) ? 0 : 1;
Error += glm::all(glm::equal(A, K)) ? 0 : 1;
Error += glm::all(glm::equal(A, L)) ? 0 : 1;
Error += glm::all(glm::equal(A, M)) ? 0 : 1;
}
# endif
# if GLM_CONFIG_SWIZZLE
{
glm::ivec4 A = glm::vec4(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = A.xyzw();
glm::ivec4 C(A.xyzw());
glm::ivec4 D(A.xyzw());
glm::ivec4 E(A.x, A.yzw());
glm::ivec4 F(A.x, A.yzw());
glm::ivec4 G(A.xyz(), A.w);
glm::ivec4 H(A.xyz(), A.w);
glm::ivec4 I(A.xy(), A.zw());
glm::ivec4 J(A.xy(), A.zw());
glm::ivec4 K(A.x, A.y, A.zw());
glm::ivec4 L(A.x, A.yz(), A.w);
glm::ivec4 M(A.xy(), A.z, A.w);
Error += glm::all(glm::equal(A, B)) ? 0 : 1;
Error += glm::all(glm::equal(A, C)) ? 0 : 1;
Error += glm::all(glm::equal(A, D)) ? 0 : 1;
Error += glm::all(glm::equal(A, E)) ? 0 : 1;
Error += glm::all(glm::equal(A, F)) ? 0 : 1;
Error += glm::all(glm::equal(A, G)) ? 0 : 1;
Error += glm::all(glm::equal(A, H)) ? 0 : 1;
Error += glm::all(glm::equal(A, I)) ? 0 : 1;
Error += glm::all(glm::equal(A, J)) ? 0 : 1;
Error += glm::all(glm::equal(A, K)) ? 0 : 1;
Error += glm::all(glm::equal(A, L)) ? 0 : 1;
Error += glm::all(glm::equal(A, M)) ? 0 : 1;
}
# endif//GLM_CONFIG_SWIZZLE
{
glm::ivec4 A(1);
glm::ivec4 B(1, 1, 1, 1);
Error += A == B ? 0 : 1;
}
{
std::vector<glm::ivec4> Tests;
Tests.push_back(glm::ivec4(glm::ivec2(1, 2), 3, 4));
Tests.push_back(glm::ivec4(1, glm::ivec2(2, 3), 4));
Tests.push_back(glm::ivec4(1, 2, glm::ivec2(3, 4)));
Tests.push_back(glm::ivec4(glm::ivec3(1, 2, 3), 4));
Tests.push_back(glm::ivec4(1, glm::ivec3(2, 3, 4)));
Tests.push_back(glm::ivec4(glm::ivec2(1, 2), glm::ivec2(3, 4)));
Tests.push_back(glm::ivec4(1, 2, 3, 4));
Tests.push_back(glm::ivec4(glm::ivec4(1, 2, 3, 4)));
for(std::size_t i = 0; i < Tests.size(); ++i)
Error += Tests[i] == glm::ivec4(1, 2, 3, 4) ? 0 : 1;
}
return Error;
}
static int test_bvec4_ctor()
{
int Error = 0;
glm::bvec4 A(true);
glm::bvec4 B(true);
glm::bvec4 C(false);
glm::bvec4 D = A && B;
glm::bvec4 E = A && C;
glm::bvec4 F = A || C;
Error += (D == A) ? 0 : 1;
Error += (E == C) ? 0 : 1;
Error += (F == A) ? 0 : 1;
bool G = A == C;
bool H = A != C;
Error += !G ? 0 : 1;
Error += H ? 0 : 1;
return Error;
}
static int test_vec4_operators()
{
int Error = 0;
{
glm::ivec4 A(1);
glm::ivec4 B(1);
bool R = A != B;
bool S = A == B;
Error += (S && !R) ? 0 : 1;
}
{
glm::vec4 const A(1.0f, 2.0f, 3.0f, 4.0f);
glm::vec4 const B(4.0f, 5.0f, 6.0f, 7.0f);
glm::vec4 const C = A + B;
Error += glm::all(glm::equal(C, glm::vec4(5, 7, 9, 11), 0.001f)) ? 0 : 1;
glm::vec4 D = B - A;
Error += glm::all(glm::equal(D, glm::vec4(3, 3, 3, 3), 0.001f)) ? 0 : 1;
glm::vec4 E = A * B;
Error += glm::all(glm::equal(E, glm::vec4(4, 10, 18, 28), 0.001f)) ? 0 : 1;
glm::vec4 F = B / A;
Error += glm::all(glm::equal(F, glm::vec4(4, 2.5, 2, 7.0f / 4.0f), 0.001f)) ? 0 : 1;
glm::vec4 G = A + 1.0f;
Error += glm::all(glm::equal(G, glm::vec4(2, 3, 4, 5), 0.001f)) ? 0 : 1;
glm::vec4 H = B - 1.0f;
Error += glm::all(glm::equal(H, glm::vec4(3, 4, 5, 6), 0.001f)) ? 0 : 1;
glm::vec4 I = A * 2.0f;
Error += glm::all(glm::equal(I, glm::vec4(2, 4, 6, 8), 0.001f)) ? 0 : 1;
glm::vec4 J = B / 2.0f;
Error += glm::all(glm::equal(J, glm::vec4(2, 2.5, 3, 3.5), 0.001f)) ? 0 : 1;
glm::vec4 K = 1.0f + A;
Error += glm::all(glm::equal(K, glm::vec4(2, 3, 4, 5), 0.001f)) ? 0 : 1;
glm::vec4 L = 1.0f - B;
Error += glm::all(glm::equal(L, glm::vec4(-3, -4, -5, -6), 0.001f)) ? 0 : 1;
glm::vec4 M = 2.0f * A;
Error += glm::all(glm::equal(M, glm::vec4(2, 4, 6, 8), 0.001f)) ? 0 : 1;
glm::vec4 const N = 2.0f / B;
Error += glm::all(glm::equal(N, glm::vec4(0.5, 2.0 / 5.0, 2.0 / 6.0, 2.0 / 7.0), 0.0001f)) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B(4.0f, 5.0f, 6.0f, 7.0f);
A += B;
Error += A == glm::ivec4(5, 7, 9, 11) ? 0 : 1;
A += 1;
Error += A == glm::ivec4(6, 8, 10, 12) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B(4.0f, 5.0f, 6.0f, 7.0f);
B -= A;
Error += B == glm::ivec4(3, 3, 3, 3) ? 0 : 1;
B -= 1;
Error += B == glm::ivec4(2, 2, 2, 2) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B(4.0f, 5.0f, 6.0f, 7.0f);
A *= B;
Error += A == glm::ivec4(4, 10, 18, 28) ? 0 : 1;
A *= 2;
Error += A == glm::ivec4(8, 20, 36, 56) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B(4.0f, 4.0f, 6.0f, 8.0f);
B /= A;
Error += B == glm::ivec4(4, 2, 2, 2) ? 0 : 1;
B /= 2;
Error += B == glm::ivec4(2, 1, 1, 1) ? 0 : 1;
}
{
glm::ivec4 B(2);
B /= B.y;
Error += B == glm::ivec4(1) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = -A;
Error += B == glm::ivec4(-1.0f, -2.0f, -3.0f, -4.0f) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = --A;
Error += B == glm::ivec4(0.0f, 1.0f, 2.0f, 3.0f) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = A--;
Error += B == glm::ivec4(1.0f, 2.0f, 3.0f, 4.0f) ? 0 : 1;
Error += A == glm::ivec4(0.0f, 1.0f, 2.0f, 3.0f) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = ++A;
Error += B == glm::ivec4(2.0f, 3.0f, 4.0f, 5.0f) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 3.0f, 4.0f);
glm::ivec4 B = A++;
Error += B == glm::ivec4(1.0f, 2.0f, 3.0f, 4.0f) ? 0 : 1;
Error += A == glm::ivec4(2.0f, 3.0f, 4.0f, 5.0f) ? 0 : 1;
}
return Error;
}
static int test_vec4_equal()
{
int Error = 0;
{
glm::uvec4 A(1, 2, 3, 4);
Error += (A == glm::uvec4(1, 2, 3, 4)) ? 0 : 1;
Error += (A != glm::uvec4(1, 2, 3, 4)) ? 1 : 0;
}
{
glm::ivec4 A(1, 2, 3, 4);
Error += (A == glm::ivec4(1, 2, 3, 4)) ? 0 : 1;
Error += (A != glm::ivec4(1, 2, 3, 4)) ? 1 : 0;
}
return Error;
}
static int test_vec4_size()
{
int Error = 0;
Error += sizeof(glm::vec4) == sizeof(glm::lowp_vec4) ? 0 : 1;
Error += sizeof(glm::vec4) == sizeof(glm::mediump_vec4) ? 0 : 1;
Error += sizeof(glm::vec4) == sizeof(glm::highp_vec4) ? 0 : 1;
Error += 16 == sizeof(glm::mediump_vec4) ? 0 : 1;
Error += sizeof(glm::dvec4) == sizeof(glm::lowp_dvec4) ? 0 : 1;
Error += sizeof(glm::dvec4) == sizeof(glm::mediump_dvec4) ? 0 : 1;
Error += sizeof(glm::dvec4) == sizeof(glm::highp_dvec4) ? 0 : 1;
Error += 32 == sizeof(glm::highp_dvec4) ? 0 : 1;
Error += glm::vec4().length() == 4 ? 0 : 1;
Error += glm::dvec4().length() == 4 ? 0 : 1;
return Error;
}
static int test_vec4_swizzle_partial()
{
int Error = 0;
# if GLM_CONFIG_SWIZZLE == GLM_SWIZZLE_OPERATOR
glm::ivec4 A(1, 2, 3, 4);
{
glm::ivec4 B(A.xy, A.zw);
Error += A == B ? 0 : 1;
}
{
glm::ivec4 B(A.xy, 3, 4);
Error += A == B ? 0 : 1;
}
{
glm::ivec4 B(1, A.yz, 4);
Error += A == B ? 0 : 1;
}
{
glm::ivec4 B(1, 2, A.zw);
Error += A == B ? 0 : 1;
}
{
glm::ivec4 B(A.xyz, 4);
Error += A == B ? 0 : 1;
}
{
glm::ivec4 B(1, A.yzw);
Error += A == B ? 0 : 1;
}
# endif
return Error;
}
static int test_operator_increment()
{
int Error(0);
glm::ivec4 v0(1);
glm::ivec4 v1(v0);
glm::ivec4 v2(v0);
glm::ivec4 v3 = ++v1;
glm::ivec4 v4 = v2++;
Error += glm::all(glm::equal(v0, v4)) ? 0 : 1;
Error += glm::all(glm::equal(v1, v2)) ? 0 : 1;
Error += glm::all(glm::equal(v1, v3)) ? 0 : 1;
int i0(1);
int i1(i0);
int i2(i0);
int i3 = ++i1;
int i4 = i2++;
Error += i0 == i4 ? 0 : 1;
Error += i1 == i2 ? 0 : 1;
Error += i1 == i3 ? 0 : 1;
return Error;
}
static int test_vec4_simd()
{
int Error = 0;
glm::vec4 const a(std::clock(), std::clock(), std::clock(), std::clock());
glm::vec4 const b(std::clock(), std::clock(), std::clock(), std::clock());
glm::vec4 const c(b * a);
glm::vec4 const d(a + c);
Error += glm::all(glm::greaterThanEqual(d, glm::vec4(0))) ? 0 : 1;
return Error;
}
int main()
{
int Error = 0;
Error += test_vec4_ctor();
Error += test_bvec4_ctor();
Error += test_vec4_size();
Error += test_vec4_operators();
Error += test_vec4_equal();
Error += test_vec4_swizzle_partial();
Error += test_vec4_simd();
Error += test_operator_increment();
return Error;
}

View file

@ -1,7 +1,7 @@
#ifndef GLM_FORCE_PURE
# define GLM_FORCE_PURE
#endif//GLM_FORCE_PURE
#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
//#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
#define GLM_FORCE_SWIZZLE
#include <glm/ext/scalar_constants.hpp>
#include <glm/ext/vector_relational.hpp>

View file

@ -176,7 +176,7 @@ static int pop9(unsigned x)
return static_cast<int>(y);
}
int errors;
static int errors;
static void error(int x, int y)
{
errors = errors + 1;
@ -208,7 +208,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop0(test[i]) != test[i+1]) error(test[i], pop0(test[i]));}
if (pop0(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop0(test[i]));}
TimestampEnd = std::clock();
std::printf("pop0: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -216,7 +216,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop1(test[i]) != test[i+1]) error(test[i], pop1(test[i]));}
if (pop1(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop1(test[i]));}
TimestampEnd = std::clock();
std::printf("pop1: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -224,7 +224,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop2(test[i]) != test[i+1]) error(test[i], pop2(test[i]));}
if (pop2(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop2(test[i]));}
TimestampEnd = std::clock();
std::printf("pop2: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -232,7 +232,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop3(test[i]) != test[i+1]) error(test[i], pop3(test[i]));}
if (pop3(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop3(test[i]));}
TimestampEnd = std::clock();
std::printf("pop3: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -240,7 +240,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop4(test[i]) != test[i+1]) error(test[i], pop4(test[i]));}
if (pop4(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop4(test[i]));}
TimestampEnd = std::clock();
std::printf("pop4: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -248,7 +248,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop5(test[i]) != test[i+1]) error(test[i], pop5(test[i]));}
if (pop5(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop5(test[i]));}
TimestampEnd = std::clock();
std::printf("pop5: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -256,7 +256,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop5a(test[i]) != test[i+1]) error(test[i], pop5a(test[i]));}
if (pop5a(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop5a(test[i]));}
TimestampEnd = std::clock();
std::printf("pop5a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -264,7 +264,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (pop6(test[i]) != test[i+1]) error(test[i], pop6(test[i]));}
if (pop6(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop6(test[i]));}
TimestampEnd = std::clock();
std::printf("pop6: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -273,7 +273,7 @@ int main()
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if ((test[i] & 0xffffff00) == 0)
if (pop7(test[i]) != test[i+1]) error(test[i], pop7(test[i]));}
if (pop7(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop7(test[i]));}
TimestampEnd = std::clock();
std::printf("pop7: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -282,7 +282,7 @@ int main()
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if ((test[i] & 0xffffff80) == 0)
if (pop8(test[i]) != test[i+1]) error(test[i], pop8(test[i]));}
if (pop8(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop8(test[i]));}
TimestampEnd = std::clock();
std::printf("pop8: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -291,7 +291,7 @@ int main()
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if ((test[i] & 0xffff8000) == 0)
if (pop9(test[i]) != test[i+1]) error(test[i], pop9(test[i]));}
if (pop9(test[i]) != static_cast<int>(test[i+1])) error(test[i], pop9(test[i]));}
TimestampEnd = std::clock();
std::printf("pop9: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));

View file

@ -45,7 +45,7 @@ static int ntz3(unsigned x)
if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;}
if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;}
if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;}
return n - (x & 1);
return n - static_cast<int>(x & 1);
}
static int ntz4(unsigned x)
@ -74,7 +74,7 @@ static int ntz4a(unsigned x)
y = x << 8; if (y != 0) {n = n - 8; x = y;}
y = x << 4; if (y != 0) {n = n - 4; x = y;}
y = x << 2; if (y != 0) {n = n - 2; x = y;}
n = n - ((x << 1) >> 31);
n = n - static_cast<int>((x << 1) >> 31);
return n;
}
@ -145,7 +145,8 @@ could then all run in parallel). */
static int ntz7(unsigned x)
{
unsigned y, bz, b4, b3, b2, b1, b0;
unsigned y;
int bz, b4, b3, b2, b1, b0;
y = x & -x; // Isolate rightmost 1-bit.
bz = y ? 0 : 1; // 1 if y = 0.
@ -279,8 +280,8 @@ static int ntz11(unsigned int n) {
# pragma warning(pop)
#endif
int errors;
static void error(int x, int y) {
static int errors;
static void error(unsigned x, int y) {
errors = errors + 1;
std::printf("Error for x = %08x, got %d\n", x, y);
}
@ -312,7 +313,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz1(test[i]) != test[i+1]) error(test[i], ntz1(test[i]));}
if (ntz1(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz1(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz1: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -320,7 +321,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz2(test[i]) != test[i+1]) error(test[i], ntz2(test[i]));}
if (ntz2(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz2(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz2: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -328,7 +329,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz3(test[i]) != test[i+1]) error(test[i], ntz3(test[i]));}
if (ntz3(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz3(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz3: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -336,7 +337,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz4(test[i]) != test[i+1]) error(test[i], ntz4(test[i]));}
if (ntz4(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz4(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz4: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -344,7 +345,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz4a(test[i]) != test[i+1]) error(test[i], ntz4a(test[i]));}
if (ntz4a(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz4a(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz4a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -353,7 +354,7 @@ int main()
for(std::size_t k = 0; k < Count; ++k)
for(i = 0; i < n; i += 2)
{
m = test[i+1];
m = static_cast<int>(test[i+1]);
if(m > 8)
m = 8;
if(ntz5(static_cast<char>(test[i])) != m)
@ -366,7 +367,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz6(test[i]) != test[i+1]) error(test[i], ntz6(test[i]));}
if (ntz6(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz6(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz6: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -374,7 +375,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz6a(test[i]) != test[i+1]) error(test[i], ntz6a(test[i]));}
if (ntz6a(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz6a(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz6a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -382,7 +383,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz7(test[i]) != test[i+1]) error(test[i], ntz7(test[i]));}
if (ntz7(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz7(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz7: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -390,7 +391,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz7_christophe(test[i]) != test[i+1]) error(test[i], ntz7(test[i]));}
if (ntz7_christophe(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz7(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz7_christophe: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -398,7 +399,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz8(test[i]) != test[i+1]) error(test[i], ntz8(test[i]));}
if (ntz8(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz8(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz8: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -406,7 +407,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz8a(test[i]) != test[i+1]) error(test[i], ntz8a(test[i]));}
if (ntz8a(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz8a(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz8a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -414,7 +415,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz9(test[i]) != test[i+1]) error(test[i], ntz9(test[i]));}
if (ntz9(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz9(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz9: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -422,7 +423,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz10(test[i]) != test[i+1]) error(test[i], ntz10(test[i]));}
if (ntz10(test[i]) != static_cast<int>(test[i+1])) error(test[i], ntz10(test[i]));}
TimestampEnd = std::clock();
std::printf("ntz10: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -430,7 +431,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (ntz11(test[i]) != test[i + 1]) error(test[i], ntz11(test[i]));
if (ntz11(test[i]) != static_cast<int>(test[i + 1])) error(test[i], ntz11(test[i]));
}
TimestampEnd = std::clock();

View file

@ -39,7 +39,7 @@ static int nlz1a(unsigned x) {
if ((x >> 24) == 0) {n = n + 8; x = x << 8;}
if ((x >> 28) == 0) {n = n + 4; x = x << 4;}
if ((x >> 30) == 0) {n = n + 2; x = x << 2;}
n = n - (x >> 31);
n = n - static_cast<int>(x >> 31);
return n;
}
// On basic Risc, 12 to 20 instructions.
@ -54,7 +54,7 @@ static int nlz2(unsigned x) {
y = x >> 4; if (y != 0) {n = n - 4; x = y;}
y = x >> 2; if (y != 0) {n = n - 2; x = y;}
y = x >> 1; if (y != 0) return n - 2;
return n - x;
return n - static_cast<int>(x);
}
// As above but coded as a loop for compactness:
@ -69,15 +69,15 @@ static int nlz2a(unsigned x) {
y = x >> c; if (y != 0) {n = n - c; x = y;}
c = c >> 1;
} while (c != 0);
return n - x;
return n - static_cast<int>(x);
}
static int nlz3(int x) {
static int nlz3(unsigned x) {
int y, n;
n = 0;
y = x;
L: if (x < 0) return n;
y = static_cast<int>(x);
L: if (x > 0x7fffffff) return n;
if (y == 0) return 32 - n;
n = n + 1;
x = x << 1;
@ -98,19 +98,19 @@ static int nlz4(unsigned x) {
n = 16 - m; // is nonzero, set n = 0 and
x = x >> m; // shift x right 16.
// Now x is of the form 0000xxxx.
y = x - 0x100; // If positions 8-15 are 0,
m = (y >> 16) & 8; // add 8 to n and shift x left 8.
n = n + m;
y = static_cast<int>(x) - 0x100;
m = (y >> 16) & 8; // If positions 8-15 are 0,
n = n + m; // add 8 to n and shift x left 8.
x = x << m;
y = x - 0x1000; // If positions 12-15 are 0,
m = (y >> 16) & 4; // add 4 to n and shift x left 4.
n = n + m;
y = static_cast<int>(x) - 0x1000;
m = (y >> 16) & 4; // If positions 12-15 are 0,
n = n + m; // add 4 to n and shift x left 4.
x = x << m;
y = x - 0x4000; // If positions 14-15 are 0,
m = (y >> 16) & 2; // add 2 to n and shift x left 2.
n = n + m;
y = static_cast<int>(x) - 0x4000;
m = (y >> 16) & 2; // If positions 14-15 are 0,
n = n + m; // add 2 to n and shift x left 2.
x = x << m;
y = x >> 14; // Set y = 0, 1, 2, or 3.
@ -305,8 +305,8 @@ static int nlz10b(unsigned x)
return table[x >> 26];
}
int errors;
static void error(int x, int y)
static int errors;
static void error(unsigned x, int y)
{
errors = errors + 1;
std::printf("Error for x = %08x, got %d\n", x, y);
@ -338,7 +338,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz1(test[i]) != test[i+1]) error(test[i], nlz1(test[i]));}
if (nlz1(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz1(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz1: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -346,7 +346,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz1a(test[i]) != test[i+1]) error(test[i], nlz1a(test[i]));}
if (nlz1a(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz1a(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz1a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -354,7 +354,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz2(test[i]) != test[i+1]) error(test[i], nlz2(test[i]));}
if (nlz2(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz2(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz2: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -362,7 +362,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz2a(test[i]) != test[i+1]) error(test[i], nlz2a(test[i]));}
if (nlz2a(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz2a(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz2a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -370,7 +370,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz3(test[i]) != test[i+1]) error(test[i], nlz3(test[i]));}
if (nlz3(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz3(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz3: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -378,7 +378,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz4(test[i]) != test[i+1]) error(test[i], nlz4(test[i]));}
if (nlz4(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz4(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz4: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -386,7 +386,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz5(test[i]) != test[i+1]) error(test[i], nlz5(test[i]));}
if (nlz5(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz5(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz5: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -394,7 +394,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz6(test[i]) != test[i+1]) error(test[i], nlz6(test[i]));}
if (nlz6(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz6(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz6: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -402,7 +402,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz7(test[i]) != test[i+1]) error(test[i], nlz7(test[i]));}
if (nlz7(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz7(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz7: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -410,7 +410,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz8(test[i]) != test[i+1]) error(test[i], nlz8(test[i]));}
if (nlz8(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz8(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz8: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -418,7 +418,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz9(test[i]) != test[i+1]) error(test[i], nlz9(test[i]));}
if (nlz9(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz9(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz9: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -426,7 +426,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz10(test[i]) != test[i+1]) error(test[i], nlz10(test[i]));}
if (nlz10(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz10(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz10: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -434,7 +434,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz10a(test[i]) != test[i+1]) error(test[i], nlz10a(test[i]));}
if (nlz10a(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz10a(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz10a: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));
@ -442,7 +442,7 @@ int main()
TimestampBeg = std::clock();
for (std::size_t k = 0; k < Count; ++k)
for (i = 0; i < n; i += 2) {
if (nlz10b(test[i]) != test[i+1]) error(test[i], nlz10b(test[i]));}
if (nlz10b(test[i]) != static_cast<int>(test[i + 1])) error(test[i], nlz10b(test[i]));}
TimestampEnd = std::clock();
std::printf("nlz10b: %d clocks\n", static_cast<int>(TimestampEnd - TimestampBeg));

View file

@ -392,7 +392,7 @@ static int test_inverse_perf(std::size_t Count, std::size_t Instance, char const
//glm::uint Ulp = 0;
//Ulp = glm::max(glm::float_distance(*Dst, *Src), Ulp);
std::printf("inverse<%s>(%f): %lu\n", Message, static_cast<double>(Diff), EndTime - StartTime);
std::printf("inverse<%s>(%f): %lu\n", Message, static_cast<double>(Diff), static_cast<unsigned long>(EndTime - StartTime));
return 0;
}

View file

@ -1,4 +1,16 @@
#include <glm/detail/setup.hpp>
#if GLM_PLATFORM & GLM_PLATFORM_APPLE // Fail on Github macOS-latest (macOS-13 was fine)
int main()
{
return 0;
}
#else
#ifndef GLM_FORCE_PURE
#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
#endif
#include <glm/glm.hpp>
#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
@ -108,3 +120,5 @@ int main()
return Error;
}
#endif//GLM_PLATFORM & GLM_PLATFORM_APPLE

View file

@ -176,6 +176,10 @@ static int test_constexpr()
int main()
{
// Suppress unused variable warnings
(void)g1;
(void)g2;
int Error = 0;
Error += test_size();

View file

@ -164,7 +164,17 @@ static int test_operators()
B /= A;
Error += B == glm::ivec2(4, 8) ? 0 : 1;
B /= 2.0f;
B /= 2;
Error += B == glm::ivec2(2, 4) ? 0 : 1;
}
{
glm::ivec2 A(1.0f, 2.0f);
glm::ivec2 B(4.0f, 16.0f);
B = B / A;
Error += B == glm::ivec2(4, 8) ? 0 : 1;
B = B / 2;
Error += B == glm::ivec2(2, 4) ? 0 : 1;
}
{
@ -400,6 +410,11 @@ static int test_swizzle()
int main()
{
// Suppress unused variable warnings
(void)g1;
(void)g2;
(void)g3;
int Error = 0;
Error += test_size();

View file

@ -253,6 +253,18 @@ static int test_vec3_operators()
B /= 2;
Error += B == glm::ivec3(2, 1, 1) ? 0 : 1;
}
{
glm::ivec3 A(1.0f, 2.0f, 3.0f);
glm::ivec3 B(4.0f, 4.0f, 6.0f);
B = B / A;
Error += B == glm::ivec3(4, 2, 2) ? 0 : 1;
B = B / 2;
Error += B == glm::ivec3(2, 1, 1) ? 0 : 1;
}
{
glm::ivec3 B(2);
@ -612,6 +624,11 @@ static int test_constexpr()
int main()
{
// Suppress unused variable warnings
(void)g1;
(void)g2;
(void)g3;
int Error = 0;
Error += test_vec3_ctor();

View file

@ -390,6 +390,16 @@ static int test_operators()
B /= 2;
Error += B == glm::ivec4(2, 1, 2, 1) ? 0 : 1;
}
{
glm::ivec4 A(1.0f, 2.0f, 2.0f, 4.0f);
glm::ivec4 B(4.0f, 4.0f, 8.0f, 8.0f);
B = B / A;
Error += B == glm::ivec4(4, 2, 4, 2) ? 0 : 1;
B = B / 2;
Error += B == glm::ivec4(2, 1, 2, 1) ? 0 : 1;
}
{
glm::ivec4 B(2);
@ -770,6 +780,11 @@ static int test_simd_gen()
*/
int main()
{
// Suppress unused variable warnings
(void)g1;
(void)g2;
(void)g3;
int Error = 0;
//Error += test_simd_gen();

View file

@ -222,7 +222,7 @@ namespace nextPowerOfTwo_advanced
int Error(0);
std::vector<glm::uint> v;
v.resize(100000000);
v.resize(10000);
std::clock_t Timestramp0 = std::clock();
@ -586,7 +586,7 @@ namespace nextMultiple
{
int Error = 0;
glm::uint const Samples = 10000;
glm::uint const Samples = 100;
for(int i = 0; i < 4; ++i)
{

View file

@ -154,6 +154,10 @@ static int test_constexpr()
int main()
{
// Suppress unused variable warnings
(void)g1;
(void)g2;
int Error = 0;
Error += test_vec1_size();

View file

@ -20,10 +20,12 @@ namespace mask
# pragma clang diagnostic ignored "-Wsign-conversion"
#endif
#ifdef GLM_TEST_PERF
static inline int mask_zero(int Bits)
{
return ~((~0) << Bits);
}
#endif//GLM_TEST_PERF
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic push
@ -32,7 +34,7 @@ namespace mask
static inline int mask_mix(int Bits)
{
return Bits >= sizeof(int) * 8 ? 0xffffffff : (static_cast<int>(1) << Bits) - static_cast<int>(1);
return Bits >= static_cast<int>(sizeof(int) * 8) ? 0xffffffff : (static_cast<int>(1) << Bits) - static_cast<int>(1);
}
#if GLM_COMPILER & GLM_COMPILER_CLANG
@ -60,9 +62,10 @@ namespace mask
return Mask;
}
#ifdef GLM_TEST_PERF
static int perf()
{
int const Count = 100000000;
int const Count = 1000;
std::clock_t Timestamp1 = std::clock();
@ -123,8 +126,9 @@ namespace mask
std::printf("mask[zero]: %d\n", static_cast<unsigned int>(TimeZero));
std::printf("mask[half]: %d\n", static_cast<unsigned int>(TimeHalf));
return TimeDefault < TimeLoop ? 0 : 1;
return TimeDefault <= TimeLoop ? 0 : 1;
}
#endif//GLM_TEST_PERF
#if GLM_COMPILER & GLM_COMPILER_CLANG
# pragma clang diagnostic pop
@ -208,6 +212,7 @@ namespace mask
}
}//namespace mask
#ifdef GLM_TEST_PERF
namespace bitfieldInterleave3
{
template<typename PARAM, typename RET>
@ -227,9 +232,13 @@ namespace bitfieldInterleave3
{
int Error(0);
glm::uint16 x_max = 1 << 11;
glm::uint16 y_max = 1 << 11;
glm::uint16 z_max = 1 << 11;
std::clock_t const LastTime = std::clock();
glm::uint16 const test_max = 5; // previously 11
glm::uint16 x_max = 1 << test_max;
glm::uint16 y_max = 1 << test_max;
glm::uint16 z_max = 1 << test_max;
for(glm::uint16 z = 0; z < z_max; z += 27)
for(glm::uint16 y = 0; y < y_max; y += 27)
@ -240,6 +249,10 @@ namespace bitfieldInterleave3
Error += ResultA == ResultB ? 0 : 1;
}
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldInterleave3 Test %d clocks\n", static_cast<int>(Time));
return Error;
}
}
@ -265,10 +278,14 @@ namespace bitfieldInterleave4
{
int Error(0);
glm::uint16 x_max = 1 << 11;
glm::uint16 y_max = 1 << 11;
glm::uint16 z_max = 1 << 11;
glm::uint16 w_max = 1 << 11;
std::clock_t const LastTime = std::clock();
glm::uint16 const test_max = 5; // previously 11
glm::uint16 x_max = 1 << test_max;
glm::uint16 y_max = 1 << test_max;
glm::uint16 z_max = 1 << test_max;
glm::uint16 w_max = 1 << test_max;
for(glm::uint16 w = 0; w < w_max; w += 27)
for(glm::uint16 z = 0; z < z_max; z += 27)
@ -280,12 +297,18 @@ namespace bitfieldInterleave4
Error += ResultA == ResultB ? 0 : 1;
}
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldInterleave4 Test %d clocks\n", static_cast<int>(Time));
return Error;
}
}
#endif//GLM_TEST_PERF
namespace bitfieldInterleave
{
#ifdef GLM_TEST_PERF
static inline glm::uint64 fastBitfieldInterleave(glm::uint32 x, glm::uint32 y)
{
glm::uint64 REG1;
@ -491,11 +514,15 @@ namespace bitfieldInterleave
#endif
}
#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
#endif//GLM_TEST_PERF
static int test()
{
int Error = 0;
std::clock_t const LastTime = std::clock();
glm::uint8 const test_loop = 15; // 127 ideally
/*
{
for(glm::uint32 y = 0; y < (1 << 10); ++y)
@ -525,8 +552,8 @@ namespace bitfieldInterleave
}
*/
{
for(glm::uint8 y = 0; y < 127; ++y)
for(glm::uint8 x = 0; x < 127; ++x)
for(glm::uint8 y = 0; y < test_loop; ++y)
for(glm::uint8 x = 0; x < test_loop; ++x)
{
glm::uint64 A(glm::bitfieldInterleave(glm::u8vec2(x, y)));
glm::uint64 B(glm::bitfieldInterleave(glm::u16vec2(x, y)));
@ -542,8 +569,8 @@ namespace bitfieldInterleave
}
{
for(glm::uint8 y = 0; y < 127; ++y)
for(glm::uint8 x = 0; x < 127; ++x)
for(glm::uint8 y = 0; y < test_loop; ++y)
for(glm::uint8 x = 0; x < test_loop; ++x)
{
glm::int64 A(glm::bitfieldInterleave(glm::int8(x), glm::int8(y)));
glm::int64 B(glm::bitfieldInterleave(glm::int16(x), glm::int16(y)));
@ -554,19 +581,25 @@ namespace bitfieldInterleave
}
}
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldInterleave Test %d clocks\n", static_cast<int>(Time));
return Error;
}
#ifdef GLM_TEST_PERF
static int perf()
{
glm::uint32 x_max = 1 << 11;
glm::uint32 y_max = 1 << 10;
glm::uint32 x_max = 1 << 4;
glm::uint32 y_max = 1 << 3;
// ALU
std::vector<glm::uint64> Data(x_max * y_max);
std::vector<glm::u32vec2> Param(x_max * y_max);
for(glm::uint32 i = 0; i < Param.size(); ++i)
for(glm::uint32 i = 0; i < Param.size(); ++i) {
Param[i] = glm::u32vec2(i % x_max, i / y_max);
}
{
std::clock_t LastTime = std::clock();
@ -670,8 +703,10 @@ namespace bitfieldInterleave
return 0;
}
#endif//GLM_TEST_PERF
}//namespace bitfieldInterleave
#ifdef GLM_TEST_PERF
namespace bitfieldInterleave5
{
GLM_FUNC_QUALIFIER
@ -757,6 +792,8 @@ namespace bitfieldInterleave5
{
int Error = 0;
std::clock_t const LastTime = std::clock();
glm::size_t count = 256 / divider;
for(glm::size_t j = 0; j < count; ++j)
@ -796,6 +833,10 @@ namespace bitfieldInterleave5
Error += A == B ? 0 : 1;
}
*/
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldInterleave4 Test %d clocks\n", static_cast<int>(Time));
return Error;
}
@ -807,7 +848,7 @@ namespace bitfieldInterleave5
const std::clock_t BeginTime = std::clock();
for(glm::size_t k = 0; k < 10000; ++k)
for(glm::size_t k = 0; k < 100; ++k)
for(glm::size_t j = 0; j < count; ++j)
for(glm::size_t i = 0; i < count; ++i)
Error += Result[j * count + i] == glm::bitfieldInterleave(glm::uint8(i), glm::uint8(j)) ? 0 : 1;
@ -827,7 +868,7 @@ namespace bitfieldInterleave5
const std::clock_t BeginTime = std::clock();
for(glm::size_t k = 0; k < 10000; ++k)
for(glm::size_t k = 0; k < 100; ++k)
for(glm::size_t j = 0; j < count; ++j)
for(glm::size_t i = 0; i < count; ++i)
Error += Result[j * count + i] == bitfieldInterleave_u8vec2(glm::uint8(i), glm::uint8(j)) ? 0 : 1;
@ -847,7 +888,7 @@ namespace bitfieldInterleave5
const std::clock_t BeginTime = std::clock();
for(glm::size_t k = 0; k < 10000; ++k)
for(glm::size_t k = 0; k < 100; ++k)
for(glm::size_t j = 0; j < count; ++j)
for(glm::size_t i = 0; i < count; ++i)
Error += Result[j * count + i] == glm::bitfieldInterleave(glm::uint8(i), glm::uint8(j), glm::uint8(i), glm::uint8(j)) ? 0 : 1;
@ -887,7 +928,7 @@ namespace bitfieldInterleave5
const std::clock_t BeginTime = std::clock();
for(glm::size_t k = 0; k < 10000; ++k)
for(glm::size_t k = 0; k < 100; ++k)
for(glm::size_t j = 0; j < count; ++j)
for(glm::size_t i = 0; i < count; ++i)
Error += Result[j * count + i] == glm::bitfieldInterleave(glm::uint16(i), glm::uint16(j)) ? 0 : 1;
@ -955,22 +996,34 @@ namespace bitfieldInterleave5
return Error;
}
}//namespace bitfieldInterleave5
#endif//GLM_TEST_PERF
static int test_bitfieldRotateRight()
{
std::clock_t const LastTime = std::clock();
glm::ivec4 const A = glm::bitfieldRotateRight(glm::ivec4(2), 1);
glm::ivec4 const B = glm::ivec4(2) >> 1;
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldRotateRight Test %d clocks\n", static_cast<int>(Time));
return A == B;
}
static int test_bitfieldRotateLeft()
{
std::clock_t const LastTime = std::clock();
glm::ivec4 const A = glm::bitfieldRotateLeft(glm::ivec4(2), 1);
glm::ivec4 const B = glm::ivec4(2) << 1;
std::clock_t const Time = std::clock() - LastTime;
std::printf("glm::bitfieldRotateLeft Test %d clocks\n", static_cast<int>(Time));
return A == B;
}
@ -978,20 +1031,31 @@ int main()
{
int Error = 0;
Error += ::bitfieldInterleave::test();
#ifdef GLM_TEST_PERF
Error += ::bitfieldInterleave3::test();
Error += ::bitfieldInterleave4::test();
// Tests for a faster and to reserve bitfieldInterleave
Error += ::bitfieldInterleave5::test(64);
Error += ::bitfieldInterleave5::perf(64);
Error += ::bitfieldInterleave::perf();
#endif//GLM_TEST_PERF
Error += ::mask::test();
Error += ::bitfieldInterleave3::test();
Error += ::bitfieldInterleave4::test();
Error += ::bitfieldInterleave::test();
#ifdef GLM_TEST_PERF
Error += ::mask::perf();
#endif//GLM_TEST_PERF
Error += test_bitfieldRotateRight();
Error += test_bitfieldRotateLeft();
Error += ::mask::perf();
Error += ::bitfieldInterleave::perf();
return Error;
}

View file

@ -1,4 +1,6 @@
#ifndef GLM_FORCE_PURE
#define GLM_FORCE_DEFAULT_ALIGNED_GENTYPES
#endif
#include <glm/gtc/random.hpp>
#include <glm/gtc/epsilon.hpp>
#include <glm/gtc/type_precision.hpp>

View file

@ -244,7 +244,7 @@ namespace ceilPowerOfTwo_advanced
int Error(0);
std::vector<glm::uint> v;
v.resize(100000000);
v.resize(10000);
std::clock_t Timestramp0 = std::clock();

View file

@ -1,6 +1,6 @@
#include <glm/glm.hpp>
#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && !(GLM_ARCH & GLM_ARCH_NEON_BIT) // Fail on Github macOS latest C.I.
#include <glm/gtc/type_aligned.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/ext/scalar_relational.hpp>
@ -200,6 +200,195 @@ static int test_copy_vec3()
return Error;
}
static int test_splat_vec3()
{
int Error = 0;
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec3 const v(glm::splatX(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.x, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec3 const v(glm::splatY(u));
Error += glm::equal(v.x, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.y, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec3 const v(glm::splatZ(u));
Error += glm::equal(v.x, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec3 const v(glm::splatX(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.x, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec3 const v(glm::splatY(u));
Error += glm::equal(v.x, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.y, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec3 const v(glm::splatZ(u));
Error += glm::equal(v.x, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
}
return Error;
}
static int test_splat_vec4()
{
int Error = 0;
{
glm::aligned_vec4 const u(1.f, 2.f, 3.f, 4.f);
{
glm::aligned_vec4 const v(glm::splatX(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, u.x, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_vec4 const v(glm::splatY(u));
Error += glm::equal(v.x, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, u.y, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_vec4 const v(glm::splatZ(u));
Error += glm::equal(v.x, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, u.z, glm::epsilon<float>()) ? 0 : 1;
}
}
{
glm::aligned_dvec4 const u(1., 2., 3., 4.);
{
glm::aligned_dvec4 const v(glm::splatX(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, u.x, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_dvec4 const v(glm::splatY(u));
Error += glm::equal(v.x, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, u.y, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_dvec4 const v(glm::splatZ(u));
Error += glm::equal(v.x, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, u.z, glm::epsilon<double>()) ? 0 : 1;
}
}
return Error;
}
static int test_copy_vec4_vec3()
{
int Error = 0;
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec4 const v(glm::xyz0(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, 0.0f, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec4 const v(glm::xyz1(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, 1.0f, glm::epsilon<float>()) ? 0 : 1; ;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec4 const v(glm::xyz0(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, 0.0, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec4 const v(glm::xyz1(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, 1.0, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_vec3 const u(1.f, 2.f, 3.f);
glm::aligned_vec4 const v(glm::xyzz(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.w, u.z, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_dvec3 const u(1., 2., 3.);
glm::aligned_dvec4 const v(glm::xyzz(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.w, u.z, glm::epsilon<double>()) ? 0 : 1;
}
{
glm::aligned_vec4 const u(1.f, 2.f, 3.f, 4.f);
glm::aligned_vec3 const v(glm::xyz(u));
Error += glm::equal(v.x, u.x, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<float>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<float>()) ? 0 : 1;
}
{
glm::aligned_dvec4 const u(1., 2., 3., 4.);
glm::aligned_dvec3 const v(glm::xyz(u));
Error += glm::equal(v.x, u.x, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.y, u.y, glm::epsilon<double>()) ? 0 : 1;
Error += glm::equal(v.z, u.z, glm::epsilon<double>()) ? 0 : 1;
}
return Error;
}
static int test_copy()
{
int Error = 0;
@ -207,7 +396,6 @@ static int test_copy()
{
glm::aligned_ivec4 const a(1, 2, 3, 4);
glm::ivec4 const u(a);
Error += a.x == u.x ? 0 : 1;
Error += a.y == u.y ? 0 : 1;
Error += a.z == u.z ? 0 : 1;
@ -297,17 +485,24 @@ static int test_aligned_mat4()
return Error;
}
int main()
{
int Error = 0;
int Error = 0;
Error += test_ctor();
Error += test_copy_vec4();
Error += test_copy_vec3();
Error += test_splat_vec3();
Error += test_splat_vec4();
Error += test_copy_vec4_vec3();
Error += test_copy();
Error += test_copy_vec4();
Error += test_copy_vec3();
Error += test_aligned_ivec4();
Error += test_aligned_mat4();
return Error;
}

View file

@ -50,6 +50,7 @@ glmCreateTestGTC(gtx_scalar_multiplication)
glmCreateTestGTC(gtx_scalar_relational)
glmCreateTestGTC(gtx_spline)
glmCreateTestGTC(gtx_string_cast)
glmCreateTestGTC(gtx_structured_bindings)
glmCreateTestGTC(gtx_texture)
glmCreateTestGTC(gtx_type_aligned)
glmCreateTestGTC(gtx_type_trait)

View file

@ -12,42 +12,70 @@ namespace
T r;
r = glm::linearInterpolation(a);
(void)r;
r = glm::quadraticEaseIn(a);
(void)r;
r = glm::quadraticEaseOut(a);
(void)r;
r = glm::quadraticEaseInOut(a);
(void)r;
r = glm::cubicEaseIn(a);
(void)r;
r = glm::cubicEaseOut(a);
(void)r;
r = glm::cubicEaseInOut(a);
(void)r;
r = glm::quarticEaseIn(a);
(void)r;
r = glm::quarticEaseOut(a);
(void)r;
r = glm::quinticEaseInOut(a);
(void)r;
r = glm::sineEaseIn(a);
(void)r;
r = glm::sineEaseOut(a);
(void)r;
r = glm::sineEaseInOut(a);
(void)r;
r = glm::circularEaseIn(a);
(void)r;
r = glm::circularEaseOut(a);
(void)r;
r = glm::circularEaseInOut(a);
(void)r;
r = glm::exponentialEaseIn(a);
(void)r;
r = glm::exponentialEaseOut(a);
(void)r;
r = glm::exponentialEaseInOut(a);
(void)r;
r = glm::elasticEaseIn(a);
(void)r;
r = glm::elasticEaseOut(a);
(void)r;
r = glm::elasticEaseInOut(a);
(void)r;
r = glm::backEaseIn(a);
(void)r;
r = glm::backEaseOut(a);
(void)r;
r = glm::backEaseInOut(a);
(void)r;
r = glm::bounceEaseIn(a);
(void)r;
r = glm::bounceEaseOut(a);
(void)r;
r = glm::bounceEaseInOut(a);
(void)r;
}
}

View file

@ -22,11 +22,11 @@ namespace fastCos
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastCos(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::cos(i);
const std::clock_t timestamp3 = std::clock();
@ -58,11 +58,11 @@ namespace fastSin
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastSin(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::sin(i);
const std::clock_t timestamp3 = std::clock();
@ -86,11 +86,11 @@ namespace fastTan
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastTan(i);
const std::clock_t timestamp2 = std::clock();
for (float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for (float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::tan(i);
const std::clock_t timestamp3 = std::clock();
@ -114,11 +114,11 @@ namespace fastAcos
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAcos(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::acos(i);
const std::clock_t timestamp3 = std::clock();
@ -142,10 +142,10 @@ namespace fastAsin
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAsin(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::asin(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;
@ -167,10 +167,10 @@ namespace fastAtan
const float end = glm::pi<float>();
float result = 0.f;
const std::clock_t timestamp1 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::fastAtan(i);
const std::clock_t timestamp2 = std::clock();
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i += 0.1f)
for(float i = begin; i < end; i = NextFloat ? glm::nextFloat(i) : i + 0.1f)
result = glm::atan(i);
const std::clock_t timestamp3 = std::clock();
const std::clock_t time_fast = timestamp2 - timestamp1;

View file

@ -57,6 +57,7 @@ static int test_intersectRayTriangle()
return Error;
}
#if GLM_PLATFORM != GLM_PLATFORM_LINUX
static int test_intersectLineTriangle()
{
int Error = 0;
@ -75,14 +76,17 @@ static int test_intersectLineTriangle()
return Error;
}
#endif//GLM_PLATFORM != GLM_PLATFORM_LINUX
int main()
{
int Error = 0;
#if GLM_PLATFORM != GLM_PLATFORM_LINUX
Error += test_intersectRayPlane();
Error += test_intersectRayTriangle();
Error += test_intersectLineTriangle();
Error += test_intersectLineTriangle(); // Disabled on 2025/01/16, C.I. failing on Ubuntu latest, GCC 13.3.0
#endif//GLM_PLATFORM != GLM_PLATFORM_LINUX
return Error;
}

View file

@ -1,5 +1,9 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/norm.hpp>
#include <glm/ext/scalar_relational.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
static int test_lMaxNorm()
{
@ -7,12 +11,12 @@ static int test_lMaxNorm()
{
float norm = glm::lMaxNorm(glm::vec3(-1, -2, -3));
Error += glm::epsilonEqual(norm, 3.f, 0.00001f) ? 0 : 1;
Error += glm::equal(norm, 3.f, 0.00001f) ? 0 : 1;
}
{
float norm = glm::lMaxNorm(glm::vec3(2, 3, 1));
Error += glm::epsilonEqual(norm, 3.f, 0.00001f) ? 0 : 1;
Error += glm::equal(norm, 3.f, 0.00001f) ? 0 : 1;
}
return Error;
@ -26,44 +30,44 @@ static int test_lxNorm()
unsigned int depth_1 = 1;
float normA = glm::lxNorm(glm::vec3(2, 3, 1), depth_1);
float normB = glm::l1Norm(glm::vec3(2, 3, 1));
Error += glm::epsilonEqual(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::epsilonEqual(normA, 6.f, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 6.f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_1 = 1;
float normA = glm::lxNorm(glm::vec3(-1, -2, -3), depth_1);
float normB = glm::l1Norm(glm::vec3(-1, -2, -3));
Error += glm::epsilonEqual(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::epsilonEqual(normA, 6.f, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 6.f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_2 = 2;
float normA = glm::lxNorm(glm::vec3(2, 3, 1), depth_2);
float normB = glm::l2Norm(glm::vec3(2, 3, 1));
Error += glm::epsilonEqual(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::epsilonEqual(normA, 3.741657387f, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 3.741657387f, 0.00001f) ? 0 : 1;
}
{
unsigned int depth_2 = 2;
float normA = glm::lxNorm(glm::vec3(-1, -2, -3), depth_2);
float normB = glm::l2Norm(glm::vec3(-1, -2, -3));
Error += glm::epsilonEqual(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::epsilonEqual(normA, 3.741657387f, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, normB, 0.00001f) ? 0 : 1;
Error += glm::equal(normA, 3.741657387f, 0.00001f) ? 0 : 1;
}
{
unsigned int oddDepth = 3;
float norm = glm::lxNorm(glm::vec3(2, 3, 1), oddDepth);
Error += glm::epsilonEqual(norm, 3.301927249f, 0.00001f) ? 0 : 1;
Error += glm::equal(norm, 3.301927249f, 0.00001f) ? 0 : 1;
}
{
unsigned int oddDepth = 3;
float norm = glm::lxNorm(glm::vec3(-1, -2, -3), oddDepth);
Error += glm::epsilonEqual(norm, 3.301927249f, 0.00001f) ? 0 : 1;
Error += glm::equal(norm, 3.301927249f, 0.00001f) ? 0 : 1;
}
return Error;

View file

@ -468,7 +468,7 @@ static int testCovar(
return failReport(__LINE__);
}
// #2: test function variant consitency with random data
// #2: test function variant consistency with random data
#if GLM_HAS_CXX11_STL == 1
std::default_random_engine rndEng(randomEngineSeed);
std::normal_distribution<T> normalDist;
@ -560,7 +560,7 @@ static int smokeTest()
if(eCnt != 3u)
return failReport(__LINE__);
// sort eVec by decending eVal
// sort eVec by descending eVal
if(eVal[0] < eVal[1])
{
std::swap(eVal[0], eVal[1]);

View file

@ -0,0 +1,366 @@
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/structured_bindings.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/vec1.hpp>
static int test_vec1() {
glm::vec1 v(0);
float& x = glm::get<0>(v);
return (&x != &v.x);
}
static int test_vec2() {
glm::vec2 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
return (&x != &v.x) + (&y != &v.y);
}
static int test_vec3() {
glm::vec3 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
float& z = glm::get<2>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_vec4() {
glm::vec4 v(0);
float& x = glm::get<0>(v);
float& y = glm::get<1>(v);
float& z = glm::get<2>(v);
float& w = glm::get<3>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_const_vec1() {
glm::vec1 const v(0);
float const& x = glm::get<0>(v);
return (&x != &v.x);
}
static int test_const_vec2() {
glm::vec2 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
return (&x != &v.x) + (&y != &v.y);
}
static int test_const_vec3() {
glm::vec3 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
float const& z = glm::get<2>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_const_vec4() {
glm::vec4 const v(0);
float const& x = glm::get<0>(v);
float const& y = glm::get<1>(v);
float const& z = glm::get<2>(v);
float const& w = glm::get<3>(v);
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_quat() {
glm::quat q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
float& w = glm::get<0>(q);
float& x = glm::get<1>(q);
float& y = glm::get<2>(q);
float& z = glm::get<3>(q);
#else
float& x = glm::get<0>(q);
float& y = glm::get<1>(q);
float& z = glm::get<2>(q);
float& w = glm::get<3>(q);
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
static int test_const_quat() {
glm::quat const q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
float const& w = glm::get<0>(q);
float const& x = glm::get<1>(q);
float const& y = glm::get<2>(q);
float const& z = glm::get<3>(q);
#else
float const& x = glm::get<0>(q);
float const& y = glm::get<1>(q);
float const& z = glm::get<2>(q);
float const& w = glm::get<3>(q);
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
template<glm::length_t R>
static int test_mat2xR() {
typedef glm::mat<2, R, float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_const_mat2xR() {
typedef glm::mat<2,R,float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_mat3xR() {
typedef glm::mat<3, R, float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
typename Mat::col_type& c3 = glm::get<2>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_const_mat3xR() {
typedef glm::mat< 3, R, float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
typename Mat::col_type const& c3 = glm::get<2>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_mat4xR() {
typedef glm::mat<4,R,float> Mat;
Mat m(0);
typename Mat::col_type& c1 = glm::get<0>(m);
typename Mat::col_type& c2 = glm::get<1>(m);
typename Mat::col_type& c3 = glm::get<2>(m);
typename Mat::col_type& c4 = glm::get<3>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
template<glm::length_t R>
static int test_const_mat4xR() {
typedef glm::mat<4,R,float> Mat;
Mat const m(0);
typename Mat::col_type const& c1 = glm::get<0>(m);
typename Mat::col_type const& c2 = glm::get<1>(m);
typename Mat::col_type const& c3 = glm::get<2>(m);
typename Mat::col_type const& c4 = glm::get<3>(m);
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
#if defined(__cpp_structured_bindings)
#if __cpp_structured_bindings >= 201606L
static int test_structured_vec1() {
glm::vec1 v(0);
auto& [x] = v;
return (&x != &v.x);
}
static int test_structured_vec2() {
glm::vec2 v(0);
auto& [x, y] = v;
return (&x != &v.x) + (&y != &v.y);
}
static int test_structured_vec3() {
glm::vec3 v(0);
auto& [x, y, z] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_structured_vec4() {
glm::vec4 v(0);
auto& [x, y, z, w] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
static int test_const_structured_vec1() {
glm::vec1 const v(0);
auto const& [x] = v;
return (&x != &v.x);
}
static int test_const_structured_vec2() {
glm::vec2 const v(0);
auto const& [x, y] = v;
return (&x != &v.x) + (&y != &v.y);
}
static int test_const_structured_vec3() {
glm::vec3 const v(0);
auto const& [x, y, z] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z);
}
static int test_const_structured_vec4() {
glm::vec4 const v(0);
auto const& [x, y, z, w] = v;
return (&x != &v.x) + (&y != &v.y) + (&z != &v.z) + (&w != &v.w);
}
template<glm::length_t R>
static int test_structured_mat2xR() {
glm::mat<2,R,float,glm::defaultp> m(0);
auto& [c1, c2] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_const_structured_mat2xR() {
glm::mat<2, R, float, glm::defaultp> const m(0);
auto const& [c1, c2] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]);
}
template<glm::length_t R>
static int test_structured_mat3xR() {
glm::mat<3, R, float, glm::defaultp> m(0);
auto& [c1, c2,c3] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_const_structured_mat3xR() {
glm::mat<3, R, float, glm::defaultp> const m(0);
auto const& [c1, c2, c3] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]);
}
template<glm::length_t R>
static int test_structured_mat4xR() {
glm::mat<4, R, float, glm::defaultp> m(0);
auto& [c1, c2, c3,c4] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
template<glm::length_t R>
static int test_const_structured_mat4xR() {
glm::mat<4, R, float, glm::defaultp> const m(0);
auto const& [c1, c2, c3, c4] = m;
return (&c1 != &m[0]) + (&c2 != &m[1]) + (&c3 != &m[2]) + (&c4 != &m[3]);
}
static int test_structured_quat() {
glm::quat q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
auto& [w, x, y, z] = q;
#else
auto& [x, y, z, w] = q;
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
static int test_const_structured_quat() {
glm::quat const q(0.0f, 0.0f, 0.0f, 0.0f);
#ifdef GLM_FORCE_QUAT_DATA_WXYZ
auto const& [w, x, y, z] = q;
#else
auto const& [x, y, z, w] = q;
#endif
return (&x != &q.x) + (&y != &q.y) + (&z != &q.z) + (&w != &q.w);
}
#endif
#endif
int main()
{
int Error = 0;
Error += test_vec1();
Error += test_vec2();
Error += test_vec3();
Error += test_vec4();
Error += test_const_vec1();
Error += test_const_vec2();
Error += test_const_vec3();
Error += test_const_vec4();
Error += test_quat();
Error += test_const_quat();
Error += test_mat2xR<2>();
Error += test_const_mat2xR<2>();
Error += test_mat2xR<3>();
Error += test_const_mat2xR<3>();
Error += test_mat2xR<4>();
Error += test_const_mat2xR<4>();
Error += test_mat3xR<2>();
Error += test_const_mat3xR<2>();
Error += test_mat3xR<3>();
Error += test_const_mat3xR<3>();
Error += test_mat3xR<4>();
Error += test_const_mat3xR<4>();
Error += test_mat4xR<2>();
Error += test_const_mat4xR<2>();
Error += test_mat4xR<3>();
Error += test_const_mat4xR<3>();
Error += test_mat4xR<4>();
Error += test_const_mat4xR<4>();
#ifdef __cpp_structured_bindings
#if __cpp_structured_bindings >= 201606L
Error += test_structured_vec1();
Error += test_structured_vec2();
Error += test_structured_vec3();
Error += test_structured_vec4();
Error += test_const_structured_vec1();
Error += test_const_structured_vec2();
Error += test_const_structured_vec3();
Error += test_const_structured_vec4();
Error += test_structured_quat();
Error += test_const_structured_quat();
Error += test_structured_mat2xR<2>();
Error += test_const_structured_mat2xR<2>();
Error += test_structured_mat2xR<3>();
Error += test_const_structured_mat2xR<3>();
Error += test_structured_mat2xR<4>();
Error += test_const_structured_mat2xR<4>();
Error += test_structured_mat3xR<2>();
Error += test_const_structured_mat3xR<2>();
Error += test_structured_mat3xR<3>();
Error += test_const_structured_mat3xR<3>();
Error += test_structured_mat3xR<4>();
Error += test_const_structured_mat3xR<4>();
Error += test_structured_mat4xR<2>();
Error += test_const_structured_mat4xR<2>();
Error += test_structured_mat4xR<3>();
Error += test_const_structured_mat4xR<3>();
Error += test_structured_mat4xR<4>();
Error += test_const_structured_mat4xR<4>();
#endif
#endif
return Error;
}

View file

@ -14,6 +14,31 @@
#include <chrono>
#include <cstdio>
inline bool
is_aligned(const void* ptr, std::uintptr_t alignment) noexcept {
auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
return !(iptr % alignment);
}
template <typename matType>
static void align_check(matType const& M, std::vector<matType> const& I, std::vector<matType>& O)
{
if (matType::col_type::is_aligned::value)
{
if (!is_aligned(&M, 16))
abort();
for (std::size_t i = 0, n = I.size(); i < n; ++i)
{
if (!is_aligned(&I[i], 16))
abort();
if (!is_aligned(&O[i], 16))
abort();
}
}
}
template <typename matType>
static void test_mat_mul_mat(matType const& M, std::vector<matType> const& I, std::vector<matType>& O)
{
@ -32,6 +57,8 @@ static int launch_mat_mul_mat(std::vector<matType>& O, matType const& Transform,
for(std::size_t i = 0; i < Samples; ++i)
I[i] = Scale * static_cast<T>(i);
align_check<matType>(Transform, I, O);
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
test_mat_mul_mat<matType>(Transform, I, O);
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
@ -65,27 +92,49 @@ static int comp_mat2_mul_mat2(std::size_t Samples)
return Error;
}
template<typename T1, typename T2>
bool percent_error(const T1& a, const T2& b, float percentThreshold)
{
typedef typename T1::value_type value_type;
for (int i = 0; i < a.length(); ++i)
for (int j = 0; j < a[i].length(); ++j)
{
value_type v;
if (a[i][j] != value_type(0))
v = ((b[i][j] - a[i][j]) / a[i][j]) * value_type(100);
else
v = b[i][j] * value_type(100);
if (v > value_type(percentThreshold))
return false;
}
return true;
}
template <typename packedMatType, typename alignedMatType>
static int comp_mat3_mul_mat3(std::size_t Samples)
{
typedef typename packedMatType::value_type T;
int Error = 0;
packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
packedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01);
std::vector<packedMatType> SISD;
std::printf("- SISD: %d us\n", launch_mat_mul_mat<packedMatType>(SISD, Transform, Scale, Samples));
{
packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
packedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01);
std::printf("- SISD: %d us\n", launch_mat_mul_mat<packedMatType>(SISD, Transform, Scale, Samples));
}
std::vector<alignedMatType> SIMD;
std::printf("- SIMD: %d us\n", launch_mat_mul_mat<alignedMatType>(SIMD, Transform, Scale, Samples));
{
alignedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
alignedMatType const Scale(0.01, 0.02, 0.03, 0.05, 0.01, 0.02, 0.03, 0.05, 0.01);
std::printf("- SIMD: %d us\n", launch_mat_mul_mat<alignedMatType>(SIMD, Transform, Scale, Samples));
}
for(std::size_t i = 0; i < Samples; ++i)
{
packedMatType const A = SISD[i];
packedMatType const B = SIMD[i];
Error += glm::all(glm::equal(A, B, static_cast<T>(0.001))) ? 0 : 1;
Error += percent_error(A, B, 0.01f) ? 0 : 1;
}
return Error;
@ -94,7 +143,6 @@ static int comp_mat3_mul_mat3(std::size_t Samples)
template <typename packedMatType, typename alignedMatType>
static int comp_mat4_mul_mat4(std::size_t Samples)
{
typedef typename packedMatType::value_type T;
int Error = 0;
@ -111,7 +159,7 @@ static int comp_mat4_mul_mat4(std::size_t Samples)
{
packedMatType const A = SISD[i];
packedMatType const B = SIMD[i];
Error += glm::all(glm::equal(A, B, static_cast<T>(0.001))) ? 0 : 1;
Error += percent_error(A, B, 0.01f) ? 0 : 1;
}
return Error;
@ -125,13 +173,13 @@ int main()
std::printf("mat2 * mat2:\n");
Error += comp_mat2_mul_mat2<glm::mat2, glm::aligned_mat2>(Samples);
std::printf("dmat2 * dmat2:\n");
Error += comp_mat2_mul_mat2<glm::dmat2, glm::aligned_dmat2>(Samples);
std::printf("mat3 * mat3:\n");
Error += comp_mat3_mul_mat3<glm::mat3, glm::aligned_mat3>(Samples);
std::printf("dmat3 * dmat3:\n");
Error += comp_mat3_mul_mat3<glm::dmat3, glm::aligned_dmat3>(Samples);

View file

@ -72,14 +72,19 @@ static int comp_mat3_mul_vec3(std::size_t Samples)
int Error = 0;
packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
packedVecType const Scale(0.01, 0.02, 0.05);
std::vector<packedVecType> SISD;
std::printf("- SISD: %d us\n", launch_mat_mul_vec<packedMatType, packedVecType>(SISD, Transform, Scale, Samples));
{
packedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
packedVecType const Scale(0.01, 0.02, 0.05);
std::printf("- SISD: %d us\n", launch_mat_mul_vec<packedMatType, packedVecType>(SISD, Transform, Scale, Samples));
}
std::vector<alignedVecType> SIMD;
std::printf("- SIMD: %d us\n", launch_mat_mul_vec<alignedMatType, alignedVecType>(SIMD, Transform, Scale, Samples));
{
alignedMatType const Transform(1, 2, 3, 4, 5, 6, 7, 8, 9);
alignedVecType const Scale(0.01, 0.02, 0.05);
std::printf("- SIMD: %d us\n", launch_mat_mul_vec<alignedMatType, alignedVecType>(SIMD, Transform, Scale, Samples));
}
for(std::size_t i = 0; i < Samples; ++i)
{
@ -125,9 +130,9 @@ int main()
std::printf("mat2 * vec2:\n");
Error += comp_mat2_mul_vec2<glm::mat2, glm::vec2, glm::aligned_mat2, glm::aligned_vec2>(Samples);
std::printf("dmat2 * dvec2:\n");
Error += comp_mat2_mul_vec2<glm::dmat2, glm::dvec2,glm::aligned_dmat2, glm::aligned_dvec2>(Samples);
Error += comp_mat2_mul_vec2<glm::dmat2, glm::dvec2, glm::aligned_dmat2, glm::aligned_dvec2>(Samples);
std::printf("mat3 * vec3:\n");
Error += comp_mat3_mul_vec3<glm::mat3, glm::vec3, glm::aligned_mat3, glm::aligned_vec3>(Samples);

View file

@ -14,14 +14,30 @@
#include <chrono>
#include <cstdio>
template <typename matType, typename vecType>
static void test_vec_mul_mat(matType const& M, std::vector<vecType> const& I, std::vector<vecType>& O)
{
for (std::size_t i = 0, n = I.size(); i < n; ++i)
O[i] = I[i] * M;
}
template <typename matType, typename vecType, bool reverseOp>
struct test_vec_mul_mat {};
template <typename matType, typename vecType>
struct test_vec_mul_mat< matType, vecType, false>
{
void operator()(matType const& M, std::vector<vecType> const& I, std::vector<vecType>& O)
{
for (std::size_t i = 0, n = I.size(); i < n; ++i)
O[i] = I[i] * M;
}
};
template <typename matType, typename vecType>
struct test_vec_mul_mat< matType, vecType, true>
{
void operator()(matType const& M, std::vector<vecType> const& I, std::vector<vecType>& O)
{
for (std::size_t i = 0, n = I.size(); i < n; ++i)
O[i] = M * I[i];
}
};
template <typename matType, typename vecType, bool reverseOp>
static int launch_vec_mul_mat(std::vector<vecType>& O, matType const& Transform, vecType const& Scale, std::size_t Samples)
{
typedef typename matType::value_type T;
@ -29,17 +45,20 @@ static int launch_vec_mul_mat(std::vector<vecType>& O, matType const& Transform,
std::vector<vecType> I(Samples);
O.resize(Samples);
memset(I.data(), 0, I.size() * sizeof(vecType));
for(std::size_t i = 0; i < Samples; ++i)
I[i] = Scale * static_cast<T>(i);
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
test_vec_mul_mat<matType, vecType>(Transform, I, O);
test_vec_mul_mat<matType, vecType, reverseOp> fct;
fct(Transform, I, O);
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
return static_cast<int>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count());
}
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType>
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType, bool reverseOp>
static int comp_vec2_mul_mat2(std::size_t Samples)
{
typedef typename packedMatType::value_type T;
@ -50,10 +69,10 @@ static int comp_vec2_mul_mat2(std::size_t Samples)
packedVecType const Scale(0.01, 0.02);
std::vector<packedVecType> SISD;
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType>(SISD, Transform, Scale, Samples));
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType, reverseOp>(SISD, Transform, Scale, Samples));
std::vector<alignedVecType> SIMD;
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType>(SIMD, Transform, Scale, Samples));
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType, reverseOp>(SIMD, Transform, Scale, Samples));
for(std::size_t i = 0; i < Samples; ++i)
{
@ -65,7 +84,7 @@ static int comp_vec2_mul_mat2(std::size_t Samples)
return Error;
}
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType>
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType, bool reverseOp>
static int comp_vec3_mul_mat3(std::size_t Samples)
{
typedef typename packedMatType::value_type T;
@ -76,10 +95,10 @@ static int comp_vec3_mul_mat3(std::size_t Samples)
packedVecType const Scale(0.01, 0.02, 0.05);
std::vector<packedVecType> SISD;
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType>(SISD, Transform, Scale, Samples));
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType, reverseOp>(SISD, Transform, Scale, Samples));
std::vector<alignedVecType> SIMD;
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType>(SIMD, Transform, Scale, Samples));
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType, reverseOp>(SIMD, Transform, Scale, Samples));
for(std::size_t i = 0; i < Samples; ++i)
{
@ -91,7 +110,7 @@ static int comp_vec3_mul_mat3(std::size_t Samples)
return Error;
}
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType>
template <typename packedMatType, typename packedVecType, typename alignedMatType, typename alignedVecType, bool reverseOp>
static int comp_vec4_mul_mat4(std::size_t Samples)
{
typedef typename packedMatType::value_type T;
@ -102,10 +121,10 @@ static int comp_vec4_mul_mat4(std::size_t Samples)
packedVecType const Scale(0.01, 0.02, 0.03, 0.05);
std::vector<packedVecType> SISD;
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType>(SISD, Transform, Scale, Samples));
std::printf("- SISD: %d us\n", launch_vec_mul_mat<packedMatType, packedVecType, reverseOp>(SISD, Transform, Scale, Samples));
std::vector<alignedVecType> SIMD;
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType>(SIMD, Transform, Scale, Samples));
std::printf("- SIMD: %d us\n", launch_vec_mul_mat<alignedMatType, alignedVecType, reverseOp>(SIMD, Transform, Scale, Samples));
for(std::size_t i = 0; i < Samples; ++i)
{
@ -124,22 +143,41 @@ int main()
int Error = 0;
std::printf("vec2 * mat2:\n");
Error += comp_vec2_mul_mat2<glm::mat2, glm::vec2, glm::aligned_mat2, glm::aligned_vec2>(Samples);
Error += comp_vec2_mul_mat2<glm::mat2, glm::vec2, glm::aligned_mat2, glm::aligned_vec2, false>(Samples);
std::printf("dvec2 * dmat2:\n");
Error += comp_vec2_mul_mat2<glm::dmat2, glm::dvec2,glm::aligned_dmat2, glm::aligned_dvec2>(Samples);
Error += comp_vec2_mul_mat2<glm::dmat2, glm::dvec2,glm::aligned_dmat2, glm::aligned_dvec2, false>(Samples);
std::printf("vec3 * mat3:\n");
Error += comp_vec3_mul_mat3<glm::mat3, glm::vec3, glm::aligned_mat3, glm::aligned_vec3>(Samples);
Error += comp_vec3_mul_mat3<glm::mat3, glm::vec3, glm::aligned_mat3, glm::aligned_vec3, false>(Samples);
std::printf("dvec3 * dmat3:\n");
Error += comp_vec3_mul_mat3<glm::dmat3, glm::dvec3, glm::aligned_dmat3, glm::aligned_dvec3>(Samples);
Error += comp_vec3_mul_mat3<glm::dmat3, glm::dvec3, glm::aligned_dmat3, glm::aligned_dvec3, false>(Samples);
std::printf("vec4 * mat4:\n");
Error += comp_vec4_mul_mat4<glm::mat4, glm::vec4, glm::aligned_mat4, glm::aligned_vec4>(Samples);
Error += comp_vec4_mul_mat4<glm::mat4, glm::vec4, glm::aligned_mat4, glm::aligned_vec4, false>(Samples);
std::printf("dvec4 * dmat4:\n");
Error += comp_vec4_mul_mat4<glm::dmat4, glm::dvec4, glm::aligned_dmat4, glm::aligned_dvec4>(Samples);
Error += comp_vec4_mul_mat4<glm::dmat4, glm::dvec4, glm::aligned_dmat4, glm::aligned_dvec4, false>(Samples);
std::printf("mat2 * vec2:\n");
Error += comp_vec2_mul_mat2<glm::mat2, glm::vec2, glm::aligned_mat2, glm::aligned_vec2, true>(Samples);
std::printf("dmat2 * dvec2 :\n");
Error += comp_vec2_mul_mat2<glm::dmat2, glm::dvec2, glm::aligned_dmat2, glm::aligned_dvec2, true>(Samples);
std::printf("mat3 * vec3:\n");
Error += comp_vec3_mul_mat3<glm::mat3, glm::vec3, glm::aligned_mat3, glm::aligned_vec3, true>(Samples);
std::printf("dmat3 * dvec3 :\n");
Error += comp_vec3_mul_mat3<glm::dmat3, glm::dvec3, glm::aligned_dmat3, glm::aligned_dvec3, true>(Samples);
std::printf("mat4 * vec4 :\n");
Error += comp_vec4_mul_mat4<glm::mat4, glm::vec4, glm::aligned_mat4, glm::aligned_vec4, true>(Samples);
std::printf("dmat4 * dvec4 :\n");
Error += comp_vec4_mul_mat4<glm::dmat4, glm::dvec4, glm::aligned_dmat4, glm::aligned_dvec4, true>(Samples);
return Error;
}

View file

@ -403,7 +403,7 @@
</Expand>
</Type>
<Type Name="glm::mat&lt;3,2*,*&gt;">
<Type Name="glm::mat&lt;3,2,*,*&gt;">
<DisplayString>[{value[0]} {value[1]} {value[2]}]</DisplayString>
<Expand HideRawView="1">
<!-- display matrix in row major order - it makes more sense -->