Merge branch 'g-truc:master' into c5eaa

This commit is contained in:
Gabriel Almeida 2025-03-24 17:32:15 -03:00 committed by GitHub
commit a68c50557b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 1246 additions and 273 deletions

View file

@ -2,6 +2,9 @@ name: ci
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on:
pull_request:
branches:
- master
push:
workflow_dispatch:
@ -68,7 +71,7 @@ jobs:
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -T ${{matrix.toolkit}} -DGLM_BUILD_TESTS=ON -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
@ -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."
@ -147,7 +152,7 @@ jobs:
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -DGLM_BUILD_TESTS=ON -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
@ -178,17 +183,14 @@ jobs:
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."
@ -223,7 +225,7 @@ jobs:
- name: Run with GLM_ENABLE_SIMD_SSE2
run: |
cmake -S. -B ./build_sse2_std -DGLM_BUILD_TESTS=ON -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
@ -242,4 +244,56 @@ jobs:
cmake -S. -B ./build_avx1_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_AVX=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_avx1_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_avx1_ext
macos-latest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest]
std: [98, 11, 14, 17, 20]
config: [Debug, Release]
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- name: CMake Version
run: cmake --version
- name: Run with automagic detection
run: |
cmake -S. -B ./build_auto -DGLM_BUILD_TESTS=ON
cmake --build ./build_auto --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_auto
- name: Run with GLM_FORCE_PURE
run: |
cmake -S. -B ./build_pure_std -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_pure_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_std
- name: Run with GLM_FORCE_PURE and language extensions
run: |
cmake -S. -B ./build_pure_ext -DGLM_BUILD_TESTS=ON -DGLM_FORCE_PURE=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_pure_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_pure_ext
- name: Run with GLM_ENABLE_SIMD_NEON
run: |
cmake -S. -B ./build_neon_std -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_NEON=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON
cmake --build ./build_neon_std --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_neon_std
- name: Run with GLM_ENABLE_SIMD_NEON and language extensions
run: |
cmake -S. -B ./build_neon_ext -DGLM_BUILD_TESTS=ON -DGLM_ENABLE_SIMD_NEON=ON -DGLM_ENABLE_CXX_${{matrix.std}}=ON -DGLM_ENABLE_LANG_EXTENSIONS=ON
cmake --build ./build_neon_ext --config ${{matrix.config}}
ctest --verbose -C ${{matrix.config}} --test-dir ./build_neon_ext

View file

@ -15,7 +15,7 @@ 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
@ -29,13 +29,13 @@ jobs:
- name: Create 7z archive
run: 7z a glm-${{ env.RELEASE_VERSION }}.7z .
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
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 }}.zip

View file

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.6 FATAL_ERROR)
cmake_policy(VERSION 3.6)
# 3.6 is the actual minimun. 3.14 as the upper policy limit avoids CMake deprecation warnings.
cmake_minimum_required(VERSION 3.6...3.14 FATAL_ERROR)
cmake_policy(VERSION 3.6...3.14)
file(READ "glm/detail/setup.hpp" GLM_SETUP_FILE)
string(REGEX MATCH "#define[ ]+GLM_VERSION_MAJOR[ ]+([0-9]+)" _ ${GLM_SETUP_FILE})
@ -149,7 +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_TEST_ENABLE_SIMD_NEON "Enable ARM NEON optimizations" OFF)
option(GLM_ENABLE_SIMD_NEON "Enable ARM NEON optimizations" OFF)
option(GLM_FORCE_PURE "Force 'pure' instructions" OFF)
if(GLM_FORCE_PURE)
@ -192,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")
@ -243,8 +244,9 @@ elseif(GLM_ENABLE_SIMD_SSE2)
add_compile_options(/arch:SSE2)
endif()
message(STATUS "GLM: SSE2 instruction set")
elseif(GLM_TEST_ENABLE_SIMD_NEON)
add_definitions(-DGLM_FORCE_NEON)
elseif(GLM_ENABLE_SIMD_NEON)
add_definitions(-DGLM_FORCE_INTRINSICS)
message(STATUS "GLM: ARM NEON instruction set")
endif()

View file

@ -345,7 +345,7 @@ namespace detail
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;
vec<L, T, Q> v(0.0f);
for (int i = 0; i < L; ++i)
v[i] = a[c];
return v;

View file

@ -573,7 +573,9 @@ namespace glm {
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)

View file

@ -240,6 +240,7 @@ namespace detail
struct storage<3, unsigned int, true> : public storage<4, unsigned int, true>
{};
# if GLM_HAS_ALIGNOF
template<>
struct storage<3, double, true>
{
@ -247,6 +248,7 @@ namespace detail
double data[4];
} type;
};
# endif//GLM_HAS_ALIGNOF
# endif

View file

@ -148,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
@ -506,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

View file

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

View file

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

View file

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

View file

@ -501,11 +501,11 @@ namespace glm
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]);
mat<3, 3, T, Q> Result;
Result[0] = xyz(glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
Result[1] = xyz(glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
Result[2] = xyz(glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
return mat<3, 3, T, Q>(Result);
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
@ -522,26 +522,22 @@ namespace glm
typename mat<3, 3, T, Q>::col_type const& SrcB1 = m2[1];
typename mat<3, 3, T, Q>::col_type const& SrcB2 = m2[2];
mat<3, 3, T, Q> Result;
// 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 * SrcB1.z + SrcA1 * SrcB1.y + SrcA0 * SrcB1.x;
//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 tmp;
tmp = SrcA0 * SrcB0.x;
tmp += SrcA1 * SrcB0.y;
tmp += SrcA2 * SrcB0.z;
Result[0] = tmp;
tmp = SrcA0 * SrcB1.x;
tmp += SrcA1 * SrcB1.y;
tmp += SrcA2 * SrcB1.z;
Result[1] = tmp;
tmp = SrcA0 * SrcB2.x;
tmp += SrcA1 * SrcB2.y;
tmp += SrcA2 * SrcB2.z;
Result[2] = tmp;
return Result;
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);
}
};
}

View file

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

View file

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

View file

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

View file

@ -647,12 +647,12 @@ namespace glm
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] = glm::fma(SrcA3, splatW(SrcB0), glm::fma(SrcA2, splatZ(SrcB0), glm::fma(SrcA1, splatY(SrcB0), SrcA0 * splatX(SrcB0))));
Result[1] = glm::fma(SrcA3, splatW(SrcB1), glm::fma(SrcA2, splatZ(SrcB1), glm::fma(SrcA1, splatY(SrcB1), SrcA0 * splatX(SrcB1))));
Result[2] = glm::fma(SrcA3, splatW(SrcB2), glm::fma(SrcA2, splatZ(SrcB2), glm::fma(SrcA1, splatY(SrcB2), SrcA0 * splatX(SrcB2))));
Result[3] = glm::fma(SrcA3, splatW(SrcB3), glm::fma(SrcA2, splatZ(SrcB3), glm::fma(SrcA1, splatY(SrcB3), SrcA0 * splatX(SrcB3))));
return mat < 4, 4, T, Q > (Result);
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);
}
};
@ -671,36 +671,30 @@ namespace glm
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;
// 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 tmp;
tmp = SrcA0 * SrcB0.x;
tmp += SrcA1 * SrcB0.y;
tmp += SrcA2 * SrcB0.z;
tmp += SrcA3 * SrcB0.w;
Result[0] = tmp;
tmp = SrcA0 * SrcB1.x;
tmp += SrcA1 * SrcB1.y;
tmp += SrcA2 * SrcB1.z;
tmp += SrcA3 * SrcB1.w;
Result[1] = tmp;
tmp = SrcA0 * SrcB2.x;
tmp += SrcA1 * SrcB2.y;
tmp += SrcA2 * SrcB2.z;
tmp += SrcA3 * SrcB2.w;
Result[2] = tmp;
tmp = SrcA0 * SrcB3.x;
tmp += SrcA1 * SrcB3.y;
tmp += SrcA2 * SrcB3.z;
tmp += SrcA3 * SrcB3.w;
Result[3] = tmp;
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 Result;
return mat<4, 4, T, Q>(tmp0, tmp1, tmp2, tmp3);
}
};
}

View file

@ -921,7 +921,7 @@ struct _swizzle_base1<L, uint, Q, E0, E1, E2, E3, true> : public _swizzle_base1<
{
static bool call(vec<L, float, Q> const& v1, vec<L, float, Q> const& v2)
{
return !compute_vec_equal<float, Q, false, 32, true>::call(v1, v2);
return !compute_vec_equal<L, float, Q, false, 32, true>::call(v1, v2);
}
};
@ -930,7 +930,7 @@ struct _swizzle_base1<L, uint, Q, E0, E1, E2, E3, true> : public _swizzle_base1<
{
static bool call(vec<L, uint, Q> const& v1, vec<L, uint, Q> const& v2)
{
return !compute_vec_equal<uint, Q, false, 32, true>::call(v1, v2);
return !compute_vec_equal<L, uint, Q, false, 32, true>::call(v1, v2);
}
};
@ -939,7 +939,7 @@ struct _swizzle_base1<L, uint, Q, E0, E1, E2, E3, true> : public _swizzle_base1<
{
static bool call(vec<L, int, Q> const& v1, vec<L, int, Q> const& v2)
{
return !compute_vec_equal<int, Q, false, 32, true>::call(v1, v2);
return !compute_vec_equal<L, int, Q, false, 32, true>::call(v1, v2);
}
};

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -105,7 +105,7 @@ target_link_libraries(main PRIVATE glm::glm)
## Release notes
### [GLM 1.0.2](https://github.com/g-truc/glm/tree/master) - 2024-0X-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.

View file

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

View file

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

View file

@ -1,3 +1,12 @@
#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
@ -111,3 +120,5 @@ int main()
return Error;
}
#endif//GLM_PLATFORM & GLM_PLATFORM_APPLE

View file

@ -1,6 +1,6 @@
#include <glm/glm.hpp>
#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE
#if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && !(GLM_ARCH & GLM_ARCH_NEON_BIT) // Fail on Github macOS latest C.I.
#include <glm/gtc/type_aligned.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/ext/scalar_relational.hpp>

View file

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

View file

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

View file

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

View file

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