source: abuse/trunk/src/lol/matrix.h @ 682

Last change on this file since 682 was 682, checked in by Sam Hocevar, 8 years ago

core: rename vec2i to ivec2 and update matrix.h from Lol Engine.

  • Property svn:keywords set to Id
File size: 7.8 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_MATRIX_H__
17#define __LOL_MATRIX_H__
18
19#include <cmath>
20#if !defined __ANDROID__
21#   include <iostream>
22#endif
23
24namespace lol
25{
26
27#define VECTOR_OP(elems, op) \
28    template<typename U> \
29    inline Vec##elems<T> operator op(Vec##elems<U> const &val) const \
30    { \
31        Vec##elems<T> ret; \
32        for (int n = 0; n < elems; n++) \
33            ret[n] = (*this)[n] op val[n]; \
34        return ret; \
35    } \
36    \
37    template<typename U> \
38    inline Vec##elems<T> operator op##=(Vec##elems<U> const &val) \
39    { \
40        return *this = (*this) op val; \
41    }
42
43#define BOOL_OP(elems, op, op2, ret) \
44    inline bool operator op(Vec##elems<T> const &val) const \
45    { \
46        for (int n = 0; n < elems; n++) \
47            if (!((*this)[n] op2 val[n])) \
48                return !ret; \
49        return ret; \
50    }
51
52#define SCALAR_OP(elems, op) \
53    inline Vec##elems<T> operator op(T const &val) const \
54    { \
55        Vec##elems<T> ret; \
56        for (int n = 0; n < elems; n++) \
57            ret[n] = (*this)[n] op val; \
58        return ret; \
59    } \
60    \
61    inline Vec##elems<T> operator op##=(T const &val) \
62    { \
63        return *this = (*this) op val; \
64    }
65
66#define CAST_OP(elems, dest) \
67    inline operator Vec##dest<T>() const \
68    { \
69        Vec##dest<T> ret; \
70        for (int n = 0; n < elems && n < dest; n++) \
71            ret[n] = (*this)[n]; \
72        for (int n = elems; n < dest; n++) \
73            ret[n] = 0; \
74        return ret; \
75    }
76
77#define OPERATORS(elems) \
78    inline T& operator[](int n) { return *(&x + n); } \
79    inline T const& operator[](int n) const { return *(&x + n); } \
80    \
81    VECTOR_OP(elems, -) \
82    VECTOR_OP(elems, +) \
83    VECTOR_OP(elems, *) \
84    VECTOR_OP(elems, /) \
85    \
86    BOOL_OP(elems, ==, ==, true) \
87    BOOL_OP(elems, !=, ==, false) \
88    BOOL_OP(elems, <=, <=, true) \
89    BOOL_OP(elems, >=, >=, true) \
90    BOOL_OP(elems, <, <, true) \
91    BOOL_OP(elems, >, >, true) \
92    \
93    SCALAR_OP(elems, -) \
94    SCALAR_OP(elems, +) \
95    SCALAR_OP(elems, *) \
96    SCALAR_OP(elems, /) \
97    \
98    CAST_OP(elems, 2) \
99    CAST_OP(elems, 3) \
100    CAST_OP(elems, 4) \
101    \
102    template<typename U> \
103    inline operator Vec##elems<U>() const \
104    { \
105        Vec##elems<U> ret; \
106        for (int n = 0; n < elems; n++) \
107            ret[n] = static_cast<U>((*this)[n]); \
108        return ret; \
109    } \
110    \
111    inline Vec##elems<T> operator -() const \
112    { \
113        Vec##elems<T> ret; \
114        for (int n = 0; n < elems; n++) \
115            ret[n] = -(*this)[n]; \
116        return ret; \
117    } \
118    \
119    inline T sqlen() const \
120    { \
121        T acc = 0; \
122        for (int n = 0; n < elems; n++) \
123            acc += (*this)[n] * (*this)[n]; \
124        return acc; \
125    } \
126    \
127    inline float len() const \
128    { \
129        using namespace std; \
130        return sqrtf((float)sqlen()); \
131    }
132
133template <typename T> struct Vec2;
134template <typename T> struct Vec3;
135template <typename T> struct Vec4;
136
137template <typename T> struct Vec2
138{
139    inline Vec2() { }
140    inline Vec2(T val) { x = y = val; }
141    inline Vec2(T _x, T _y) { x = _x; y = _y; }
142
143    OPERATORS(2)
144
145#if !defined __ANDROID__
146    template<typename U>
147    friend std::ostream &operator<<(std::ostream &stream, Vec2<U> const &v);
148#endif
149
150    union { T x; T a; T i; };
151    union { T y; T b; T j; };
152};
153
154typedef Vec2<float> vec2;
155typedef Vec2<int> ivec2;
156
157template <typename T> struct Vec3
158{
159    inline Vec3() { }
160    inline Vec3(T val) { x = y = z = val; }
161    inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
162
163    OPERATORS(3)
164
165#if !defined __ANDROID__
166    template<typename U>
167    friend std::ostream &operator<<(std::ostream &stream, Vec3<U> const &v);
168#endif
169
170    union { T x; T a; T i; };
171    union { T y; T b; T j; };
172    union { T z; T c; T k; };
173};
174
175typedef Vec3<float> vec3;
176typedef Vec3<int> ivec3;
177
178template <typename T> struct Vec4
179{
180    inline Vec4() { }
181    inline Vec4(T val) { x = y = z = w = val; }
182    inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; }
183
184    OPERATORS(4)
185
186#if !defined __ANDROID__
187    template<typename U>
188    friend std::ostream &operator<<(std::ostream &stream, Vec4<U> const &v);
189#endif
190
191    union { T x; T a; T i; };
192    union { T y; T b; T j; };
193    union { T z; T c; T k; };
194    union { T w; T d; T l; };
195};
196
197typedef Vec4<float> vec4;
198typedef Vec4<int> ivec4;
199
200#define SCALAR_GLOBAL(elems, op, U) \
201    template<typename T> \
202    static inline Vec##elems<U> operator op(U const &val, \
203                                            Vec##elems<T> const &that) \
204    { \
205        Vec##elems<U> ret; \
206        for (int n = 0; n < elems; n++) \
207            ret[n] = val op that[n]; \
208        return ret; \
209    }
210
211#define SCALAR_GLOBAL2(elems, op) \
212    SCALAR_GLOBAL(elems, op, int) \
213    SCALAR_GLOBAL(elems, op, float)
214
215#define GLOBALS(elems) \
216    SCALAR_GLOBAL2(elems, -) \
217    SCALAR_GLOBAL2(elems, +) \
218    SCALAR_GLOBAL2(elems, *) \
219    SCALAR_GLOBAL2(elems, /)
220
221GLOBALS(2)
222GLOBALS(3)
223GLOBALS(4)
224
225template <typename T> struct Mat4
226{
227    inline Mat4() { }
228    inline Mat4(T val)
229    {
230        for (int j = 0; j < 4; j++)
231            for (int i = 0; i < 4; i++)
232                v[i][j] = (i == j) ? val : 0;
233    }
234    inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
235    {
236        v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
237    }
238
239    inline Vec4<T>& operator[](int n) { return v[n]; }
240    inline Vec4<T> const& operator[](int n) const { return v[n]; }
241
242    T det() const;
243    Mat4<T> invert() const;
244
245    static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
246    static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
247    static Mat4<T> perspective(T theta, T width, T height, T near, T far);
248    static Mat4<T> translate(T x, T y, T z);
249    static Mat4<T> rotate(T theta, T x, T y, T z);
250
251    void printf() const;
252
253#if !defined __ANDROID__
254    template<class U>
255    friend std::ostream &operator<<(std::ostream &stream, Mat4<U> const &m);
256#endif
257
258    inline Mat4<T> operator +(Mat4<T> const val) const
259    {
260        Mat4<T> ret;
261        for (int j = 0; j < 4; j++)
262            for (int i = 0; i < 4; i++)
263                ret[i][j] = v[i][j] + val[i][j];
264        return ret;
265    }
266
267    inline Mat4<T> operator +=(Mat4<T> const val)
268    {
269        return *this = *this + val;
270    }
271
272    inline Mat4<T> operator -(Mat4<T> const val) const
273    {
274        Mat4<T> ret;
275        for (int j = 0; j < 4; j++)
276            for (int i = 0; i < 4; i++)
277                ret[i][j] = v[i][j] - val[i][j];
278        return ret;
279    }
280
281    inline Mat4<T> operator -=(Mat4<T> const val)
282    {
283        return *this = *this - val;
284    }
285
286    inline Mat4<T> operator *(Mat4<T> const val) const
287    {
288        Mat4<T> ret;
289        for (int j = 0; j < 4; j++)
290            for (int i = 0; i < 4; i++)
291            {
292                T tmp = 0;
293                for (int k = 0; k < 4; k++)
294                    tmp += v[k][j] * val[i][k];
295                ret[i][j] = tmp;
296            }
297        return ret;
298    }
299
300    inline Mat4<T> operator *=(Mat4<T> const val)
301    {
302        return *this = *this * val;
303    }
304
305    inline Vec4<T> operator *(Vec4<T> const val) const
306    {
307        Vec4<T> ret;
308        for (int j = 0; j < 4; j++)
309        {
310            T tmp = 0;
311            for (int i = 0; i < 4; i++)
312                tmp += v[i][j] * val[i];
313            ret[j] = tmp;
314        }
315        return ret;
316    }
317
318    Vec4<T> v[4];
319};
320
321typedef Mat4<float> mat4;
322typedef Mat4<int> imat4;
323
324} /* namespace lol */
325
326#endif // __LOL_MATRIX_H__
327
Note: See TracBrowser for help on using the repository browser.