Codebase list glm / e5ed5a6
Update upstream source from tag 'upstream/0.9.9.7+ds' Update to upstream version '0.9.9.7+ds' with Debian dir ede85ac73ca8aeac829b69f06ffe55da52b11295 Carsten Schoenert 4 years ago
43 changed file(s) with 1135 addition(s) and 445 deletion(s). Raw diff Collapse all Expand all
1818 - GLM_ARGUMENTS: -DGLM_TEST_FORCE_PURE=ON
1919 - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
2020 - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
21 - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
22 - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
2123
2224 matrix:
2325 exclude:
2426 - image: Visual Studio 2013
2527 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
2628 - image: Visual Studio 2013
29 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
30 - image: Visual Studio 2013
31 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
32 - image: Visual Studio 2013
2733 configuration: Debug
2834 - image: Visual Studio 2015
2935 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON
36 - image: Visual Studio 2015
37 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_14=ON
38 - image: Visual Studio 2015
39 GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON -DGLM_TEST_ENABLE_CXX_17=ON
3040 - image: Visual Studio 2015
3141 platform: x86
3242 - image: Visual Studio 2015
22
33 set(GLM_VERSION "0.9.9")
44 project(glm VERSION ${GLM_VERSION} LANGUAGES CXX)
5
65 enable_testing()
76
8 option(GLM_QUIET "No CMake Message" OFF)
9 option(BUILD_SHARED_LIBS "Build shared library" ON)
10 option(BUILD_STATIC_LIBS "Build static library" ON)
11 option(GLM_TEST_ENABLE_CXX_98 "Enable C++ 98" OFF)
12 option(GLM_TEST_ENABLE_CXX_11 "Enable C++ 11" OFF)
13 option(GLM_TEST_ENABLE_CXX_14 "Enable C++ 14" OFF)
14 option(GLM_TEST_ENABLE_CXX_17 "Enable C++ 17" OFF)
15 option(GLM_TEST_ENABLE_CXX_20 "Enable C++ 20" OFF)
7 add_subdirectory(glm)
8 add_library(glm::glm ALIAS glm)
169
17 set(CMAKE_CXX_STANDARD_REQUIRED ON)
10 if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
1811
19 if(GLM_TEST_ENABLE_CXX_20)
20 set(CMAKE_CXX_STANDARD 20)
21 add_definitions(-DGLM_FORCE_CXX2A)
22 if(NOT GLM_QUIET)
23 message(STATUS "GLM: Build with C++20 features")
24 endif()
25
26 elseif(GLM_TEST_ENABLE_CXX_17)
27 set(CMAKE_CXX_STANDARD 17)
28 add_definitions(-DGLM_FORCE_CXX17)
29 if(NOT GLM_QUIET)
30 message(STATUS "GLM: Build with C++17 features")
31 endif()
32
33 elseif(GLM_TEST_ENABLE_CXX_14)
34 set(CMAKE_CXX_STANDARD 14)
35 add_definitions(-DGLM_FORCE_CXX14)
36 if(NOT GLM_QUIET)
37 message(STATUS "GLM: Build with C++14 features")
38 endif()
39
40 elseif(GLM_TEST_ENABLE_CXX_11)
41 set(CMAKE_CXX_STANDARD 11)
42 add_definitions(-DGLM_FORCE_CXX11)
43 if(NOT GLM_QUIET)
44 message(STATUS "GLM: Build with C++11 features")
45 endif()
46
47 elseif(GLM_TEST_ENABLE_CXX_98)
48 set(CMAKE_CXX_STANDARD 98)
49 add_definitions(-DGLM_FORCE_CXX98)
50 if(NOT GLM_QUIET)
51 message(STATUS "GLM: Build with C++98 features")
52 endif()
53 endif()
54
55 option(GLM_TEST_ENABLE_LANG_EXTENSIONS "Enable language extensions" OFF)
56
57 option(GLM_DISABLE_AUTO_DETECTION "Enable language extensions" OFF)
58
59 if(GLM_DISABLE_AUTO_DETECTION)
60 add_definitions(-DGLM_FORCE_PLATFORM_UNKNOWN -DGLM_FORCE_COMPILER_UNKNOWN -DGLM_FORCE_ARCH_UNKNOWN -DGLM_FORCE_CXX_UNKNOWN)
61 endif()
62
63 if(GLM_TEST_ENABLE_LANG_EXTENSIONS)
64 set(CMAKE_CXX_EXTENSIONS ON)
65 if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
66 add_compile_options(-fms-extensions)
67 endif()
68 message(STATUS "GLM: Build with C++ language extensions")
69 else()
70 set(CMAKE_CXX_EXTENSIONS OFF)
71 if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
72 add_compile_options(/Za)
73 if(MSVC15)
74 add_compile_options(/permissive-)
75 endif()
76 endif()
77 endif()
78
79 option(GLM_TEST_ENABLE_FAST_MATH "Enable fast math optimizations" OFF)
80 if(GLM_TEST_ENABLE_FAST_MATH)
81 if(NOT GLM_QUIET)
82 message(STATUS "GLM: Build with fast math optimizations")
83 endif()
84
85 if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
86 add_compile_options(-ffast-math)
87
88 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
89 add_compile_options(/fp:fast)
90 endif()
91 else()
92 if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
93 add_compile_options(/fp:precise)
94 endif()
95 endif()
96
97 option(GLM_TEST_ENABLE "Build unit tests" ON)
98 option(GLM_TEST_ENABLE_SIMD_SSE2 "Enable SSE2 optimizations" OFF)
99 option(GLM_TEST_ENABLE_SIMD_SSE3 "Enable SSE3 optimizations" OFF)
100 option(GLM_TEST_ENABLE_SIMD_SSSE3 "Enable SSSE3 optimizations" OFF)
101 option(GLM_TEST_ENABLE_SIMD_SSE4_1 "Enable SSE 4.1 optimizations" OFF)
102 option(GLM_TEST_ENABLE_SIMD_SSE4_2 "Enable SSE 4.2 optimizations" OFF)
103 option(GLM_TEST_ENABLE_SIMD_AVX "Enable AVX optimizations" OFF)
104 option(GLM_TEST_ENABLE_SIMD_AVX2 "Enable AVX2 optimizations" OFF)
105 option(GLM_TEST_FORCE_PURE "Force 'pure' instructions" OFF)
106
107 if(GLM_TEST_FORCE_PURE)
108 add_definitions(-DGLM_FORCE_PURE)
109
110 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
111 add_compile_options(-mfpmath=387)
112 endif()
113 message(STATUS "GLM: No SIMD instruction set")
114
115 elseif(GLM_TEST_ENABLE_SIMD_AVX2)
116 add_definitions(-DGLM_FORCE_PURE)
117
118 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
119 add_compile_options(-mavx2)
120 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
121 add_compile_options(/QxAVX2)
122 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
123 add_compile_options(/arch:AVX2)
124 endif()
125 message(STATUS "GLM: AVX2 instruction set")
126
127 elseif(GLM_TEST_ENABLE_SIMD_AVX)
128 add_definitions(-DGLM_FORCE_INTRINSICS)
129
130 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
131 add_compile_options(-mavx)
132 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
133 add_compile_options(/QxAVX)
134 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
135 add_compile_options(/arch:AVX)
136 endif()
137 message(STATUS "GLM: AVX instruction set")
138
139 elseif(GLM_TEST_ENABLE_SIMD_SSE4_2)
140 add_definitions(-DGLM_FORCE_INTRINSICS)
141
142 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
143 add_compile_options(-msse4.2)
144 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
145 add_compile_options(/QxSSE4.2)
146 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
147 add_compile_options(/arch:SSE2) # VC doesn't support SSE4.2
148 endif()
149 message(STATUS "GLM: SSE4.2 instruction set")
150
151 elseif(GLM_TEST_ENABLE_SIMD_SSE4_1)
152 add_definitions(-DGLM_FORCE_INTRINSICS)
153
154 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
155 add_compile_options(-msse4.1)
156 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
157 add_compile_options(/QxSSE4.1)
158 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
159 add_compile_options(/arch:SSE2) # VC doesn't support SSE4.1
160 endif()
161 message(STATUS "GLM: SSE4.1 instruction set")
162
163 elseif(GLM_TEST_ENABLE_SIMD_SSSE3)
164 add_definitions(-DGLM_FORCE_INTRINSICS)
165
166 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
167 add_compile_options(-mssse3)
168 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
169 add_compile_options(/QxSSSE3)
170 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
171 add_compile_options(/arch:SSE2) # VC doesn't support SSSE3
172 endif()
173 message(STATUS "GLM: SSSE3 instruction set")
174
175 elseif(GLM_TEST_ENABLE_SIMD_SSE3)
176 add_definitions(-DGLM_FORCE_INTRINSICS)
177
178 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
179 add_compile_options(-msse3)
180 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
181 add_compile_options(/QxSSE3)
182 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
183 add_compile_options(/arch:SSE2) # VC doesn't support SSE3
184 endif()
185 message(STATUS "GLM: SSE3 instruction set")
186
187 elseif(GLM_TEST_ENABLE_SIMD_SSE2)
188 add_definitions(-DGLM_FORCE_INTRINSICS)
189
190 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
191 add_compile_options(-msse2)
192 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
193 add_compile_options(/QxSSE2)
194 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
195 add_compile_options(/arch:SSE2)
196 endif()
197 message(STATUS "GLM: SSE2 instruction set")
198 endif()
199
200 # Compiler and default options
201
202 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
203 if(NOT GLM_QUIET)
204 message("GLM: Clang - ${CMAKE_CXX_COMPILER_ID} compiler")
205 endif()
206
207 add_compile_options(-Werror -Weverything)
208 add_compile_options(-Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-c++11-long-long -Wno-padded -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
209 add_compile_options(-Wno-undefined-reinterpret-cast -Wno-sign-conversion -Wno-unused-variable -Wno-missing-prototypes -Wno-unreachable-code -Wno-missing-variable-declarations -Wno-sign-compare -Wno-global-constructors -Wno-unused-macros -Wno-format-nonliteral)
210
211 elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
212 if(NOT GLM_QUIET)
213 message("GLM: GCC - ${CMAKE_CXX_COMPILER_ID} compiler")
214 endif()
215
216 add_compile_options(-O2)
217 add_compile_options(-Wno-long-long)
218
219 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
220 if(NOT GLM_QUIET)
221 message("GLM: Intel - ${CMAKE_CXX_COMPILER_ID} compiler")
222 endif()
223
224 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
225 if(NOT GLM_QUIET)
226 message("GLM: Visual C++ - ${CMAKE_CXX_COMPILER_ID} compiler")
227 endif()
228
229 add_compile_options(/W4 /WX)
230 add_compile_options(/wd4309 /wd4324 /wd4389 /wd4127 /wd4267 /wd4146 /wd4201 /wd4464 /wd4514 /wd4701 /wd4820 /wd4365)
231 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
232 endif()
233
234 include_directories("${PROJECT_SOURCE_DIR}")
235
236 add_subdirectory(glm)
23712 add_subdirectory(test)
23813
14 endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
00 ================================================================================
11 OpenGL Mathematics (GLM)
22 --------------------------------------------------------------------------------
3 GLM is licensed under The Happy Bunny License and MIT License
3 GLM is licensed under The Happy Bunny License or MIT License
44
55 ================================================================================
66 The Happy Bunny License (Modified MIT License)
77 --------------------------------------------------------------------------------
8 Copyright (c) 2005 - 2014 G-Truc Creation
8 Copyright (c) 2005 - G-Truc Creation
99
1010 Permission is hereby granted, free of charge, to any person obtaining a copy
1111 of this software and associated documentation files (the "Software"), to deal
3232 ================================================================================
3333 The MIT License
3434 --------------------------------------------------------------------------------
35 Copyright (c) 2005 - 2014 G-Truc Creation
35 Copyright (c) 2005 - G-Truc Creation
3636
3737 Permission is hereby granted, free of charge, to any person obtaining a copy
3838 of this software and associated documentation files (the "Software"), to deal
4141 source_group("SIMD Files" FILES ${SIMD_INLINE})
4242 source_group("SIMD Files" FILES ${SIMD_HEADER})
4343
44 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
44 add_library(glm INTERFACE)
45 target_include_directories(glm INTERFACE ../)
4546
4647 if(BUILD_STATIC_LIBS)
4748 add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT}
5152 ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
5253 ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
5354 ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER})
55 target_link_libraries(glm_static PUBLIC glm)
56 add_library(glm::glm_static ALIAS glm_static)
5457 endif()
5558
5659 if(BUILD_SHARED_LIBS)
6164 ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER}
6265 ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}
6366 ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER})
67 target_link_libraries(glm_shared PUBLIC glm)
68 add_library(glm::glm_shared ALIAS glm_shared)
6469 endif()
65
286286 std::numeric_limits<genFIType>::is_iec559 || (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer),
287287 "'sign' only accept signed inputs");
288288
289 return detail::compute_sign<1, genFIType, defaultp, std::numeric_limits<genFIType>::is_iec559, highp>::call(vec<1, genFIType>(x)).x;
289 return detail::compute_sign<1, genFIType, defaultp,
290 std::numeric_limits<genFIType>::is_iec559, detail::is_aligned<highp>::value>::call(vec<1, genFIType>(x)).x;
290291 }
291292
292293 template<length_t L, typename T, qualifier Q>
736737 return reinterpret_cast<vec<L, float, Q>&>(const_cast<vec<L, uint, Q>&>(v));
737738 }
738739
739 template<typename genType>
740 GLM_FUNC_QUALIFIER genType fma(genType const& a, genType const& b, genType const& c)
741 {
742 return a * b + c;
743 }
740 # if GLM_HAS_CXX11_STL
741 using std::fma;
742 # else
743 template<typename genType>
744 GLM_FUNC_QUALIFIER genType fma(genType const& a, genType const& b, genType const& c)
745 {
746 return a * b + c;
747 }
748 # endif
744749
745750 template<typename genType>
746751 GLM_FUNC_QUALIFIER genType frexp(genType x, int& exp)
9595 }//namespace detail
9696 }//namespace glm
9797
98 #elif GLM_ARCH & GLM_ARCH_NEON_BIT
99 namespace glm{
100 namespace detail
101 {
102 template<qualifier Q>
103 struct compute_length<4, float, Q, true>
104 {
105 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& v)
106 {
107 return compute_dot<vec<4, float, Q>, float, true>::call(v, v);
108 }
109 };
110
111 template<qualifier Q>
112 struct compute_distance<4, float, Q, true>
113 {
114 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& p0, vec<4, float, Q> const& p1)
115 {
116 return compute_length<4, float, Q, true>::call(p1 - p0);
117 }
118 };
119
120
121 template<qualifier Q>
122 struct compute_dot<vec<4, float, Q>, float, true>
123 {
124 GLM_FUNC_QUALIFIER static float call(vec<4, float, Q> const& x, vec<4, float, Q> const& y)
125 {
126 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
127 float32x4_t v = vmulq_f32(x.data, y.data);
128 v = vpaddq_f32(v, v);
129 v = vpaddq_f32(v, v);
130 return vgetq_lane_f32(v, 0);
131 #else // Armv7a with Neon
132 float32x4_t p = vmulq_f32(x.data, y.data);
133 float32x2_t v = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
134 v = vpadd_f32(v, v);
135 return vget_lane_f32(v, 0);
136 #endif
137 }
138 };
139
140 template<qualifier Q>
141 struct compute_normalize<4, float, Q, true>
142 {
143 GLM_FUNC_QUALIFIER static vec<4, float, Q> call(vec<4, float, Q> const& v)
144 {
145 float32x4_t p = vmulq_f32(v.data, v.data);
146 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
147 p = vpaddq_f32(p, p);
148 p = vpaddq_f32(p, p);
149 #else
150 float32x2_t t = vpadd_f32(vget_low_f32(p), vget_high_f32(p));
151 t = vpadd_f32(t, t);
152 p = vcombine_f32(t, t);
153 #endif
154
155 float32x4_t vd = vrsqrteq_f32(p);
156 vec<4, float, Q> Result;
157 Result.data = vmulq_f32(v.data, vd);
158 return Result;
159 }
160 };
161 }//namespace detail
162 }//namespace glm
163
98164 #endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
9090 # endif
9191 }//namespace glm
9292
93 #elif GLM_ARCH & GLM_ARCH_NEON_BIT
94
95 namespace glm {
96 #if GLM_LANG & GLM_LANG_CXX11_FLAG
97 template <qualifier Q>
98 GLM_FUNC_QUALIFIER
99 typename std::enable_if<detail::is_aligned<Q>::value, mat<4, 4, float, Q>>::type
100 operator*(mat<4, 4, float, Q> const & m1, mat<4, 4, float, Q> const & m2)
101 {
102 auto MulRow = [&](int l) {
103 float32x4_t const SrcA = m2[l].data;
104
105 float32x4_t r = neon::mul_lane(m1[0].data, SrcA, 0);
106 r = neon::madd_lane(r, m1[1].data, SrcA, 1);
107 r = neon::madd_lane(r, m1[2].data, SrcA, 2);
108 r = neon::madd_lane(r, m1[3].data, SrcA, 3);
109
110 return r;
111 };
112
113 mat<4, 4, float, aligned_highp> Result;
114 Result[0].data = MulRow(0);
115 Result[1].data = MulRow(1);
116 Result[2].data = MulRow(2);
117 Result[3].data = MulRow(3);
118
119 return Result;
120 }
121 #endif // CXX11
122
123 template<qualifier Q>
124 struct detail::compute_inverse<4, 4, float, Q, true>
125 {
126 GLM_FUNC_QUALIFIER static mat<4, 4, float, Q> call(mat<4, 4, float, Q> const& m)
127 {
128 float32x4_t const& m0 = m[0].data;
129 float32x4_t const& m1 = m[1].data;
130 float32x4_t const& m2 = m[2].data;
131 float32x4_t const& m3 = m[3].data;
132
133 // m[2][2] * m[3][3] - m[3][2] * m[2][3];
134 // m[2][2] * m[3][3] - m[3][2] * m[2][3];
135 // m[1][2] * m[3][3] - m[3][2] * m[1][3];
136 // m[1][2] * m[2][3] - m[2][2] * m[1][3];
137
138 float32x4_t Fac0;
139 {
140 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
141 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
142 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
143 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
144 Fac0 = w0 * w1 - w2 * w3;
145 }
146
147 // m[2][1] * m[3][3] - m[3][1] * m[2][3];
148 // m[2][1] * m[3][3] - m[3][1] * m[2][3];
149 // m[1][1] * m[3][3] - m[3][1] * m[1][3];
150 // m[1][1] * m[2][3] - m[2][1] * m[1][3];
151
152 float32x4_t Fac1;
153 {
154 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
155 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
156 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
157 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
158 Fac1 = w0 * w1 - w2 * w3;
159 }
160
161 // m[2][1] * m[3][2] - m[3][1] * m[2][2];
162 // m[2][1] * m[3][2] - m[3][1] * m[2][2];
163 // m[1][1] * m[3][2] - m[3][1] * m[1][2];
164 // m[1][1] * m[2][2] - m[2][1] * m[1][2];
165
166 float32x4_t Fac2;
167 {
168 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
169 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
170 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
171 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
172 Fac2 = w0 * w1 - w2 * w3;
173 }
174
175 // m[2][0] * m[3][3] - m[3][0] * m[2][3];
176 // m[2][0] * m[3][3] - m[3][0] * m[2][3];
177 // m[1][0] * m[3][3] - m[3][0] * m[1][3];
178 // m[1][0] * m[2][3] - m[2][0] * m[1][3];
179
180 float32x4_t Fac3;
181 {
182 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
183 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 3), 3, m2, 3);
184 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
185 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 3), neon::dup_lane(m1, 3));
186 Fac3 = w0 * w1 - w2 * w3;
187 }
188
189 // m[2][0] * m[3][2] - m[3][0] * m[2][2];
190 // m[2][0] * m[3][2] - m[3][0] * m[2][2];
191 // m[1][0] * m[3][2] - m[3][0] * m[1][2];
192 // m[1][0] * m[2][2] - m[2][0] * m[1][2];
193
194 float32x4_t Fac4;
195 {
196 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
197 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 2), 3, m2, 2);
198 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
199 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 2), neon::dup_lane(m1, 2));
200 Fac4 = w0 * w1 - w2 * w3;
201 }
202
203 // m[2][0] * m[3][1] - m[3][0] * m[2][1];
204 // m[2][0] * m[3][1] - m[3][0] * m[2][1];
205 // m[1][0] * m[3][1] - m[3][0] * m[1][1];
206 // m[1][0] * m[2][1] - m[2][0] * m[1][1];
207
208 float32x4_t Fac5;
209 {
210 float32x4_t w0 = vcombine_f32(neon::dup_lane(m2, 0), neon::dup_lane(m1, 0));
211 float32x4_t w1 = neon::copy_lane(neon::dupq_lane(m3, 1), 3, m2, 1);
212 float32x4_t w2 = neon::copy_lane(neon::dupq_lane(m3, 0), 3, m2, 0);
213 float32x4_t w3 = vcombine_f32(neon::dup_lane(m2, 1), neon::dup_lane(m1, 1));
214 Fac5 = w0 * w1 - w2 * w3;
215 }
216
217 float32x4_t Vec0 = neon::copy_lane(neon::dupq_lane(m0, 0), 0, m1, 0); // (m[1][0], m[0][0], m[0][0], m[0][0]);
218 float32x4_t Vec1 = neon::copy_lane(neon::dupq_lane(m0, 1), 0, m1, 1); // (m[1][1], m[0][1], m[0][1], m[0][1]);
219 float32x4_t Vec2 = neon::copy_lane(neon::dupq_lane(m0, 2), 0, m1, 2); // (m[1][2], m[0][2], m[0][2], m[0][2]);
220 float32x4_t Vec3 = neon::copy_lane(neon::dupq_lane(m0, 3), 0, m1, 3); // (m[1][3], m[0][3], m[0][3], m[0][3]);
221
222 float32x4_t Inv0 = Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2;
223 float32x4_t Inv1 = Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4;
224 float32x4_t Inv2 = Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5;
225 float32x4_t Inv3 = Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5;
226
227 float32x4_t r0 = float32x4_t{-1, +1, -1, +1} * Inv0;
228 float32x4_t r1 = float32x4_t{+1, -1, +1, -1} * Inv1;
229 float32x4_t r2 = float32x4_t{-1, +1, -1, +1} * Inv2;
230 float32x4_t r3 = float32x4_t{+1, -1, +1, -1} * Inv3;
231
232 float32x4_t det = neon::mul_lane(r0, m0, 0);
233 det = neon::madd_lane(det, r1, m0, 1);
234 det = neon::madd_lane(det, r2, m0, 2);
235 det = neon::madd_lane(det, r3, m0, 3);
236
237 float32x4_t rdet = vdupq_n_f32(1 / vgetq_lane_f32(det, 0));
238
239 mat<4, 4, float, Q> r;
240 r[0].data = vmulq_f32(r0, rdet);
241 r[1].data = vmulq_f32(r1, rdet);
242 r[2].data = vmulq_f32(r2, rdet);
243 r[3].data = vmulq_f32(r3, rdet);
244 return r;
245 }
246 };
247 }//namespace glm
93248 #endif
55 #define GLM_VERSION_MAJOR 0
66 #define GLM_VERSION_MINOR 9
77 #define GLM_VERSION_PATCH 9
8 #define GLM_VERSION_REVISION 6
9 #define GLM_VERSION 996
10 #define GLM_VERSION_MESSAGE "GLM: version 0.9.9.6"
8 #define GLM_VERSION_REVISION 7
9 #define GLM_VERSION 997
10 #define GLM_VERSION_MESSAGE "GLM: version 0.9.9.7"
1111
1212 #define GLM_SETUP_INCLUDED GLM_VERSION
1313
3434 ///////////////////////////////////////////////////////////////////////////////////
3535 // Build model
3636
37 #if defined(__arch64__) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__)
37 #if defined(_M_ARM64) || defined(__LP64__) || defined(_M_X64) || defined(__ppc64__) || defined(__x86_64__)
3838 # define GLM_MODEL GLM_MODEL_64
39 #elif defined(__i386__) || defined(__ppc__)
39 #elif defined(__i386__) || defined(__ppc__) || defined(__ILP32__) || defined(_M_ARM)
4040 # define GLM_MODEL GLM_MODEL_32
4141 #else
4242 # define GLM_MODEL GLM_MODEL_32
4141 # if GLM_LANG & GLM_LANG_CXXMS_FLAG
4242 union
4343 {
44 struct { T x, y, z, w;};
44 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
45 struct { T w, x, y, z; };
46 # else
47 struct { T x, y, z, w; };
48 # endif
4549
4650 typename detail::storage<4, T, detail::is_aligned<Q>::value>::type data;
4751 };
4852 # else
49 T x, y, z, w;
53 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
54 T w, x, y, z;
55 # else
56 T x, y, z, w;
57 # endif
5058 # endif
5159
5260 # if GLM_SILENT_WARNINGS == GLM_ENABLE
101109 GLM_FUNC_DECL qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v);
102110
103111 /// Build a quaternion from euler angles (pitch, yaw, roll), in radians.
104 GLM_FUNC_DECL GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles);
112 GLM_FUNC_DECL GLM_CONSTEXPR GLM_EXPLICIT qua(vec<3, T, Q> const& eulerAngles);
105113 GLM_FUNC_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q);
106114 GLM_FUNC_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q);
107115
108116 // -- Unary arithmetic operators --
109117
110 GLM_FUNC_DECL qua<T, Q>& operator=(qua<T, Q> const& q) GLM_DEFAULT;
118 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator=(qua<T, Q> const& q) GLM_DEFAULT;
111119
112120 template<typename U>
113 GLM_FUNC_DECL qua<T, Q>& operator=(qua<U, Q> const& q);
121 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator=(qua<U, Q> const& q);
114122 template<typename U>
115 GLM_FUNC_DECL qua<T, Q>& operator+=(qua<U, Q> const& q);
123 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator+=(qua<U, Q> const& q);
116124 template<typename U>
117 GLM_FUNC_DECL qua<T, Q>& operator-=(qua<U, Q> const& q);
125 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator-=(qua<U, Q> const& q);
118126 template<typename U>
119 GLM_FUNC_DECL qua<T, Q>& operator*=(qua<U, Q> const& q);
127 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator*=(qua<U, Q> const& q);
120128 template<typename U>
121 GLM_FUNC_DECL qua<T, Q>& operator*=(U s);
129 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator*=(U s);
122130 template<typename U>
123 GLM_FUNC_DECL qua<T, Q>& operator/=(U s);
131 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q>& operator/=(U s);
124132 };
125133
126134 // -- Unary bit operators --
127135
128136 template<typename T, qualifier Q>
129 GLM_FUNC_DECL qua<T, Q> operator+(qua<T, Q> const& q);
137 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q);
130138
131139 template<typename T, qualifier Q>
132 GLM_FUNC_DECL qua<T, Q> operator-(qua<T, Q> const& q);
140 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q);
133141
134142 // -- Binary operators --
135143
136144 template<typename T, qualifier Q>
137 GLM_FUNC_DECL qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p);
145 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p);
138146
139147 template<typename T, qualifier Q>
140 GLM_FUNC_DECL qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p);
148 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p);
141149
142150 template<typename T, qualifier Q>
143 GLM_FUNC_DECL qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p);
151 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p);
144152
145153 template<typename T, qualifier Q>
146 GLM_FUNC_DECL vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v);
154 GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v);
147155
148156 template<typename T, qualifier Q>
149 GLM_FUNC_DECL vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q);
157 GLM_FUNC_DECL GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q);
150158
151159 template<typename T, qualifier Q>
152 GLM_FUNC_DECL vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v);
160 GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v);
153161
154162 template<typename T, qualifier Q>
155 GLM_FUNC_DECL vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q);
163 GLM_FUNC_DECL GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q);
156164
157165 template<typename T, qualifier Q>
158 GLM_FUNC_DECL qua<T, Q> operator*(qua<T, Q> const& q, T const& s);
166 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, T const& s);
159167
160168 template<typename T, qualifier Q>
161 GLM_FUNC_DECL qua<T, Q> operator*(T const& s, qua<T, Q> const& q);
169 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator*(T const& s, qua<T, Q> const& q);
162170
163171 template<typename T, qualifier Q>
164 GLM_FUNC_DECL qua<T, Q> operator/(qua<T, Q> const& q, T const& s);
172 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> operator/(qua<T, Q> const& q, T const& s);
165173
166174 // -- Boolean operators --
167175
1414 template<typename T, qualifier Q, bool Aligned>
1515 struct compute_dot<qua<T, Q>, T, Aligned>
1616 {
17 static GLM_FUNC_QUALIFIER T call(qua<T, Q> const& a, qua<T, Q> const& b)
17 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(qua<T, Q> const& a, qua<T, Q> const& b)
1818 {
1919 vec<4, T, Q> tmp(a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z);
2020 return (tmp.x + tmp.y) + (tmp.z + tmp.w);
2424 template<typename T, qualifier Q, bool Aligned>
2525 struct compute_quat_add
2626 {
27 static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
27 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
2828 {
2929 return qua<T, Q>(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z);
3030 }
3333 template<typename T, qualifier Q, bool Aligned>
3434 struct compute_quat_sub
3535 {
36 static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
36 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, qua<T, Q> const& p)
3737 {
3838 return qua<T, Q>(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z);
3939 }
4242 template<typename T, qualifier Q, bool Aligned>
4343 struct compute_quat_mul_scalar
4444 {
45 static qua<T, Q> call(qua<T, Q> const& q, T s)
45 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
4646 {
4747 return qua<T, Q>(q.w * s, q.x * s, q.y * s, q.z * s);
4848 }
5151 template<typename T, qualifier Q, bool Aligned>
5252 struct compute_quat_div_scalar
5353 {
54 static qua<T, Q> call(qua<T, Q> const& q, T s)
54 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static qua<T, Q> call(qua<T, Q> const& q, T s)
5555 {
5656 return qua<T, Q>(q.w / s, q.x / s, q.y / s, q.z / s);
5757 }
6060 template<typename T, qualifier Q, bool Aligned>
6161 struct compute_quat_mul_vec4
6262 {
63 static vec<4, T, Q> call(qua<T, Q> const& q, vec<4, T, Q> const& v)
63 GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<4, T, Q> call(qua<T, Q> const& q, vec<4, T, Q> const& v)
6464 {
6565 return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w);
6666 }
7373 GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua<T, Q>::operator[](typename qua<T, Q>::length_type i)
7474 {
7575 assert(i >= 0 && i < this->length());
76 return (&x)[i];
76 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
77 return (&w)[i];
78 # else
79 return (&x)[i];
80 # endif
7781 }
7882
7983 template<typename T, qualifier Q>
8084 GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua<T, Q>::operator[](typename qua<T, Q>::length_type i) const
8185 {
8286 assert(i >= 0 && i < this->length());
83 return (&x)[i];
87 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
88 return (&w)[i];
89 # else
90 return (&x)[i];
91 # endif
8492 }
8593
8694 // -- Implicit basic constructors --
8997 template<typename T, qualifier Q>
9098 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua()
9199 # if GLM_CONFIG_CTOR_INIT != GLM_CTOR_INIT_DISABLE
92 : x(0), y(0), z(0), w(1)
100 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
101 : w(1), x(0), y(0), z(0)
102 # else
103 : x(0), y(0), z(0), w(1)
104 # endif
93105 # endif
94106 {}
95107
96108 template<typename T, qualifier Q>
97109 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<T, Q> const& q)
98 : x(q.x), y(q.y), z(q.z), w(q.w)
110 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
111 : w(q.w), x(q.x), y(q.y), z(q.z)
112 # else
113 : x(q.x), y(q.y), z(q.z), w(q.w)
114 # endif
99115 {}
100116 # endif
101117
102118 template<typename T, qualifier Q>
103119 template<qualifier P>
104120 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<T, P> const& q)
105 : x(q.x), y(q.y), z(q.z), w(q.w)
121 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
122 : w(q.w), x(q.x), y(q.y), z(q.z)
123 # else
124 : x(q.x), y(q.y), z(q.z), w(q.w)
125 # endif
106126 {}
107127
108128 // -- Explicit basic constructors --
109129
110130 template<typename T, qualifier Q>
111131 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T s, vec<3, T, Q> const& v)
112 : x(v.x), y(v.y), z(v.z), w(s)
132 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
133 : w(s), x(v.x), y(v.y), z(v.z)
134 # else
135 : x(v.x), y(v.y), z(v.z), w(s)
136 # endif
113137 {}
114138
115139 template <typename T, qualifier Q>
116140 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(T _w, T _x, T _y, T _z)
117 : x(_x), y(_y), z(_z), w(_w)
141 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
142 : w(_w), x(_x), y(_y), z(_z)
143 # else
144 : x(_x), y(_y), z(_z), w(_w)
145 # endif
118146 {}
119147
120148 // -- Conversion constructors --
122150 template<typename T, qualifier Q>
123151 template<typename U, qualifier P>
124152 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(qua<U, P> const& q)
125 : x(static_cast<T>(q.x))
126 , y(static_cast<T>(q.y))
127 , z(static_cast<T>(q.z))
128 , w(static_cast<T>(q.w))
153 # ifdef GLM_FORCE_QUAT_DATA_WXYZ
154 : w(static_cast<T>(q.w)), x(static_cast<T>(q.x)), y(static_cast<T>(q.y)), z(static_cast<T>(q.z))
155 # else
156 : x(static_cast<T>(q.x)), y(static_cast<T>(q.y)), z(static_cast<T>(q.z)), w(static_cast<T>(q.w))
157 # endif
129158 {}
130159
131160 //template<typename valType>
171200 }
172201
173202 template<typename T, qualifier Q>
174 GLM_FUNC_QUALIFIER qua<T, Q>::qua(vec<3, T, Q> const& eulerAngle)
203 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua(vec<3, T, Q> const& eulerAngle)
175204 {
176205 vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5));
177206 vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5));
212241
213242 # if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE
214243 template<typename T, qualifier Q>
215 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator=(qua<T, Q> const& q)
244 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator=(qua<T, Q> const& q)
216245 {
217246 this->w = q.w;
218247 this->x = q.x;
224253
225254 template<typename T, qualifier Q>
226255 template<typename U>
227 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator=(qua<U, Q> const& q)
256 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator=(qua<U, Q> const& q)
228257 {
229258 this->w = static_cast<T>(q.w);
230259 this->x = static_cast<T>(q.x);
235264
236265 template<typename T, qualifier Q>
237266 template<typename U>
238 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator+=(qua<U, Q> const& q)
267 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator+=(qua<U, Q> const& q)
239268 {
240269 return (*this = detail::compute_quat_add<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
241270 }
242271
243272 template<typename T, qualifier Q>
244273 template<typename U>
245 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator-=(qua<U, Q> const& q)
274 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator-=(qua<U, Q> const& q)
246275 {
247276 return (*this = detail::compute_quat_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q)));
248277 }
249278
250279 template<typename T, qualifier Q>
251280 template<typename U>
252 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator*=(qua<U, Q> const& r)
281 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator*=(qua<U, Q> const& r)
253282 {
254283 qua<T, Q> const p(*this);
255284 qua<T, Q> const q(r);
263292
264293 template<typename T, qualifier Q>
265294 template<typename U>
266 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator*=(U s)
295 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator*=(U s)
267296 {
268297 return (*this = detail::compute_quat_mul_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
269298 }
270299
271300 template<typename T, qualifier Q>
272301 template<typename U>
273 GLM_FUNC_QUALIFIER qua<T, Q> & qua<T, Q>::operator/=(U s)
302 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> & qua<T, Q>::operator/=(U s)
274303 {
275304 return (*this = detail::compute_quat_div_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s)));
276305 }
278307 // -- Unary bit operators --
279308
280309 template<typename T, qualifier Q>
281 GLM_FUNC_QUALIFIER qua<T, Q> operator+(qua<T, Q> const& q)
310 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q)
282311 {
283312 return q;
284313 }
285314
286315 template<typename T, qualifier Q>
287 GLM_FUNC_QUALIFIER qua<T, Q> operator-(qua<T, Q> const& q)
316 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q)
288317 {
289318 return qua<T, Q>(-q.w, -q.x, -q.y, -q.z);
290319 }
292321 // -- Binary operators --
293322
294323 template<typename T, qualifier Q>
295 GLM_FUNC_QUALIFIER qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p)
324 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator+(qua<T, Q> const& q, qua<T, Q> const& p)
296325 {
297326 return qua<T, Q>(q) += p;
298327 }
299328
300329 template<typename T, qualifier Q>
301 GLM_FUNC_QUALIFIER qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p)
330 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator-(qua<T, Q> const& q, qua<T, Q> const& p)
302331 {
303332 return qua<T, Q>(q) -= p;
304333 }
305334
306335 template<typename T, qualifier Q>
307 GLM_FUNC_QUALIFIER qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p)
336 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, qua<T, Q> const& p)
308337 {
309338 return qua<T, Q>(q) *= p;
310339 }
311340
312341 template<typename T, qualifier Q>
313 GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
342 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
314343 {
315344 vec<3, T, Q> const QuatVector(q.x, q.y, q.z);
316345 vec<3, T, Q> const uv(glm::cross(QuatVector, v));
320349 }
321350
322351 template<typename T, qualifier Q>
323 GLM_FUNC_QUALIFIER vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q)
352 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, T, Q> operator*(vec<3, T, Q> const& v, qua<T, Q> const& q)
324353 {
325354 return glm::inverse(q) * v;
326355 }
327356
328357 template<typename T, qualifier Q>
329 GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v)
358 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(qua<T, Q> const& q, vec<4, T, Q> const& v)
330359 {
331360 return detail::compute_quat_mul_vec4<T, Q, detail::is_aligned<Q>::value>::call(q, v);
332361 }
333362
334363 template<typename T, qualifier Q>
335 GLM_FUNC_QUALIFIER vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q)
364 GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<4, T, Q> operator*(vec<4, T, Q> const& v, qua<T, Q> const& q)
336365 {
337366 return glm::inverse(q) * v;
338367 }
339368
340369 template<typename T, qualifier Q>
341 GLM_FUNC_QUALIFIER qua<T, Q> operator*(qua<T, Q> const& q, T const& s)
370 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(qua<T, Q> const& q, T const& s)
342371 {
343372 return qua<T, Q>(
344373 q.w * s, q.x * s, q.y * s, q.z * s);
345374 }
346375
347376 template<typename T, qualifier Q>
348 GLM_FUNC_QUALIFIER qua<T, Q> operator*(T const& s, qua<T, Q> const& q)
377 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator*(T const& s, qua<T, Q> const& q)
349378 {
350379 return q * s;
351380 }
352381
353382 template<typename T, qualifier Q>
354 GLM_FUNC_QUALIFIER qua<T, Q> operator/(qua<T, Q> const& q, T const& s)
383 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> operator/(qua<T, Q> const& q, T const& s)
355384 {
356385 return qua<T, Q>(
357386 q.w / s, q.x / s, q.y / s, q.z / s);
577577 {
578578 vec<4, float, Q> Result;
579579 Result.data = vdivq_f32(a.data, b.data);
580 return Result;
581 }
582 };
583
584 template<qualifier Q>
585 struct compute_vec4_div<uint, Q, true>
586 {
587 static vec<4, uint, Q> call(vec<4, uint, Q> const& a, vec<4, uint, Q> const& b)
588 {
589 vec<4, uint, Q> Result;
590 Result.data = vdivq_u32(a.data, b.data);
591 return Result;
592 }
593 };
594
595 template<qualifier Q>
596 struct compute_vec4_div<int, Q, true>
597 {
598 static vec<4, int, Q> call(vec<4, float, Q> const& a, vec<4, int, Q> const& b)
599 {
600 vec<4, int, Q> Result;
601 Result.data = vdivq_s32(a.data, b.data);
602580 return Result;
603581 }
604582 };
6666 template<typename T>
6767 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar)
6868 {
69 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
69 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
7070 return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
71 else
71 # else
7272 return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
73 # endif
7374 }
7475
7576 template<typename T>
7677 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar)
7778 {
78 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
79 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
7980 return orthoLH_NO(left, right, bottom, top, zNear, zFar);
80 else
81 # else
8182 return orthoRH_NO(left, right, bottom, top, zNear, zFar);
83 # endif
8284 }
8385
8486 template<typename T>
8587 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar)
8688 {
87 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
89 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
8890 return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
89 else
91 # else
9092 return orthoLH_NO(left, right, bottom, top, zNear, zFar);
93 # endif
9194
9295 }
9396
9497 template<typename T>
9598 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar)
9699 {
97 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
100 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
98101 return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
99 else
102 # else
100103 return orthoRH_NO(left, right, bottom, top, zNear, zFar);
104 # endif
101105 }
102106
103107 template<typename T>
104108 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar)
105109 {
106 if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
110 # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
107111 return orthoLH_ZO(left, right, bottom, top, zNear, zFar);
108 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
112 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
109113 return orthoLH_NO(left, right, bottom, top, zNear, zFar);
110 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
114 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
111115 return orthoRH_ZO(left, right, bottom, top, zNear, zFar);
112 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
116 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
113117 return orthoRH_NO(left, right, bottom, top, zNear, zFar);
118 # endif
114119 }
115120
116121 template<typename T>
172177 template<typename T>
173178 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal)
174179 {
175 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
180 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
176181 return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
177 else
182 # else
178183 return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
184 # endif
179185 }
180186
181187 template<typename T>
182188 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal)
183189 {
184 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
190 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
185191 return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
186 else
192 # else
187193 return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
194 # endif
188195 }
189196
190197 template<typename T>
191198 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal)
192199 {
193 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
200 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
194201 return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
195 else
202 # else
196203 return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
204 # endif
197205 }
198206
199207 template<typename T>
200208 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal)
201209 {
202 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
210 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
203211 return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
204 else
212 # else
205213 return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
214 # endif
206215 }
207216
208217 template<typename T>
209218 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal)
210219 {
211 if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
220 # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
212221 return frustumLH_ZO(left, right, bottom, top, nearVal, farVal);
213 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
222 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
214223 return frustumLH_NO(left, right, bottom, top, nearVal, farVal);
215 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
224 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
216225 return frustumRH_ZO(left, right, bottom, top, nearVal, farVal);
217 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
226 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
218227 return frustumRH_NO(left, right, bottom, top, nearVal, farVal);
228 # endif
219229 }
220230
221231 template<typename T>
285295 template<typename T>
286296 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar)
287297 {
288 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
298 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
289299 return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
290 else
300 # else
291301 return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
302 # endif
292303 }
293304
294305 template<typename T>
295306 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar)
296307 {
297 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
308 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
298309 return perspectiveLH_NO(fovy, aspect, zNear, zFar);
299 else
310 # else
300311 return perspectiveRH_NO(fovy, aspect, zNear, zFar);
312 # endif
301313 }
302314
303315 template<typename T>
304316 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar)
305317 {
306 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
318 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
307319 return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
308 else
320 # else
309321 return perspectiveLH_NO(fovy, aspect, zNear, zFar);
322 # endif
310323
311324 }
312325
313326 template<typename T>
314327 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar)
315328 {
316 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
329 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
317330 return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
318 else
331 # else
319332 return perspectiveRH_NO(fovy, aspect, zNear, zFar);
333 # endif
320334 }
321335
322336 template<typename T>
323337 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar)
324338 {
325 GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
339 # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
326340 return perspectiveLH_ZO(fovy, aspect, zNear, zFar);
327 else GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
341 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
328342 return perspectiveLH_NO(fovy, aspect, zNear, zFar);
329 else GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
343 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
330344 return perspectiveRH_ZO(fovy, aspect, zNear, zFar);
331 else GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
345 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
332346 return perspectiveRH_NO(fovy, aspect, zNear, zFar);
347 # endif
333348 }
334349
335350 template<typename T>
415430 template<typename T>
416431 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar)
417432 {
418 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
433 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
419434 return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
420 else
435 # else
421436 return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
437 # endif
422438 }
423439
424440 template<typename T>
425441 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar)
426442 {
427 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
443 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
428444 return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
429 else
445 # else
430446 return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
447 # endif
431448 }
432449
433450 template<typename T>
434451 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar)
435452 {
436 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
453 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
437454 return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
438 else
455 # else
439456 return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
457 # endif
440458 }
441459
442460 template<typename T>
443461 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar)
444462 {
445 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT)
463 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT
446464 return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
447 else
465 # else
448466 return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
467 # endif
449468 }
450469
451470 template<typename T>
452471 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar)
453472 {
454 if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO)
473 # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO
455474 return perspectiveFovLH_ZO(fov, width, height, zNear, zFar);
456 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO)
475 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_NO
457476 return perspectiveFovLH_NO(fov, width, height, zNear, zFar);
458 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO)
477 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_ZO
459478 return perspectiveFovRH_ZO(fov, width, height, zNear, zFar);
460 else if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO)
479 # elif GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_RH_NO
461480 return perspectiveFovRH_NO(fov, width, height, zNear, zFar);
481 # endif
462482 }
463483
464484 template<typename T>
500520 template<typename T>
501521 GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear)
502522 {
503 if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT)
523 # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT
504524 return infinitePerspectiveLH(fovy, aspect, zNear);
505 else
525 # else
506526 return infinitePerspectiveRH(fovy, aspect, zNear);
527 # endif
507528 }
508529
509530 // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf
0 #include "scalar_constants.hpp"
1
02 namespace glm
13 {
24 template<typename T, qualifier Q>
4547 //To deal with non-unit quaternions
4648 T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w);
4749
48 //Equivalent to raising a real number to a power
49 //Needed to prevent a division by 0 error later on
50 if(abs(x.w / magnitude) > static_cast<T>(1) - epsilon<T>() && abs(x.w / magnitude) < static_cast<T>(1) + epsilon<T>())
51 return qua<T, Q>(pow(x.w, y), 0, 0, 0);
50 T Angle;
51 if(abs(x.w / magnitude) > cos_one_over_two<T>())
52 {
53 //Scalar component is close to 1; using it to recover angle would lose precision
54 //Instead, we use the non-scalar components since sin() is accurate around 0
5255
53 T Angle = acos(x.w / magnitude);
56 //Prevent a division by 0 error later on
57 T VectorMagnitude = x.x * x.x + x.y * x.y + x.z * x.z;
58 if (glm::abs(VectorMagnitude - static_cast<T>(0)) < glm::epsilon<T>()) {
59 //Equivalent to raising a real number to a power
60 return qua<T, Q>(pow(x.w, y), 0, 0, 0);
61 }
62
63 Angle = asin(sqrt(VectorMagnitude) / magnitude);
64 }
65 else
66 {
67 //Scalar component is small, shouldn't cause loss of precision
68 Angle = acos(x.w / magnitude);
69 }
70
5471 T NewAngle = Angle * y;
5572 T Div = sin(NewAngle) / sin(Angle);
5673 T Mag = pow(magnitude, y - static_cast<T>(1));
57
5874 return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
5975 }
6076
0 #include "scalar_constants.hpp"
1
02 namespace glm
13 {
24 template<typename T, qualifier Q>
35 GLM_FUNC_QUALIFIER T angle(qua<T, Q> const& x)
46 {
7 if (abs(x.w) > cos_one_over_two<T>())
8 {
9 return asin(sqrt(x.x * x.x + x.y * x.y + x.z * x.z)) * static_cast<T>(2);
10 }
11
512 return acos(x.w) * static_cast<T>(2);
613 }
714
2929 template<typename genType>
3030 GLM_FUNC_DECL GLM_CONSTEXPR genType pi();
3131
32 /// Return the value of cos(1 / 2) for floating point types.
33 template<typename genType>
34 GLM_FUNC_DECL GLM_CONSTEXPR genType cos_one_over_two();
35
3236 /// @}
3337 } //namespace glm
3438
1414 GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'pi' only accepts floating-point inputs");
1515 return static_cast<genType>(3.14159265358979323846264338327950288);
1616 }
17
18 template<typename genType>
19 GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType cos_one_over_two()
20 {
21 return genType(0.877582561890372716130286068203503191);
22 }
1723 } //namespace glm
2424
2525 // Different signs means they do not match.
2626 if(a.negative() != b.negative())
27 {
28 // Check for equality to make sure +0==-0
29 return a.mantissa() == b.mantissa() && a.exponent() == b.exponent();
30 }
27 return false;
3128
3229 // Find the difference in ULPs.
3330 typename detail::float_t<genType>::int_type const DiffULPs = abs(a.i - b.i);
162162 {
163163 return genType(1.61803398874989484820458683436563811);
164164 }
165
165166 } //namespace glm
1212 typename genType::value_type d = glm::dot(dir, planeNormal);
1313 typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
1414
15 if(d < -Epsilon)
16 {
17 intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d;
18 return true;
15 if(glm::abs(d) > Epsilon) // if dir and planeNormal are not perpendicular
16 {
17 typename genType::value_type const tmp_intersectionDistance = glm::dot(planeOrig - orig, planeNormal) / d;
18 if (tmp_intersectionDistance > static_cast<typename genType::value_type>(0)) { // allow only intersections
19 intersectionDistance = tmp_intersectionDistance;
20 return true;
21 }
1922 }
2023
2124 return false;
3636 ///
3737 /// @see gtx_quaternion
3838 template<typename T, qualifier Q>
39 GLM_FUNC_DECL qua<T, Q> quat_identity();
39 GLM_FUNC_DECL GLM_CONSTEXPR qua<T, Q> quat_identity();
4040
4141 /// Compute a cross product between a quaternion and a vector.
4242 ///
165165 ///
166166 /// @see gtx_quaternion
167167 template<typename T, qualifier Q>
168 GLM_FUNC_DECL T length2(qua<T, Q> const& q);
168 GLM_FUNC_DECL GLM_CONSTEXPR T length2(qua<T, Q> const& q);
169169
170170 /// @}
171171 }//namespace glm
55 namespace glm
66 {
77 template<typename T, qualifier Q>
8 GLM_FUNC_QUALIFIER qua<T, Q> quat_identity()
8 GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q> quat_identity()
99 {
1010 return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
1111 }
6969 }
7070
7171 template<typename T, qualifier Q>
72 GLM_FUNC_QUALIFIER T length2(qua<T, Q> const& q)
72 GLM_FUNC_QUALIFIER GLM_CONSTEXPR T length2(qua<T, Q> const& q)
7373 {
7474 return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
7575 }
5353 template<typename T> \
5454 return_type_scalar_multiplication<T, Vec> \
5555 operator/(Vec lh, T const& s){ \
56 return lh *= 1.0f / s; \
56 return lh *= 1.0f / static_cast<float>(s); \
5757 }
5858
5959 GLM_IMPLEMENT_SCAL_MULT(vec2)
0 /// @ref simd_neon
1 /// @file glm/simd/neon.h
2
3 #pragma once
4
5 #if GLM_ARCH & GLM_ARCH_NEON_BIT
6 #include <arm_neon.h>
7
8 namespace glm {
9 namespace neon {
10 static float32x4_t dupq_lane(float32x4_t vsrc, int lane) {
11 switch(lane) {
12 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
13 case 0: return vdupq_laneq_f32(vsrc, 0);
14 case 1: return vdupq_laneq_f32(vsrc, 1);
15 case 2: return vdupq_laneq_f32(vsrc, 2);
16 case 3: return vdupq_laneq_f32(vsrc, 3);
17 #else
18 case 0: return vdupq_n_f32(vgetq_lane_f32(vsrc, 0));
19 case 1: return vdupq_n_f32(vgetq_lane_f32(vsrc, 1));
20 case 2: return vdupq_n_f32(vgetq_lane_f32(vsrc, 2));
21 case 3: return vdupq_n_f32(vgetq_lane_f32(vsrc, 3));
22 #endif
23 }
24 assert(!"Unreachable code executed!");
25 return vdupq_n_f32(0.0f);
26 }
27
28 static float32x2_t dup_lane(float32x4_t vsrc, int lane) {
29 switch(lane) {
30 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
31 case 0: return vdup_laneq_f32(vsrc, 0);
32 case 1: return vdup_laneq_f32(vsrc, 1);
33 case 2: return vdup_laneq_f32(vsrc, 2);
34 case 3: return vdup_laneq_f32(vsrc, 3);
35 #else
36 case 0: return vdup_n_f32(vgetq_lane_f32(vsrc, 0));
37 case 1: return vdup_n_f32(vgetq_lane_f32(vsrc, 1));
38 case 2: return vdup_n_f32(vgetq_lane_f32(vsrc, 2));
39 case 3: return vdup_n_f32(vgetq_lane_f32(vsrc, 3));
40 #endif
41 }
42 assert(!"Unreachable code executed!");
43 return vdup_n_f32(0.0f);
44 }
45
46 static float32x4_t copy_lane(float32x4_t vdst, int dlane, float32x4_t vsrc, int slane) {
47 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
48 switch(dlane) {
49 case 0:
50 switch(slane) {
51 case 0: return vcopyq_laneq_f32(vdst, 0, vsrc, 0);
52 case 1: return vcopyq_laneq_f32(vdst, 0, vsrc, 1);
53 case 2: return vcopyq_laneq_f32(vdst, 0, vsrc, 2);
54 case 3: return vcopyq_laneq_f32(vdst, 0, vsrc, 3);
55 }
56 assert(!"Unreachable code executed!");
57 case 1:
58 switch(slane) {
59 case 0: return vcopyq_laneq_f32(vdst, 1, vsrc, 0);
60 case 1: return vcopyq_laneq_f32(vdst, 1, vsrc, 1);
61 case 2: return vcopyq_laneq_f32(vdst, 1, vsrc, 2);
62 case 3: return vcopyq_laneq_f32(vdst, 1, vsrc, 3);
63 }
64 assert(!"Unreachable code executed!");
65 case 2:
66 switch(slane) {
67 case 0: return vcopyq_laneq_f32(vdst, 2, vsrc, 0);
68 case 1: return vcopyq_laneq_f32(vdst, 2, vsrc, 1);
69 case 2: return vcopyq_laneq_f32(vdst, 2, vsrc, 2);
70 case 3: return vcopyq_laneq_f32(vdst, 2, vsrc, 3);
71 }
72 assert(!"Unreachable code executed!");
73 case 3:
74 switch(slane) {
75 case 0: return vcopyq_laneq_f32(vdst, 3, vsrc, 0);
76 case 1: return vcopyq_laneq_f32(vdst, 3, vsrc, 1);
77 case 2: return vcopyq_laneq_f32(vdst, 3, vsrc, 2);
78 case 3: return vcopyq_laneq_f32(vdst, 3, vsrc, 3);
79 }
80 assert(!"Unreachable code executed!");
81 }
82 #else
83
84 float l;
85 switch(slane) {
86 case 0: l = vgetq_lane_f32(vsrc, 0); break;
87 case 1: l = vgetq_lane_f32(vsrc, 1); break;
88 case 2: l = vgetq_lane_f32(vsrc, 2); break;
89 case 3: l = vgetq_lane_f32(vsrc, 3); break;
90 default:
91 assert(!"Unreachable code executed!");
92 }
93 switch(dlane) {
94 case 0: return vsetq_lane_f32(l, vdst, 0);
95 case 1: return vsetq_lane_f32(l, vdst, 1);
96 case 2: return vsetq_lane_f32(l, vdst, 2);
97 case 3: return vsetq_lane_f32(l, vdst, 3);
98 }
99 #endif
100 assert(!"Unreachable code executed!");
101 return vdupq_n_f32(0.0f);
102 }
103
104 static float32x4_t mul_lane(float32x4_t v, float32x4_t vlane, int lane) {
105 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
106 switch(lane) {
107 case 0: return vmulq_laneq_f32(v, vlane, 0); break;
108 case 1: return vmulq_laneq_f32(v, vlane, 1); break;
109 case 2: return vmulq_laneq_f32(v, vlane, 2); break;
110 case 3: return vmulq_laneq_f32(v, vlane, 3); break;
111 default:
112 assert(!"Unreachable code executed!");
113 }
114 assert(!"Unreachable code executed!");
115 return vdupq_n_f32(0.0f);
116 #else
117 return vmulq_f32(v, dupq_lane(vlane, lane));
118 #endif
119 }
120
121 static float32x4_t madd_lane(float32x4_t acc, float32x4_t v, float32x4_t vlane, int lane) {
122 #if GLM_ARCH & GLM_ARCH_ARMV8_BIT
123 #ifdef GLM_CONFIG_FORCE_FMA
124 # define FMADD_LANE(acc, x, y, L) do { asm volatile ("fmla %0.4s, %1.4s, %2.4s" : "+w"(acc) : "w"(x), "w"(dup_lane(y, L))); } while(0)
125 #else
126 # define FMADD_LANE(acc, x, y, L) do { acc = vmlaq_laneq_f32(acc, x, y, L); } while(0)
127 #endif
128
129 switch(lane) {
130 case 0:
131 FMADD_LANE(acc, v, vlane, 0);
132 return acc;
133 case 1:
134 FMADD_LANE(acc, v, vlane, 1);
135 return acc;
136 case 2:
137 FMADD_LANE(acc, v, vlane, 2);
138 return acc;
139 case 3:
140 FMADD_LANE(acc, v, vlane, 3);
141 return acc;
142 default:
143 assert(!"Unreachable code executed!");
144 }
145 assert(!"Unreachable code executed!");
146 return vdupq_n_f32(0.0f);
147 # undef FMADD_LANE
148 #else
149 return vaddq_f32(acc, vmulq_f32(v, dupq_lane(vlane, lane)));
150 #endif
151 }
152 } //namespace neon
153 } // namespace glm
154 #endif // GLM_ARCH & GLM_ARCH_NEON_BIT
363363 #elif GLM_ARCH & GLM_ARCH_SSE2_BIT
364364 # include <emmintrin.h>
365365 #elif GLM_ARCH & GLM_ARCH_NEON_BIT
366 # include <arm_neon.h>
366 # include "neon.h"
367367 #endif//GLM_ARCH
368368
369369 #if GLM_ARCH & GLM_ARCH_SSE2_BIT
3434 + [2.18. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size type](#section2_18)
3535 + [2.19. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction](#section2_19)
3636 + [2.20. GLM\_FORCE\_SILENT\_WARNINGS: Silent C++ warnings from language extensions](#section2_20)
37 + [2.21. GLM\_FORCE\_QUAT\_DATA\_WXYZ: Force GLM to store quat data as w,x,y,z instead of x,y,z,w](#section2_21)
3738 + [3. Stable extensions](#section3)
3839 + [3.1. Scalar types](#section3_1)
3940 + [3.2. Scalar functions](#section3_2)
715716 When using /W4 on Visual C++ or -Wpedantic on GCC, for example, the compilers will generate warnings for using C++ language extensions (/Za with Visual C++) such as anonymous struct.
716717 GLM relies on anonymous structs for swizzle operators and aligned vector types. To silent those warnings define `GLM_FORCE_SILENT_WARNINGS` before including GLM headers.
717718
719
720 ### <a name="section2_21"></a> 2.21. GLM\_FORCE\_QUAT\_DATA\_WXYZ: Force GLM to store quat data as w,x,y,z instead of x,y,z,w
721
722 By default GLM store quaternion components with the x, y, z, w order. `GLM_FORCE_QUAT_DATA_WXYZ` allows switching the quaternion data storage to the w, x, y, z order.
723
718724 ---
719725 <div style="page-break-after: always;"> </div>
720726
5252
5353 ## Release notes
5454
55 ### [GLM 0.9.9.7](https://github.com/g-truc/glm/releases/tag/0.9.9.7) - 2020-01-05
56 #### Improvements:
57 - Improved Neon support with more functions optimized #950
58 - Added CMake GLM interface #963
59 - Added fma implementation based on std::fma #969
60 - Added missing quat constexpr #955
61 - Added GLM_FORCE_QUAT_DATA_WXYZ to store quat data as w,x,y,z instead of x,y,z,w #983
62
63 #### Fixes:
64 - Fixed equal ULP variation when using negative sign #965
65 - Fixed for intersection ray/plane and added related tests #953
66 - Fixed ARM 64bit detection #949
67 - Fixed GLM_EXT_matrix_clip_space warnings #980
68 - Fixed Wimplicit-int-float-conversion warnings with clang 10+ #986
69 - Fixed EXT_matrix_clip_space perspectiveFov
70
5571 ### [GLM 0.9.9.6](https://github.com/g-truc/glm/releases/tag/0.9.9.6) - 2019-09-08
5672 #### Features:
57 - Added Neon support to glm #945
73 - Added Neon support #945
5874 - Added SYCL support #914
5975 - Added EXT_scalar_integer extension with power of two and multiple scalar functions
6076 - Added EXT_vector_integer extension with power of two and multiple vector functions
0 option(GLM_QUIET "No CMake Message" OFF)
1 option(BUILD_SHARED_LIBS "Build shared library" ON)
2 option(BUILD_STATIC_LIBS "Build static library" ON)
3 option(GLM_TEST_ENABLE_CXX_98 "Enable C++ 98" OFF)
4 option(GLM_TEST_ENABLE_CXX_11 "Enable C++ 11" OFF)
5 option(GLM_TEST_ENABLE_CXX_14 "Enable C++ 14" OFF)
6 option(GLM_TEST_ENABLE_CXX_17 "Enable C++ 17" OFF)
7 option(GLM_TEST_ENABLE_CXX_20 "Enable C++ 20" OFF)
8
9 set(CMAKE_CXX_STANDARD_REQUIRED ON)
10
11 if(GLM_TEST_ENABLE_CXX_20)
12 set(CMAKE_CXX_STANDARD 20)
13 add_definitions(-DGLM_FORCE_CXX2A)
14 if(NOT GLM_QUIET)
15 message(STATUS "GLM: Build with C++20 features")
16 endif()
17
18 elseif(GLM_TEST_ENABLE_CXX_17)
19 set(CMAKE_CXX_STANDARD 17)
20 add_definitions(-DGLM_FORCE_CXX17)
21 if(NOT GLM_QUIET)
22 message(STATUS "GLM: Build with C++17 features")
23 endif()
24
25 elseif(GLM_TEST_ENABLE_CXX_14)
26 set(CMAKE_CXX_STANDARD 14)
27 add_definitions(-DGLM_FORCE_CXX14)
28 if(NOT GLM_QUIET)
29 message(STATUS "GLM: Build with C++14 features")
30 endif()
31
32 elseif(GLM_TEST_ENABLE_CXX_11)
33 set(CMAKE_CXX_STANDARD 11)
34 add_definitions(-DGLM_FORCE_CXX11)
35 if(NOT GLM_QUIET)
36 message(STATUS "GLM: Build with C++11 features")
37 endif()
38
39 elseif(GLM_TEST_ENABLE_CXX_98)
40 set(CMAKE_CXX_STANDARD 98)
41 add_definitions(-DGLM_FORCE_CXX98)
42 if(NOT GLM_QUIET)
43 message(STATUS "GLM: Build with C++98 features")
44 endif()
45 endif()
46
47 option(GLM_TEST_ENABLE_LANG_EXTENSIONS "Enable language extensions" OFF)
48
49 option(GLM_DISABLE_AUTO_DETECTION "Enable language extensions" OFF)
50
51 if(GLM_DISABLE_AUTO_DETECTION)
52 add_definitions(-DGLM_FORCE_PLATFORM_UNKNOWN -DGLM_FORCE_COMPILER_UNKNOWN -DGLM_FORCE_ARCH_UNKNOWN -DGLM_FORCE_CXX_UNKNOWN)
53 endif()
54
55 if(GLM_TEST_ENABLE_LANG_EXTENSIONS)
56 set(CMAKE_CXX_EXTENSIONS ON)
57 if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
58 add_compile_options(-fms-extensions)
59 endif()
60 message(STATUS "GLM: Build with C++ language extensions")
61 else()
62 set(CMAKE_CXX_EXTENSIONS OFF)
63 if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
64 add_compile_options(/Za)
65 if(MSVC15)
66 add_compile_options(/permissive-)
67 endif()
68 endif()
69 endif()
70
71 option(GLM_TEST_ENABLE_FAST_MATH "Enable fast math optimizations" OFF)
72 if(GLM_TEST_ENABLE_FAST_MATH)
73 if(NOT GLM_QUIET)
74 message(STATUS "GLM: Build with fast math optimizations")
75 endif()
76
77 if((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
78 add_compile_options(-ffast-math)
79
80 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
81 add_compile_options(/fp:fast)
82 endif()
83 else()
84 if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
85 add_compile_options(/fp:precise)
86 endif()
87 endif()
88
89 option(GLM_TEST_ENABLE "Build unit tests" ON)
90 option(GLM_TEST_ENABLE_SIMD_SSE2 "Enable SSE2 optimizations" OFF)
91 option(GLM_TEST_ENABLE_SIMD_SSE3 "Enable SSE3 optimizations" OFF)
92 option(GLM_TEST_ENABLE_SIMD_SSSE3 "Enable SSSE3 optimizations" OFF)
93 option(GLM_TEST_ENABLE_SIMD_SSE4_1 "Enable SSE 4.1 optimizations" OFF)
94 option(GLM_TEST_ENABLE_SIMD_SSE4_2 "Enable SSE 4.2 optimizations" OFF)
95 option(GLM_TEST_ENABLE_SIMD_AVX "Enable AVX optimizations" OFF)
96 option(GLM_TEST_ENABLE_SIMD_AVX2 "Enable AVX2 optimizations" OFF)
97 option(GLM_TEST_FORCE_PURE "Force 'pure' instructions" OFF)
98
99 if(GLM_TEST_FORCE_PURE)
100 add_definitions(-DGLM_FORCE_PURE)
101
102 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
103 add_compile_options(-mfpmath=387)
104 endif()
105 message(STATUS "GLM: No SIMD instruction set")
106
107 elseif(GLM_TEST_ENABLE_SIMD_AVX2)
108 add_definitions(-DGLM_FORCE_PURE)
109
110 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
111 add_compile_options(-mavx2)
112 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
113 add_compile_options(/QxAVX2)
114 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
115 add_compile_options(/arch:AVX2)
116 endif()
117 message(STATUS "GLM: AVX2 instruction set")
118
119 elseif(GLM_TEST_ENABLE_SIMD_AVX)
120 add_definitions(-DGLM_FORCE_INTRINSICS)
121
122 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
123 add_compile_options(-mavx)
124 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
125 add_compile_options(/QxAVX)
126 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
127 add_compile_options(/arch:AVX)
128 endif()
129 message(STATUS "GLM: AVX instruction set")
130
131 elseif(GLM_TEST_ENABLE_SIMD_SSE4_2)
132 add_definitions(-DGLM_FORCE_INTRINSICS)
133
134 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
135 add_compile_options(-msse4.2)
136 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
137 add_compile_options(/QxSSE4.2)
138 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
139 add_compile_options(/arch:SSE2) # VC doesn't support SSE4.2
140 endif()
141 message(STATUS "GLM: SSE4.2 instruction set")
142
143 elseif(GLM_TEST_ENABLE_SIMD_SSE4_1)
144 add_definitions(-DGLM_FORCE_INTRINSICS)
145
146 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
147 add_compile_options(-msse4.1)
148 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
149 add_compile_options(/QxSSE4.1)
150 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
151 add_compile_options(/arch:SSE2) # VC doesn't support SSE4.1
152 endif()
153 message(STATUS "GLM: SSE4.1 instruction set")
154
155 elseif(GLM_TEST_ENABLE_SIMD_SSSE3)
156 add_definitions(-DGLM_FORCE_INTRINSICS)
157
158 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
159 add_compile_options(-mssse3)
160 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
161 add_compile_options(/QxSSSE3)
162 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
163 add_compile_options(/arch:SSE2) # VC doesn't support SSSE3
164 endif()
165 message(STATUS "GLM: SSSE3 instruction set")
166
167 elseif(GLM_TEST_ENABLE_SIMD_SSE3)
168 add_definitions(-DGLM_FORCE_INTRINSICS)
169
170 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
171 add_compile_options(-msse3)
172 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
173 add_compile_options(/QxSSE3)
174 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
175 add_compile_options(/arch:SSE2) # VC doesn't support SSE3
176 endif()
177 message(STATUS "GLM: SSE3 instruction set")
178
179 elseif(GLM_TEST_ENABLE_SIMD_SSE2)
180 add_definitions(-DGLM_FORCE_INTRINSICS)
181
182 if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
183 add_compile_options(-msse2)
184 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
185 add_compile_options(/QxSSE2)
186 elseif((CMAKE_CXX_COMPILER_ID MATCHES "MSVC") AND NOT CMAKE_CL_64)
187 add_compile_options(/arch:SSE2)
188 endif()
189 message(STATUS "GLM: SSE2 instruction set")
190 endif()
191
192 # Compiler and default options
193
194 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
195 if(NOT GLM_QUIET)
196 message("GLM: Clang - ${CMAKE_CXX_COMPILER_ID} compiler")
197 endif()
198
199 add_compile_options(-Werror -Weverything)
200 add_compile_options(-Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-c++11-long-long -Wno-padded -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
201 add_compile_options(-Wno-undefined-reinterpret-cast -Wno-sign-conversion -Wno-unused-variable -Wno-missing-prototypes -Wno-unreachable-code -Wno-missing-variable-declarations -Wno-sign-compare -Wno-global-constructors -Wno-unused-macros -Wno-format-nonliteral)
202
203 elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
204 if(NOT GLM_QUIET)
205 message("GLM: GCC - ${CMAKE_CXX_COMPILER_ID} compiler")
206 endif()
207
208 add_compile_options(-O2)
209 add_compile_options(-Wno-long-long)
210
211 elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
212 if(NOT GLM_QUIET)
213 message("GLM: Intel - ${CMAKE_CXX_COMPILER_ID} compiler")
214 endif()
215
216 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
217 if(NOT GLM_QUIET)
218 message("GLM: Visual C++ - ${CMAKE_CXX_COMPILER_ID} compiler")
219 endif()
220
221 add_compile_options(/W4 /WX)
222 add_compile_options(/wd4309 /wd4324 /wd4389 /wd4127 /wd4267 /wd4146 /wd4201 /wd4464 /wd4514 /wd4701 /wd4820 /wd4365)
223 add_definitions(-D_CRT_SECURE_NO_WARNINGS)
224 endif()
225
0226 function(glmCreateTestGTC NAME)
1227 set(SAMPLE_NAME test-${NAME})
2228 add_executable(${SAMPLE_NAME} ${NAME}.cpp)
4230 add_test(
5231 NAME ${SAMPLE_NAME}
6232 COMMAND $<TARGET_FILE:${SAMPLE_NAME}> )
233 target_link_libraries(${SAMPLE_NAME} PRIVATE glm::glm)
7234 endfunction()
8235
9236 if(GLM_TEST_ENABLE)
11 glmCreateTestGTC(core_cpp_defaulted_ctor)
22 glmCreateTestGTC(core_force_aligned_gentypes)
33 glmCreateTestGTC(core_force_ctor_init)
4 glmCreateTestGTC(core_force_cxx03)
5 glmCreateTestGTC(core_force_cxx98)
6 glmCreateTestGTC(core_force_arch_unknown)
7 glmCreateTestGTC(core_force_compiler_unknown)
8 glmCreateTestGTC(core_force_cxx_unknown)
49 glmCreateTestGTC(core_force_explicit_ctor)
510 glmCreateTestGTC(core_force_inline)
11 glmCreateTestGTC(core_force_platform_unknown)
612 glmCreateTestGTC(core_force_pure)
713 glmCreateTestGTC(core_force_unrestricted_gentype)
814 glmCreateTestGTC(core_force_xyzw_only)
15 glmCreateTestGTC(core_force_quat_wxyz)
916 glmCreateTestGTC(core_type_aligned)
1017 glmCreateTestGTC(core_type_cast)
1118 glmCreateTestGTC(core_type_ctor)
0 #ifndef GLM_FORCE_ARCH_UNKNOWN
1 # define GLM_FORCE_ARCH_UNKNOWN
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #ifndef GLM_FORCE_COMPILER_UNKNOWN
1 # define GLM_FORCE_COMPILER_UNKNOWN
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #ifndef GLM_FORCE_CXX03
1 # define GLM_FORCE_CXX03
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #ifndef GLM_FORCE_CXX98
1 # define GLM_FORCE_CXX98
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #ifndef GLM_FORCE_CXX_UNKNOWN
1 # define GLM_FORCE_CXX_UNKNOWN
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #define GLM_FORCE_DEPTH_ZERO_TO_ONE
1
2 #include <glm/glm.hpp>
3 #include <glm/ext.hpp>
4
5 int main()
6 {
7 int Error = 0;
8
9 return Error;
10 }
11
0 #define GLM_FORCE_LEFT_HANDED
1
2 #include <glm/glm.hpp>
3 #include <glm/ext.hpp>
4
5 int main()
6 {
7 int Error = 0;
8
9 return Error;
10 }
11
0 #ifndef GLM_FORCE_PLATFORM_UNKNOWN
1 # define GLM_FORCE_PLATFORM_UNKNOWN
2 #endif
3
4 #include <glm/glm.hpp>
5 #include <glm/ext.hpp>
6
7 int main()
8 {
9 int Error = 0;
10
11 return Error;
12 }
13
0 #define GLM_FORCE_QUAT_DATA_WXYZ
1 #define GLM_FORCE_INLINE
2
3 #include <glm/glm.hpp>
4 #include <glm/ext.hpp>
5
6 int main()
7 {
8 int Error = 0;
9
10 return Error;
11 }
12
0 #define GLM_FORCE_SIZE_T_LENGTH
1
2 #include <glm/glm.hpp>
3 #include <glm/ext.hpp>
4
5 int main()
6 {
7 int Error = 0;
8
9 return Error;
10 }
11
275275 int Error = 0;
276276
277277 glm::vec1 A0 = glm::min(glm::vec1(1), glm::vec1(1));
278 bool A1 = glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>()));
279 Error += A1 ? 0 : 1;
278280
279281 glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1));
280282 glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f);
358360 int Error = 0;
359361
360362 glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
363 bool A1 = glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>()));
364 Error += A1 ? 0 : 1;
365
361366
362367 glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
363368 glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
7070 return Error;
7171 }
7272
73 static int test_equal_sign()
74 {
75 int Error = 0;
76
77 Error += !glm::equal(-0.0f, 0.0f, 2) ? 0 : 1;
78 Error += !glm::equal(-0.0, 0.0, 2) ? 0 : 1;
79
80 Error += !glm::equal(-1.0f, 2.0f, 2) ? 0 : 1;
81 Error += !glm::equal(-1.0, 2.0, 2) ? 0 : 1;
82
83 Error += !glm::equal(-0.00001f, 1.00000f, 2) ? 0 : 1;
84 Error += !glm::equal(-0.00001, 1.00000, 2) ? 0 : 1;
85
86 Error += !glm::equal(-1.0f, 1.0f, 2) ? 0 : 1;
87 Error += !glm::equal(-1.0, 1.0, 2) ? 0 : 1;
88
89 return Error;
90 }
91
7392 int main()
7493 {
7594 int Error = 0;
8099 Error += test_equal_ulps();
81100 Error += test_notEqual_ulps();
82101
102 Error += test_equal_sign();
103
83104 return Error;
84105 }
1313 Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec3(1.0)), glm::dvec3(1.0), 0.01)) ? 0 : 1;
1414 Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec4(1.0)), glm::dvec4(1.0), 0.01)) ? 0 : 1;
1515
16 return 0;
16 return Error;
1717 }
1818
1919 int test_fastDistance()
238238 std::vector<glm::vec4> Results;
239239 Results.resize(Samples);
240240
241 float Steps = (End - Begin) / Samples;
242
243 std::clock_t const TimeStampBegin = std::clock();
244
245 for(std::size_t i = 0; i < Samples; ++i)
246 Results[i] = fastCosNew(AngleShift + glm::vec4(Begin + Steps * i));
241 float const Steps = (End - Begin) / static_cast<float>(Samples);
242
243 std::clock_t const TimeStampBegin = std::clock();
244
245 for(std::size_t i = 0; i < Samples; ++i)
246 Results[i] = fastCosNew(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
247247
248248 std::clock_t const TimeStampEnd = std::clock();
249249
279279 std::vector<glm::vec4> Results;
280280 Results.resize(Samples);
281281
282 float Steps = (End - Begin) / Samples;
283
284 std::clock_t const TimeStampBegin = std::clock();
285
286 for(std::size_t i = 0; i < Samples; ++i)
287 Results[i] = taylorCos::fastCosDeterminisctic(AngleShift + glm::vec4(Begin + Steps * i));
282 float const Steps = (End - Begin) / static_cast<float>(Samples);
283
284 std::clock_t const TimeStampBegin = std::clock();
285
286 for(std::size_t i = 0; i < Samples; ++i)
287 Results[i] = taylorCos::fastCosDeterminisctic(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
288288
289289 std::clock_t const TimeStampEnd = std::clock();
290290
326326 std::vector<glm::vec4> Results;
327327 Results.resize(Samples);
328328
329 float Steps = (End - Begin) / Samples;
330
331 std::clock_t const TimeStampBegin = std::clock();
332
333 for(std::size_t i = 0; i < Samples; ++i)
334 Results[i] = taylorCos::fastRefCos(AngleShift + glm::vec4(Begin + Steps * i));
329 float const Steps = (End - Begin) / static_cast<float>(Samples);
330
331 std::clock_t const TimeStampBegin = std::clock();
332
333 for(std::size_t i = 0; i < Samples; ++i)
334 Results[i] = taylorCos::fastRefCos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
335335
336336 std::clock_t const TimeStampEnd = std::clock();
337337
348348 std::vector<glm::vec4> Results;
349349 Results.resize(Samples);
350350
351 float Steps = (End - Begin) / Samples;
352
353 std::clock_t const TimeStampBegin = std::clock();
354
355 for(std::size_t i = 0; i < Samples; ++i)
356 Results[i] = glm::fastCos(AngleShift + glm::vec4(Begin + Steps * i));
351 float const Steps = (End - Begin) / static_cast<float>(Samples);
352
353 std::clock_t const TimeStampBegin = std::clock();
354
355 for(std::size_t i = 0; i < Samples; ++i)
356 Results[i] = glm::fastCos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
357357
358358 std::clock_t const TimeStampEnd = std::clock();
359359
370370 std::vector<glm::vec4> Results;
371371 Results.resize(Samples);
372372
373 float Steps = (End - Begin) / Samples;
374
375 std::clock_t const TimeStampBegin = std::clock();
376
377 for(std::size_t i = 0; i < Samples; ++i)
378 Results[i] = glm::cos(AngleShift + glm::vec4(Begin + Steps * i));
373 float const Steps = (End - Begin) / static_cast<float>(Samples);
374
375 std::clock_t const TimeStampBegin = std::clock();
376
377 for(std::size_t i = 0; i < Samples; ++i)
378 Results[i] = glm::cos(AngleShift + glm::vec4(Begin + Steps * static_cast<float>(i)));
379379
380380 std::clock_t const TimeStampEnd = std::clock();
381381
465465 std::vector<float> Results;
466466 Results.resize(Samples);
467467
468 float Steps = (End - Begin) / Samples;
469
470 std::clock_t const TimeStampBegin = std::clock();
471
472 for(std::size_t i = 0; i < Samples; ++i)
473 Results[i] = taylorCosA(AngleShift.x + Begin + Steps * i);
468 float const Steps = (End - Begin) / static_cast<float>(Samples);
469
470 std::clock_t const TimeStampBegin = std::clock();
471
472 for(std::size_t i = 0; i < Samples; ++i)
473 Results[i] = taylorCosA(AngleShift.x + Begin + Steps * static_cast<float>(i));
474474
475475 std::clock_t const TimeStampEnd = std::clock();
476476
487487 std::vector<float> Results;
488488 Results.resize(Samples);
489489
490 float Steps = (End - Begin) / Samples;
491
492 std::clock_t const TimeStampBegin = std::clock();
493
494 for(std::size_t i = 0; i < Samples; ++i)
495 Results[i] = taylorCosB(AngleShift.x + Begin + Steps * i);
490 float const Steps = (End - Begin) / static_cast<float>(Samples);
491
492 std::clock_t const TimeStampBegin = std::clock();
493
494 for(std::size_t i = 0; i < Samples; ++i)
495 Results[i] = taylorCosB(AngleShift.x + Begin + Steps * static_cast<float>(i));
496496
497497 std::clock_t const TimeStampEnd = std::clock();
498498
509509 std::vector<float> Results;
510510 Results.resize(Samples);
511511
512 float Steps = (End - Begin) / Samples;
513
514 std::clock_t const TimeStampBegin = std::clock();
515
516 for(std::size_t i = 0; i < Samples; ++i)
517 Results[i] = taylorCosC(AngleShift.x + Begin + Steps * i);
512 float const Steps = (End - Begin) / static_cast<float>(Samples);
513
514 std::clock_t const TimeStampBegin = std::clock();
515
516 for(std::size_t i = 0; i < Samples; ++i)
517 Results[i] = taylorCosC(AngleShift.x + Begin + Steps * static_cast<float>(i));
518518
519519 std::clock_t const TimeStampEnd = std::clock();
520520
11 #include <glm/glm.hpp>
22 #include <glm/gtc/epsilon.hpp>
33 #include <glm/gtx/intersect.hpp>
4
5 int test_intersectRayPlane()
6 {
7 int Error = 0;
8 glm::vec3 const PlaneOrigin(0, 0, 1);
9 glm::vec3 const PlaneNormal(0, 0, -1);
10 glm::vec3 const RayOrigin(0, 0, 0);
11 glm::vec3 const RayDir(0, 0, 1);
12
13 // check that inversion of the plane normal has no effect
14 {
15 float Distance = 0;
16 bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, PlaneOrigin, PlaneNormal, Distance);
17 Error += glm::abs(Distance - 1.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
18 Error += Result ? 0 : 1;
19 }
20 {
21 float Distance = 0;
22 bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, PlaneOrigin, -1.f * PlaneNormal, Distance);
23 Error += glm::abs(Distance - 1.f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
24 Error += Result ? 0 : 1;
25 }
26
27 // check if plane is before of behind the ray origin
28 {
29 float Distance = 9.9999f; // value should not be changed
30 bool const Result = glm::intersectRayPlane(RayOrigin, RayDir, -1.f * PlaneOrigin, PlaneNormal, Distance);
31 Error += glm::abs(Distance - 9.9999f) <= std::numeric_limits<float>::epsilon() ? 0 : 1;
32 Error += Result ? 1 : 0; // there is no intersection in front of the ray origin, only behind
33 }
34
35 return Error;
36 }
437
538 int test_intersectRayTriangle()
639 {
4679 {
4780 int Error = 0;
4881
82 Error += test_intersectRayPlane();
4983 Error += test_intersectRayTriangle();
5084 Error += test_intersectLineTriangle();
5185