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
18 | 18 | - GLM_ARGUMENTS: -DGLM_TEST_FORCE_PURE=ON |
19 | 19 | - GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_SSE2=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON |
20 | 20 | - 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 | |
21 | 23 | |
22 | 24 | matrix: |
23 | 25 | exclude: |
24 | 26 | - image: Visual Studio 2013 |
25 | 27 | GLM_ARGUMENTS: -DGLM_TEST_ENABLE_SIMD_AVX=ON -DGLM_TEST_ENABLE_LANG_EXTENSIONS=ON |
26 | 28 | - 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 | |
27 | 33 | configuration: Debug |
28 | 34 | - image: Visual Studio 2015 |
29 | 35 | 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 | |
30 | 40 | - image: Visual Studio 2015 |
31 | 41 | platform: x86 |
32 | 42 | - image: Visual Studio 2015 |
2 | 2 | |
3 | 3 | set(GLM_VERSION "0.9.9") |
4 | 4 | project(glm VERSION ${GLM_VERSION} LANGUAGES CXX) |
5 | ||
6 | 5 | enable_testing() |
7 | 6 | |
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) | |
16 | 9 | |
17 | set(CMAKE_CXX_STANDARD_REQUIRED ON) | |
10 | if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) | |
18 | 11 | |
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) | |
237 | 12 | add_subdirectory(test) |
238 | 13 | |
14 | endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) |
0 | 0 | ================================================================================ |
1 | 1 | OpenGL Mathematics (GLM) |
2 | 2 | -------------------------------------------------------------------------------- |
3 | GLM is licensed under The Happy Bunny License and MIT License | |
3 | GLM is licensed under The Happy Bunny License or MIT License | |
4 | 4 | |
5 | 5 | ================================================================================ |
6 | 6 | The Happy Bunny License (Modified MIT License) |
7 | 7 | -------------------------------------------------------------------------------- |
8 | Copyright (c) 2005 - 2014 G-Truc Creation | |
8 | Copyright (c) 2005 - G-Truc Creation | |
9 | 9 | |
10 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy |
11 | 11 | of this software and associated documentation files (the "Software"), to deal |
32 | 32 | ================================================================================ |
33 | 33 | The MIT License |
34 | 34 | -------------------------------------------------------------------------------- |
35 | Copyright (c) 2005 - 2014 G-Truc Creation | |
35 | Copyright (c) 2005 - G-Truc Creation | |
36 | 36 | |
37 | 37 | Permission is hereby granted, free of charge, to any person obtaining a copy |
38 | 38 | of this software and associated documentation files (the "Software"), to deal |
41 | 41 | source_group("SIMD Files" FILES ${SIMD_INLINE}) |
42 | 42 | source_group("SIMD Files" FILES ${SIMD_HEADER}) |
43 | 43 | |
44 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) | |
44 | add_library(glm INTERFACE) | |
45 | target_include_directories(glm INTERFACE ../) | |
45 | 46 | |
46 | 47 | if(BUILD_STATIC_LIBS) |
47 | 48 | add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} |
51 | 52 | ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} |
52 | 53 | ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} |
53 | 54 | ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) |
55 | target_link_libraries(glm_static PUBLIC glm) | |
56 | add_library(glm::glm_static ALIAS glm_static) | |
54 | 57 | endif() |
55 | 58 | |
56 | 59 | if(BUILD_SHARED_LIBS) |
61 | 64 | ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} |
62 | 65 | ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} |
63 | 66 | ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) |
67 | target_link_libraries(glm_shared PUBLIC glm) | |
68 | add_library(glm::glm_shared ALIAS glm_shared) | |
64 | 69 | endif() |
65 |
286 | 286 | std::numeric_limits<genFIType>::is_iec559 || (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), |
287 | 287 | "'sign' only accept signed inputs"); |
288 | 288 | |
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; | |
290 | 291 | } |
291 | 292 | |
292 | 293 | template<length_t L, typename T, qualifier Q> |
736 | 737 | return reinterpret_cast<vec<L, float, Q>&>(const_cast<vec<L, uint, Q>&>(v)); |
737 | 738 | } |
738 | 739 | |
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 | |
744 | 749 | |
745 | 750 | template<typename genType> |
746 | 751 | GLM_FUNC_QUALIFIER genType frexp(genType x, int& exp) |
95 | 95 | }//namespace detail |
96 | 96 | }//namespace glm |
97 | 97 | |
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 | ||
98 | 164 | #endif//GLM_ARCH & GLM_ARCH_SSE2_BIT |
90 | 90 | # endif |
91 | 91 | }//namespace glm |
92 | 92 | |
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 | |
93 | 248 | #endif |
5 | 5 | #define GLM_VERSION_MAJOR 0 |
6 | 6 | #define GLM_VERSION_MINOR 9 |
7 | 7 | #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" | |
11 | 11 | |
12 | 12 | #define GLM_SETUP_INCLUDED GLM_VERSION |
13 | 13 | |
34 | 34 | /////////////////////////////////////////////////////////////////////////////////// |
35 | 35 | // Build model |
36 | 36 | |
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__) | |
38 | 38 | # define GLM_MODEL GLM_MODEL_64 |
39 | #elif defined(__i386__) || defined(__ppc__) | |
39 | #elif defined(__i386__) || defined(__ppc__) || defined(__ILP32__) || defined(_M_ARM) | |
40 | 40 | # define GLM_MODEL GLM_MODEL_32 |
41 | 41 | #else |
42 | 42 | # define GLM_MODEL GLM_MODEL_32 |
41 | 41 | # if GLM_LANG & GLM_LANG_CXXMS_FLAG |
42 | 42 | union |
43 | 43 | { |
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 | |
45 | 49 | |
46 | 50 | typename detail::storage<4, T, detail::is_aligned<Q>::value>::type data; |
47 | 51 | }; |
48 | 52 | # 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 | |
50 | 58 | # endif |
51 | 59 | |
52 | 60 | # if GLM_SILENT_WARNINGS == GLM_ENABLE |
101 | 109 | GLM_FUNC_DECL qua(vec<3, T, Q> const& u, vec<3, T, Q> const& v); |
102 | 110 | |
103 | 111 | /// 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); | |
105 | 113 | GLM_FUNC_DECL GLM_EXPLICIT qua(mat<3, 3, T, Q> const& q); |
106 | 114 | GLM_FUNC_DECL GLM_EXPLICIT qua(mat<4, 4, T, Q> const& q); |
107 | 115 | |
108 | 116 | // -- Unary arithmetic operators -- |
109 | 117 | |
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; | |
111 | 119 | |
112 | 120 | 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); | |
114 | 122 | 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); | |
116 | 124 | 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); | |
118 | 126 | 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); | |
120 | 128 | 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); | |
122 | 130 | 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); | |
124 | 132 | }; |
125 | 133 | |
126 | 134 | // -- Unary bit operators -- |
127 | 135 | |
128 | 136 | 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); | |
130 | 138 | |
131 | 139 | 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); | |
133 | 141 | |
134 | 142 | // -- Binary operators -- |
135 | 143 | |
136 | 144 | 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); | |
138 | 146 | |
139 | 147 | 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); | |
141 | 149 | |
142 | 150 | 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); | |
144 | 152 | |
145 | 153 | 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); | |
147 | 155 | |
148 | 156 | 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); | |
150 | 158 | |
151 | 159 | 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); | |
153 | 161 | |
154 | 162 | 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); | |
156 | 164 | |
157 | 165 | 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); | |
159 | 167 | |
160 | 168 | 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); | |
162 | 170 | |
163 | 171 | 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); | |
165 | 173 | |
166 | 174 | // -- Boolean operators -- |
167 | 175 |
14 | 14 | template<typename T, qualifier Q, bool Aligned> |
15 | 15 | struct compute_dot<qua<T, Q>, T, Aligned> |
16 | 16 | { |
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) | |
18 | 18 | { |
19 | 19 | vec<4, T, Q> tmp(a.w * b.w, a.x * b.x, a.y * b.y, a.z * b.z); |
20 | 20 | return (tmp.x + tmp.y) + (tmp.z + tmp.w); |
24 | 24 | template<typename T, qualifier Q, bool Aligned> |
25 | 25 | struct compute_quat_add |
26 | 26 | { |
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) | |
28 | 28 | { |
29 | 29 | return qua<T, Q>(q.w + p.w, q.x + p.x, q.y + p.y, q.z + p.z); |
30 | 30 | } |
33 | 33 | template<typename T, qualifier Q, bool Aligned> |
34 | 34 | struct compute_quat_sub |
35 | 35 | { |
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) | |
37 | 37 | { |
38 | 38 | return qua<T, Q>(q.w - p.w, q.x - p.x, q.y - p.y, q.z - p.z); |
39 | 39 | } |
42 | 42 | template<typename T, qualifier Q, bool Aligned> |
43 | 43 | struct compute_quat_mul_scalar |
44 | 44 | { |
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) | |
46 | 46 | { |
47 | 47 | return qua<T, Q>(q.w * s, q.x * s, q.y * s, q.z * s); |
48 | 48 | } |
51 | 51 | template<typename T, qualifier Q, bool Aligned> |
52 | 52 | struct compute_quat_div_scalar |
53 | 53 | { |
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) | |
55 | 55 | { |
56 | 56 | return qua<T, Q>(q.w / s, q.x / s, q.y / s, q.z / s); |
57 | 57 | } |
60 | 60 | template<typename T, qualifier Q, bool Aligned> |
61 | 61 | struct compute_quat_mul_vec4 |
62 | 62 | { |
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) | |
64 | 64 | { |
65 | 65 | return vec<4, T, Q>(q * vec<3, T, Q>(v), v.w); |
66 | 66 | } |
73 | 73 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR T & qua<T, Q>::operator[](typename qua<T, Q>::length_type i) |
74 | 74 | { |
75 | 75 | 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 | |
77 | 81 | } |
78 | 82 | |
79 | 83 | template<typename T, qualifier Q> |
80 | 84 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR T const& qua<T, Q>::operator[](typename qua<T, Q>::length_type i) const |
81 | 85 | { |
82 | 86 | 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 | |
84 | 92 | } |
85 | 93 | |
86 | 94 | // -- Implicit basic constructors -- |
89 | 97 | template<typename T, qualifier Q> |
90 | 98 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR qua<T, Q>::qua() |
91 | 99 | # 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 | |
93 | 105 | # endif |
94 | 106 | {} |
95 | 107 | |
96 | 108 | template<typename T, qualifier Q> |
97 | 109 | 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 | |
99 | 115 | {} |
100 | 116 | # endif |
101 | 117 | |
102 | 118 | template<typename T, qualifier Q> |
103 | 119 | template<qualifier P> |
104 | 120 | 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 | |
106 | 126 | {} |
107 | 127 | |
108 | 128 | // -- Explicit basic constructors -- |
109 | 129 | |
110 | 130 | template<typename T, qualifier Q> |
111 | 131 | 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 | |
113 | 137 | {} |
114 | 138 | |
115 | 139 | template <typename T, qualifier Q> |
116 | 140 | 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 | |
118 | 146 | {} |
119 | 147 | |
120 | 148 | // -- Conversion constructors -- |
122 | 150 | template<typename T, qualifier Q> |
123 | 151 | template<typename U, qualifier P> |
124 | 152 | 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 | |
129 | 158 | {} |
130 | 159 | |
131 | 160 | //template<typename valType> |
171 | 200 | } |
172 | 201 | |
173 | 202 | 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) | |
175 | 204 | { |
176 | 205 | vec<3, T, Q> c = glm::cos(eulerAngle * T(0.5)); |
177 | 206 | vec<3, T, Q> s = glm::sin(eulerAngle * T(0.5)); |
212 | 241 | |
213 | 242 | # if GLM_CONFIG_DEFAULTED_FUNCTIONS == GLM_DISABLE |
214 | 243 | 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) | |
216 | 245 | { |
217 | 246 | this->w = q.w; |
218 | 247 | this->x = q.x; |
224 | 253 | |
225 | 254 | template<typename T, qualifier Q> |
226 | 255 | 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) | |
228 | 257 | { |
229 | 258 | this->w = static_cast<T>(q.w); |
230 | 259 | this->x = static_cast<T>(q.x); |
235 | 264 | |
236 | 265 | template<typename T, qualifier Q> |
237 | 266 | 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) | |
239 | 268 | { |
240 | 269 | return (*this = detail::compute_quat_add<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q))); |
241 | 270 | } |
242 | 271 | |
243 | 272 | template<typename T, qualifier Q> |
244 | 273 | 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) | |
246 | 275 | { |
247 | 276 | return (*this = detail::compute_quat_sub<T, Q, detail::is_aligned<Q>::value>::call(*this, qua<T, Q>(q))); |
248 | 277 | } |
249 | 278 | |
250 | 279 | template<typename T, qualifier Q> |
251 | 280 | 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) | |
253 | 282 | { |
254 | 283 | qua<T, Q> const p(*this); |
255 | 284 | qua<T, Q> const q(r); |
263 | 292 | |
264 | 293 | template<typename T, qualifier Q> |
265 | 294 | 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) | |
267 | 296 | { |
268 | 297 | return (*this = detail::compute_quat_mul_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s))); |
269 | 298 | } |
270 | 299 | |
271 | 300 | template<typename T, qualifier Q> |
272 | 301 | 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) | |
274 | 303 | { |
275 | 304 | return (*this = detail::compute_quat_div_scalar<T, Q, detail::is_aligned<Q>::value>::call(*this, static_cast<U>(s))); |
276 | 305 | } |
278 | 307 | // -- Unary bit operators -- |
279 | 308 | |
280 | 309 | 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) | |
282 | 311 | { |
283 | 312 | return q; |
284 | 313 | } |
285 | 314 | |
286 | 315 | 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) | |
288 | 317 | { |
289 | 318 | return qua<T, Q>(-q.w, -q.x, -q.y, -q.z); |
290 | 319 | } |
292 | 321 | // -- Binary operators -- |
293 | 322 | |
294 | 323 | 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) | |
296 | 325 | { |
297 | 326 | return qua<T, Q>(q) += p; |
298 | 327 | } |
299 | 328 | |
300 | 329 | 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) | |
302 | 331 | { |
303 | 332 | return qua<T, Q>(q) -= p; |
304 | 333 | } |
305 | 334 | |
306 | 335 | 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) | |
308 | 337 | { |
309 | 338 | return qua<T, Q>(q) *= p; |
310 | 339 | } |
311 | 340 | |
312 | 341 | 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) | |
314 | 343 | { |
315 | 344 | vec<3, T, Q> const QuatVector(q.x, q.y, q.z); |
316 | 345 | vec<3, T, Q> const uv(glm::cross(QuatVector, v)); |
320 | 349 | } |
321 | 350 | |
322 | 351 | 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) | |
324 | 353 | { |
325 | 354 | return glm::inverse(q) * v; |
326 | 355 | } |
327 | 356 | |
328 | 357 | 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) | |
330 | 359 | { |
331 | 360 | return detail::compute_quat_mul_vec4<T, Q, detail::is_aligned<Q>::value>::call(q, v); |
332 | 361 | } |
333 | 362 | |
334 | 363 | 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) | |
336 | 365 | { |
337 | 366 | return glm::inverse(q) * v; |
338 | 367 | } |
339 | 368 | |
340 | 369 | 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) | |
342 | 371 | { |
343 | 372 | return qua<T, Q>( |
344 | 373 | q.w * s, q.x * s, q.y * s, q.z * s); |
345 | 374 | } |
346 | 375 | |
347 | 376 | 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) | |
349 | 378 | { |
350 | 379 | return q * s; |
351 | 380 | } |
352 | 381 | |
353 | 382 | 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) | |
355 | 384 | { |
356 | 385 | return qua<T, Q>( |
357 | 386 | q.w / s, q.x / s, q.y / s, q.z / s); |
577 | 577 | { |
578 | 578 | vec<4, float, Q> Result; |
579 | 579 | 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); | |
602 | 580 | return Result; |
603 | 581 | } |
604 | 582 | }; |
66 | 66 | template<typename T> |
67 | 67 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoZO(T left, T right, T bottom, T top, T zNear, T zFar) |
68 | 68 | { |
69 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
69 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
70 | 70 | return orthoLH_ZO(left, right, bottom, top, zNear, zFar); |
71 | else | |
71 | # else | |
72 | 72 | return orthoRH_ZO(left, right, bottom, top, zNear, zFar); |
73 | # endif | |
73 | 74 | } |
74 | 75 | |
75 | 76 | template<typename T> |
76 | 77 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoNO(T left, T right, T bottom, T top, T zNear, T zFar) |
77 | 78 | { |
78 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
79 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
79 | 80 | return orthoLH_NO(left, right, bottom, top, zNear, zFar); |
80 | else | |
81 | # else | |
81 | 82 | return orthoRH_NO(left, right, bottom, top, zNear, zFar); |
83 | # endif | |
82 | 84 | } |
83 | 85 | |
84 | 86 | template<typename T> |
85 | 87 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoLH(T left, T right, T bottom, T top, T zNear, T zFar) |
86 | 88 | { |
87 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
89 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
88 | 90 | return orthoLH_ZO(left, right, bottom, top, zNear, zFar); |
89 | else | |
91 | # else | |
90 | 92 | return orthoLH_NO(left, right, bottom, top, zNear, zFar); |
93 | # endif | |
91 | 94 | |
92 | 95 | } |
93 | 96 | |
94 | 97 | template<typename T> |
95 | 98 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> orthoRH(T left, T right, T bottom, T top, T zNear, T zFar) |
96 | 99 | { |
97 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
100 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
98 | 101 | return orthoRH_ZO(left, right, bottom, top, zNear, zFar); |
99 | else | |
102 | # else | |
100 | 103 | return orthoRH_NO(left, right, bottom, top, zNear, zFar); |
104 | # endif | |
101 | 105 | } |
102 | 106 | |
103 | 107 | template<typename T> |
104 | 108 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> ortho(T left, T right, T bottom, T top, T zNear, T zFar) |
105 | 109 | { |
106 | if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO) | |
110 | # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO | |
107 | 111 | 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 | |
109 | 113 | 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 | |
111 | 115 | 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 | |
113 | 117 | return orthoRH_NO(left, right, bottom, top, zNear, zFar); |
118 | # endif | |
114 | 119 | } |
115 | 120 | |
116 | 121 | template<typename T> |
172 | 177 | template<typename T> |
173 | 178 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumZO(T left, T right, T bottom, T top, T nearVal, T farVal) |
174 | 179 | { |
175 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
180 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
176 | 181 | return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); |
177 | else | |
182 | # else | |
178 | 183 | return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); |
184 | # endif | |
179 | 185 | } |
180 | 186 | |
181 | 187 | template<typename T> |
182 | 188 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumNO(T left, T right, T bottom, T top, T nearVal, T farVal) |
183 | 189 | { |
184 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
190 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
185 | 191 | return frustumLH_NO(left, right, bottom, top, nearVal, farVal); |
186 | else | |
192 | # else | |
187 | 193 | return frustumRH_NO(left, right, bottom, top, nearVal, farVal); |
194 | # endif | |
188 | 195 | } |
189 | 196 | |
190 | 197 | template<typename T> |
191 | 198 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumLH(T left, T right, T bottom, T top, T nearVal, T farVal) |
192 | 199 | { |
193 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
200 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
194 | 201 | return frustumLH_ZO(left, right, bottom, top, nearVal, farVal); |
195 | else | |
202 | # else | |
196 | 203 | return frustumLH_NO(left, right, bottom, top, nearVal, farVal); |
204 | # endif | |
197 | 205 | } |
198 | 206 | |
199 | 207 | template<typename T> |
200 | 208 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustumRH(T left, T right, T bottom, T top, T nearVal, T farVal) |
201 | 209 | { |
202 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
210 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
203 | 211 | return frustumRH_ZO(left, right, bottom, top, nearVal, farVal); |
204 | else | |
212 | # else | |
205 | 213 | return frustumRH_NO(left, right, bottom, top, nearVal, farVal); |
214 | # endif | |
206 | 215 | } |
207 | 216 | |
208 | 217 | template<typename T> |
209 | 218 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> frustum(T left, T right, T bottom, T top, T nearVal, T farVal) |
210 | 219 | { |
211 | if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO) | |
220 | # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO | |
212 | 221 | 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 | |
214 | 223 | 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 | |
216 | 225 | 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 | |
218 | 227 | return frustumRH_NO(left, right, bottom, top, nearVal, farVal); |
228 | # endif | |
219 | 229 | } |
220 | 230 | |
221 | 231 | template<typename T> |
285 | 295 | template<typename T> |
286 | 296 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveZO(T fovy, T aspect, T zNear, T zFar) |
287 | 297 | { |
288 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
298 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
289 | 299 | return perspectiveLH_ZO(fovy, aspect, zNear, zFar); |
290 | else | |
300 | # else | |
291 | 301 | return perspectiveRH_ZO(fovy, aspect, zNear, zFar); |
302 | # endif | |
292 | 303 | } |
293 | 304 | |
294 | 305 | template<typename T> |
295 | 306 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveNO(T fovy, T aspect, T zNear, T zFar) |
296 | 307 | { |
297 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
308 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
298 | 309 | return perspectiveLH_NO(fovy, aspect, zNear, zFar); |
299 | else | |
310 | # else | |
300 | 311 | return perspectiveRH_NO(fovy, aspect, zNear, zFar); |
312 | # endif | |
301 | 313 | } |
302 | 314 | |
303 | 315 | template<typename T> |
304 | 316 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveLH(T fovy, T aspect, T zNear, T zFar) |
305 | 317 | { |
306 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
318 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
307 | 319 | return perspectiveLH_ZO(fovy, aspect, zNear, zFar); |
308 | else | |
320 | # else | |
309 | 321 | return perspectiveLH_NO(fovy, aspect, zNear, zFar); |
322 | # endif | |
310 | 323 | |
311 | 324 | } |
312 | 325 | |
313 | 326 | template<typename T> |
314 | 327 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveRH(T fovy, T aspect, T zNear, T zFar) |
315 | 328 | { |
316 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
329 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
317 | 330 | return perspectiveRH_ZO(fovy, aspect, zNear, zFar); |
318 | else | |
331 | # else | |
319 | 332 | return perspectiveRH_NO(fovy, aspect, zNear, zFar); |
333 | # endif | |
320 | 334 | } |
321 | 335 | |
322 | 336 | template<typename T> |
323 | 337 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspective(T fovy, T aspect, T zNear, T zFar) |
324 | 338 | { |
325 | GLM_IF_CONSTEXPR(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO) | |
339 | # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO | |
326 | 340 | 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 | |
328 | 342 | 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 | |
330 | 344 | 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 | |
332 | 346 | return perspectiveRH_NO(fovy, aspect, zNear, zFar); |
347 | # endif | |
333 | 348 | } |
334 | 349 | |
335 | 350 | template<typename T> |
415 | 430 | template<typename T> |
416 | 431 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovZO(T fov, T width, T height, T zNear, T zFar) |
417 | 432 | { |
418 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
433 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
419 | 434 | return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); |
420 | else | |
435 | # else | |
421 | 436 | return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); |
437 | # endif | |
422 | 438 | } |
423 | 439 | |
424 | 440 | template<typename T> |
425 | 441 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovNO(T fov, T width, T height, T zNear, T zFar) |
426 | 442 | { |
427 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
443 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
428 | 444 | return perspectiveFovLH_NO(fov, width, height, zNear, zFar); |
429 | else | |
445 | # else | |
430 | 446 | return perspectiveFovRH_NO(fov, width, height, zNear, zFar); |
447 | # endif | |
431 | 448 | } |
432 | 449 | |
433 | 450 | template<typename T> |
434 | 451 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovLH(T fov, T width, T height, T zNear, T zFar) |
435 | 452 | { |
436 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
453 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
437 | 454 | return perspectiveFovLH_ZO(fov, width, height, zNear, zFar); |
438 | else | |
455 | # else | |
439 | 456 | return perspectiveFovLH_NO(fov, width, height, zNear, zFar); |
457 | # endif | |
440 | 458 | } |
441 | 459 | |
442 | 460 | template<typename T> |
443 | 461 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFovRH(T fov, T width, T height, T zNear, T zFar) |
444 | 462 | { |
445 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT) | |
463 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT | |
446 | 464 | return perspectiveFovRH_ZO(fov, width, height, zNear, zFar); |
447 | else | |
465 | # else | |
448 | 466 | return perspectiveFovRH_NO(fov, width, height, zNear, zFar); |
467 | # endif | |
449 | 468 | } |
450 | 469 | |
451 | 470 | template<typename T> |
452 | 471 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> perspectiveFov(T fov, T width, T height, T zNear, T zFar) |
453 | 472 | { |
454 | if(GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO) | |
473 | # if GLM_CONFIG_CLIP_CONTROL == GLM_CLIP_CONTROL_LH_ZO | |
455 | 474 | 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 | |
457 | 476 | 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 | |
459 | 478 | 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 | |
461 | 480 | return perspectiveFovRH_NO(fov, width, height, zNear, zFar); |
481 | # endif | |
462 | 482 | } |
463 | 483 | |
464 | 484 | template<typename T> |
500 | 520 | template<typename T> |
501 | 521 | GLM_FUNC_QUALIFIER mat<4, 4, T, defaultp> infinitePerspective(T fovy, T aspect, T zNear) |
502 | 522 | { |
503 | if(GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT) | |
523 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_LH_BIT | |
504 | 524 | return infinitePerspectiveLH(fovy, aspect, zNear); |
505 | else | |
525 | # else | |
506 | 526 | return infinitePerspectiveRH(fovy, aspect, zNear); |
527 | # endif | |
507 | 528 | } |
508 | 529 | |
509 | 530 | // Infinite projection matrix: http://www.terathon.com/gdc07_lengyel.pdf |
0 | #include "scalar_constants.hpp" | |
1 | ||
0 | 2 | namespace glm |
1 | 3 | { |
2 | 4 | template<typename T, qualifier Q> |
45 | 47 | //To deal with non-unit quaternions |
46 | 48 | T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w); |
47 | 49 | |
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 | |
52 | 55 | |
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 | ||
54 | 71 | T NewAngle = Angle * y; |
55 | 72 | T Div = sin(NewAngle) / sin(Angle); |
56 | 73 | T Mag = pow(magnitude, y - static_cast<T>(1)); |
57 | ||
58 | 74 | return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag); |
59 | 75 | } |
60 | 76 |
0 | #include "scalar_constants.hpp" | |
1 | ||
0 | 2 | namespace glm |
1 | 3 | { |
2 | 4 | template<typename T, qualifier Q> |
3 | 5 | GLM_FUNC_QUALIFIER T angle(qua<T, Q> const& x) |
4 | 6 | { |
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 | ||
5 | 12 | return acos(x.w) * static_cast<T>(2); |
6 | 13 | } |
7 | 14 |
29 | 29 | template<typename genType> |
30 | 30 | GLM_FUNC_DECL GLM_CONSTEXPR genType pi(); |
31 | 31 | |
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 | ||
32 | 36 | /// @} |
33 | 37 | } //namespace glm |
34 | 38 |
14 | 14 | GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'pi' only accepts floating-point inputs"); |
15 | 15 | return static_cast<genType>(3.14159265358979323846264338327950288); |
16 | 16 | } |
17 | ||
18 | template<typename genType> | |
19 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR genType cos_one_over_two() | |
20 | { | |
21 | return genType(0.877582561890372716130286068203503191); | |
22 | } | |
17 | 23 | } //namespace glm |
24 | 24 | |
25 | 25 | // Different signs means they do not match. |
26 | 26 | 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; | |
31 | 28 | |
32 | 29 | // Find the difference in ULPs. |
33 | 30 | typename detail::float_t<genType>::int_type const DiffULPs = abs(a.i - b.i); |
162 | 162 | { |
163 | 163 | return genType(1.61803398874989484820458683436563811); |
164 | 164 | } |
165 | ||
165 | 166 | } //namespace glm |
12 | 12 | typename genType::value_type d = glm::dot(dir, planeNormal); |
13 | 13 | typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon(); |
14 | 14 | |
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 | } | |
19 | 22 | } |
20 | 23 | |
21 | 24 | return false; |
36 | 36 | /// |
37 | 37 | /// @see gtx_quaternion |
38 | 38 | 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(); | |
40 | 40 | |
41 | 41 | /// Compute a cross product between a quaternion and a vector. |
42 | 42 | /// |
165 | 165 | /// |
166 | 166 | /// @see gtx_quaternion |
167 | 167 | 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); | |
169 | 169 | |
170 | 170 | /// @} |
171 | 171 | }//namespace glm |
5 | 5 | namespace glm |
6 | 6 | { |
7 | 7 | 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() | |
9 | 9 | { |
10 | 10 | return qua<T, Q>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)); |
11 | 11 | } |
69 | 69 | } |
70 | 70 | |
71 | 71 | 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) | |
73 | 73 | { |
74 | 74 | return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; |
75 | 75 | } |
53 | 53 | template<typename T> \ |
54 | 54 | return_type_scalar_multiplication<T, Vec> \ |
55 | 55 | operator/(Vec lh, T const& s){ \ |
56 | return lh *= 1.0f / s; \ | |
56 | return lh *= 1.0f / static_cast<float>(s); \ | |
57 | 57 | } |
58 | 58 | |
59 | 59 | 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 |
363 | 363 | #elif GLM_ARCH & GLM_ARCH_SSE2_BIT |
364 | 364 | # include <emmintrin.h> |
365 | 365 | #elif GLM_ARCH & GLM_ARCH_NEON_BIT |
366 | # include <arm_neon.h> | |
366 | # include "neon.h" | |
367 | 367 | #endif//GLM_ARCH |
368 | 368 | |
369 | 369 | #if GLM_ARCH & GLM_ARCH_SSE2_BIT |
34 | 34 | + [2.18. GLM\_FORCE\_SIZE\_T\_LENGTH: Vector and matrix static size type](#section2_18) |
35 | 35 | + [2.19. GLM\_FORCE\_UNRESTRICTED\_GENTYPE: Removing genType restriction](#section2_19) |
36 | 36 | + [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) | |
37 | 38 | + [3. Stable extensions](#section3) |
38 | 39 | + [3.1. Scalar types](#section3_1) |
39 | 40 | + [3.2. Scalar functions](#section3_2) |
715 | 716 | 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. |
716 | 717 | 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. |
717 | 718 | |
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 | ||
718 | 724 | --- |
719 | 725 | <div style="page-break-after: always;"> </div> |
720 | 726 |
52 | 52 | |
53 | 53 | ## Release notes |
54 | 54 | |
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 | ||
55 | 71 | ### [GLM 0.9.9.6](https://github.com/g-truc/glm/releases/tag/0.9.9.6) - 2019-09-08 |
56 | 72 | #### Features: |
57 | - Added Neon support to glm #945 | |
73 | - Added Neon support #945 | |
58 | 74 | - Added SYCL support #914 |
59 | 75 | - Added EXT_scalar_integer extension with power of two and multiple scalar functions |
60 | 76 | - 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 | ||
0 | 226 | function(glmCreateTestGTC NAME) |
1 | 227 | set(SAMPLE_NAME test-${NAME}) |
2 | 228 | add_executable(${SAMPLE_NAME} ${NAME}.cpp) |
4 | 230 | add_test( |
5 | 231 | NAME ${SAMPLE_NAME} |
6 | 232 | COMMAND $<TARGET_FILE:${SAMPLE_NAME}> ) |
233 | target_link_libraries(${SAMPLE_NAME} PRIVATE glm::glm) | |
7 | 234 | endfunction() |
8 | 235 | |
9 | 236 | if(GLM_TEST_ENABLE) |
1 | 1 | glmCreateTestGTC(core_cpp_defaulted_ctor) |
2 | 2 | glmCreateTestGTC(core_force_aligned_gentypes) |
3 | 3 | 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) | |
4 | 9 | glmCreateTestGTC(core_force_explicit_ctor) |
5 | 10 | glmCreateTestGTC(core_force_inline) |
11 | glmCreateTestGTC(core_force_platform_unknown) | |
6 | 12 | glmCreateTestGTC(core_force_pure) |
7 | 13 | glmCreateTestGTC(core_force_unrestricted_gentype) |
8 | 14 | glmCreateTestGTC(core_force_xyzw_only) |
15 | glmCreateTestGTC(core_force_quat_wxyz) | |
9 | 16 | glmCreateTestGTC(core_type_aligned) |
10 | 17 | glmCreateTestGTC(core_type_cast) |
11 | 18 | 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 |
275 | 275 | int Error = 0; |
276 | 276 | |
277 | 277 | 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; | |
278 | 280 | |
279 | 281 | glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1)); |
280 | 282 | glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f); |
358 | 360 | int Error = 0; |
359 | 361 | |
360 | 362 | 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 | ||
361 | 366 | |
362 | 367 | glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1)); |
363 | 368 | glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f); |
70 | 70 | return Error; |
71 | 71 | } |
72 | 72 | |
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 | ||
73 | 92 | int main() |
74 | 93 | { |
75 | 94 | int Error = 0; |
80 | 99 | Error += test_equal_ulps(); |
81 | 100 | Error += test_notEqual_ulps(); |
82 | 101 | |
102 | Error += test_equal_sign(); | |
103 | ||
83 | 104 | return Error; |
84 | 105 | } |
13 | 13 | Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec3(1.0)), glm::dvec3(1.0), 0.01)) ? 0 : 1; |
14 | 14 | Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec4(1.0)), glm::dvec4(1.0), 0.01)) ? 0 : 1; |
15 | 15 | |
16 | return 0; | |
16 | return Error; | |
17 | 17 | } |
18 | 18 | |
19 | 19 | int test_fastDistance() |
238 | 238 | std::vector<glm::vec4> Results; |
239 | 239 | Results.resize(Samples); |
240 | 240 | |
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))); | |
247 | 247 | |
248 | 248 | std::clock_t const TimeStampEnd = std::clock(); |
249 | 249 | |
279 | 279 | std::vector<glm::vec4> Results; |
280 | 280 | Results.resize(Samples); |
281 | 281 | |
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))); | |
288 | 288 | |
289 | 289 | std::clock_t const TimeStampEnd = std::clock(); |
290 | 290 | |
326 | 326 | std::vector<glm::vec4> Results; |
327 | 327 | Results.resize(Samples); |
328 | 328 | |
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))); | |
335 | 335 | |
336 | 336 | std::clock_t const TimeStampEnd = std::clock(); |
337 | 337 | |
348 | 348 | std::vector<glm::vec4> Results; |
349 | 349 | Results.resize(Samples); |
350 | 350 | |
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))); | |
357 | 357 | |
358 | 358 | std::clock_t const TimeStampEnd = std::clock(); |
359 | 359 | |
370 | 370 | std::vector<glm::vec4> Results; |
371 | 371 | Results.resize(Samples); |
372 | 372 | |
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))); | |
379 | 379 | |
380 | 380 | std::clock_t const TimeStampEnd = std::clock(); |
381 | 381 | |
465 | 465 | std::vector<float> Results; |
466 | 466 | Results.resize(Samples); |
467 | 467 | |
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)); | |
474 | 474 | |
475 | 475 | std::clock_t const TimeStampEnd = std::clock(); |
476 | 476 | |
487 | 487 | std::vector<float> Results; |
488 | 488 | Results.resize(Samples); |
489 | 489 | |
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)); | |
496 | 496 | |
497 | 497 | std::clock_t const TimeStampEnd = std::clock(); |
498 | 498 | |
509 | 509 | std::vector<float> Results; |
510 | 510 | Results.resize(Samples); |
511 | 511 | |
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)); | |
518 | 518 | |
519 | 519 | std::clock_t const TimeStampEnd = std::clock(); |
520 | 520 |
1 | 1 | #include <glm/glm.hpp> |
2 | 2 | #include <glm/gtc/epsilon.hpp> |
3 | 3 | #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 | } | |
4 | 37 | |
5 | 38 | int test_intersectRayTriangle() |
6 | 39 | { |
46 | 79 | { |
47 | 80 | int Error = 0; |
48 | 81 | |
82 | Error += test_intersectRayPlane(); | |
49 | 83 | Error += test_intersectRayTriangle(); |
50 | 84 | Error += test_intersectLineTriangle(); |
51 | 85 |