mirror of
https://github.com/g-truc/glm.git
synced 2025-04-13 08:43:00 +00:00
Compare commits
65 commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d4c4b4dd3 | ||
|
69b130c162 | ||
|
af86309663 | ||
|
e54e16f3da | ||
|
5847dd91b2 | ||
|
edc3607b39 | ||
|
624090a855 | ||
|
af69cb1a6e | ||
|
c11bff7853 | ||
|
6dddbfb066 | ||
|
57738871cc | ||
|
fe26a526cd | ||
|
242233ea20 | ||
|
97995f4713 | ||
|
08a6421adb | ||
|
44c0039c7c | ||
|
abcc96b4b9 | ||
|
a036baa4d8 | ||
|
303a9d79ed | ||
|
9e6f0ec1f6 | ||
|
c8132b31f7 | ||
|
7a878c2372 | ||
|
e7d5bdafa7 | ||
|
f27f0e0026 | ||
|
18feaec455 | ||
|
5221557360 | ||
|
f6341a1feb | ||
|
5b295d8a45 | ||
|
3c18b0f815 | ||
|
86bdcc44e8 | ||
|
7d3e3cdd62 | ||
|
37112e419c | ||
|
f7485100cb | ||
|
3adb4236fe | ||
|
4006273cb3 | ||
|
d03194c053 | ||
|
9b15c54c8c | ||
|
23551ae74e | ||
|
b30313ac30 | ||
|
437fe63665 | ||
|
1926a11cac | ||
|
0d8637447c | ||
|
33b4a621a6 | ||
|
45008b225e | ||
|
a2844eede8 | ||
|
0904870e37 | ||
|
4137519418 | ||
|
ab913bbdd0 | ||
|
c32a481dd4 | ||
|
05c93eeae0 | ||
|
0df8dcb454 | ||
|
08a11905cf | ||
|
c48d16b911 | ||
|
7a812397a2 | ||
|
61caae4d05 | ||
|
e009bcbe7c | ||
|
ab2d7b4291 | ||
|
49942a611c | ||
|
dcc5cfdc4a | ||
|
f8df2f3e2e | ||
|
be3beb7788 | ||
|
0892ccd214 | ||
|
1f25000a30 | ||
|
b9424441b1 | ||
|
3ac3589ed2 |
86 changed files with 4461 additions and 1973 deletions
116
.github/workflows/ci.yml
vendored
116
.github/workflows/ci.yml
vendored
|
@ -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
|
||||
|
||||
|
||||
|
|
22
.github/workflows/make_light_release.yml
vendored
22
.github/workflows/make_light_release.yml
vendored
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }; \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 --
|
||||
|
||||
|
|
|
@ -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
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1032
glm/detail/type_vec_simd.inl
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
// Dependency:
|
||||
#include "../geometric.hpp"
|
||||
#include "../gtx/quaternion.hpp"
|
||||
#include "../gtx/component_wise.hpp"
|
||||
|
||||
#ifndef GLM_ENABLE_EXPERIMENTAL
|
||||
|
|
|
@ -42,4 +42,3 @@ namespace glm{
|
|||
/// @}
|
||||
}//namespace glm
|
||||
|
||||
#include "number_precision.inl"
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
#ifndef GLM_HAS_CXX11_STL
|
||||
#include <algorithm>
|
||||
#else
|
||||
#include <utility>
|
||||
#endif
|
||||
#include <utility>
|
||||
|
||||
namespace glm {
|
||||
|
||||
|
|
92
glm/gtx/structured_bindings.hpp
Normal file
92
glm/gtx/structured_bindings.hpp
Normal 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"
|
55
glm/gtx/structured_bindings.inl
Normal file
55
glm/gtx/structured_bindings.inl
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 doesn’t support AVX2 instrinsics, compiler errors will happen.
|
||||
// If the compiler doesn’t 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
|
||||
|
||||
|
|
37
readme.md
37
readme.md
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
442
test/core/core_force_intrinsics.cpp
Normal file
442
test/core/core_force_intrinsics.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -176,6 +176,10 @@ static int test_constexpr()
|
|||
|
||||
int main()
|
||||
{
|
||||
// Suppress unused variable warnings
|
||||
(void)g1;
|
||||
(void)g2;
|
||||
|
||||
int Error = 0;
|
||||
|
||||
Error += test_size();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
366
test/gtx/gtx_structured_bindings.cpp
Normal file
366
test/gtx/gtx_structured_bindings.cpp
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -403,7 +403,7 @@
|
|||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="glm::mat<3,2*,*>">
|
||||
<Type Name="glm::mat<3,2,*,*>">
|
||||
<DisplayString>[{value[0]} {value[1]} {value[2]}]</DisplayString>
|
||||
<Expand HideRawView="1">
|
||||
<!-- display matrix in row major order - it makes more sense -->
|
||||
|
|
Loading…
Add table
Reference in a new issue