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