source: trunk/src/lol/math/matrix.h @ 1137

Last change on this file since 1137 was 1137, checked in by sam, 8 years ago

math: finally get the GLSL-like swizzling to work.

  • Property svn:keywords set to Id
File size: 39.6 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11//
12// The Matrix classes
13// ------------------
14//
15
16#if !defined __LOL_MATH_MATRIX_H__
17#define __LOL_MATH_MATRIX_H__
18
19#include <stdint.h>
20#include <cmath>
21#if !defined __ANDROID__
22#   include <iostream>
23#endif
24
25namespace lol
26{
27
28class half;
29class real;
30
31#define VECTOR_TYPES(tname, suffix) \
32    template <typename T> struct tname; \
33    typedef tname<half> f16##suffix; \
34    typedef tname<float> suffix; \
35    typedef tname<double> f64##suffix; \
36    typedef tname<int8_t> i8##suffix; \
37    typedef tname<uint8_t> u8##suffix; \
38    typedef tname<int16_t> i16##suffix; \
39    typedef tname<uint16_t> u16##suffix; \
40    typedef tname<int32_t> i##suffix; \
41    typedef tname<uint32_t> u##suffix; \
42    typedef tname<int64_t> i64##suffix; \
43    typedef tname<uint64_t> u64##suffix;
44
45VECTOR_TYPES(Vec2, vec2)
46VECTOR_TYPES(Cmplx, cmplx)
47VECTOR_TYPES(Vec3, vec3)
48VECTOR_TYPES(Vec4, vec4)
49VECTOR_TYPES(Quat, quat)
50VECTOR_TYPES(Mat4, mat4)
51
52/*
53 * Magic swizzling (part 1/2)
54 */
55
56template<typename T, int I, int J> struct MagicVec2
57{
58    inline Vec2<T> operator =(Vec2<T> that);
59
60    float ptr[1 + (I > J ? I : J)];
61};
62
63template<typename T, int I, int J, int K> struct MagicVec3
64{
65    inline Vec3<T> operator =(Vec3<T> that);
66
67    float ptr[1 + (I > J ? I > K ? I : K
68                         : J > K ? J : K)];
69};
70
71template<typename T, int I, int J, int K, int L> struct MagicVec4
72{
73    inline Vec4<T> operator =(Vec4<T> that);
74
75    float ptr[1 + (I > J ? I > K ? I > L ? I : L : K > L ? K : L
76                         : J > K ? J > L ? J : L : K > L ? K : L)];
77};
78
79/*
80 * Helper macros for vector type member functions
81 */
82
83#define MEMBER_OPS() \
84    inline T& operator[](int n) { return *(&x + n); } \
85    inline T const& operator[](int n) const { return *(&x + n); } \
86    \
87    void printf() const;
88
89#define COMPLEX_OPS() \
90    inline type_t operator *(type_t const &val) const \
91    { \
92        return type_t(x * val.x - y * val.y, x * val.y + y * val.x); \
93    } \
94    \
95    inline type_t operator *=(type_t const &val) \
96    { \
97        return *this = (*this) * val; \
98    } \
99    \
100    inline type_t operator ~() const \
101    { \
102        return type_t(x, -y); \
103    } \
104    \
105    inline T norm() const { return len(*this); }
106
107#define QUATERNION_OPS() \
108    inline type_t operator *(type_t const &val) const \
109    { \
110        type_t ret; \
111        Vec3<T> v1(x, y, z); \
112        Vec3<T> v2(val.x, val.y, val.z); \
113        Vec3<T> v3 = cross(v1, v2) + w * v2 + val.w * v1; \
114        ret.x = v3.x; \
115        ret.y = v3.y; \
116        ret.z = v3.z; \
117        ret.w = w * val.w - dot(v1, v2); \
118        return ret; \
119    } \
120    \
121    inline type_t operator *=(type_t const &val) \
122    { \
123        return *this = (*this) * val; \
124    } \
125    \
126    inline type_t operator ~() const \
127    { \
128        type_t ret; \
129        for (int n = 0; n < 3; n++) \
130            ret[n] = -(*this)[n]; \
131        ret[3] = (*this)[3]; \
132        return ret; \
133    }
134
135#define OTHER_MEMBER_OPS(tname) \
136    template<typename U> \
137    inline operator tname<U>() const \
138    { \
139        tname<U> ret; \
140        for (size_t n = 0; n < sizeof(*this) / sizeof(T); n++) \
141            ret[n] = static_cast<U>((*this)[n]); \
142        return ret; \
143    }
144
145/*
146 * 2-element vectors
147 */
148
149template <typename T> struct Vec2
150{
151    typedef Vec2<T> type_t;
152
153    inline Vec2() { }
154    explicit inline Vec2(T val) { x = y = val; }
155    inline Vec2(T _x, T _y) { x = _x; y = _y; }
156
157    template<int I, int J>
158    inline Vec2(MagicVec2<T, I, J> const &v)
159      : x(v.ptr[I]), y(v.ptr[J]) {}
160
161    template<typename U, int I, int J>
162    explicit inline Vec2(MagicVec2<U, I, J> const &v)
163      : x(v.ptr[I]), y(v.ptr[J]) {}
164
165    MEMBER_OPS()
166    OTHER_MEMBER_OPS(Vec2)
167
168#if !defined __ANDROID__
169    template<typename U>
170    friend std::ostream &operator<<(std::ostream &stream, Vec2<U> const &v);
171#endif
172
173    union
174    {
175        struct { T x, y; };
176        struct { T r, g; };
177        struct { T s, t; };
178
179        MagicVec2<T,0,0> xx, rr, ss;
180        MagicVec2<T,0,1> xy, rg, st;
181        MagicVec2<T,1,0> yx, gr, ts;
182        MagicVec2<T,1,1> yy, gg, tt;
183        MagicVec3<T,0,0,0> xxx, rrr, sss;
184        MagicVec3<T,0,0,1> xxy, rrg, sst;
185        MagicVec3<T,0,1,0> xyx, rgr, sts;
186        MagicVec3<T,0,1,1> xyy, rgg, stt;
187        MagicVec3<T,1,0,0> yxx, grr, tss;
188        MagicVec3<T,1,0,1> yxy, grg, tst;
189        MagicVec3<T,1,1,0> yyx, ggr, tts;
190        MagicVec3<T,1,1,1> yyy, ggg, ttt;
191        MagicVec4<T,0,0,0,0> xxxx, rrrr, ssss;
192        MagicVec4<T,0,0,0,1> xxxy, rrrg, ssst;
193        MagicVec4<T,0,0,1,0> xxyx, rrgr, ssts;
194        MagicVec4<T,0,0,1,1> xxyy, rrgg, sstt;
195        MagicVec4<T,0,1,0,0> xyxx, rgrr, stss;
196        MagicVec4<T,0,1,0,1> xyxy, rgrg, stst;
197        MagicVec4<T,0,1,1,0> xyyx, rggr, stts;
198        MagicVec4<T,0,1,1,1> xyyy, rggg, sttt;
199        MagicVec4<T,1,0,0,0> yxxx, grrr, tsss;
200        MagicVec4<T,1,0,0,1> yxxy, grrg, tsst;
201        MagicVec4<T,1,0,1,0> yxyx, grgr, tsts;
202        MagicVec4<T,1,0,1,1> yxyy, grgg, tstt;
203        MagicVec4<T,1,1,0,0> yyxx, ggrr, ttss;
204        MagicVec4<T,1,1,0,1> yyxy, ggrg, ttst;
205        MagicVec4<T,1,1,1,0> yyyx, gggr, ttts;
206        MagicVec4<T,1,1,1,1> yyyy, gggg, tttt;
207    };
208};
209
210/*
211 * 2-element complexes
212 */
213
214template <typename T> struct Cmplx
215{
216    typedef Cmplx<T> type_t;
217
218    inline Cmplx() { }
219    inline Cmplx(T val) : x(val), y(0) { }
220    inline Cmplx(T _x, T _y) : x(_x), y(_y) { }
221
222    MEMBER_OPS()
223
224    COMPLEX_OPS()
225
226#if !defined __ANDROID__
227    template<typename U>
228    friend std::ostream &operator<<(std::ostream &stream, Cmplx<U> const &v);
229#endif
230
231    T x, y;
232};
233
234template<typename T>
235static inline Cmplx<T> re(Cmplx<T> const &val)
236{
237    return ~val / sqlen(val);
238}
239
240template<typename T>
241static inline Cmplx<T> operator /(T a, Cmplx<T> const &b)
242{
243    return a * re(b);
244}
245
246template<typename T>
247static inline Cmplx<T> operator /(Cmplx<T> a, Cmplx<T> const &b)
248{
249    return a * re(b);
250}
251
252template<typename T>
253static inline bool operator ==(Cmplx<T> const &a, T b)
254{
255    return (a.x == b) && !a.y;
256}
257
258template<typename T>
259static inline bool operator !=(Cmplx<T> const &a, T b)
260{
261    return (a.x != b) || a.y;
262}
263
264template<typename T>
265static inline bool operator ==(T a, Cmplx<T> const &b) { return b == a; }
266
267template<typename T>
268static inline bool operator !=(T a, Cmplx<T> const &b) { return b != a; }
269
270/*
271 * 3-element vectors
272 */
273
274template <typename T> struct Vec3
275{
276    typedef Vec3<T> type_t;
277
278    inline Vec3() { }
279    explicit inline Vec3(T val) { x = y = z = val; }
280    inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
281    inline Vec3(Vec2<T> _xy, T _z) { x = _xy.x; y = _xy.y; z = _z; }
282    inline Vec3(T _x, Vec2<T> _yz) { x = _x; y = _yz.x; z = _yz.y; }
283
284    template<int I, int J, int K>
285    inline Vec3(MagicVec3<T, I, J, K> const &v)
286      : x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]) {}
287
288    template<typename U, int I, int J, int K>
289    explicit inline Vec3(MagicVec3<U, I, J, K> const &v)
290      : x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]) {}
291
292    MEMBER_OPS()
293    OTHER_MEMBER_OPS(Vec3)
294
295    template<typename U>
296    friend Vec3<U> cross(Vec3<U>, Vec3<U>);
297
298#if !defined __ANDROID__
299    template<typename U>
300    friend std::ostream &operator<<(std::ostream &stream, Vec3<U> const &v);
301#endif
302
303    union
304    {
305        struct { T x, y, z; };
306        struct { T r, g, b; };
307        struct { T s, t, p; };
308
309        MagicVec2<T,0,0> xx, rr, ss;
310        MagicVec2<T,0,1> xy, rg, st;
311        MagicVec2<T,0,2> xz, rb, sp;
312        MagicVec2<T,1,0> yx, gr, ts;
313        MagicVec2<T,1,1> yy, gg, tt;
314        MagicVec2<T,1,2> yz, gb, tp;
315        MagicVec2<T,2,0> zx, br, ps;
316        MagicVec2<T,2,1> zy, bg, pt;
317        MagicVec2<T,2,2> zz, bb, pp;
318        MagicVec3<T,0,0,0> xxx, rrr, sss;
319        MagicVec3<T,0,0,1> xxy, rrg, sst;
320        MagicVec3<T,0,0,2> xxz, rrb, ssp;
321        MagicVec3<T,0,1,0> xyx, rgr, sts;
322        MagicVec3<T,0,1,1> xyy, rgg, stt;
323        MagicVec3<T,0,1,2> xyz, rgb, stp;
324        MagicVec3<T,0,2,0> xzx, rbr, sps;
325        MagicVec3<T,0,2,1> xzy, rbg, spt;
326        MagicVec3<T,0,2,2> xzz, rbb, spp;
327        MagicVec3<T,1,0,0> yxx, grr, tss;
328        MagicVec3<T,1,0,1> yxy, grg, tst;
329        MagicVec3<T,1,0,2> yxz, grb, tsp;
330        MagicVec3<T,1,1,0> yyx, ggr, tts;
331        MagicVec3<T,1,1,1> yyy, ggg, ttt;
332        MagicVec3<T,1,1,2> yyz, ggb, ttp;
333        MagicVec3<T,1,2,0> yzx, gbr, tps;
334        MagicVec3<T,1,2,1> yzy, gbg, tpt;
335        MagicVec3<T,1,2,2> yzz, gbb, tpp;
336        MagicVec3<T,2,0,0> zxx, brr, pss;
337        MagicVec3<T,2,0,1> zxy, brg, pst;
338        MagicVec3<T,2,0,2> zxz, brb, psp;
339        MagicVec3<T,2,1,0> zyx, bgr, pts;
340        MagicVec3<T,2,1,1> zyy, bgg, ptt;
341        MagicVec3<T,2,1,2> zyz, bgb, ptp;
342        MagicVec3<T,2,2,0> zzx, bbr, pps;
343        MagicVec3<T,2,2,1> zzy, bbg, ppt;
344        MagicVec3<T,2,2,2> zzz, bbb, ppp;
345        MagicVec4<T,0,0,0,0> xxxx, rrrr, ssss;
346        MagicVec4<T,0,0,0,1> xxxy, rrrg, ssst;
347        MagicVec4<T,0,0,0,2> xxxz, rrrb, sssp;
348        MagicVec4<T,0,0,1,0> xxyx, rrgr, ssts;
349        MagicVec4<T,0,0,1,1> xxyy, rrgg, sstt;
350        MagicVec4<T,0,0,1,2> xxyz, rrgb, sstp;
351        MagicVec4<T,0,0,2,0> xxzx, rrbr, ssps;
352        MagicVec4<T,0,0,2,1> xxzy, rrbg, sspt;
353        MagicVec4<T,0,0,2,2> xxzz, rrbb, sspp;
354        MagicVec4<T,0,1,0,0> xyxx, rgrr, stss;
355        MagicVec4<T,0,1,0,1> xyxy, rgrg, stst;
356        MagicVec4<T,0,1,0,2> xyxz, rgrb, stsp;
357        MagicVec4<T,0,1,1,0> xyyx, rggr, stts;
358        MagicVec4<T,0,1,1,1> xyyy, rggg, sttt;
359        MagicVec4<T,0,1,1,2> xyyz, rggb, sttp;
360        MagicVec4<T,0,1,2,0> xyzx, rgbr, stps;
361        MagicVec4<T,0,1,2,1> xyzy, rgbg, stpt;
362        MagicVec4<T,0,1,2,2> xyzz, rgbb, stpp;
363        MagicVec4<T,0,2,0,0> xzxx, rbrr, spss;
364        MagicVec4<T,0,2,0,1> xzxy, rbrg, spst;
365        MagicVec4<T,0,2,0,2> xzxz, rbrb, spsp;
366        MagicVec4<T,0,2,1,0> xzyx, rbgr, spts;
367        MagicVec4<T,0,2,1,1> xzyy, rbgg, sptt;
368        MagicVec4<T,0,2,1,2> xzyz, rbgb, sptp;
369        MagicVec4<T,0,2,2,0> xzzx, rbbr, spps;
370        MagicVec4<T,0,2,2,1> xzzy, rbbg, sppt;
371        MagicVec4<T,0,2,2,2> xzzz, rbbb, sppp;
372        MagicVec4<T,1,0,0,0> yxxx, grrr, tsss;
373        MagicVec4<T,1,0,0,1> yxxy, grrg, tsst;
374        MagicVec4<T,1,0,0,2> yxxz, grrb, tssp;
375        MagicVec4<T,1,0,1,0> yxyx, grgr, tsts;
376        MagicVec4<T,1,0,1,1> yxyy, grgg, tstt;
377        MagicVec4<T,1,0,1,2> yxyz, grgb, tstp;
378        MagicVec4<T,1,0,2,0> yxzx, grbr, tsps;
379        MagicVec4<T,1,0,2,1> yxzy, grbg, tspt;
380        MagicVec4<T,1,0,2,2> yxzz, grbb, tspp;
381        MagicVec4<T,1,1,0,0> yyxx, ggrr, ttss;
382        MagicVec4<T,1,1,0,1> yyxy, ggrg, ttst;
383        MagicVec4<T,1,1,0,2> yyxz, ggrb, ttsp;
384        MagicVec4<T,1,1,1,0> yyyx, gggr, ttts;
385        MagicVec4<T,1,1,1,1> yyyy, gggg, tttt;
386        MagicVec4<T,1,1,1,2> yyyz, gggb, tttp;
387        MagicVec4<T,1,1,2,0> yyzx, ggbr, ttps;
388        MagicVec4<T,1,1,2,1> yyzy, ggbg, ttpt;
389        MagicVec4<T,1,1,2,2> yyzz, ggbb, ttpp;
390        MagicVec4<T,1,2,0,0> yzxx, gbrr, tpss;
391        MagicVec4<T,1,2,0,1> yzxy, gbrg, tpst;
392        MagicVec4<T,1,2,0,2> yzxz, gbrb, tpsp;
393        MagicVec4<T,1,2,1,0> yzyx, gbgr, tpts;
394        MagicVec4<T,1,2,1,1> yzyy, gbgg, tptt;
395        MagicVec4<T,1,2,1,2> yzyz, gbgb, tptp;
396        MagicVec4<T,1,2,2,0> yzzx, gbbr, tpps;
397        MagicVec4<T,1,2,2,1> yzzy, gbbg, tppt;
398        MagicVec4<T,1,2,2,2> yzzz, gbbb, tppp;
399        MagicVec4<T,2,0,0,0> zxxx, brrr, psss;
400        MagicVec4<T,2,0,0,1> zxxy, brrg, psst;
401        MagicVec4<T,2,0,0,2> zxxz, brrb, pssp;
402        MagicVec4<T,2,0,1,0> zxyx, brgr, psts;
403        MagicVec4<T,2,0,1,1> zxyy, brgg, pstt;
404        MagicVec4<T,2,0,1,2> zxyz, brgb, pstp;
405        MagicVec4<T,2,0,2,0> zxzx, brbr, psps;
406        MagicVec4<T,2,0,2,1> zxzy, brbg, pspt;
407        MagicVec4<T,2,0,2,2> zxzz, brbb, pspp;
408        MagicVec4<T,2,1,0,0> zyxx, bgrr, ptss;
409        MagicVec4<T,2,1,0,1> zyxy, bgrg, ptst;
410        MagicVec4<T,2,1,0,2> zyxz, bgrb, ptsp;
411        MagicVec4<T,2,1,1,0> zyyx, bggr, ptts;
412        MagicVec4<T,2,1,1,1> zyyy, bggg, pttt;
413        MagicVec4<T,2,1,1,2> zyyz, bggb, pttp;
414        MagicVec4<T,2,1,2,0> zyzx, bgbr, ptps;
415        MagicVec4<T,2,1,2,1> zyzy, bgbg, ptpt;
416        MagicVec4<T,2,1,2,2> zyzz, bgbb, ptpp;
417        MagicVec4<T,2,2,0,0> zzxx, bbrr, ppss;
418        MagicVec4<T,2,2,0,1> zzxy, bbrg, ppst;
419        MagicVec4<T,2,2,0,2> zzxz, bbrb, ppsp;
420        MagicVec4<T,2,2,1,0> zzyx, bbgr, ppts;
421        MagicVec4<T,2,2,1,1> zzyy, bbgg, pptt;
422        MagicVec4<T,2,2,1,2> zzyz, bbgb, pptp;
423        MagicVec4<T,2,2,2,0> zzzx, bbbr, ppps;
424        MagicVec4<T,2,2,2,1> zzzy, bbbg, pppt;
425        MagicVec4<T,2,2,2,2> zzzz, bbbb, pppp;
426    };
427};
428
429/*
430 * 4-element vectors
431 */
432
433template <typename T> struct Vec4
434{
435    typedef Vec4<T> type_t;
436
437    inline Vec4() { }
438    explicit inline Vec4(T val) : x(val), y(val), z(val), w(val) { }
439    inline Vec4(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w) { }
440    inline Vec4(Vec2<T> _xy, T _z, T _w) : x(_xy.x), y(_xy.y), z(_z), w(_w) { }
441    inline Vec4(T _x, Vec2<T> _yz, T _w) : x(_x), y(_yz.x), z(_yz.y), w(_w) { }
442    inline Vec4(T _x, T _y, Vec2<T> _zw) : x(_x), y(_y), z(_zw.x), w(_zw.y) { }
443    inline Vec4(Vec2<T> _xy, Vec2<T> _zw) : x(_xy.x), y(_xy.y), z(_zw.x), w(_zw.y) { }
444    inline Vec4(Vec3<T> _xyz, T _w) : x(_xyz.x), y(_xyz.y), z(_xyz.z), w(_w) { }
445    inline Vec4(T _x, Vec3<T> _yzw) : x(_x), y(_yzw.x), z(_yzw.y), w(_yzw.z) { }
446
447    template<int I, int J, int K, int L>
448    inline Vec4(MagicVec4<T, I, J, K, L> const &v)
449      : x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]), w(v.ptr[L]) {}
450
451    template<typename U, int I, int J, int K, int L>
452    explicit inline Vec4(MagicVec4<U, I, J, K, L> const &v)
453      : x(v.ptr[I]), y(v.ptr[J]), z(v.ptr[K]), w(v.ptr[L]) {}
454
455    MEMBER_OPS()
456    OTHER_MEMBER_OPS(Vec4)
457
458#if !defined __ANDROID__
459    template<typename U>
460    friend std::ostream &operator<<(std::ostream &stream, Vec4<U> const &v);
461#endif
462
463    union
464    {
465        struct { T x, y, z, w; };
466        struct { T r, g, b, a; };
467        struct { T s, t, p, q; };
468
469        MagicVec2<T,0,0> xx, rr, ss;
470        MagicVec2<T,0,1> xy, rg, st;
471        MagicVec2<T,0,2> xz, rb, sp;
472        MagicVec2<T,0,3> xw, ra, sq;
473        MagicVec2<T,1,0> yx, gr, ts;
474        MagicVec2<T,1,1> yy, gg, tt;
475        MagicVec2<T,1,2> yz, gb, tp;
476        MagicVec2<T,1,3> yw, ga, tq;
477        MagicVec2<T,2,0> zx, br, ps;
478        MagicVec2<T,2,1> zy, bg, pt;
479        MagicVec2<T,2,2> zz, bb, pp;
480        MagicVec2<T,2,3> zw, ba, pq;
481        MagicVec2<T,3,0> wx, ar, qs;
482        MagicVec2<T,3,1> wy, ag, qt;
483        MagicVec2<T,3,2> wz, ab, qp;
484        MagicVec2<T,3,3> ww, aa, qq;
485        MagicVec3<T,0,0,0> xxx, rrr, sss;
486        MagicVec3<T,0,0,1> xxy, rrg, sst;
487        MagicVec3<T,0,0,2> xxz, rrb, ssp;
488        MagicVec3<T,0,0,3> xxw, rra, ssq;
489        MagicVec3<T,0,1,0> xyx, rgr, sts;
490        MagicVec3<T,0,1,1> xyy, rgg, stt;
491        MagicVec3<T,0,1,2> xyz, rgb, stp;
492        MagicVec3<T,0,1,3> xyw, rga, stq;
493        MagicVec3<T,0,2,0> xzx, rbr, sps;
494        MagicVec3<T,0,2,1> xzy, rbg, spt;
495        MagicVec3<T,0,2,2> xzz, rbb, spp;
496        MagicVec3<T,0,2,3> xzw, rba, spq;
497        MagicVec3<T,0,3,0> xwx, rar, sqs;
498        MagicVec3<T,0,3,1> xwy, rag, sqt;
499        MagicVec3<T,0,3,2> xwz, rab, sqp;
500        MagicVec3<T,0,3,3> xww, raa, sqq;
501        MagicVec3<T,1,0,0> yxx, grr, tss;
502        MagicVec3<T,1,0,1> yxy, grg, tst;
503        MagicVec3<T,1,0,2> yxz, grb, tsp;
504        MagicVec3<T,1,0,3> yxw, gra, tsq;
505        MagicVec3<T,1,1,0> yyx, ggr, tts;
506        MagicVec3<T,1,1,1> yyy, ggg, ttt;
507        MagicVec3<T,1,1,2> yyz, ggb, ttp;
508        MagicVec3<T,1,1,3> yyw, gga, ttq;
509        MagicVec3<T,1,2,0> yzx, gbr, tps;
510        MagicVec3<T,1,2,1> yzy, gbg, tpt;
511        MagicVec3<T,1,2,2> yzz, gbb, tpp;
512        MagicVec3<T,1,2,3> yzw, gba, tpq;
513        MagicVec3<T,1,3,0> ywx, gar, tqs;
514        MagicVec3<T,1,3,1> ywy, gag, tqt;
515        MagicVec3<T,1,3,2> ywz, gab, tqp;
516        MagicVec3<T,1,3,3> yww, gaa, tqq;
517        MagicVec3<T,2,0,0> zxx, brr, pss;
518        MagicVec3<T,2,0,1> zxy, brg, pst;
519        MagicVec3<T,2,0,2> zxz, brb, psp;
520        MagicVec3<T,2,0,3> zxw, bra, psq;
521        MagicVec3<T,2,1,0> zyx, bgr, pts;
522        MagicVec3<T,2,1,1> zyy, bgg, ptt;
523        MagicVec3<T,2,1,2> zyz, bgb, ptp;
524        MagicVec3<T,2,1,3> zyw, bga, ptq;
525        MagicVec3<T,2,2,0> zzx, bbr, pps;
526        MagicVec3<T,2,2,1> zzy, bbg, ppt;
527        MagicVec3<T,2,2,2> zzz, bbb, ppp;
528        MagicVec3<T,2,2,3> zzw, bba, ppq;
529        MagicVec3<T,2,3,0> zwx, bar, pqs;
530        MagicVec3<T,2,3,1> zwy, bag, pqt;
531        MagicVec3<T,2,3,2> zwz, bab, pqp;
532        MagicVec3<T,2,3,3> zww, baa, pqq;
533        MagicVec3<T,3,0,0> wxx, arr, qss;
534        MagicVec3<T,3,0,1> wxy, arg, qst;
535        MagicVec3<T,3,0,2> wxz, arb, qsp;
536        MagicVec3<T,3,0,3> wxw, ara, qsq;
537        MagicVec3<T,3,1,0> wyx, agr, qts;
538        MagicVec3<T,3,1,1> wyy, agg, qtt;
539        MagicVec3<T,3,1,2> wyz, agb, qtp;
540        MagicVec3<T,3,1,3> wyw, aga, qtq;
541        MagicVec3<T,3,2,0> wzx, abr, qps;
542        MagicVec3<T,3,2,1> wzy, abg, qpt;
543        MagicVec3<T,3,2,2> wzz, abb, qpp;
544        MagicVec3<T,3,2,3> wzw, aba, qpq;
545        MagicVec3<T,3,3,0> wwx, aar, qqs;
546        MagicVec3<T,3,3,1> wwy, aag, qqt;
547        MagicVec3<T,3,3,2> wwz, aab, qqp;
548        MagicVec3<T,3,3,3> www, aaa, qqq;
549        MagicVec4<T,0,0,0,0> xxxx, rrrr, ssss;
550        MagicVec4<T,0,0,0,1> xxxy, rrrg, ssst;
551        MagicVec4<T,0,0,0,2> xxxz, rrrb, sssp;
552        MagicVec4<T,0,0,0,3> xxxw, rrra, sssq;
553        MagicVec4<T,0,0,1,0> xxyx, rrgr, ssts;
554        MagicVec4<T,0,0,1,1> xxyy, rrgg, sstt;
555        MagicVec4<T,0,0,1,2> xxyz, rrgb, sstp;
556        MagicVec4<T,0,0,1,3> xxyw, rrga, sstq;
557        MagicVec4<T,0,0,2,0> xxzx, rrbr, ssps;
558        MagicVec4<T,0,0,2,1> xxzy, rrbg, sspt;
559        MagicVec4<T,0,0,2,2> xxzz, rrbb, sspp;
560        MagicVec4<T,0,0,2,3> xxzw, rrba, sspq;
561        MagicVec4<T,0,0,3,0> xxwx, rrar, ssqs;
562        MagicVec4<T,0,0,3,1> xxwy, rrag, ssqt;
563        MagicVec4<T,0,0,3,2> xxwz, rrab, ssqp;
564        MagicVec4<T,0,0,3,3> xxww, rraa, ssqq;
565        MagicVec4<T,0,1,0,0> xyxx, rgrr, stss;
566        MagicVec4<T,0,1,0,1> xyxy, rgrg, stst;
567        MagicVec4<T,0,1,0,2> xyxz, rgrb, stsp;
568        MagicVec4<T,0,1,0,3> xyxw, rgra, stsq;
569        MagicVec4<T,0,1,1,0> xyyx, rggr, stts;
570        MagicVec4<T,0,1,1,1> xyyy, rggg, sttt;
571        MagicVec4<T,0,1,1,2> xyyz, rggb, sttp;
572        MagicVec4<T,0,1,1,3> xyyw, rgga, sttq;
573        MagicVec4<T,0,1,2,0> xyzx, rgbr, stps;
574        MagicVec4<T,0,1,2,1> xyzy, rgbg, stpt;
575        MagicVec4<T,0,1,2,2> xyzz, rgbb, stpp;
576        MagicVec4<T,0,1,2,3> xyzw, rgba, stpq;
577        MagicVec4<T,0,1,3,0> xywx, rgar, stqs;
578        MagicVec4<T,0,1,3,1> xywy, rgag, stqt;
579        MagicVec4<T,0,1,3,2> xywz, rgab, stqp;
580        MagicVec4<T,0,1,3,3> xyww, rgaa, stqq;
581        MagicVec4<T,0,2,0,0> xzxx, rbrr, spss;
582        MagicVec4<T,0,2,0,1> xzxy, rbrg, spst;
583        MagicVec4<T,0,2,0,2> xzxz, rbrb, spsp;
584        MagicVec4<T,0,2,0,3> xzxw, rbra, spsq;
585        MagicVec4<T,0,2,1,0> xzyx, rbgr, spts;
586        MagicVec4<T,0,2,1,1> xzyy, rbgg, sptt;
587        MagicVec4<T,0,2,1,2> xzyz, rbgb, sptp;
588        MagicVec4<T,0,2,1,3> xzyw, rbga, sptq;
589        MagicVec4<T,0,2,2,0> xzzx, rbbr, spps;
590        MagicVec4<T,0,2,2,1> xzzy, rbbg, sppt;
591        MagicVec4<T,0,2,2,2> xzzz, rbbb, sppp;
592        MagicVec4<T,0,2,2,3> xzzw, rbba, sppq;
593        MagicVec4<T,0,2,3,0> xzwx, rbar, spqs;
594        MagicVec4<T,0,2,3,1> xzwy, rbag, spqt;
595        MagicVec4<T,0,2,3,2> xzwz, rbab, spqp;
596        MagicVec4<T,0,2,3,3> xzww, rbaa, spqq;
597        MagicVec4<T,0,3,0,0> xwxx, rarr, sqss;
598        MagicVec4<T,0,3,0,1> xwxy, rarg, sqst;
599        MagicVec4<T,0,3,0,2> xwxz, rarb, sqsp;
600        MagicVec4<T,0,3,0,3> xwxw, rara, sqsq;
601        MagicVec4<T,0,3,1,0> xwyx, ragr, sqts;
602        MagicVec4<T,0,3,1,1> xwyy, ragg, sqtt;
603        MagicVec4<T,0,3,1,2> xwyz, ragb, sqtp;
604        MagicVec4<T,0,3,1,3> xwyw, raga, sqtq;
605        MagicVec4<T,0,3,2,0> xwzx, rabr, sqps;
606        MagicVec4<T,0,3,2,1> xwzy, rabg, sqpt;
607        MagicVec4<T,0,3,2,2> xwzz, rabb, sqpp;
608        MagicVec4<T,0,3,2,3> xwzw, raba, sqpq;
609        MagicVec4<T,0,3,3,0> xwwx, raar, sqqs;
610        MagicVec4<T,0,3,3,1> xwwy, raag, sqqt;
611        MagicVec4<T,0,3,3,2> xwwz, raab, sqqp;
612        MagicVec4<T,0,3,3,3> xwww, raaa, sqqq;
613        MagicVec4<T,1,0,0,0> yxxx, grrr, tsss;
614        MagicVec4<T,1,0,0,1> yxxy, grrg, tsst;
615        MagicVec4<T,1,0,0,2> yxxz, grrb, tssp;
616        MagicVec4<T,1,0,0,3> yxxw, grra, tssq;
617        MagicVec4<T,1,0,1,0> yxyx, grgr, tsts;
618        MagicVec4<T,1,0,1,1> yxyy, grgg, tstt;
619        MagicVec4<T,1,0,1,2> yxyz, grgb, tstp;
620        MagicVec4<T,1,0,1,3> yxyw, grga, tstq;
621        MagicVec4<T,1,0,2,0> yxzx, grbr, tsps;
622        MagicVec4<T,1,0,2,1> yxzy, grbg, tspt;
623        MagicVec4<T,1,0,2,2> yxzz, grbb, tspp;
624        MagicVec4<T,1,0,2,3> yxzw, grba, tspq;
625        MagicVec4<T,1,0,3,0> yxwx, grar, tsqs;
626        MagicVec4<T,1,0,3,1> yxwy, grag, tsqt;
627        MagicVec4<T,1,0,3,2> yxwz, grab, tsqp;
628        MagicVec4<T,1,0,3,3> yxww, graa, tsqq;
629        MagicVec4<T,1,1,0,0> yyxx, ggrr, ttss;
630        MagicVec4<T,1,1,0,1> yyxy, ggrg, ttst;
631        MagicVec4<T,1,1,0,2> yyxz, ggrb, ttsp;
632        MagicVec4<T,1,1,0,3> yyxw, ggra, ttsq;
633        MagicVec4<T,1,1,1,0> yyyx, gggr, ttts;
634        MagicVec4<T,1,1,1,1> yyyy, gggg, tttt;
635        MagicVec4<T,1,1,1,2> yyyz, gggb, tttp;
636        MagicVec4<T,1,1,1,3> yyyw, ggga, tttq;
637        MagicVec4<T,1,1,2,0> yyzx, ggbr, ttps;
638        MagicVec4<T,1,1,2,1> yyzy, ggbg, ttpt;
639        MagicVec4<T,1,1,2,2> yyzz, ggbb, ttpp;
640        MagicVec4<T,1,1,2,3> yyzw, ggba, ttpq;
641        MagicVec4<T,1,1,3,0> yywx, ggar, ttqs;
642        MagicVec4<T,1,1,3,1> yywy, ggag, ttqt;
643        MagicVec4<T,1,1,3,2> yywz, ggab, ttqp;
644        MagicVec4<T,1,1,3,3> yyww, ggaa, ttqq;
645        MagicVec4<T,1,2,0,0> yzxx, gbrr, tpss;
646        MagicVec4<T,1,2,0,1> yzxy, gbrg, tpst;
647        MagicVec4<T,1,2,0,2> yzxz, gbrb, tpsp;
648        MagicVec4<T,1,2,0,3> yzxw, gbra, tpsq;
649        MagicVec4<T,1,2,1,0> yzyx, gbgr, tpts;
650        MagicVec4<T,1,2,1,1> yzyy, gbgg, tptt;
651        MagicVec4<T,1,2,1,2> yzyz, gbgb, tptp;
652        MagicVec4<T,1,2,1,3> yzyw, gbga, tptq;
653        MagicVec4<T,1,2,2,0> yzzx, gbbr, tpps;
654        MagicVec4<T,1,2,2,1> yzzy, gbbg, tppt;
655        MagicVec4<T,1,2,2,2> yzzz, gbbb, tppp;
656        MagicVec4<T,1,2,2,3> yzzw, gbba, tppq;
657        MagicVec4<T,1,2,3,0> yzwx, gbar, tpqs;
658        MagicVec4<T,1,2,3,1> yzwy, gbag, tpqt;
659        MagicVec4<T,1,2,3,2> yzwz, gbab, tpqp;
660        MagicVec4<T,1,2,3,3> yzww, gbaa, tpqq;
661        MagicVec4<T,1,3,0,0> ywxx, garr, tqss;
662        MagicVec4<T,1,3,0,1> ywxy, garg, tqst;
663        MagicVec4<T,1,3,0,2> ywxz, garb, tqsp;
664        MagicVec4<T,1,3,0,3> ywxw, gara, tqsq;
665        MagicVec4<T,1,3,1,0> ywyx, gagr, tqts;
666        MagicVec4<T,1,3,1,1> ywyy, gagg, tqtt;
667        MagicVec4<T,1,3,1,2> ywyz, gagb, tqtp;
668        MagicVec4<T,1,3,1,3> ywyw, gaga, tqtq;
669        MagicVec4<T,1,3,2,0> ywzx, gabr, tqps;
670        MagicVec4<T,1,3,2,1> ywzy, gabg, tqpt;
671        MagicVec4<T,1,3,2,2> ywzz, gabb, tqpp;
672        MagicVec4<T,1,3,2,3> ywzw, gaba, tqpq;
673        MagicVec4<T,1,3,3,0> ywwx, gaar, tqqs;
674        MagicVec4<T,1,3,3,1> ywwy, gaag, tqqt;
675        MagicVec4<T,1,3,3,2> ywwz, gaab, tqqp;
676        MagicVec4<T,1,3,3,3> ywww, gaaa, tqqq;
677        MagicVec4<T,2,0,0,0> zxxx, brrr, psss;
678        MagicVec4<T,2,0,0,1> zxxy, brrg, psst;
679        MagicVec4<T,2,0,0,2> zxxz, brrb, pssp;
680        MagicVec4<T,2,0,0,3> zxxw, brra, pssq;
681        MagicVec4<T,2,0,1,0> zxyx, brgr, psts;
682        MagicVec4<T,2,0,1,1> zxyy, brgg, pstt;
683        MagicVec4<T,2,0,1,2> zxyz, brgb, pstp;
684        MagicVec4<T,2,0,1,3> zxyw, brga, pstq;
685        MagicVec4<T,2,0,2,0> zxzx, brbr, psps;
686        MagicVec4<T,2,0,2,1> zxzy, brbg, pspt;
687        MagicVec4<T,2,0,2,2> zxzz, brbb, pspp;
688        MagicVec4<T,2,0,2,3> zxzw, brba, pspq;
689        MagicVec4<T,2,0,3,0> zxwx, brar, psqs;
690        MagicVec4<T,2,0,3,1> zxwy, brag, psqt;
691        MagicVec4<T,2,0,3,2> zxwz, brab, psqp;
692        MagicVec4<T,2,0,3,3> zxww, braa, psqq;
693        MagicVec4<T,2,1,0,0> zyxx, bgrr, ptss;
694        MagicVec4<T,2,1,0,1> zyxy, bgrg, ptst;
695        MagicVec4<T,2,1,0,2> zyxz, bgrb, ptsp;
696        MagicVec4<T,2,1,0,3> zyxw, bgra, ptsq;
697        MagicVec4<T,2,1,1,0> zyyx, bggr, ptts;
698        MagicVec4<T,2,1,1,1> zyyy, bggg, pttt;
699        MagicVec4<T,2,1,1,2> zyyz, bggb, pttp;
700        MagicVec4<T,2,1,1,3> zyyw, bgga, pttq;
701        MagicVec4<T,2,1,2,0> zyzx, bgbr, ptps;
702        MagicVec4<T,2,1,2,1> zyzy, bgbg, ptpt;
703        MagicVec4<T,2,1,2,2> zyzz, bgbb, ptpp;
704        MagicVec4<T,2,1,2,3> zyzw, bgba, ptpq;
705        MagicVec4<T,2,1,3,0> zywx, bgar, ptqs;
706        MagicVec4<T,2,1,3,1> zywy, bgag, ptqt;
707        MagicVec4<T,2,1,3,2> zywz, bgab, ptqp;
708        MagicVec4<T,2,1,3,3> zyww, bgaa, ptqq;
709        MagicVec4<T,2,2,0,0> zzxx, bbrr, ppss;
710        MagicVec4<T,2,2,0,1> zzxy, bbrg, ppst;
711        MagicVec4<T,2,2,0,2> zzxz, bbrb, ppsp;
712        MagicVec4<T,2,2,0,3> zzxw, bbra, ppsq;
713        MagicVec4<T,2,2,1,0> zzyx, bbgr, ppts;
714        MagicVec4<T,2,2,1,1> zzyy, bbgg, pptt;
715        MagicVec4<T,2,2,1,2> zzyz, bbgb, pptp;
716        MagicVec4<T,2,2,1,3> zzyw, bbga, pptq;
717        MagicVec4<T,2,2,2,0> zzzx, bbbr, ppps;
718        MagicVec4<T,2,2,2,1> zzzy, bbbg, pppt;
719        MagicVec4<T,2,2,2,2> zzzz, bbbb, pppp;
720        MagicVec4<T,2,2,2,3> zzzw, bbba, pppq;
721        MagicVec4<T,2,2,3,0> zzwx, bbar, ppqs;
722        MagicVec4<T,2,2,3,1> zzwy, bbag, ppqt;
723        MagicVec4<T,2,2,3,2> zzwz, bbab, ppqp;
724        MagicVec4<T,2,2,3,3> zzww, bbaa, ppqq;
725        MagicVec4<T,2,3,0,0> zwxx, barr, pqss;
726        MagicVec4<T,2,3,0,1> zwxy, barg, pqst;
727        MagicVec4<T,2,3,0,2> zwxz, barb, pqsp;
728        MagicVec4<T,2,3,0,3> zwxw, bara, pqsq;
729        MagicVec4<T,2,3,1,0> zwyx, bagr, pqts;
730        MagicVec4<T,2,3,1,1> zwyy, bagg, pqtt;
731        MagicVec4<T,2,3,1,2> zwyz, bagb, pqtp;
732        MagicVec4<T,2,3,1,3> zwyw, baga, pqtq;
733        MagicVec4<T,2,3,2,0> zwzx, babr, pqps;
734        MagicVec4<T,2,3,2,1> zwzy, babg, pqpt;
735        MagicVec4<T,2,3,2,2> zwzz, babb, pqpp;
736        MagicVec4<T,2,3,2,3> zwzw, baba, pqpq;
737        MagicVec4<T,2,3,3,0> zwwx, baar, pqqs;
738        MagicVec4<T,2,3,3,1> zwwy, baag, pqqt;
739        MagicVec4<T,2,3,3,2> zwwz, baab, pqqp;
740        MagicVec4<T,2,3,3,3> zwww, baaa, pqqq;
741        MagicVec4<T,3,0,0,0> wxxx, arrr, qsss;
742        MagicVec4<T,3,0,0,1> wxxy, arrg, qsst;
743        MagicVec4<T,3,0,0,2> wxxz, arrb, qssp;
744        MagicVec4<T,3,0,0,3> wxxw, arra, qssq;
745        MagicVec4<T,3,0,1,0> wxyx, argr, qsts;
746        MagicVec4<T,3,0,1,1> wxyy, argg, qstt;
747        MagicVec4<T,3,0,1,2> wxyz, argb, qstp;
748        MagicVec4<T,3,0,1,3> wxyw, arga, qstq;
749        MagicVec4<T,3,0,2,0> wxzx, arbr, qsps;
750        MagicVec4<T,3,0,2,1> wxzy, arbg, qspt;
751        MagicVec4<T,3,0,2,2> wxzz, arbb, qspp;
752        MagicVec4<T,3,0,2,3> wxzw, arba, qspq;
753        MagicVec4<T,3,0,3,0> wxwx, arar, qsqs;
754        MagicVec4<T,3,0,3,1> wxwy, arag, qsqt;
755        MagicVec4<T,3,0,3,2> wxwz, arab, qsqp;
756        MagicVec4<T,3,0,3,3> wxww, araa, qsqq;
757        MagicVec4<T,3,1,0,0> wyxx, agrr, qtss;
758        MagicVec4<T,3,1,0,1> wyxy, agrg, qtst;
759        MagicVec4<T,3,1,0,2> wyxz, agrb, qtsp;
760        MagicVec4<T,3,1,0,3> wyxw, agra, qtsq;
761        MagicVec4<T,3,1,1,0> wyyx, aggr, qtts;
762        MagicVec4<T,3,1,1,1> wyyy, aggg, qttt;
763        MagicVec4<T,3,1,1,2> wyyz, aggb, qttp;
764        MagicVec4<T,3,1,1,3> wyyw, agga, qttq;
765        MagicVec4<T,3,1,2,0> wyzx, agbr, qtps;
766        MagicVec4<T,3,1,2,1> wyzy, agbg, qtpt;
767        MagicVec4<T,3,1,2,2> wyzz, agbb, qtpp;
768        MagicVec4<T,3,1,2,3> wyzw, agba, qtpq;
769        MagicVec4<T,3,1,3,0> wywx, agar, qtqs;
770        MagicVec4<T,3,1,3,1> wywy, agag, qtqt;
771        MagicVec4<T,3,1,3,2> wywz, agab, qtqp;
772        MagicVec4<T,3,1,3,3> wyww, agaa, qtqq;
773        MagicVec4<T,3,2,0,0> wzxx, abrr, qpss;
774        MagicVec4<T,3,2,0,1> wzxy, abrg, qpst;
775        MagicVec4<T,3,2,0,2> wzxz, abrb, qpsp;
776        MagicVec4<T,3,2,0,3> wzxw, abra, qpsq;
777        MagicVec4<T,3,2,1,0> wzyx, abgr, qpts;
778        MagicVec4<T,3,2,1,1> wzyy, abgg, qptt;
779        MagicVec4<T,3,2,1,2> wzyz, abgb, qptp;
780        MagicVec4<T,3,2,1,3> wzyw, abga, qptq;
781        MagicVec4<T,3,2,2,0> wzzx, abbr, qpps;
782        MagicVec4<T,3,2,2,1> wzzy, abbg, qppt;
783        MagicVec4<T,3,2,2,2> wzzz, abbb, qppp;
784        MagicVec4<T,3,2,2,3> wzzw, abba, qppq;
785        MagicVec4<T,3,2,3,0> wzwx, abar, qpqs;
786        MagicVec4<T,3,2,3,1> wzwy, abag, qpqt;
787        MagicVec4<T,3,2,3,2> wzwz, abab, qpqp;
788        MagicVec4<T,3,2,3,3> wzww, abaa, qpqq;
789        MagicVec4<T,3,3,0,0> wwxx, aarr, qqss;
790        MagicVec4<T,3,3,0,1> wwxy, aarg, qqst;
791        MagicVec4<T,3,3,0,2> wwxz, aarb, qqsp;
792        MagicVec4<T,3,3,0,3> wwxw, aara, qqsq;
793        MagicVec4<T,3,3,1,0> wwyx, aagr, qqts;
794        MagicVec4<T,3,3,1,1> wwyy, aagg, qqtt;
795        MagicVec4<T,3,3,1,2> wwyz, aagb, qqtp;
796        MagicVec4<T,3,3,1,3> wwyw, aaga, qqtq;
797        MagicVec4<T,3,3,2,0> wwzx, aabr, qqps;
798        MagicVec4<T,3,3,2,1> wwzy, aabg, qqpt;
799        MagicVec4<T,3,3,2,2> wwzz, aabb, qqpp;
800        MagicVec4<T,3,3,2,3> wwzw, aaba, qqpq;
801        MagicVec4<T,3,3,3,0> wwwx, aaar, qqqs;
802        MagicVec4<T,3,3,3,1> wwwy, aaag, qqqt;
803        MagicVec4<T,3,3,3,2> wwwz, aaab, qqqp;
804        MagicVec4<T,3,3,3,3> wwww, aaaa, qqqq;
805    };
806};
807
808/*
809 * 4-element quaternions
810 */
811
812template <typename T> struct Quat
813{
814    typedef Quat<T> type_t;
815
816    inline Quat() { }
817    inline Quat(T val) : x(0), y(0), z(0), w(val) { }
818    inline Quat(T _x, T _y, T _z, T _w) : x(_x), y(_y), z(_z), w(_w) { }
819
820    Quat(Mat4<T> const &m);
821
822    MEMBER_OPS()
823
824    QUATERNION_OPS()
825
826#if !defined __ANDROID__
827    template<typename U>
828    friend std::ostream &operator<<(std::ostream &stream, Quat<U> const &v);
829#endif
830
831    T x, y, z, w;
832};
833
834template<typename T>
835inline T norm(Quat<T> const &val)
836{
837    return sqlen(val);
838}
839
840template<typename T>
841static inline Quat<T> re(Quat<T> const &val)
842{
843    return ~val / norm(val);
844}
845
846template<typename T>
847static inline Quat<T> operator /(T x, Quat<T> const &y)
848{
849    return x * re(y);
850}
851
852template<typename T>
853static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)
854{
855    return x * re(y);
856}
857
858/*
859 * Common operators for all vector types, including quaternions
860 */
861
862#define VECTOR_OP(tname, op, tprefix, T) \
863    tprefix \
864    static inline tname<T> operator op(tname<T> const &a, tname<T> const &b) \
865    { \
866        tname<T> ret; \
867        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
868            ret[n] = a[n] op b[n]; \
869        return ret; \
870    } \
871    \
872    tprefix \
873    static inline tname<T> operator op##=(tname<T> &a, tname<T> const &b) \
874    { \
875        return a = a op b; \
876    }
877
878#define BOOL_OP(tname, op, op2, ret, tprefix, T) \
879    tprefix \
880    static inline bool operator op(tname<T> const &a, tname<T> const &b) \
881    { \
882        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
883            if (!(a[n] op2 b[n])) \
884                return !ret; \
885        return ret; \
886    }
887
888#define SCALAR_OP(tname, op, tprefix, T) \
889    tprefix \
890    static inline tname<T> operator op(tname<T> const &a, T const &val) \
891    { \
892        tname<T> ret; \
893        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
894            ret[n] = a[n] op val; \
895        return ret; \
896    } \
897    \
898    tprefix \
899    static inline tname<T> operator op(T const &val, tname<T> const &a) \
900    { \
901        tname<T> ret; \
902        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
903            ret[n] = a[n] op val; \
904        return ret; \
905    } \
906    \
907    tprefix \
908    static inline tname<T> operator op##=(tname<T> &a, T const &val) \
909    { \
910        return a = a op val; \
911    }
912
913#define SCALAR_PROMOTE_OP(tname, op, U) \
914    template<typename T> \
915    static inline tname<U> operator op(U const &val, tname<T> const &a) \
916    { \
917        tname<U> ret; \
918        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
919            ret[n] = val op a[n]; \
920        return ret; \
921    }
922
923#define GLOBAL_OPS(tname, tprefix, T) \
924    SCALAR_OP(tname, *, tprefix, T) \
925    SCALAR_OP(tname, /, tprefix, T) \
926    \
927    VECTOR_OP(tname, -, tprefix, T) \
928    VECTOR_OP(tname, +, tprefix, T) \
929    \
930    BOOL_OP(tname, ==, ==, true, tprefix, T) \
931    BOOL_OP(tname, !=, ==, false, tprefix, T) \
932    \
933    tprefix \
934    static inline tname<T> operator -(tname<T> const &a) \
935    { \
936        tname<T> ret; \
937        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
938            ret[n] = -a[n]; \
939        return ret; \
940    } \
941    \
942    tprefix \
943    static inline T sqlen(tname<T> const &a) \
944    { \
945        T acc = 0; \
946        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
947            acc += a[n] * a[n]; \
948        return acc; \
949    } \
950    \
951    tprefix \
952    static inline double len(tname<T> const &a) \
953    { \
954        using namespace std; \
955        return sqrt((double)sqlen(a)); \
956    } \
957    \
958    tprefix \
959    static inline T dot(tname<T> const &a, tname<T> const &b) \
960    { \
961        T ret = 0; \
962        for (size_t n = 0; n < sizeof(a) / sizeof(T); n++) \
963            ret += a[n] * b[n]; \
964        return ret; \
965    } \
966    \
967    tprefix \
968    static inline tname<T> normalize(tname<T> const &val) \
969    { \
970        T norm = len(val); \
971        return norm ? val / norm : val * (T)0; \
972    }
973
974#define GLOBAL_TEMPLATE_OPS(tname) \
975    GLOBAL_OPS(tname, template<typename T>, T)
976
977#define ALL_GLOBAL_OPS(tname, tprefix, T) \
978    VECTOR_OP(tname, *, tprefix, T) \
979    VECTOR_OP(tname, /, tprefix, T) \
980    \
981    GLOBAL_OPS(tname, tprefix, T) \
982    \
983    BOOL_OP(tname, <=, <=, true, tprefix, T) \
984    BOOL_OP(tname, >=, >=, true, tprefix, T) \
985    BOOL_OP(tname, <, <, true, tprefix, T) \
986    BOOL_OP(tname, >, >, true, tprefix, T)
987
988/* FIXME: a few problems need to be fixed before we can use "half" here. It
989 * will probably never work until we switch to C++11 because it's not really
990 * a POD class. */
991#define GLOBAL_TYPED_OPS(tname) \
992    ALL_GLOBAL_OPS(tname, , float) \
993    ALL_GLOBAL_OPS(tname, , double) \
994    ALL_GLOBAL_OPS(tname, , int8_t) \
995    ALL_GLOBAL_OPS(tname, , uint8_t) \
996    ALL_GLOBAL_OPS(tname, , int16_t) \
997    ALL_GLOBAL_OPS(tname, , uint16_t) \
998    ALL_GLOBAL_OPS(tname, , int32_t) \
999    ALL_GLOBAL_OPS(tname, , uint32_t) \
1000    ALL_GLOBAL_OPS(tname, , int64_t) \
1001    ALL_GLOBAL_OPS(tname, , uint64_t)
1002
1003GLOBAL_TEMPLATE_OPS(Cmplx)
1004GLOBAL_TEMPLATE_OPS(Quat)
1005
1006GLOBAL_TYPED_OPS(Vec2)
1007GLOBAL_TYPED_OPS(Vec3)
1008GLOBAL_TYPED_OPS(Vec4)
1009
1010/*
1011 * Magic swizzling (part 2/2)
1012 */
1013
1014template<typename T, int I, int J>
1015inline Vec2<T> MagicVec2<T, I, J>::operator =(Vec2<T> that)
1016{
1017    ptr[I] = that.x; ptr[J] = that.y;
1018    return *this;
1019}
1020
1021template<typename T, int I, int J, int K>
1022inline Vec3<T> MagicVec3<T, I, J, K>::operator =(Vec3<T> that)
1023{
1024    ptr[I] = that.x; ptr[J] = that.y; ptr[K] = that.z;
1025    return *this;
1026}
1027
1028template<typename T, int I, int J, int K, int L>
1029inline Vec4<T> MagicVec4<T, I, J, K, L>::operator =(Vec4<T> that)
1030{
1031    ptr[I] = that.x; ptr[J] = that.y; ptr[K] = that.z; ptr[L] = that.w;
1032    return *this;
1033}
1034
1035/*
1036 * 4×4-element matrices
1037 */
1038
1039template <typename T> struct Mat4
1040{
1041    typedef Mat4<T> type_t;
1042
1043    inline Mat4() { }
1044    explicit inline Mat4(T val)
1045    {
1046        for (int j = 0; j < 4; j++)
1047            for (int i = 0; i < 4; i++)
1048                v[i][j] = (i == j) ? val : 0;
1049    }
1050    inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
1051    {
1052        v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
1053    }
1054
1055    inline Vec4<T>& operator[](int n) { return v[n]; }
1056    inline Vec4<T> const& operator[](int n) const { return v[n]; }
1057
1058    T det() const;
1059    Mat4<T> invert() const;
1060
1061    /* Helpers for transformation matrices */
1062    static Mat4<T> translate(T x, T y, T z);
1063    static Mat4<T> translate(Vec3<T> v);
1064    static Mat4<T> rotate(T angle, T x, T y, T z);
1065    static Mat4<T> rotate(T angle, Vec3<T> v);
1066    static Mat4<T> rotate(Quat<T> q);
1067
1068    static inline Mat4<T> translate(Mat4<T> mat, Vec3<T> v)
1069    {
1070        return translate(v) * mat;
1071    }
1072
1073    static inline Mat4<T> rotate(Mat4<T> mat, T angle, Vec3<T> v)
1074    {
1075        return rotate(angle, v) * mat;
1076    }
1077
1078    /* Helpers for view matrices */
1079    static Mat4<T> lookat(Vec3<T> eye, Vec3<T> center, Vec3<T> up);
1080
1081    /* Helpers for projection matrices */
1082    static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
1083    static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
1084    static Mat4<T> perspective(T fov_y, T width, T height, T near, T far);
1085
1086    void printf() const;
1087
1088#if !defined __ANDROID__
1089    template<class U>
1090    friend std::ostream &operator<<(std::ostream &stream, Mat4<U> const &m);
1091#endif
1092
1093    inline Mat4<T> operator +(Mat4<T> const val) const
1094    {
1095        Mat4<T> ret;
1096        for (int j = 0; j < 4; j++)
1097            for (int i = 0; i < 4; i++)
1098                ret[i][j] = v[i][j] + val[i][j];
1099        return ret;
1100    }
1101
1102    inline Mat4<T> operator +=(Mat4<T> const val)
1103    {
1104        return *this = *this + val;
1105    }
1106
1107    inline Mat4<T> operator -(Mat4<T> const val) const
1108    {
1109        Mat4<T> ret;
1110        for (int j = 0; j < 4; j++)
1111            for (int i = 0; i < 4; i++)
1112                ret[i][j] = v[i][j] - val[i][j];
1113        return ret;
1114    }
1115
1116    inline Mat4<T> operator -=(Mat4<T> const val)
1117    {
1118        return *this = *this - val;
1119    }
1120
1121    inline Mat4<T> operator *(Mat4<T> const val) const
1122    {
1123        Mat4<T> ret;
1124        for (int j = 0; j < 4; j++)
1125            for (int i = 0; i < 4; i++)
1126            {
1127                T tmp = 0;
1128                for (int k = 0; k < 4; k++)
1129                    tmp += v[k][j] * val[i][k];
1130                ret[i][j] = tmp;
1131            }
1132        return ret;
1133    }
1134
1135    inline Mat4<T> operator *=(Mat4<T> const val)
1136    {
1137        return *this = *this * val;
1138    }
1139
1140    inline Vec4<T> operator *(Vec4<T> const val) const
1141    {
1142        Vec4<T> ret;
1143        for (int j = 0; j < 4; j++)
1144        {
1145            T tmp = 0;
1146            for (int i = 0; i < 4; i++)
1147                tmp += v[i][j] * val[i];
1148            ret[j] = tmp;
1149        }
1150        return ret;
1151    }
1152
1153    Vec4<T> v[4];
1154};
1155
1156/*
1157 * Arbitrarily-sized square matrices; for now this only supports
1158 * naive inversion and is used for the Remez inversion method.
1159 */
1160
1161template<int N, typename T> struct Mat
1162{
1163    inline Mat<N, T>() {}
1164
1165    Mat(T x)
1166    {
1167        for (int j = 0; j < N; j++)
1168            for (int i = 0; i < N; i++)
1169                if (i == j)
1170                    m[i][j] = x;
1171                else
1172                    m[i][j] = 0;
1173    }
1174
1175    /* Naive matrix inversion */
1176    Mat<N, T> inv() const
1177    {
1178        Mat a = *this, b((T)1);
1179
1180        /* Inversion method: iterate through all columns and make sure
1181         * all the terms are 1 on the diagonal and 0 everywhere else */
1182        for (int i = 0; i < N; i++)
1183        {
1184            /* If the expected coefficient is zero, add one of
1185             * the other lines. The first we meet will do. */
1186            if (!a.m[i][i])
1187            {
1188                for (int j = i + 1; j < N; j++)
1189                {
1190                    if (!a.m[i][j])
1191                        continue;
1192                    /* Add row j to row i */
1193                    for (int n = 0; n < N; n++)
1194                    {
1195                        a.m[n][i] += a.m[n][j];
1196                        b.m[n][i] += b.m[n][j];
1197                    }
1198                    break;
1199                }
1200            }
1201
1202            /* Now we know the diagonal term is non-zero. Get its inverse
1203             * and use that to nullify all other terms in the column */
1204            T x = (T)1 / a.m[i][i];
1205            for (int j = 0; j < N; j++)
1206            {
1207                if (j == i)
1208                    continue;
1209                T mul = x * a.m[i][j];
1210                for (int n = 0; n < N; n++)
1211                {
1212                    a.m[n][j] -= mul * a.m[n][i];
1213                    b.m[n][j] -= mul * b.m[n][i];
1214                }
1215            }
1216
1217            /* Finally, ensure the diagonal term is 1 */
1218            for (int n = 0; n < N; n++)
1219            {
1220                a.m[n][i] *= x;
1221                b.m[n][i] *= x;
1222            }
1223        }
1224
1225        return b;
1226    }
1227
1228    T m[N][N];
1229};
1230
1231} /* namespace lol */
1232
1233#endif // __LOL_MATH_MATRIX_H__
1234
Note: See TracBrowser for help on using the repository browser.