1 | #pragma once |
2 | |
3 | #include "setup.hpp" |
4 | |
5 | namespace glm |
6 | { |
7 | /// Qualify GLM types in term of alignment (packed, aligned) and precision in term of ULPs (lowp, mediump, highp) |
8 | enum qualifier |
9 | { |
10 | packed_highp, ///< Typed data is tightly packed in memory and operations are executed with high precision in term of ULPs |
11 | packed_mediump, ///< Typed data is tightly packed in memory and operations are executed with medium precision in term of ULPs for higher performance |
12 | packed_lowp, ///< Typed data is tightly packed in memory and operations are executed with low precision in term of ULPs to maximize performance |
13 | |
14 | # if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE |
15 | aligned_highp, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs |
16 | aligned_mediump, ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs for higher performance |
17 | aligned_lowp, // ///< Typed data is aligned in memory allowing SIMD optimizations and operations are executed with high precision in term of ULPs to maximize performance |
18 | aligned = aligned_highp, ///< By default aligned qualifier is also high precision |
19 | # endif |
20 | |
21 | highp = packed_highp, ///< By default highp qualifier is also packed |
22 | mediump = packed_mediump, ///< By default mediump qualifier is also packed |
23 | lowp = packed_lowp, ///< By default lowp qualifier is also packed |
24 | packed = packed_highp, ///< By default packed qualifier is also high precision |
25 | |
26 | # if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE && defined(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES) |
27 | defaultp = aligned_highp |
28 | # else |
29 | defaultp = highp |
30 | # endif |
31 | }; |
32 | |
33 | typedef qualifier precision; |
34 | |
35 | template<length_t L, typename T, qualifier Q = defaultp> struct vec; |
36 | template<length_t C, length_t R, typename T, qualifier Q = defaultp> struct mat; |
37 | template<typename T, qualifier Q = defaultp> struct qua; |
38 | |
39 | # if GLM_HAS_TEMPLATE_ALIASES |
40 | template <typename T, qualifier Q = defaultp> using tvec1 = vec<1, T, Q>; |
41 | template <typename T, qualifier Q = defaultp> using tvec2 = vec<2, T, Q>; |
42 | template <typename T, qualifier Q = defaultp> using tvec3 = vec<3, T, Q>; |
43 | template <typename T, qualifier Q = defaultp> using tvec4 = vec<4, T, Q>; |
44 | template <typename T, qualifier Q = defaultp> using tmat2x2 = mat<2, 2, T, Q>; |
45 | template <typename T, qualifier Q = defaultp> using tmat2x3 = mat<2, 3, T, Q>; |
46 | template <typename T, qualifier Q = defaultp> using tmat2x4 = mat<2, 4, T, Q>; |
47 | template <typename T, qualifier Q = defaultp> using tmat3x2 = mat<3, 2, T, Q>; |
48 | template <typename T, qualifier Q = defaultp> using tmat3x3 = mat<3, 3, T, Q>; |
49 | template <typename T, qualifier Q = defaultp> using tmat3x4 = mat<3, 4, T, Q>; |
50 | template <typename T, qualifier Q = defaultp> using tmat4x2 = mat<4, 2, T, Q>; |
51 | template <typename T, qualifier Q = defaultp> using tmat4x3 = mat<4, 3, T, Q>; |
52 | template <typename T, qualifier Q = defaultp> using tmat4x4 = mat<4, 4, T, Q>; |
53 | template <typename T, qualifier Q = defaultp> using tquat = qua<T, Q>; |
54 | # endif |
55 | |
56 | namespace detail |
57 | { |
58 | template<glm::qualifier P> |
59 | struct is_aligned |
60 | { |
61 | static const bool value = false; |
62 | }; |
63 | |
64 | # if GLM_CONFIG_ALIGNED_GENTYPES == GLM_ENABLE |
65 | template<> |
66 | struct is_aligned<glm::aligned_lowp> |
67 | { |
68 | static const bool value = true; |
69 | }; |
70 | |
71 | template<> |
72 | struct is_aligned<glm::aligned_mediump> |
73 | { |
74 | static const bool value = true; |
75 | }; |
76 | |
77 | template<> |
78 | struct is_aligned<glm::aligned_highp> |
79 | { |
80 | static const bool value = true; |
81 | }; |
82 | # endif |
83 | |
84 | template<length_t L, typename T, bool is_aligned> |
85 | struct storage |
86 | { |
87 | typedef struct type { |
88 | T data[L]; |
89 | } type; |
90 | }; |
91 | |
92 | # if GLM_HAS_ALIGNOF |
93 | template<length_t L, typename T> |
94 | struct storage<L, T, true> |
95 | { |
96 | typedef struct alignas(L * sizeof(T)) type { |
97 | T data[L]; |
98 | } type; |
99 | }; |
100 | |
101 | template<typename T> |
102 | struct storage<3, T, true> |
103 | { |
104 | typedef struct alignas(4 * sizeof(T)) type { |
105 | T data[4]; |
106 | } type; |
107 | }; |
108 | # endif |
109 | |
110 | # if GLM_ARCH & GLM_ARCH_SSE2_BIT |
111 | template<> |
112 | struct storage<4, float, true> |
113 | { |
114 | typedef glm_f32vec4 type; |
115 | }; |
116 | |
117 | template<> |
118 | struct storage<4, int, true> |
119 | { |
120 | typedef glm_i32vec4 type; |
121 | }; |
122 | |
123 | template<> |
124 | struct storage<4, unsigned int, true> |
125 | { |
126 | typedef glm_u32vec4 type; |
127 | }; |
128 | |
129 | template<> |
130 | struct storage<2, double, true> |
131 | { |
132 | typedef glm_f64vec2 type; |
133 | }; |
134 | |
135 | template<> |
136 | struct storage<2, detail::int64, true> |
137 | { |
138 | typedef glm_i64vec2 type; |
139 | }; |
140 | |
141 | template<> |
142 | struct storage<2, detail::uint64, true> |
143 | { |
144 | typedef glm_u64vec2 type; |
145 | }; |
146 | # endif |
147 | |
148 | # if (GLM_ARCH & GLM_ARCH_AVX_BIT) |
149 | template<> |
150 | struct storage<4, double, true> |
151 | { |
152 | typedef glm_f64vec4 type; |
153 | }; |
154 | # endif |
155 | |
156 | # if (GLM_ARCH & GLM_ARCH_AVX2_BIT) |
157 | template<> |
158 | struct storage<4, detail::int64, true> |
159 | { |
160 | typedef glm_i64vec4 type; |
161 | }; |
162 | |
163 | template<> |
164 | struct storage<4, detail::uint64, true> |
165 | { |
166 | typedef glm_u64vec4 type; |
167 | }; |
168 | # endif |
169 | |
170 | # if GLM_ARCH & GLM_ARCH_NEON_BIT |
171 | template<> |
172 | struct storage<4, float, true> |
173 | { |
174 | typedef glm_f32vec4 type; |
175 | }; |
176 | |
177 | template<> |
178 | struct storage<4, int, true> |
179 | { |
180 | typedef glm_i32vec4 type; |
181 | }; |
182 | |
183 | template<> |
184 | struct storage<4, unsigned int, true> |
185 | { |
186 | typedef glm_u32vec4 type; |
187 | }; |
188 | # endif |
189 | |
190 | enum genTypeEnum |
191 | { |
192 | GENTYPE_VEC, |
193 | GENTYPE_MAT, |
194 | GENTYPE_QUAT |
195 | }; |
196 | |
197 | template <typename genType> |
198 | struct genTypeTrait |
199 | {}; |
200 | |
201 | template <length_t C, length_t R, typename T> |
202 | struct genTypeTrait<mat<C, R, T> > |
203 | { |
204 | static const genTypeEnum GENTYPE = GENTYPE_MAT; |
205 | }; |
206 | |
207 | template<typename genType, genTypeEnum type> |
208 | struct init_gentype |
209 | { |
210 | }; |
211 | |
212 | template<typename genType> |
213 | struct init_gentype<genType, GENTYPE_QUAT> |
214 | { |
215 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() |
216 | { |
217 | return genType(1, 0, 0, 0); |
218 | } |
219 | }; |
220 | |
221 | template<typename genType> |
222 | struct init_gentype<genType, GENTYPE_MAT> |
223 | { |
224 | GLM_FUNC_QUALIFIER GLM_CONSTEXPR static genType identity() |
225 | { |
226 | return genType(1); |
227 | } |
228 | }; |
229 | }//namespace detail |
230 | }//namespace glm |
231 | |