summaryrefslogtreecommitdiff
path: root/src/common/vector_math.h
diff options
context:
space:
mode:
authorGravatar Emmanuel Gil Peyrot2016-09-18 09:38:01 +0900
committerGravatar Emmanuel Gil Peyrot2016-09-18 09:38:01 +0900
commitdc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch)
tree569a7f13128450bbab973236615587ff00bced5f /src/common/vector_math.h
parentTravis: Import Dolphin’s clang-format hook. (diff)
downloadyuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip
Sources: Run clang-format on everything.
Diffstat (limited to 'src/common/vector_math.h')
-rw-r--r--src/common/vector_math.h707
1 files changed, 382 insertions, 325 deletions
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index cfb9481b6..b2d630829 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -1,7 +1,6 @@
1// Licensed under GPLv2 or any later version 1// Licensed under GPLv2 or any later version
2// Refer to the license.txt file included. 2// Refer to the license.txt file included.
3 3
4
5// Copyright 2014 Tony Wasserka 4// Copyright 2014 Tony Wasserka
6// All rights reserved. 5// All rights reserved.
7// 6//
@@ -36,158 +35,178 @@
36 35
37namespace Math { 36namespace Math {
38 37
39template<typename T> class Vec2; 38template <typename T>
40template<typename T> class Vec3; 39class Vec2;
41template<typename T> class Vec4; 40template <typename T>
41class Vec3;
42template <typename T>
43class Vec4;
42 44
43template<typename T> 45template <typename T>
44static inline Vec2<T> MakeVec(const T& x, const T& y); 46static inline Vec2<T> MakeVec(const T& x, const T& y);
45template<typename T> 47template <typename T>
46static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z); 48static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z);
47template<typename T> 49template <typename T>
48static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w); 50static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w);
49 51
50 52template <typename T>
51template<typename T>
52class Vec2 { 53class Vec2 {
53public: 54public:
54 T x; 55 T x;
55 T y; 56 T y;
56 57
57 T* AsArray() { return &x; } 58 T* AsArray() {
59 return &x;
60 }
58 61
59 Vec2() = default; 62 Vec2() = default;
60 Vec2(const T a[2]) : x(a[0]), y(a[1]) {} 63 Vec2(const T a[2]) : x(a[0]), y(a[1]) {
61 Vec2(const T& _x, const T& _y) : x(_x), y(_y) {} 64 }
65 Vec2(const T& _x, const T& _y) : x(_x), y(_y) {
66 }
62 67
63 template<typename T2> 68 template <typename T2>
64 Vec2<T2> Cast() const { 69 Vec2<T2> Cast() const {
65 return Vec2<T2>((T2)x, (T2)y); 70 return Vec2<T2>((T2)x, (T2)y);
66 } 71 }
67 72
68 static Vec2 AssignToAll(const T& f) 73 static Vec2 AssignToAll(const T& f) {
69 {
70 return Vec2<T>(f, f); 74 return Vec2<T>(f, f);
71 } 75 }
72 76
73 void Write(T a[2]) 77 void Write(T a[2]) {
74 { 78 a[0] = x;
75 a[0] = x; a[1] = y; 79 a[1] = y;
76 } 80 }
77 81
78 Vec2<decltype(T{}+T{})> operator +(const Vec2& other) const 82 Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const {
79 { 83 return MakeVec(x + other.x, y + other.y);
80 return MakeVec(x+other.x, y+other.y);
81 } 84 }
82 void operator += (const Vec2 &other) 85 void operator+=(const Vec2& other) {
83 { 86 x += other.x;
84 x+=other.x; y+=other.y; 87 y += other.y;
85 } 88 }
86 Vec2<decltype(T{}-T{})> operator -(const Vec2& other) const 89 Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const {
87 { 90 return MakeVec(x - other.x, y - other.y);
88 return MakeVec(x-other.x, y-other.y);
89 } 91 }
90 void operator -= (const Vec2& other) 92 void operator-=(const Vec2& other) {
91 { 93 x -= other.x;
92 x-=other.x; y-=other.y; 94 y -= other.y;
93 } 95 }
94 template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> 96 template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type>
95 Vec2<decltype(-T{})> operator -() const 97 Vec2<decltype(-T{})> operator-() const {
96 { 98 return MakeVec(-x, -y);
97 return MakeVec(-x,-y);
98 } 99 }
99 Vec2<decltype(T{}*T{})> operator * (const Vec2& other) const 100 Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const {
100 { 101 return MakeVec(x * other.x, y * other.y);
101 return MakeVec(x*other.x, y*other.y);
102 } 102 }
103 template<typename V> 103 template <typename V>
104 Vec2<decltype(T{}*V{})> operator * (const V& f) const 104 Vec2<decltype(T{} * V{})> operator*(const V& f) const {
105 { 105 return MakeVec(x * f, y * f);
106 return MakeVec(x*f,y*f);
107 } 106 }
108 template<typename V> 107 template <typename V>
109 void operator *= (const V& f) 108 void operator*=(const V& f) {
110 { 109 x *= f;
111 x*=f; y*=f; 110 y *= f;
112 } 111 }
113 template<typename V> 112 template <typename V>
114 Vec2<decltype(T{}/V{})> operator / (const V& f) const 113 Vec2<decltype(T{} / V{})> operator/(const V& f) const {
115 { 114 return MakeVec(x / f, y / f);
116 return MakeVec(x/f,y/f);
117 } 115 }
118 template<typename V> 116 template <typename V>
119 void operator /= (const V& f) 117 void operator/=(const V& f) {
120 {
121 *this = *this / f; 118 *this = *this / f;
122 } 119 }
123 120
124 T Length2() const 121 T Length2() const {
125 { 122 return x * x + y * y;
126 return x*x + y*y;
127 } 123 }
128 124
129 // Only implemented for T=float 125 // Only implemented for T=float
130 float Length() const; 126 float Length() const;
131 void SetLength(const float l); 127 void SetLength(const float l);
132 Vec2 WithLength(const float l) const; 128 Vec2 WithLength(const float l) const;
133 float Distance2To(Vec2 &other); 129 float Distance2To(Vec2& other);
134 Vec2 Normalized() const; 130 Vec2 Normalized() const;
135 float Normalize(); // returns the previous length, which is often useful 131 float Normalize(); // returns the previous length, which is often useful
136 132
137 T& operator [] (int i) //allow vector[1] = 3 (vector.y=3) 133 T& operator[](int i) // allow vector[1] = 3 (vector.y=3)
138 { 134 {
139 return *((&x) + i); 135 return *((&x) + i);
140 } 136 }
141 T operator [] (const int i) const 137 T operator[](const int i) const {
142 {
143 return *((&x) + i); 138 return *((&x) + i);
144 } 139 }
145 140
146 void SetZero() 141 void SetZero() {
147 { 142 x = 0;
148 x=0; y=0; 143 y = 0;
149 } 144 }
150 145
151 // Common aliases: UV (texel coordinates), ST (texture coordinates) 146 // Common aliases: UV (texel coordinates), ST (texture coordinates)
152 T& u() { return x; } 147 T& u() {
153 T& v() { return y; } 148 return x;
154 T& s() { return x; } 149 }
155 T& t() { return y; } 150 T& v() {
151 return y;
152 }
153 T& s() {
154 return x;
155 }
156 T& t() {
157 return y;
158 }
156 159
157 const T& u() const { return x; } 160 const T& u() const {
158 const T& v() const { return y; } 161 return x;
159 const T& s() const { return x; } 162 }
160 const T& t() const { return y; } 163 const T& v() const {
164 return y;
165 }
166 const T& s() const {
167 return x;
168 }
169 const T& t() const {
170 return y;
171 }
161 172
162 // swizzlers - create a subvector of specific components 173 // swizzlers - create a subvector of specific components
163 const Vec2 yx() const { return Vec2(y, x); } 174 const Vec2 yx() const {
164 const Vec2 vu() const { return Vec2(y, x); } 175 return Vec2(y, x);
165 const Vec2 ts() const { return Vec2(y, x); } 176 }
177 const Vec2 vu() const {
178 return Vec2(y, x);
179 }
180 const Vec2 ts() const {
181 return Vec2(y, x);
182 }
166}; 183};
167 184
168template<typename T, typename V> 185template <typename T, typename V>
169Vec2<T> operator * (const V& f, const Vec2<T>& vec) 186Vec2<T> operator*(const V& f, const Vec2<T>& vec) {
170{ 187 return Vec2<T>(f * vec.x, f * vec.y);
171 return Vec2<T>(f*vec.x,f*vec.y);
172} 188}
173 189
174typedef Vec2<float> Vec2f; 190typedef Vec2<float> Vec2f;
175 191
176template<typename T> 192template <typename T>
177class Vec3 193class Vec3 {
178{
179public: 194public:
180 T x; 195 T x;
181 T y; 196 T y;
182 T z; 197 T z;
183 198
184 T* AsArray() { return &x; } 199 T* AsArray() {
200 return &x;
201 }
185 202
186 Vec3() = default; 203 Vec3() = default;
187 Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {} 204 Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {
188 Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {} 205 }
206 Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {
207 }
189 208
190 template<typename T2> 209 template <typename T2>
191 Vec3<T2> Cast() const { 210 Vec3<T2> Cast() const {
192 return MakeVec<T2>((T2)x, (T2)y, (T2)z); 211 return MakeVec<T2>((T2)x, (T2)y, (T2)z);
193 } 212 }
@@ -196,126 +215,161 @@ public:
196 static Vec3 FromRGB(unsigned int rgb); 215 static Vec3 FromRGB(unsigned int rgb);
197 unsigned int ToRGB() const; // alpha bits set to zero 216 unsigned int ToRGB() const; // alpha bits set to zero
198 217
199 static Vec3 AssignToAll(const T& f) 218 static Vec3 AssignToAll(const T& f) {
200 {
201 return MakeVec(f, f, f); 219 return MakeVec(f, f, f);
202 } 220 }
203 221
204 void Write(T a[3]) 222 void Write(T a[3]) {
205 { 223 a[0] = x;
206 a[0] = x; a[1] = y; a[2] = z; 224 a[1] = y;
225 a[2] = z;
207 } 226 }
208 227
209 Vec3<decltype(T{}+T{})> operator +(const Vec3 &other) const 228 Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const {
210 { 229 return MakeVec(x + other.x, y + other.y, z + other.z);
211 return MakeVec(x+other.x, y+other.y, z+other.z);
212 } 230 }
213 void operator += (const Vec3 &other) 231 void operator+=(const Vec3& other) {
214 { 232 x += other.x;
215 x+=other.x; y+=other.y; z+=other.z; 233 y += other.y;
234 z += other.z;
216 } 235 }
217 Vec3<decltype(T{}-T{})> operator -(const Vec3 &other) const 236 Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const {
218 { 237 return MakeVec(x - other.x, y - other.y, z - other.z);
219 return MakeVec(x-other.x, y-other.y, z-other.z);
220 } 238 }
221 void operator -= (const Vec3 &other) 239 void operator-=(const Vec3& other) {
222 { 240 x -= other.x;
223 x-=other.x; y-=other.y; z-=other.z; 241 y -= other.y;
242 z -= other.z;
224 } 243 }
225 template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> 244 template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type>
226 Vec3<decltype(-T{})> operator -() const 245 Vec3<decltype(-T{})> operator-() const {
227 { 246 return MakeVec(-x, -y, -z);
228 return MakeVec(-x,-y,-z);
229 } 247 }
230 Vec3<decltype(T{}*T{})> operator * (const Vec3 &other) const 248 Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const {
231 { 249 return MakeVec(x * other.x, y * other.y, z * other.z);
232 return MakeVec(x*other.x, y*other.y, z*other.z);
233 } 250 }
234 template<typename V> 251 template <typename V>
235 Vec3<decltype(T{}*V{})> operator * (const V& f) const 252 Vec3<decltype(T{} * V{})> operator*(const V& f) const {
236 { 253 return MakeVec(x * f, y * f, z * f);
237 return MakeVec(x*f,y*f,z*f);
238 } 254 }
239 template<typename V> 255 template <typename V>
240 void operator *= (const V& f) 256 void operator*=(const V& f) {
241 { 257 x *= f;
242 x*=f; y*=f; z*=f; 258 y *= f;
259 z *= f;
243 } 260 }
244 template<typename V> 261 template <typename V>
245 Vec3<decltype(T{}/V{})> operator / (const V& f) const 262 Vec3<decltype(T{} / V{})> operator/(const V& f) const {
246 { 263 return MakeVec(x / f, y / f, z / f);
247 return MakeVec(x/f,y/f,z/f);
248 } 264 }
249 template<typename V> 265 template <typename V>
250 void operator /= (const V& f) 266 void operator/=(const V& f) {
251 {
252 *this = *this / f; 267 *this = *this / f;
253 } 268 }
254 269
255 T Length2() const 270 T Length2() const {
256 { 271 return x * x + y * y + z * z;
257 return x*x + y*y + z*z;
258 } 272 }
259 273
260 // Only implemented for T=float 274 // Only implemented for T=float
261 float Length() const; 275 float Length() const;
262 void SetLength(const float l); 276 void SetLength(const float l);
263 Vec3 WithLength(const float l) const; 277 Vec3 WithLength(const float l) const;
264 float Distance2To(Vec3 &other); 278 float Distance2To(Vec3& other);
265 Vec3 Normalized() const; 279 Vec3 Normalized() const;
266 float Normalize(); // returns the previous length, which is often useful 280 float Normalize(); // returns the previous length, which is often useful
267 281
268 T& operator [] (int i) //allow vector[2] = 3 (vector.z=3) 282 T& operator[](int i) // allow vector[2] = 3 (vector.z=3)
269 { 283 {
270 return *((&x) + i); 284 return *((&x) + i);
271 } 285 }
272 T operator [] (const int i) const 286 T operator[](const int i) const {
273 {
274 return *((&x) + i); 287 return *((&x) + i);
275 } 288 }
276 289
277 void SetZero() 290 void SetZero() {
278 { 291 x = 0;
279 x=0; y=0; z=0; 292 y = 0;
293 z = 0;
280 } 294 }
281 295
282 // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates) 296 // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates)
283 T& u() { return x; } 297 T& u() {
284 T& v() { return y; } 298 return x;
285 T& w() { return z; } 299 }
300 T& v() {
301 return y;
302 }
303 T& w() {
304 return z;
305 }
286 306
287 T& r() { return x; } 307 T& r() {
288 T& g() { return y; } 308 return x;
289 T& b() { return z; } 309 }
310 T& g() {
311 return y;
312 }
313 T& b() {
314 return z;
315 }
290 316
291 T& s() { return x; } 317 T& s() {
292 T& t() { return y; } 318 return x;
293 T& q() { return z; } 319 }
320 T& t() {
321 return y;
322 }
323 T& q() {
324 return z;
325 }
294 326
295 const T& u() const { return x; } 327 const T& u() const {
296 const T& v() const { return y; } 328 return x;
297 const T& w() const { return z; } 329 }
330 const T& v() const {
331 return y;
332 }
333 const T& w() const {
334 return z;
335 }
298 336
299 const T& r() const { return x; } 337 const T& r() const {
300 const T& g() const { return y; } 338 return x;
301 const T& b() const { return z; } 339 }
340 const T& g() const {
341 return y;
342 }
343 const T& b() const {
344 return z;
345 }
302 346
303 const T& s() const { return x; } 347 const T& s() const {
304 const T& t() const { return y; } 348 return x;
305 const T& q() const { return z; } 349 }
350 const T& t() const {
351 return y;
352 }
353 const T& q() const {
354 return z;
355 }
306 356
307 // swizzlers - create a subvector of specific components 357// swizzlers - create a subvector of specific components
308 // e.g. Vec2 uv() { return Vec2(x,y); } 358// e.g. Vec2 uv() { return Vec2(x,y); }
309 // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx) 359// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
310#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } 360// component names (x<->r) and permutations (xy<->yx)
311#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ 361#define _DEFINE_SWIZZLER2(a, b, name) \
312 _DEFINE_SWIZZLER2(a, b, a##b); \ 362 const Vec2<T> name() const { \
313 _DEFINE_SWIZZLER2(a, b, a2##b2); \ 363 return Vec2<T>(a, b); \
314 _DEFINE_SWIZZLER2(a, b, a3##b3); \ 364 }
315 _DEFINE_SWIZZLER2(a, b, a4##b4); \ 365#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
316 _DEFINE_SWIZZLER2(b, a, b##a); \ 366 _DEFINE_SWIZZLER2(a, b, a##b); \
317 _DEFINE_SWIZZLER2(b, a, b2##a2); \ 367 _DEFINE_SWIZZLER2(a, b, a2##b2); \
318 _DEFINE_SWIZZLER2(b, a, b3##a3); \ 368 _DEFINE_SWIZZLER2(a, b, a3##b3); \
369 _DEFINE_SWIZZLER2(a, b, a4##b4); \
370 _DEFINE_SWIZZLER2(b, a, b##a); \
371 _DEFINE_SWIZZLER2(b, a, b2##a2); \
372 _DEFINE_SWIZZLER2(b, a, b3##a3); \
319 _DEFINE_SWIZZLER2(b, a, b4##a4) 373 _DEFINE_SWIZZLER2(b, a, b4##a4)
320 374
321 DEFINE_SWIZZLER2(x, y, r, g, u, v, s, t); 375 DEFINE_SWIZZLER2(x, y, r, g, u, v, s, t);
@@ -325,41 +379,42 @@ public:
325#undef _DEFINE_SWIZZLER2 379#undef _DEFINE_SWIZZLER2
326}; 380};
327 381
328template<typename T, typename V> 382template <typename T, typename V>
329Vec3<T> operator * (const V& f, const Vec3<T>& vec) 383Vec3<T> operator*(const V& f, const Vec3<T>& vec) {
330{ 384 return Vec3<T>(f * vec.x, f * vec.y, f * vec.z);
331 return Vec3<T>(f*vec.x,f*vec.y,f*vec.z);
332} 385}
333 386
334template<> 387template <>
335inline float Vec3<float>::Length() const { 388inline float Vec3<float>::Length() const {
336 return std::sqrt(x * x + y * y + z * z); 389 return std::sqrt(x * x + y * y + z * z);
337} 390}
338 391
339template<> 392template <>
340inline Vec3<float> Vec3<float>::Normalized() const { 393inline Vec3<float> Vec3<float>::Normalized() const {
341 return *this / Length(); 394 return *this / Length();
342} 395}
343 396
344
345typedef Vec3<float> Vec3f; 397typedef Vec3<float> Vec3f;
346 398
347template<typename T> 399template <typename T>
348class Vec4 400class Vec4 {
349{
350public: 401public:
351 T x; 402 T x;
352 T y; 403 T y;
353 T z; 404 T z;
354 T w; 405 T w;
355 406
356 T* AsArray() { return &x; } 407 T* AsArray() {
408 return &x;
409 }
357 410
358 Vec4() = default; 411 Vec4() = default;
359 Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {} 412 Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {
360 Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} 413 }
414 Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {
415 }
361 416
362 template<typename T2> 417 template <typename T2>
363 Vec4<T2> Cast() const { 418 Vec4<T2> Cast() const {
364 return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w); 419 return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w);
365 } 420 }
@@ -372,81 +427,79 @@ public:
372 return Vec4<T>(f, f, f, f); 427 return Vec4<T>(f, f, f, f);
373 } 428 }
374 429
375 void Write(T a[4]) 430 void Write(T a[4]) {
376 { 431 a[0] = x;
377 a[0] = x; a[1] = y; a[2] = z; a[3] = w; 432 a[1] = y;
433 a[2] = z;
434 a[3] = w;
378 } 435 }
379 436
380 Vec4<decltype(T{}+T{})> operator +(const Vec4& other) const 437 Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const {
381 { 438 return MakeVec(x + other.x, y + other.y, z + other.z, w + other.w);
382 return MakeVec(x+other.x, y+other.y, z+other.z, w+other.w);
383 } 439 }
384 void operator += (const Vec4& other) 440 void operator+=(const Vec4& other) {
385 { 441 x += other.x;
386 x+=other.x; y+=other.y; z+=other.z; w+=other.w; 442 y += other.y;
443 z += other.z;
444 w += other.w;
387 } 445 }
388 Vec4<decltype(T{}-T{})> operator -(const Vec4 &other) const 446 Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const {
389 { 447 return MakeVec(x - other.x, y - other.y, z - other.z, w - other.w);
390 return MakeVec(x-other.x, y-other.y, z-other.z, w-other.w);
391 } 448 }
392 void operator -= (const Vec4 &other) 449 void operator-=(const Vec4& other) {
393 { 450 x -= other.x;
394 x-=other.x; y-=other.y; z-=other.z; w-=other.w; 451 y -= other.y;
452 z -= other.z;
453 w -= other.w;
395 } 454 }
396 template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> 455 template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type>
397 Vec4<decltype(-T{})> operator -() const 456 Vec4<decltype(-T{})> operator-() const {
398 { 457 return MakeVec(-x, -y, -z, -w);
399 return MakeVec(-x,-y,-z,-w);
400 } 458 }
401 Vec4<decltype(T{}*T{})> operator * (const Vec4 &other) const 459 Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const {
402 { 460 return MakeVec(x * other.x, y * other.y, z * other.z, w * other.w);
403 return MakeVec(x*other.x, y*other.y, z*other.z, w*other.w);
404 } 461 }
405 template<typename V> 462 template <typename V>
406 Vec4<decltype(T{}*V{})> operator * (const V& f) const 463 Vec4<decltype(T{} * V{})> operator*(const V& f) const {
407 { 464 return MakeVec(x * f, y * f, z * f, w * f);
408 return MakeVec(x*f,y*f,z*f,w*f);
409 } 465 }
410 template<typename V> 466 template <typename V>
411 void operator *= (const V& f) 467 void operator*=(const V& f) {
412 { 468 x *= f;
413 x*=f; y*=f; z*=f; w*=f; 469 y *= f;
470 z *= f;
471 w *= f;
414 } 472 }
415 template<typename V> 473 template <typename V>
416 Vec4<decltype(T{}/V{})> operator / (const V& f) const 474 Vec4<decltype(T{} / V{})> operator/(const V& f) const {
417 { 475 return MakeVec(x / f, y / f, z / f, w / f);
418 return MakeVec(x/f,y/f,z/f,w/f);
419 } 476 }
420 template<typename V> 477 template <typename V>
421 void operator /= (const V& f) 478 void operator/=(const V& f) {
422 {
423 *this = *this / f; 479 *this = *this / f;
424 } 480 }
425 481
426 T Length2() const 482 T Length2() const {
427 { 483 return x * x + y * y + z * z + w * w;
428 return x*x + y*y + z*z + w*w;
429 } 484 }
430 485
431 // Only implemented for T=float 486 // Only implemented for T=float
432 float Length() const; 487 float Length() const;
433 void SetLength(const float l); 488 void SetLength(const float l);
434 Vec4 WithLength(const float l) const; 489 Vec4 WithLength(const float l) const;
435 float Distance2To(Vec4 &other); 490 float Distance2To(Vec4& other);
436 Vec4 Normalized() const; 491 Vec4 Normalized() const;
437 float Normalize(); // returns the previous length, which is often useful 492 float Normalize(); // returns the previous length, which is often useful
438 493
439 T& operator [] (int i) //allow vector[2] = 3 (vector.z=3) 494 T& operator[](int i) // allow vector[2] = 3 (vector.z=3)
440 { 495 {
441 return *((&x) + i); 496 return *((&x) + i);
442 } 497 }
443 T operator [] (const int i) const 498 T operator[](const int i) const {
444 {
445 return *((&x) + i); 499 return *((&x) + i);
446 } 500 }
447 501
448 void SetZero() 502 void SetZero() {
449 {
450 x = 0; 503 x = 0;
451 y = 0; 504 y = 0;
452 z = 0; 505 z = 0;
@@ -454,30 +507,50 @@ public:
454 } 507 }
455 508
456 // Common alias: RGBA (colors) 509 // Common alias: RGBA (colors)
457 T& r() { return x; } 510 T& r() {
458 T& g() { return y; } 511 return x;
459 T& b() { return z; } 512 }
460 T& a() { return w; } 513 T& g() {
461 514 return y;
462 const T& r() const { return x; } 515 }
463 const T& g() const { return y; } 516 T& b() {
464 const T& b() const { return z; } 517 return z;
465 const T& a() const { return w; } 518 }
466 519 T& a() {
467 // Swizzlers - Create a subvector of specific components 520 return w;
468 // e.g. Vec2 uv() { return Vec2(x,y); } 521 }
469 522
470 // _DEFINE_SWIZZLER2 defines a single such function 523 const T& r() const {
471 // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) 524 return x;
472 // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx) 525 }
473#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } 526 const T& g() const {
474#define DEFINE_SWIZZLER2_COMP1(a, a2) \ 527 return y;
475 _DEFINE_SWIZZLER2(a, a, a##a); \ 528 }
529 const T& b() const {
530 return z;
531 }
532 const T& a() const {
533 return w;
534 }
535
536// Swizzlers - Create a subvector of specific components
537// e.g. Vec2 uv() { return Vec2(x,y); }
538
539// _DEFINE_SWIZZLER2 defines a single such function
540// DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r)
541// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
542// permutations (xy<->yx)
543#define _DEFINE_SWIZZLER2(a, b, name) \
544 const Vec2<T> name() const { \
545 return Vec2<T>(a, b); \
546 }
547#define DEFINE_SWIZZLER2_COMP1(a, a2) \
548 _DEFINE_SWIZZLER2(a, a, a##a); \
476 _DEFINE_SWIZZLER2(a, a, a2##a2) 549 _DEFINE_SWIZZLER2(a, a, a2##a2)
477#define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \ 550#define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \
478 _DEFINE_SWIZZLER2(a, b, a##b); \ 551 _DEFINE_SWIZZLER2(a, b, a##b); \
479 _DEFINE_SWIZZLER2(a, b, a2##b2); \ 552 _DEFINE_SWIZZLER2(a, b, a2##b2); \
480 _DEFINE_SWIZZLER2(b, a, b##a); \ 553 _DEFINE_SWIZZLER2(b, a, b##a); \
481 _DEFINE_SWIZZLER2(b, a, b2##a2) 554 _DEFINE_SWIZZLER2(b, a, b2##a2)
482 555
483 DEFINE_SWIZZLER2_COMP2(x, y, r, g); 556 DEFINE_SWIZZLER2_COMP2(x, y, r, g);
@@ -494,22 +567,25 @@ public:
494#undef DEFINE_SWIZZLER2_COMP2 567#undef DEFINE_SWIZZLER2_COMP2
495#undef _DEFINE_SWIZZLER2 568#undef _DEFINE_SWIZZLER2
496 569
497#define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); } 570#define _DEFINE_SWIZZLER3(a, b, c, name) \
498#define DEFINE_SWIZZLER3_COMP1(a, a2) \ 571 const Vec3<T> name() const { \
499 _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ 572 return Vec3<T>(a, b, c); \
573 }
574#define DEFINE_SWIZZLER3_COMP1(a, a2) \
575 _DEFINE_SWIZZLER3(a, a, a, a##a##a); \
500 _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) 576 _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2)
501#define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \ 577#define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \
502 _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ 578 _DEFINE_SWIZZLER3(a, b, c, a##b##c); \
503 _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ 579 _DEFINE_SWIZZLER3(a, c, b, a##c##b); \
504 _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ 580 _DEFINE_SWIZZLER3(b, a, c, b##a##c); \
505 _DEFINE_SWIZZLER3(b, c, a, b##c##a); \ 581 _DEFINE_SWIZZLER3(b, c, a, b##c##a); \
506 _DEFINE_SWIZZLER3(c, a, b, c##a##b); \ 582 _DEFINE_SWIZZLER3(c, a, b, c##a##b); \
507 _DEFINE_SWIZZLER3(c, b, a, c##b##a); \ 583 _DEFINE_SWIZZLER3(c, b, a, c##b##a); \
508 _DEFINE_SWIZZLER3(a, b, c, a2##b2##c2); \ 584 _DEFINE_SWIZZLER3(a, b, c, a2##b2##c2); \
509 _DEFINE_SWIZZLER3(a, c, b, a2##c2##b2); \ 585 _DEFINE_SWIZZLER3(a, c, b, a2##c2##b2); \
510 _DEFINE_SWIZZLER3(b, a, c, b2##a2##c2); \ 586 _DEFINE_SWIZZLER3(b, a, c, b2##a2##c2); \
511 _DEFINE_SWIZZLER3(b, c, a, b2##c2##a2); \ 587 _DEFINE_SWIZZLER3(b, c, a, b2##c2##a2); \
512 _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ 588 _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \
513 _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2) 589 _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2)
514 590
515 DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b); 591 DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b);
@@ -525,123 +601,104 @@ public:
525#undef _DEFINE_SWIZZLER3 601#undef _DEFINE_SWIZZLER3
526}; 602};
527 603
528 604template <typename T, typename V>
529template<typename T, typename V> 605Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) {
530Vec4<decltype(V{}*T{})> operator * (const V& f, const Vec4<T>& vec) 606 return MakeVec(f * vec.x, f * vec.y, f * vec.z, f * vec.w);
531{
532 return MakeVec(f*vec.x,f*vec.y,f*vec.z,f*vec.w);
533} 607}
534 608
535typedef Vec4<float> Vec4f; 609typedef Vec4<float> Vec4f;
536 610
537 611template <typename T>
538template<typename T> 612static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) {
539static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) 613 return a.x * b.x + a.y * b.y;
540{
541 return a.x*b.x + a.y*b.y;
542} 614}
543 615
544template<typename T> 616template <typename T>
545static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) 617static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) {
546{ 618 return a.x * b.x + a.y * b.y + a.z * b.z;
547 return a.x*b.x + a.y*b.y + a.z*b.z;
548} 619}
549 620
550template<typename T> 621template <typename T>
551static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) 622static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) {
552{ 623 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
553 return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
554} 624}
555 625
556template<typename T> 626template <typename T>
557static inline Vec3<decltype(T{}*T{}-T{}*T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) 627static inline Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) {
558{ 628 return MakeVec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
559 return MakeVec(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);
560} 629}
561 630
562// linear interpolation via float: 0.0=begin, 1.0=end 631// linear interpolation via float: 0.0=begin, 1.0=end
563template<typename X> 632template <typename X>
564static inline decltype(X{}*float{}+X{}*float{}) Lerp(const X& begin, const X& end, const float t) 633static inline decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
565{ 634 const float t) {
566 return begin*(1.f-t) + end*t; 635 return begin * (1.f - t) + end * t;
567} 636}
568 637
569// linear interpolation via int: 0=begin, base=end 638// linear interpolation via int: 0=begin, base=end
570template<typename X, int base> 639template <typename X, int base>
571static inline decltype((X{}*int{}+X{}*int{}) / base) LerpInt(const X& begin, const X& end, const int t) 640static inline decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end,
572{ 641 const int t) {
573 return (begin*(base-t) + end*t) / base; 642 return (begin * (base - t) + end * t) / base;
574} 643}
575 644
576// Utility vector factories 645// Utility vector factories
577template<typename T> 646template <typename T>
578static inline Vec2<T> MakeVec(const T& x, const T& y) 647static inline Vec2<T> MakeVec(const T& x, const T& y) {
579{
580 return Vec2<T>{x, y}; 648 return Vec2<T>{x, y};
581} 649}
582 650
583template<typename T> 651template <typename T>
584static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) 652static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) {
585{
586 return Vec3<T>{x, y, z}; 653 return Vec3<T>{x, y, z};
587} 654}
588 655
589template<typename T> 656template <typename T>
590static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) 657static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) {
591{
592 return MakeVec(x, y, zw[0], zw[1]); 658 return MakeVec(x, y, zw[0], zw[1]);
593} 659}
594 660
595template<typename T> 661template <typename T>
596static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) 662static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) {
597{
598 return MakeVec(xy[0], xy[1], z); 663 return MakeVec(xy[0], xy[1], z);
599} 664}
600 665
601template<typename T> 666template <typename T>
602static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) 667static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) {
603{
604 return MakeVec(x, yz[0], yz[1]); 668 return MakeVec(x, yz[0], yz[1]);
605} 669}
606 670
607template<typename T> 671template <typename T>
608static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) 672static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) {
609{
610 return Vec4<T>{x, y, z, w}; 673 return Vec4<T>{x, y, z, w};
611} 674}
612 675
613template<typename T> 676template <typename T>
614static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) 677static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) {
615{
616 return MakeVec(xy[0], xy[1], z, w); 678 return MakeVec(xy[0], xy[1], z, w);
617} 679}
618 680
619template<typename T> 681template <typename T>
620static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) 682static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) {
621{
622 return MakeVec(x, yz[0], yz[1], w); 683 return MakeVec(x, yz[0], yz[1], w);
623} 684}
624 685
625// NOTE: This has priority over "Vec2<Vec2<T>> MakeVec(const Vec2<T>& x, const Vec2<T>& y)". 686// NOTE: This has priority over "Vec2<Vec2<T>> MakeVec(const Vec2<T>& x, const Vec2<T>& y)".
626// Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error 687// Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error
627// out soon enough due to misuse of the returned structure. 688// out soon enough due to misuse of the returned structure.
628template<typename T> 689template <typename T>
629static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) 690static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) {
630{
631 return MakeVec(xy[0], xy[1], zw[0], zw[1]); 691 return MakeVec(xy[0], xy[1], zw[0], zw[1]);
632} 692}
633 693
634template<typename T> 694template <typename T>
635static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) 695static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) {
636{
637 return MakeVec(xyz[0], xyz[1], xyz[2], w); 696 return MakeVec(xyz[0], xyz[1], xyz[2], w);
638} 697}
639 698
640template<typename T> 699template <typename T>
641static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) 700static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) {
642{
643 return MakeVec(x, yzw[0], yzw[1], yzw[2]); 701 return MakeVec(x, yzw[0], yzw[1], yzw[2]);
644} 702}
645 703
646
647} // namespace 704} // namespace