source: trunk/src/lol/math/vector.h @ 1140

Last change on this file since 1140 was 1140, checked in by sam, 11 years ago

math: fix a syntax error in vector.h due to duplicate macro declaration.

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